--- a/net/minecraft/world/entity/EntityInsentient.java +++ b/net/minecraft/world/entity/EntityInsentient.java @@ -75,6 +75,19 @@ import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.phys.AxisAlignedBB; +// CraftBukkit start +import net.minecraft.server.level.EntityPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityCombustByEntityEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityTransformEvent; +import org.bukkit.event.entity.EntityUnleashEvent; +import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; +// CraftBukkit end + public abstract class EntityInsentient extends EntityLiving implements Targeting { private static final DataWatcherObject DATA_MOB_FLAGS_ID = DataWatcher.defineId(EntityInsentient.class, DataWatcherRegistry.BYTE); @@ -122,6 +135,8 @@ private BlockPosition restrictCenter; private float restrictRadius; + public boolean aware = true; // CraftBukkit + protected EntityInsentient(EntityTypes entitytypes, World world) { super(entitytypes, world); this.handItems = NonNullList.withSize(2, ItemStack.EMPTY); @@ -147,6 +162,12 @@ } + // CraftBukkit start + public void setPersistenceRequired(boolean persistenceRequired) { + this.persistenceRequired = persistenceRequired; + } + // CraftBukkit end + protected void registerGoals() {} public static AttributeProvider.Builder createMobAttributes() { @@ -258,7 +279,38 @@ } public void setTarget(@Nullable EntityLiving entityliving) { + // CraftBukkit start - fire event + setTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true); + } + + public boolean setTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { + if (getTarget() == entityliving) return false; + if (fireEvent) { + if (reason == EntityTargetEvent.TargetReason.UNKNOWN && getTarget() != null && entityliving == null) { + reason = getTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; + } + if (reason == EntityTargetEvent.TargetReason.UNKNOWN) { + this.level().getCraftServer().getLogger().log(java.util.logging.Level.WARNING, "Unknown target reason, please report on the issue tracker", new Exception()); + } + CraftLivingEntity ctarget = null; + if (entityliving != null) { + ctarget = (CraftLivingEntity) entityliving.getBukkitEntity(); + } + EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(this.getBukkitEntity(), ctarget, reason); + this.level().getCraftServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + + if (event.getTarget() != null) { + entityliving = ((CraftLivingEntity) event.getTarget()).getHandle(); + } else { + entityliving = null; + } + } this.target = entityliving; + return true; + // CraftBukkit end } @Override @@ -398,6 +450,12 @@ return null; } + // CraftBukkit start - Add delegate method + public SoundEffect getAmbientSound0() { + return getAmbientSound(); + } + // CraftBukkit end + @Override public void addAdditionalSaveData(NBTTagCompound nbttagcompound) { super.addAdditionalSaveData(nbttagcompound); @@ -487,16 +545,26 @@ nbttagcompound.putBoolean("NoAI", this.isNoAi()); } + nbttagcompound.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit } @Override public void readAdditionalSaveData(NBTTagCompound nbttagcompound) { super.readAdditionalSaveData(nbttagcompound); + + // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it if (nbttagcompound.contains("CanPickUpLoot", 1)) { - this.setCanPickUpLoot(nbttagcompound.getBoolean("CanPickUpLoot")); + boolean data = nbttagcompound.getBoolean("CanPickUpLoot"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.setCanPickUpLoot(data); + } } - this.persistenceRequired = nbttagcompound.getBoolean("PersistenceRequired"); + boolean data = nbttagcompound.getBoolean("PersistenceRequired"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.persistenceRequired = data; + } + // CraftBukkit end NBTTagList nbttaglist; int i; @@ -543,6 +611,11 @@ } this.setNoAi(nbttagcompound.getBoolean("NoAI")); + // CraftBukkit start + if (nbttagcompound.contains("Bukkit.Aware")) { + this.aware = nbttagcompound.getBoolean("Bukkit.Aware"); + } + // CraftBukkit end } @Override @@ -610,7 +683,7 @@ protected void pickUpItem(EntityItem entityitem) { ItemStack itemstack = entityitem.getItem(); - ItemStack itemstack1 = this.equipItemIfPossible(itemstack.copy()); + ItemStack itemstack1 = this.equipItemIfPossible(itemstack.copy(), entityitem); // CraftBukkit - add item if (!itemstack1.isEmpty()) { this.onItemPickup(entityitem); @@ -624,6 +697,12 @@ } public ItemStack equipItemIfPossible(ItemStack itemstack) { + // CraftBukkit start - add item + return this.equipItemIfPossible(itemstack, null); + } + + public ItemStack equipItemIfPossible(ItemStack itemstack, EntityItem entityitem) { + // CraftBukkit end EnumItemSlot enumitemslot = getEquipmentSlotForItem(itemstack); ItemStack itemstack1 = this.getItemBySlot(enumitemslot); boolean flag = this.canReplaceCurrentItem(itemstack, itemstack1); @@ -634,11 +713,19 @@ flag = itemstack1.isEmpty(); } - if (flag && this.canHoldItem(itemstack)) { + // CraftBukkit start + boolean canPickup = flag && this.canHoldItem(itemstack); + if (entityitem != null) { + canPickup = !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entityitem, 0, !canPickup).isCancelled(); + } + if (canPickup) { + // CraftBukkit end double d0 = (double) this.getEquipmentDropChance(enumitemslot); if (!itemstack1.isEmpty() && (double) Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d0) { + this.forceDrops = true; // CraftBukkit this.spawnAtLocation(itemstack1); + this.forceDrops = false; // CraftBukkit } if (enumitemslot.isArmor() && itemstack.getCount() > 1) { @@ -790,6 +877,7 @@ @Override protected final void serverAiStep() { ++this.noActionTime; + if (!this.aware) return; // CraftBukkit this.level().getProfiler().push("sensing"); this.sensing.tick(); this.level().getProfiler().pop(); @@ -1183,6 +1271,12 @@ if (!this.isAlive()) { return EnumInteractionResult.PASS; } else if (this.getLeashHolder() == entityhuman) { + // CraftBukkit start - fire PlayerUnleashEntityEvent + if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman, enumhand).isCancelled()) { + ((EntityPlayer) entityhuman).connection.send(new PacketPlayOutAttachEntity(this, this.getLeashHolder())); + return EnumInteractionResult.PASS; + } + // CraftBukkit end this.dropLeash(true, !entityhuman.getAbilities().instabuild); this.gameEvent(GameEvent.ENTITY_INTERACT, entityhuman); return EnumInteractionResult.sidedSuccess(this.level().isClientSide); @@ -1208,6 +1302,12 @@ ItemStack itemstack = entityhuman.getItemInHand(enumhand); if (itemstack.is(Items.LEAD) && this.canBeLeashed(entityhuman)) { + // CraftBukkit start - fire PlayerLeashEntityEvent + if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman, enumhand).isCancelled()) { + ((EntityPlayer) entityhuman).connection.send(new PacketPlayOutAttachEntity(this, this.getLeashHolder())); + return EnumInteractionResult.PASS; + } + // CraftBukkit end this.setLeashedTo(entityhuman, true); itemstack.shrink(1); return EnumInteractionResult.sidedSuccess(this.level().isClientSide); @@ -1223,7 +1323,7 @@ if (itemstack.getItem() instanceof ItemMonsterEgg) { if (this.level() instanceof WorldServer) { ItemMonsterEgg itemmonsteregg = (ItemMonsterEgg) itemstack.getItem(); - Optional optional = itemmonsteregg.spawnOffspringFromSpawnEgg(entityhuman, this, this.getType(), (WorldServer) this.level(), this.position(), itemstack); + Optional optional = itemmonsteregg.spawnOffspringFromSpawnEgg(entityhuman, this, (EntityTypes) this.getType(), (WorldServer) this.level(), this.position(), itemstack); // CraftBukkit - decompile error optional.ifPresent((entityinsentient) -> { this.onOffspringSpawnedFromEgg(entityhuman, entityinsentient); @@ -1273,12 +1373,19 @@ return this.restrictRadius != -1.0F; } + // CraftBukkit start @Nullable public T convertTo(EntityTypes entitytypes, boolean flag) { + return this.convertTo(entitytypes, flag, EntityTransformEvent.TransformReason.UNKNOWN, CreatureSpawnEvent.SpawnReason.DEFAULT); + } + + @Nullable + public T convertTo(EntityTypes entitytypes, boolean flag, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) { + // CraftBukkit end if (this.isRemoved()) { return null; } else { - T t0 = (EntityInsentient) entitytypes.create(this.level()); + T t0 = entitytypes.create(this.level()); // CraftBukkit - decompile error if (t0 == null) { return null; @@ -1312,7 +1419,12 @@ } } - this.level().addFreshEntity(t0); + // CraftBukkit start + if (CraftEventFactory.callEntityTransformEvent(this, t0, transformReason).isCancelled()) { + return null; + } + this.level().addFreshEntity(t0, spawnReason); + // CraftBukkit end if (this.isPassenger()) { Entity entity = this.getVehicle(); @@ -1333,6 +1445,7 @@ if (this.leashHolder != null) { if (!this.isAlive() || !this.leashHolder.isAlive()) { + this.level().getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), (!this.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit this.dropLeash(true, true); } @@ -1344,7 +1457,9 @@ this.leashHolder = null; this.leashInfoTag = null; if (!this.level().isClientSide && flag1) { + this.forceDrops = true; // CraftBukkit this.spawnAtLocation((IMaterial) Items.LEAD); + this.forceDrops = false; // CraftBukkit } if (!this.level().isClientSide && flag && this.level() instanceof WorldServer) { @@ -1394,6 +1509,7 @@ boolean flag1 = super.startRiding(entity, flag); if (flag1 && this.isLeashed()) { + this.level().getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit this.dropLeash(true, true); } @@ -1418,7 +1534,9 @@ } if (this.tickCount > 100) { + this.forceDrops = true; // CraftBukkit this.spawnAtLocation((IMaterial) Items.LEAD); + this.forceDrops = false; // CraftBukkit this.leashInfoTag = null; } } @@ -1500,7 +1618,14 @@ int i = EnchantmentManager.getFireAspect(this); if (i > 0) { - entity.setSecondsOnFire(i * 4); + // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item + EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), i * 4); + org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + + if (!combustEvent.isCancelled()) { + entity.setSecondsOnFire(combustEvent.getDuration(), false); + } + // CraftBukkit end } boolean flag = entity.hurt(this.damageSources().mobAttack(this), f); @@ -1574,6 +1699,7 @@ @Override protected void removeAfterChangingDimensions() { super.removeAfterChangingDimensions(); + this.level().getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit this.dropLeash(true, false); this.getAllSlots().forEach((itemstack) -> { if (!itemstack.isEmpty()) {