Capture special damage source for mod compatibility.

This commit is contained in:
IzzelAliz 2020-05-27 12:04:53 +08:00
parent d59772a89e
commit d5dcac8a45
8 changed files with 127 additions and 1 deletions

View File

@ -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<EntityDamageEvent.DamageModifier, Double> modifiers, Map<EntityDamageEvent.DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled, CallbackInfoReturnable<EntityDamageEvent> 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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -12,6 +12,7 @@
"CraftBlockStateMixin",
"CraftChunkMixin",
"CraftConsoleCommandSenderMixin",
"CraftEventFactoryMixin",
"CraftMagicNumbersMixin",
"CraftServerMixin",
"JavaPluginLoaderMixin",

View File

@ -17,6 +17,7 @@
"block.BambooBlockMixin",
"block.BambooSaplingBlockMixin",
"block.BlockMixin",
"block.BlockStateMixin",
"block.BushBlockMixin",
"block.CactusBlockMixin",
"block.CakeBlockMixin",