From d5dcac8a452e9bb1424759dba81132ac57a83d37 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Wed, 27 May 2020 12:04:53 +0800 Subject: [PATCH] Capture special damage source for mod compatibility. --- .../mixin/bukkit/CraftEventFactoryMixin.java | 43 +++++++++++++++++++ .../mixin/core/block/BlockStateMixin.java | 25 +++++++++++ .../mixin/core/entity/EntityMixin.java | 13 ++++++ .../effect/LightningBoltEntityMixin.java | 6 +++ .../server/event/EntityEventDispatcher.java | 8 ++++ .../arclight/mod/util/ArclightCaptures.java | 31 ++++++++++++- .../resources/mixins.arclight.bukkit.json | 1 + .../main/resources/mixins.arclight.core.json | 1 + 8 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 arclight-coremod/src/main/java/io/izzel/arclight/mixin/bukkit/CraftEventFactoryMixin.java create mode 100644 arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/block/BlockStateMixin.java diff --git a/arclight-coremod/src/main/java/io/izzel/arclight/mixin/bukkit/CraftEventFactoryMixin.java b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/bukkit/CraftEventFactoryMixin.java new file mode 100644 index 00000000..6b5a58a7 --- /dev/null +++ b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/bukkit/CraftEventFactoryMixin.java @@ -0,0 +1,43 @@ +package io.izzel.arclight.mixin.bukkit; + +import com.google.common.base.Function; +import io.izzel.arclight.mod.util.ArclightCaptures; +import net.minecraft.entity.Entity; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.BlockPos; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock; +import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory; +import org.bukkit.event.entity.EntityDamageEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Map; + +@Mixin(value = CraftEventFactory.class, remap = false) +public class CraftEventFactoryMixin { + + @Shadow public static Entity entityDamage; + @Shadow public static Block blockDamage; + + @Inject(method = "handleEntityDamageEvent(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/DamageSource;Ljava/util/Map;Ljava/util/Map;Z)Lorg/bukkit/event/entity/EntityDamageEvent;", at = @At("HEAD")) + private static void arclight$captureSource(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions, boolean cancelled, CallbackInfoReturnable cir) { + Entity damageEventEntity = ArclightCaptures.getDamageEventEntity(); + BlockPos damageEventBlock = ArclightCaptures.getDamageEventBlock(); + if (damageEventEntity != null && entityDamage == null) { + if (source.damageType.equals(DamageSource.LIGHTNING_BOLT.damageType)) { + entityDamage = entity; + } + } + if (damageEventBlock != null && blockDamage == null) { + if (source.damageType.equals(DamageSource.CACTUS.damageType) + || source.damageType.equals(DamageSource.SWEET_BERRY_BUSH.damageType) + || source.damageType.equals(DamageSource.HOT_FLOOR.damageType)) { + blockDamage = CraftBlock.at(entity.getEntityWorld(), damageEventBlock); + } + } + } +} diff --git a/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/block/BlockStateMixin.java b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/block/BlockStateMixin.java new file mode 100644 index 00000000..fab1a0cd --- /dev/null +++ b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/block/BlockStateMixin.java @@ -0,0 +1,25 @@ +package io.izzel.arclight.mixin.core.block; + +import io.izzel.arclight.mod.util.ArclightCaptures; +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +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.CallbackInfo; + +@Mixin(BlockState.class) +public class BlockStateMixin { + + @Inject(method = "onEntityCollision", at = @At("HEAD")) + private void arclight$captureBlockCollide(World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) { + ArclightCaptures.captureDamageEventBlock(pos); + } + + @Inject(method = "onEntityCollision", at = @At("RETURN")) + private void arclight$resetBlockCollide(World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) { + ArclightCaptures.captureDamageEventBlock(null); + } +} diff --git a/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/EntityMixin.java b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/EntityMixin.java index 8c092d37..1743fba3 100644 --- a/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/EntityMixin.java +++ b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/EntityMixin.java @@ -9,6 +9,7 @@ import io.izzel.arclight.bridge.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.bridge.world.WorldBridge; import io.izzel.arclight.bridge.world.server.ServerWorldBridge; import io.izzel.arclight.bridge.world.storage.SaveHandlerBridge; +import io.izzel.arclight.mod.util.ArclightCaptures; import net.minecraft.block.pattern.BlockPattern; import net.minecraft.command.CommandSource; import net.minecraft.entity.Entity; @@ -72,6 +73,7 @@ import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -381,6 +383,17 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, setOnFire(tick, callEvent); } + @ModifyArg(method = "move", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;onEntityWalk(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)V")) + private BlockPos arclight$captureBlockWalk(BlockPos pos) { + ArclightCaptures.captureDamageEventBlock(pos); + return pos; + } + + @Inject(method = "move", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/block/Block;onEntityWalk(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)V")) + private void arclight$resetBlockWalk(MoverType typeIn, Vec3d pos, CallbackInfo ci) { + ArclightCaptures.captureDamageEventBlock(null); + } + @Inject(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;canTriggerWalking()Z")) public void arclight$move$VehicleBlockCollisionEvent(MoverType typeIn, Vec3d pos, CallbackInfo ci) { if (collidedHorizontally && getBukkitEntity() instanceof Vehicle) { diff --git a/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/effect/LightningBoltEntityMixin.java b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/effect/LightningBoltEntityMixin.java index f4501e0c..dd7a350a 100644 --- a/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/effect/LightningBoltEntityMixin.java +++ b/arclight-coremod/src/main/java/io/izzel/arclight/mixin/core/entity/effect/LightningBoltEntityMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.mixin.core.entity.effect; import io.izzel.arclight.mixin.core.entity.EntityMixin; +import io.izzel.arclight.mod.util.ArclightCaptures; import net.minecraft.block.BlockState; import net.minecraft.entity.effect.LightningBoltEntity; import net.minecraft.util.math.BlockPos; @@ -29,6 +30,11 @@ public abstract class LightningBoltEntityMixin extends EntityMixin { this.isSilent = false; } + @Inject(method = "tick", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/Entity;onStruckByLightning(Lnet/minecraft/entity/effect/LightningBoltEntity;)V")) + private void arclight$resetEntity(CallbackInfo ci) { + ArclightCaptures.captureDamageEventEntity(null); + } + @Redirect(method = "tick", at = @At(value = "FIELD", ordinal = 6, target = "Lnet/minecraft/entity/effect/LightningBoltEntity;lightningState:I")) private int arclight$effectOnlyCheck(LightningBoltEntity entity) { return (this.lightningState >= 0 && !this.isEffect) ? this.lightningState : -1; diff --git a/arclight-coremod/src/main/java/io/izzel/arclight/mod/server/event/EntityEventDispatcher.java b/arclight-coremod/src/main/java/io/izzel/arclight/mod/server/event/EntityEventDispatcher.java index d69e245d..f2f299ea 100644 --- a/arclight-coremod/src/main/java/io/izzel/arclight/mod/server/event/EntityEventDispatcher.java +++ b/arclight-coremod/src/main/java/io/izzel/arclight/mod/server/event/EntityEventDispatcher.java @@ -1,11 +1,14 @@ package io.izzel.arclight.mod.server.event; import com.google.common.collect.Lists; +import io.izzel.arclight.mod.util.ArclightCaptures; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraftforge.event.entity.EntityStruckByLightningEvent; import net.minecraftforge.event.entity.living.AnimalTameEvent; import net.minecraftforge.event.entity.living.LivingDropsEvent; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory; import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; @@ -41,4 +44,9 @@ public class EntityEventDispatcher { public void onEntityTame(AnimalTameEvent event) { event.setCanceled(CraftEventFactory.callEntityTameEvent(event.getAnimal(), event.getTamer()).isCancelled()); } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onLightningBolt(EntityStruckByLightningEvent event) { + ArclightCaptures.captureDamageEventEntity(event.getLightning()); + } } diff --git a/arclight-coremod/src/main/java/io/izzel/arclight/mod/util/ArclightCaptures.java b/arclight-coremod/src/main/java/io/izzel/arclight/mod/util/ArclightCaptures.java index 15d9640e..a581cae8 100644 --- a/arclight-coremod/src/main/java/io/izzel/arclight/mod/util/ArclightCaptures.java +++ b/arclight-coremod/src/main/java/io/izzel/arclight/mod/util/ArclightCaptures.java @@ -1,14 +1,15 @@ package io.izzel.arclight.mod.util; +import io.izzel.arclight.mod.ArclightConstants; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.inventory.container.Container; import net.minecraft.util.Direction; import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; import org.bukkit.TreeType; import org.bukkit.block.BlockState; import org.bukkit.event.block.BlockBreakEvent; -import io.izzel.arclight.mod.ArclightConstants; import java.util.ArrayList; import java.util.List; @@ -151,6 +152,34 @@ public class ArclightCaptures { } } + private static transient Entity damageEventEntity; + + public static void captureDamageEventEntity(Entity entity) { + damageEventEntity = entity; + } + + public static Entity getDamageEventEntity() { + try { + return damageEventEntity; + } finally { + damageEventEntity = null; + } + } + + private static transient BlockPos damageEventBlock; + + public static void captureDamageEventBlock(BlockPos blockState) { + damageEventBlock = blockState; + } + + public static BlockPos getDamageEventBlock() { + try { + return damageEventBlock; + } finally { + damageEventBlock = null; + } + } + private static void recapture(String type) { throw new IllegalStateException("Recapturing " + type); } diff --git a/arclight-coremod/src/main/resources/mixins.arclight.bukkit.json b/arclight-coremod/src/main/resources/mixins.arclight.bukkit.json index d9df0815..0982e66f 100644 --- a/arclight-coremod/src/main/resources/mixins.arclight.bukkit.json +++ b/arclight-coremod/src/main/resources/mixins.arclight.bukkit.json @@ -12,6 +12,7 @@ "CraftBlockStateMixin", "CraftChunkMixin", "CraftConsoleCommandSenderMixin", + "CraftEventFactoryMixin", "CraftMagicNumbersMixin", "CraftServerMixin", "JavaPluginLoaderMixin", diff --git a/arclight-coremod/src/main/resources/mixins.arclight.core.json b/arclight-coremod/src/main/resources/mixins.arclight.core.json index eae84b96..bc523251 100644 --- a/arclight-coremod/src/main/resources/mixins.arclight.core.json +++ b/arclight-coremod/src/main/resources/mixins.arclight.core.json @@ -17,6 +17,7 @@ "block.BambooBlockMixin", "block.BambooSaplingBlockMixin", "block.BlockMixin", + "block.BlockStateMixin", "block.BushBlockMixin", "block.CactusBlockMixin", "block.CakeBlockMixin",