|
26 | 26 |
|
27 | 27 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; |
28 | 28 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; |
| 29 | +import net.minecraft.server.level.ServerLevel; |
29 | 30 | import net.minecraft.world.damagesource.DamageSource; |
30 | 31 | import net.minecraft.world.entity.LivingEntity; |
| 32 | +import net.minecraft.world.item.ItemStack; |
31 | 33 | import net.minecraftforge.event.entity.living.ShieldBlockEvent; |
32 | 34 | import org.spongepowered.api.event.cause.entity.damage.DamageStepTypes; |
33 | 35 | import org.spongepowered.asm.mixin.Mixin; |
| 36 | +import org.spongepowered.asm.mixin.Shadow; |
34 | 37 | import org.spongepowered.asm.mixin.injection.At; |
35 | 38 | import org.spongepowered.asm.mixin.injection.Constant; |
36 | 39 | import org.spongepowered.asm.mixin.injection.ModifyArg; |
|
44 | 47 | @Mixin(LivingEntity.class) |
45 | 48 | public abstract class LivingEntityMixin_Forge_Damage implements TrackedDamageBridge { |
46 | 49 |
|
| 50 | + //@formatter:off |
| 51 | + @Shadow public abstract ItemStack shadow$getUseItem(); |
| 52 | + //@formatter:on |
| 53 | + |
47 | 54 | @ModifyConstant(method = "actuallyHurt", constant = @Constant(floatValue = 0), slice = @Slice( |
48 | 55 | from = @At(value = "INVOKE", target = "Lnet/minecraftforge/common/ForgeHooks;onLivingHurt(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/damagesource/DamageSource;F)F"), |
49 | 56 | to = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getDamageAfterArmorAbsorb(Lnet/minecraft/world/damagesource/DamageSource;F)F"))) |
50 | 57 | private float damage$doNotReturnEarly(final float constant) { |
51 | 58 | return Float.NaN; |
52 | 59 | } |
53 | 60 |
|
54 | | - @WrapOperation(method = "hurtServer", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/event/ForgeEventFactory;onShieldBlock(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/damagesource/DamageSource;F)Lnet/minecraftforge/event/entity/living/ShieldBlockEvent;")) |
55 | | - private ShieldBlockEvent damage$modifyBeforeAndAfterShield(final LivingEntity self, final DamageSource source, final float originalDamage, final Operation<ShieldBlockEvent> operation) { |
| 61 | + @WrapOperation(method = "hurtServer", |
| 62 | + at = @At(value = "INVOKE", |
| 63 | + target = "Lnet/minecraft/world/entity/LivingEntity;applyItemBlocking(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/damagesource/DamageSource;F)F" |
| 64 | + )) |
| 65 | + private float damage$initiateBlockingStep( |
| 66 | + final LivingEntity self, final ServerLevel level, final DamageSource source, final float originalDamage, |
| 67 | + final Operation<Float> original) { |
56 | 68 | final SpongeDamageTracker tracker = this.damage$tracker(); |
57 | 69 | if (tracker == null) { |
58 | | - return operation.call(self, source, originalDamage); |
| 70 | + return original.call(self, level, source, originalDamage); |
59 | 71 | } |
60 | 72 |
|
61 | | - final SpongeDamageStep step = tracker.newStep(DamageStepTypes.SHIELD, ItemStackUtil.snapshotOf(self.getUseItem())); |
| 73 | + final SpongeDamageStep step = tracker.newStep(DamageStepTypes.SHIELD, ItemStackUtil.snapshotOf(this.shadow$getUseItem())); |
62 | 74 | float damage = (float) step.applyChildrenBefore(originalDamage); |
| 75 | + return original.call(self, level, source, damage); |
| 76 | + } |
| 77 | + |
| 78 | + |
| 79 | + @WrapOperation(method = "applyItemBlocking", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/event/ForgeEventFactory;onShieldBlock(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/damagesource/DamageSource;FLnet/minecraft/world/item/ItemStack;)Lnet/minecraftforge/event/entity/living/ShieldBlockEvent;")) |
| 80 | + private ShieldBlockEvent damage$modifyBeforeAndAfterShield( |
| 81 | + final LivingEntity self, final DamageSource source, final float originalDamage, final ItemStack stack, |
| 82 | + final Operation<ShieldBlockEvent> operation |
| 83 | + ) { |
| 84 | + final SpongeDamageTracker tracker = this.damage$tracker(); |
| 85 | + if (tracker == null) { |
| 86 | + return operation.call(self, source, originalDamage, stack); |
| 87 | + } |
| 88 | + final var step = tracker.currentStep(DamageStepTypes.SHIELD); |
| 89 | + if (step == null) { |
| 90 | + return operation.call(self, source, originalDamage, stack); |
| 91 | + } |
| 92 | + float damage = (float) step.damageBeforeSelf().getAsDouble(); |
63 | 93 | final ShieldBlockEvent event; |
64 | 94 | if (step.isSkipped()) { |
65 | | - event = new ShieldBlockEvent(self, source, damage); |
| 95 | + event = new ShieldBlockEvent(self, source, damage, stack); |
66 | 96 | event.setCanceled(true); |
67 | 97 | } else { |
68 | | - event = operation.call(self, source, damage); |
| 98 | + event = operation.call(self, source, damage, stack); |
69 | 99 | if (!event.isCanceled()) { |
70 | 100 | damage -= event.getBlockedDamage(); |
71 | 101 | } |
|
0 commit comments