diff --git a/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/entity/PiglinBruteController.java b/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/entity/PiglinBruteController.java new file mode 100644 index 000000000..fb3a651ec --- /dev/null +++ b/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/entity/PiglinBruteController.java @@ -0,0 +1,232 @@ +package net.citizensnpcs.nms.v1_16_R2.entity; + +import java.util.TreeMap; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_16_R2.CraftServer; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPiglinBrute; +import org.bukkit.entity.PiglinBrute; +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_R2.util.NMSImpl; +import net.citizensnpcs.npc.CitizensNPC; +import net.citizensnpcs.npc.ai.NPCHolder; +import net.citizensnpcs.util.Util; +import net.minecraft.server.v1_16_R2.BehaviorController; +import net.minecraft.server.v1_16_R2.BlockPosition; +import net.minecraft.server.v1_16_R2.DamageSource; +import net.minecraft.server.v1_16_R2.Entity; +import net.minecraft.server.v1_16_R2.EntityBoat; +import net.minecraft.server.v1_16_R2.EntityMinecartAbstract; +import net.minecraft.server.v1_16_R2.EntityPiglinBrute; +import net.minecraft.server.v1_16_R2.EntityTypes; +import net.minecraft.server.v1_16_R2.IBlockData; +import net.minecraft.server.v1_16_R2.NBTTagCompound; +import net.minecraft.server.v1_16_R2.SoundEffect; +import net.minecraft.server.v1_16_R2.Vec3D; +import net.minecraft.server.v1_16_R2.World; + +public class PiglinBruteController extends MobEntityController { + public PiglinBruteController() { + super(EntityPiglinBruteNPC.class); + } + + @Override + public PiglinBrute getBukkitEntity() { + return (PiglinBrute) super.getBukkitEntity(); + } + + public static class EntityPiglinBruteNPC extends EntityPiglinBrute implements NPCHolder { + private TreeMap behaviorMap; + private final CitizensNPC npc; + private BehaviorController previousBehaviorController; + + public EntityPiglinBruteNPC(EntityTypes types, World world) { + this(types, world, null); + } + + public EntityPiglinBruteNPC(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_R2.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 g(Vec3D vec3d) { + if (npc == null || !npc.isFlyable()) { + super.g(vec3d); + } else { + NMSImpl.flyingMoveLogic(this, vec3d); + } + } + + @Override + public CraftEntity getBukkitEntity() { + if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { + NMSImpl.setBukkitEntity(this, new PiglinBruteNPC(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 i(double x, double y, double z) { + if (npc == null) { + super.i(x, y, z); + return; + } + if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) { + if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true)) { + super.i(x, y, z); + } + return; + } + Vector vector = new Vector(x, y, z); + NPCPushEvent event = Util.callPushEvent(npc, vector); + if (!event.isCancelled()) { + vector = event.getCollisionVector(); + super.i(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); + } + setImmuneToZombification(npc.isProtected()); + } + 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 PiglinBruteNPC extends CraftPiglinBrute implements NPCHolder { + private final CitizensNPC npc; + + public PiglinBruteNPC(EntityPiglinBruteNPC entity) { + super((CraftServer) Bukkit.getServer(), entity); + this.npc = entity.npc; + } + + @Override + public NPC getNPC() { + return npc; + } + } +} diff --git a/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/util/NMSImpl.java b/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/util/NMSImpl.java index 2dfaaad4d..af48e449a 100644 --- a/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/util/NMSImpl.java +++ b/v1_16_R2/src/main/java/net/citizensnpcs/nms/v1_16_R2/util/NMSImpl.java @@ -112,6 +112,7 @@ import net.citizensnpcs.nms.v1_16_R2.entity.ParrotController; import net.citizensnpcs.nms.v1_16_R2.entity.PhantomController; import net.citizensnpcs.nms.v1_16_R2.entity.PigController; import net.citizensnpcs.nms.v1_16_R2.entity.PigZombieController; +import net.citizensnpcs.nms.v1_16_R2.entity.PiglinBruteController; import net.citizensnpcs.nms.v1_16_R2.entity.PiglinController; import net.citizensnpcs.nms.v1_16_R2.entity.PillagerController; import net.citizensnpcs.nms.v1_16_R2.entity.PolarBearController; @@ -804,6 +805,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.PIGLIN_BRUTE, PiglinBruteController.class); EntityControllers.setEntityControllerForType(EntityType.HOGLIN, HoglinController.class); EntityControllers.setEntityControllerForType(EntityType.ZOMBIFIED_PIGLIN, PigZombieController.class); EntityControllers.setEntityControllerForType(EntityType.ZOGLIN, ZoglinController.class);