From 4e9e9a36ede0cd45b97e264e9910f4b24ec5d281 Mon Sep 17 00:00:00 2001 From: alpha Date: Mon, 25 Mar 2024 11:44:47 -0500 Subject: [PATCH] Improve BreakSpeed event inject for better mod compat --- .../entity/events/PlayerEvents.java | 2 +- .../entity/extensions/PlayerExtension.java | 18 ++++++++++++ .../mixin/common/BlockBehaviourMixin.java | 29 +++++-------------- .../entity/mixin/common/PlayerMixin.java | 26 ++++++++++++++--- .../entity/src/main/resources/fabric.mod.json | 1 + 5 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension.java diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/events/PlayerEvents.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/events/PlayerEvents.java index 09968c3db..3da6467e4 100644 --- a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/events/PlayerEvents.java +++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/events/PlayerEvents.java @@ -97,7 +97,7 @@ public void sendEvent() { /** * BreakSpeed is fired when a player attempts to harvest a block.
* This event is fired whenever a player attempts to harvest a block in - * {@link Player#getDestroySpeed(BlockState)}.
+ * {@link Player#getDigSpeed(BlockState, BlockPos)}.
*
* {@link #state} contains the block being broken.
* {@link #originalSpeed} contains the original speed at which the player broke the block.
diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension.java new file mode 100644 index 000000000..539d91d2d --- /dev/null +++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension.java @@ -0,0 +1,18 @@ +package io.github.fabricators_of_create.porting_lib.entity.extensions; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.state.BlockState; + +import javax.annotation.Nullable; + +public interface PlayerExtension { + default float getDigSpeed(BlockState state, @Nullable BlockPos pos) { + setDigSpeedContext(pos); + return ((Player) this).getDestroySpeed(state); + } + + default void setDigSpeedContext(@Nullable BlockPos pos) { + throw new RuntimeException("this should be overridden via mixin. what?"); + } +} diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/BlockBehaviourMixin.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/BlockBehaviourMixin.java index 2aed530b0..0f72c88c0 100644 --- a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/BlockBehaviourMixin.java +++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/BlockBehaviourMixin.java @@ -1,33 +1,20 @@ package io.github.fabricators_of_create.porting_lib.entity.mixin.common; -import io.github.fabricators_of_create.porting_lib.entity.events.PlayerEvents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - @Mixin(BlockBehaviour.class) public abstract class BlockBehaviourMixin { - @Inject(method = "getDestroyProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getDestroySpeed(Lnet/minecraft/world/level/block/state/BlockState;)F", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) - public void getDestroySpeed(BlockState state, Player player, BlockGetter level, BlockPos pos, CallbackInfoReturnable cir, float f) { - float original = player.getDestroySpeed(state); - PlayerEvents.BreakSpeed breakSpeed = new PlayerEvents.BreakSpeed(player, state, original, pos); - breakSpeed.sendEvent(); - float newSpeed = breakSpeed.getNewSpeed(); - if (newSpeed != original) { - if (f == -1.0F) { - cir.setReturnValue(0.0F); - } else { - int i = player.hasCorrectToolForDrops(state) ? 30 : 100; - cir.setReturnValue(newSpeed / f / (float) i); - } - } + @Inject(method = "getDestroyProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;hasCorrectToolForDrops(Lnet/minecraft/world/level/block/state/BlockState;)Z")) + public void getDestroySpeed(BlockState blockState, Player player, BlockGetter blockGetter, BlockPos pos, CallbackInfoReturnable cir) { + player.setDigSpeedContext(pos); } } diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/PlayerMixin.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/PlayerMixin.java index 96b64d7de..160022f1b 100644 --- a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/PlayerMixin.java +++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/PlayerMixin.java @@ -1,6 +1,7 @@ package io.github.fabricators_of_create.porting_lib.entity.mixin.common; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef; @@ -18,6 +19,8 @@ import io.github.fabricators_of_create.porting_lib.entity.events.living.LivingDamageEvent; import io.github.fabricators_of_create.porting_lib.entity.events.living.LivingHurtEvent; import io.github.fabricators_of_create.porting_lib.entity.events.player.AttackEntityEvent; +import io.github.fabricators_of_create.porting_lib.entity.extensions.PlayerExtension; +import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; @@ -26,22 +29,22 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import org.jetbrains.annotations.Nullable; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(value = Player.class, priority = 500) -public abstract class PlayerMixin extends LivingEntity { +public abstract class PlayerMixin extends LivingEntity implements PlayerExtension { protected PlayerMixin(EntityType entityType, Level level) { super(entityType, level); } @@ -152,4 +155,19 @@ private float livingDamageEvent(float value, DamageSource pDamageSource) { return 0; return event.getAmount(); } + + private final ThreadLocal pl$destroySpeedContext = new ThreadLocal<>(); + + @Override + public void setDigSpeedContext(@Nullable BlockPos pos) { + pl$destroySpeedContext.set(pos); + } + + @ModifyReturnValue(method = "getDestroySpeed", at = @At("RETURN")) + private float breakspeedEvent(float original, BlockState state) { + PlayerEvents.BreakSpeed breakSpeed = new PlayerEvents.BreakSpeed((Player) (Object) this, state, original, pl$destroySpeedContext.get()); + breakSpeed.sendEvent(); + pl$destroySpeedContext.remove(); + return breakSpeed.getNewSpeed(); + } } diff --git a/modules/entity/src/main/resources/fabric.mod.json b/modules/entity/src/main/resources/fabric.mod.json index cc38a0ec4..a425bca1d 100644 --- a/modules/entity/src/main/resources/fabric.mod.json +++ b/modules/entity/src/main/resources/fabric.mod.json @@ -17,6 +17,7 @@ "net/minecraft/class_1291": ["io/github/fabricators_of_create/porting_lib/entity/extensions/MobEffectExtensions"], "net/minecraft/class_1297": ["io/github/fabricators_of_create/porting_lib/entity/extensions/EntityExtensions"], "net/minecraft/class_1621": ["io/github/fabricators_of_create/porting_lib/entity/extensions/SlimeExtension"], + "net/minecraft/class_1657": ["io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension"], "net/minecraft/class_1688": ["io/github/fabricators_of_create/porting_lib/entity/extensions/AbstractMinecartExtensions"], "net/minecraft/class_1792": ["io/github/fabricators_of_create/porting_lib/entity/extensions/ItemExtensions"], "net/minecraft/class_1937": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LevelExtensions"]