From 8dd82811f72fc6478f4fe11136b310ca1e4f2b46 Mon Sep 17 00:00:00 2001 From: fullwall Date: Thu, 25 Jun 2020 20:29:59 +0800 Subject: [PATCH] Add HoglinController, make pig/hoglins immune to zombification --- .../nms/v1_16_R1/entity/HoglinController.java | 232 ++++++++++++++++++ .../nms/v1_16_R1/entity/PiglinController.java | 1 + .../entity/TropicalFishController.java | 20 +- .../nms/v1_16_R1/util/NMSImpl.java | 2 + 4 files changed, 245 insertions(+), 10 deletions(-) create mode 100644 v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/HoglinController.java diff --git a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/HoglinController.java b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/HoglinController.java new file mode 100644 index 000000000..a0284b2bb --- /dev/null +++ b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/HoglinController.java @@ -0,0 +1,232 @@ +package net.citizensnpcs.nms.v1_16_R1.entity; + +import java.util.TreeMap; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_16_R1.CraftServer; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftHoglin; +import org.bukkit.entity.Hoglin; +import org.bukkit.util.Vector; + +import net.citizensnpcs.api.event.NPCEnderTeleportEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.nms.v1_16_R1.util.NMSImpl; +import net.citizensnpcs.npc.CitizensNPC; +import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.Util; +import net.minecraft.server.v1_16_R1.BehaviorController; +import net.minecraft.server.v1_16_R1.BlockPosition; +import net.minecraft.server.v1_16_R1.DamageSource; +import net.minecraft.server.v1_16_R1.Entity; +import net.minecraft.server.v1_16_R1.EntityBoat; +import net.minecraft.server.v1_16_R1.EntityHoglin; +import net.minecraft.server.v1_16_R1.EntityMinecartAbstract; +import net.minecraft.server.v1_16_R1.EntityTypes; +import net.minecraft.server.v1_16_R1.IBlockData; +import net.minecraft.server.v1_16_R1.NBTTagCompound; +import net.minecraft.server.v1_16_R1.SoundEffect; +import net.minecraft.server.v1_16_R1.Vec3D; +import net.minecraft.server.v1_16_R1.World; + +public class HoglinController extends MobEntityController { + public HoglinController() { + super(EntityHoglinNPC.class); + } + + @Override + public Hoglin getBukkitEntity() { + return (Hoglin) super.getBukkitEntity(); + } + + public static class EntityHoglinNPC extends EntityHoglin implements NPCHolder { + private TreeMap behaviorMap; + private final CitizensNPC npc; + private BehaviorController previousBehaviorController; + + public EntityHoglinNPC(EntityTypes types, World world) { + this(types, world, null); + } + + public EntityHoglinNPC(EntityTypes types, World world, NPC npc) { + super(types, world); + this.npc = (CitizensNPC) npc; + if (npc != null) { + NMSImpl.clearGoals(npc, goalSelector, targetSelector); + } + } + + @Override + protected void a(double d0, boolean flag, IBlockData block, BlockPosition blockposition) { + if (npc == null || !npc.isFlyable()) { + super.a(d0, flag, block, blockposition); + } + } + + @Override + public boolean b(float f, float f1) { + if (npc == null || !npc.isFlyable()) { + return super.b(f, f1); + } + return false; + } + + @Override + public void checkDespawn() { + if (npc == null) { + super.checkDespawn(); + } + } + + @Override + public void collide(net.minecraft.server.v1_16_R1.Entity entity) { + // this method is called by both the entities involved - cancelling + // it will not stop the NPC from moving. + super.collide(entity); + if (npc != null) + Util.callCollisionEvent(npc, entity.getBukkitEntity()); + } + + @Override + public boolean d(NBTTagCompound save) { + return npc == null ? super.d(save) : false; + } + + @Override + public void enderTeleportTo(double d0, double d1, double d2) { + if (npc == null) { + super.enderTeleportTo(d0, d1, d2); + return; + } + NPCEnderTeleportEvent event = new NPCEnderTeleportEvent(npc); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + super.enderTeleportTo(d0, d1, d2); + } + } + + @Override + public void f(Vec3D vec3d) { + if (npc == null || !npc.isFlyable()) { + super.f(vec3d); + } else { + NMSImpl.flyingMoveLogic(this, vec3d); + } + } + + @Override + public CraftEntity getBukkitEntity() { + if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { + NMSImpl.setBukkitEntity(this, new HoglinNPC(this)); + } + return super.getBukkitEntity(); + } + + @Override + public NPC getNPC() { + return npc; + } + + @Override + protected SoundEffect getSoundAmbient() { + return NMSImpl.getSoundEffect(npc, super.getSoundAmbient(), NPC.AMBIENT_SOUND_METADATA); + } + + @Override + protected SoundEffect getSoundDeath() { + return NMSImpl.getSoundEffect(npc, super.getSoundDeath(), NPC.DEATH_SOUND_METADATA); + } + + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return NMSImpl.getSoundEffect(npc, super.getSoundHurt(damagesource), NPC.HURT_SOUND_METADATA); + } + + @Override + public void h(double x, double y, double z) { + if (npc == null) { + super.h(x, y, z); + return; + } + if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) { + if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true)) { + super.h(x, y, z); + } + return; + } + Vector vector = new Vector(x, y, z); + NPCPushEvent event = Util.callPushEvent(npc, vector); + if (!event.isCancelled()) { + vector = event.getCollisionVector(); + super.h(vector.getX(), vector.getY(), vector.getZ()); + } + // when another entity collides, this method is called to push the + // NPC so we prevent it from doing anything if the event is + // cancelled. + } + + @Override + public boolean isClimbing() { + if (npc == null || !npc.isFlyable()) { + return super.isClimbing(); + } else { + return false; + } + } + + @Override + public boolean isLeashed() { + if (npc == null) + return super.isLeashed(); + boolean protectedDefault = npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true); + if (!protectedDefault || !npc.data().get(NPC.LEASH_PROTECTED_METADATA, protectedDefault)) + return super.isLeashed(); + if (super.isLeashed()) { + unleash(true, false); // clearLeash with client update + } + return false; // shouldLeash + } + + @Override + public void mobTick() { + if (npc != null) { + if (this.behaviorMap == null || this.previousBehaviorController != this.getBehaviorController()) { + this.behaviorMap = NMSImpl.getBehaviorMap(this); + this.previousBehaviorController = this.getBehaviorController(); + } + if (this.behaviorMap.size() > 0) { + this.behaviorMap.clear(); + NMSImpl.clearGoals(npc, goalSelector, targetSelector); + } + t(npc.isProtected()); // ImmuneToZombification + } + super.mobTick(); + if (npc != null) { + npc.update(); + } + } + + @Override + protected boolean n(Entity entity) { + if (npc != null && (entity instanceof EntityBoat || entity instanceof EntityMinecartAbstract)) { + return !npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true); + } + return super.n(entity); + } + } + + public static class HoglinNPC extends CraftHoglin implements NPCHolder { + private final CitizensNPC npc; + + public HoglinNPC(EntityHoglinNPC entity) { + super((CraftServer) Bukkit.getServer(), entity); + this.npc = entity.npc; + } + + @Override + public NPC getNPC() { + return npc; + } + } +} diff --git a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/PiglinController.java b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/PiglinController.java index 3ce14cc9c..5497a9126 100644 --- a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/PiglinController.java +++ b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/PiglinController.java @@ -199,6 +199,7 @@ public class PiglinController extends MobEntityController { this.behaviorMap.clear(); NMSImpl.clearGoals(npc, goalSelector, targetSelector); } + t(npc.isProtected()); // ImmuneToZombification } super.mobTick(); if (npc != null) { diff --git a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/TropicalFishController.java b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/TropicalFishController.java index 713a42fec..97446aaf5 100644 --- a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/TropicalFishController.java +++ b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/entity/TropicalFishController.java @@ -1,7 +1,6 @@ package net.citizensnpcs.nms.v1_16_R1.entity; import org.bukkit.Bukkit; -import net.minecraft.server.v1_16_R1.EntityMinecartAbstract; import org.bukkit.craftbukkit.v1_16_R1.CraftServer; import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_16_R1.entity.CraftTropicalFish; @@ -21,6 +20,7 @@ import net.minecraft.server.v1_16_R1.ControllerMove; import net.minecraft.server.v1_16_R1.DamageSource; import net.minecraft.server.v1_16_R1.Entity; import net.minecraft.server.v1_16_R1.EntityBoat; +import net.minecraft.server.v1_16_R1.EntityMinecartAbstract; import net.minecraft.server.v1_16_R1.EntityTropicalFish; import net.minecraft.server.v1_16_R1.EntityTypes; import net.minecraft.server.v1_16_R1.IBlockData; @@ -93,15 +93,6 @@ public class TropicalFishController extends MobEntityController { return npc == null ? super.d(save) : false; } - @Override - public void f(Vec3D vec3d) { - if (npc == null || !npc.isFlyable()) { - super.f(vec3d); - } else { - NMSImpl.flyingMoveLogic(this, vec3d); - } - } - @Override public void enderTeleportTo(double d0, double d1, double d2) { if (npc == null) { @@ -115,6 +106,15 @@ public class TropicalFishController extends MobEntityController { } } + @Override + public void f(Vec3D vec3d) { + if (npc == null || !npc.isFlyable()) { + super.f(vec3d); + } else { + NMSImpl.flyingMoveLogic(this, vec3d); + } + } + @Override public CraftEntity getBukkitEntity() { if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { diff --git a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/util/NMSImpl.java b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/util/NMSImpl.java index 510e86b2b..c07c6bc81 100644 --- a/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/util/NMSImpl.java +++ b/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/util/NMSImpl.java @@ -92,6 +92,7 @@ import net.citizensnpcs.nms.v1_16_R1.entity.GhastController; import net.citizensnpcs.nms.v1_16_R1.entity.GiantController; import net.citizensnpcs.nms.v1_16_R1.entity.GuardianController; import net.citizensnpcs.nms.v1_16_R1.entity.GuardianElderController; +import net.citizensnpcs.nms.v1_16_R1.entity.HoglinController; import net.citizensnpcs.nms.v1_16_R1.entity.HorseController; import net.citizensnpcs.nms.v1_16_R1.entity.HorseDonkeyController; import net.citizensnpcs.nms.v1_16_R1.entity.HorseMuleController; @@ -776,6 +777,7 @@ public class NMSImpl implements NMSBridge { EntityControllers.setEntityControllerForType(EntityType.PILLAGER, PillagerController.class); EntityControllers.setEntityControllerForType(EntityType.PIG, PigController.class); EntityControllers.setEntityControllerForType(EntityType.PIGLIN, PiglinController.class); + EntityControllers.setEntityControllerForType(EntityType.HOGLIN, HoglinController.class); EntityControllers.setEntityControllerForType(EntityType.ZOMBIFIED_PIGLIN, PigZombieController.class); EntityControllers.setEntityControllerForType(EntityType.ZOGLIN, ZoglinController.class); EntityControllers.setEntityControllerForType(EntityType.POLAR_BEAR, PolarBearController.class);