diff --git a/common/src/main/java/io/github/flemmli97/flan/api/PermissionRegistry.java b/common/src/main/java/io/github/flemmli97/flan/api/PermissionRegistry.java index ed9c261..89745e1 100644 --- a/common/src/main/java/io/github/flemmli97/flan/api/PermissionRegistry.java +++ b/common/src/main/java/io/github/flemmli97/flan/api/PermissionRegistry.java @@ -84,6 +84,7 @@ public class PermissionRegistry { public static ClaimPermission PISTONBORDER = global(new ClaimPermission("PISTONBORDER", () -> new ItemStack(Items.PISTON), "Toggle piston pull/push across claim borders")); public static ClaimPermission MOBSPAWN = global(new ClaimPermission("MOBSPAWN", () -> new ItemStack(Items.ZOMBIE_SPAWN_EGG), "Prevent hostile mobspawn in claim")); public static ClaimPermission ANIMALSPAWN = global(new ClaimPermission("ANIMALSPAWN", () -> new ItemStack(Items.PIG_SPAWN_EGG), "Prevent other spawn in claim")); + public static ClaimPermission LIGHTNING = global(new ClaimPermission("LIGHTNING", () -> new ItemStack(Items.TRIDENT), "Allow lightning to affect claims", "e.g. set blocks on fire", "or affect animals (mobs are excluded)")); private static ClaimPermission register(ClaimPermission perm) { if (locked) { diff --git a/common/src/main/java/io/github/flemmli97/flan/event/EntityInteractEvents.java b/common/src/main/java/io/github/flemmli97/flan/event/EntityInteractEvents.java index 797dd6b..2f75cc3 100644 --- a/common/src/main/java/io/github/flemmli97/flan/event/EntityInteractEvents.java +++ b/common/src/main/java/io/github/flemmli97/flan/event/EntityInteractEvents.java @@ -23,6 +23,7 @@ import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.entity.mob.EndermanEntity; import net.minecraft.entity.mob.Monster; +import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.entity.passive.SnowGolemEntity; import net.minecraft.entity.passive.TameableEntity; import net.minecraft.entity.passive.VillagerEntity; @@ -342,4 +343,12 @@ public class EntityInteractEvents { } return true; } + + public static boolean preventLightningConvert(Entity entity) { + if (entity.world.isClient || !(entity instanceof AnimalEntity)) + return false; + ClaimStorage storage = ClaimStorage.get((ServerWorld) entity.world); + IPermissionContainer claim = storage.getForPermissionCheck(entity.getBlockPos()); + return !claim.canInteract(null, PermissionRegistry.LIGHTNING, entity.getBlockPos(), false); + } } diff --git a/common/src/main/java/io/github/flemmli97/flan/event/WorldEvents.java b/common/src/main/java/io/github/flemmli97/flan/event/WorldEvents.java index fcf387e..69a7b7f 100644 --- a/common/src/main/java/io/github/flemmli97/flan/event/WorldEvents.java +++ b/common/src/main/java/io/github/flemmli97/flan/event/WorldEvents.java @@ -4,6 +4,7 @@ import io.github.flemmli97.flan.api.PermissionRegistry; import io.github.flemmli97.flan.claim.ClaimStorage; import io.github.flemmli97.flan.claim.IPermissionContainer; import net.minecraft.block.BlockState; +import net.minecraft.entity.LightningEntity; import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.mob.MobEntity; import net.minecraft.server.network.ServerPlayerEntity; @@ -76,4 +77,19 @@ public class WorldEvents { return claim.canInteract(null, PermissionRegistry.MOBSPAWN, entity.getBlockPos()); return claim.canInteract(null, PermissionRegistry.ANIMALSPAWN, entity.getBlockPos()); } + + public static boolean lightningFire(LightningEntity lightning) { + if (!(lightning.world instanceof ServerWorld)) + return true; + BlockPos.Mutable mutable = lightning.getBlockPos().mutableCopy(); + ServerWorld world = (ServerWorld) lightning.world; + for (int x = -1; x <= 1; x++) + for (int z = -1; z <= 1; z++) { + mutable.set(mutable.getX() + x, mutable.getY(), mutable.getZ() + z); + IPermissionContainer claim = ClaimStorage.get(world).getForPermissionCheck(mutable); + if (!claim.canInteract(null, PermissionRegistry.LIGHTNING, mutable)) + return false; + } + return true; + } } diff --git a/common/src/main/java/io/github/flemmli97/flan/mixin/LightningFireEntityMixin.java b/common/src/main/java/io/github/flemmli97/flan/mixin/LightningFireEntityMixin.java new file mode 100644 index 0000000..1c167ce --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/mixin/LightningFireEntityMixin.java @@ -0,0 +1,18 @@ +package io.github.flemmli97.flan.mixin; + +import io.github.flemmli97.flan.event.WorldEvents; +import net.minecraft.entity.LightningEntity; +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(LightningEntity.class) +public class LightningFireEntityMixin { + + @Inject(method = "spawnFire", at = @At(value = "HEAD"), cancellable = true) + private void stopFire(int attempts, CallbackInfo info) { + if (!WorldEvents.lightningFire((LightningEntity) (Object) this)) + info.cancel(); + } +} diff --git a/common/src/main/resources/flan.mixins.json b/common/src/main/resources/flan.mixins.json index 00c37dc..9a2d940 100644 --- a/common/src/main/resources/flan.mixins.json +++ b/common/src/main/resources/flan.mixins.json @@ -21,7 +21,8 @@ "EndermanPlaceMixin", "IItemAccessor", "IHungerAccessor", - "FrostWalkerMixin" + "FrostWalkerMixin", + "LightningFireEntityMixin" ], "server": [ ], diff --git a/fabric/src/main/java/io/github/flemmli97/flan/fabric/mixin/LightningHitMixin.java b/fabric/src/main/java/io/github/flemmli97/flan/fabric/mixin/LightningHitMixin.java new file mode 100644 index 0000000..51fc19a --- /dev/null +++ b/fabric/src/main/java/io/github/flemmli97/flan/fabric/mixin/LightningHitMixin.java @@ -0,0 +1,20 @@ +package io.github.flemmli97.flan.fabric.mixin; + +import io.github.flemmli97.flan.event.EntityInteractEvents; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LightningEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import java.util.List; + +@Mixin(LightningEntity.class) +public class LightningHitMixin { + + @ModifyVariable(method = "tick", at = @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;"), require = 1) + private List affectedEntities(List list) { + list.removeIf(EntityInteractEvents::preventLightningConvert); + return list; + } +} diff --git a/fabric/src/main/resources/flan.fabric.mixins.json b/fabric/src/main/resources/flan.fabric.mixins.json index c0542d1..3ea1918 100644 --- a/fabric/src/main/resources/flan.fabric.mixins.json +++ b/fabric/src/main/resources/flan.fabric.mixins.json @@ -14,7 +14,8 @@ "PlayerDropMixin", "WitherMixin", "SnowGolemMixin", - "FabricFireMixin" + "FabricFireMixin", + "LightningHitMixin" ], "server": [ ], diff --git a/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java b/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java index 7e291d6..4b211a9 100644 --- a/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java +++ b/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java @@ -30,6 +30,7 @@ public class FlanForge { forge.addListener(EntityInteractEventsForge::xpAbsorb); forge.addListener(EntityInteractEventsForge::canDropItem); forge.addListener(EntityInteractEventsForge::mobGriefing); + forge.addListener(EntityInteractEventsForge::entityLightningHit); forge.addListener(ServerEvents::serverStart); forge.addListener(ServerEvents::commands); diff --git a/forge/src/main/java/io/github/flemmli97/flan/forgeevent/EntityInteractEventsForge.java b/forge/src/main/java/io/github/flemmli97/flan/forgeevent/EntityInteractEventsForge.java index f2c3e00..64c6e5a 100644 --- a/forge/src/main/java/io/github/flemmli97/flan/forgeevent/EntityInteractEventsForge.java +++ b/forge/src/main/java/io/github/flemmli97/flan/forgeevent/EntityInteractEventsForge.java @@ -8,6 +8,7 @@ import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.hit.EntityHitResult; import net.minecraftforge.event.entity.EntityMobGriefingEvent; +import net.minecraftforge.event.entity.EntityStruckByLightningEvent; import net.minecraftforge.event.entity.ProjectileImpactEvent; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.LivingDamageEvent; @@ -84,4 +85,10 @@ public class EntityInteractEventsForge { event.setResult(Event.Result.DENY); } } + + public static void entityLightningHit(EntityStruckByLightningEvent event) { + if (EntityInteractEvents.preventLightningConvert(event.getEntity())) { + event.setCanceled(true); + } + } }