Move CraftBukkit per-file patches

By: Initial <noreply+automated@papermc.io>
This commit is contained in:
CraftBukkit/Spigot
2024-12-11 22:26:36 +01:00
parent a4de181b77
commit a265d64138
583 changed files with 71 additions and 857 deletions

View File

@@ -0,0 +1,41 @@
--- a/net/minecraft/world/entity/ConversionType.java
+++ b/net/minecraft/world/entity/ConversionType.java
@@ -12,6 +12,11 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.scores.Scoreboard;
+// CraftBukkit start
+import net.minecraft.core.BlockPosition;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public enum ConversionType {
SINGLE(true) {
@@ -31,7 +36,7 @@
while (iterator.hasNext()) {
entity1 = (Entity) iterator.next();
entity1.stopRiding();
- entity1.remove(Entity.RemovalReason.DISCARDED);
+ entity1.remove(Entity.RemovalReason.DISCARDED, EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause
}
entity.startRiding(entityinsentient1);
@@ -64,7 +69,7 @@
entityinsentient1.hurtTime = entityinsentient.hurtTime;
entityinsentient1.yBodyRot = entityinsentient.yBodyRot;
entityinsentient1.setOnGround(entityinsentient.onGround());
- Optional optional = entityinsentient.getSleepingPos();
+ Optional<BlockPosition> optional = entityinsentient.getSleepingPos(); // CraftBukkit - decompile error
Objects.requireNonNull(entityinsentient1);
optional.ifPresent(entityinsentient1::setSleepingPos);
@@ -156,7 +161,7 @@
entityinsentient1.setNoGravity(entityinsentient.isNoGravity());
entityinsentient1.setPortalCooldown(entityinsentient.getPortalCooldown());
entityinsentient1.setSilent(entityinsentient.isSilent());
- Set set = entityinsentient.getTags();
+ Set<String> set = entityinsentient.getTags(); // CraftBukkit - decompile error
Objects.requireNonNull(entityinsentient1);
set.forEach(entityinsentient1::addTag);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
--- a/net/minecraft/world/entity/EntityAgeable.java
+++ b/net/minecraft/world/entity/EntityAgeable.java
@@ -21,6 +21,7 @@
protected int age;
protected int forcedAge;
protected int forcedAgeTimer;
+ public boolean ageLocked; // CraftBukkit
protected EntityAgeable(EntityTypes<? extends EntityAgeable> entitytypes, World world) {
super(entitytypes, world);
@@ -104,6 +105,7 @@
super.addAdditionalSaveData(nbttagcompound);
nbttagcompound.putInt("Age", this.getAge());
nbttagcompound.putInt("ForcedAge", this.forcedAge);
+ nbttagcompound.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit
}
@Override
@@ -111,6 +113,7 @@
super.readAdditionalSaveData(nbttagcompound);
this.setAge(nbttagcompound.getInt("Age"));
this.forcedAge = nbttagcompound.getInt("ForcedAge");
+ this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); // CraftBukkit
}
@Override
@@ -125,7 +128,7 @@
@Override
public void aiStep() {
super.aiStep();
- if (this.level().isClientSide) {
+ if (this.level().isClientSide || ageLocked) { // CraftBukkit
if (this.forcedAgeTimer > 0) {
if (this.forcedAgeTimer % 4 == 0) {
this.level().addParticle(Particles.HAPPY_VILLAGER, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), 0.0D, 0.0D, 0.0D);

View File

@@ -0,0 +1,93 @@
--- a/net/minecraft/world/entity/EntityAreaEffectCloud.java
+++ b/net/minecraft/world/entity/EntityAreaEffectCloud.java
@@ -33,6 +33,12 @@
import net.minecraft.world.level.material.EnumPistonReaction;
import org.slf4j.Logger;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityAreaEffectCloud extends Entity implements TraceableEntity {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -200,7 +206,7 @@
private void serverTick(WorldServer worldserver) {
if (this.tickCount >= this.waitTime + this.duration) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
boolean flag = this.isWaiting();
boolean flag1 = this.tickCount < this.waitTime;
@@ -215,7 +221,7 @@
if (this.radiusPerTick != 0.0F) {
f += this.radiusPerTick;
if (f < 0.5F) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
return;
}
@@ -249,11 +255,12 @@
if (!list1.isEmpty()) {
Iterator iterator1 = list1.iterator();
+ List<LivingEntity> entities = new java.util.ArrayList<LivingEntity>(); // CraftBukkit
while (iterator1.hasNext()) {
EntityLiving entityliving = (EntityLiving) iterator1.next();
if (!this.victims.containsKey(entityliving) && entityliving.isAffectedByPotions()) {
- Stream stream = list.stream();
+ Stream<MobEffect> stream = list.stream(); // CraftBukkit - decompile error
Objects.requireNonNull(entityliving);
if (!stream.noneMatch(entityliving::canBeAffected)) {
@@ -262,6 +269,19 @@
double d2 = d0 * d0 + d1 * d1;
if (d2 <= (double) (f * f)) {
+ // CraftBukkit start
+ entities.add((LivingEntity) entityliving.getBukkitEntity());
+ }
+ }
+ }
+ }
+ {
+ org.bukkit.event.entity.AreaEffectCloudApplyEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callAreaEffectCloudApplyEvent(this, entities);
+ if (!event.isCancelled()) {
+ for (LivingEntity entity : event.getAffectedEntities()) {
+ if (entity instanceof CraftLivingEntity) {
+ EntityLiving entityliving = ((CraftLivingEntity) entity).getHandle();
+ // CraftBukkit end
this.victims.put(entityliving, this.tickCount + this.reapplicationDelay);
Iterator iterator2 = list.iterator();
@@ -271,14 +291,14 @@
if (((MobEffectList) mobeffect1.getEffect().value()).isInstantenous()) {
((MobEffectList) mobeffect1.getEffect().value()).applyInstantenousEffect(worldserver, this, this.getOwner(), entityliving, mobeffect1.getAmplifier(), 0.5D);
} else {
- entityliving.addEffect(new MobEffect(mobeffect1), this);
+ entityliving.addEffect(new MobEffect(mobeffect1), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AREA_EFFECT_CLOUD); // CraftBukkit
}
}
if (this.radiusOnUse != 0.0F) {
f += this.radiusOnUse;
if (f < 0.5F) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
return;
}
@@ -288,7 +308,7 @@
if (this.durationOnUse != 0) {
this.duration += this.durationOnUse;
if (this.duration <= 0) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
return;
}
}

View File

@@ -0,0 +1,13 @@
--- a/net/minecraft/world/entity/EntityCreature.java
+++ b/net/minecraft/world/entity/EntityCreature.java
@@ -11,6 +11,10 @@
import net.minecraft.world.level.World;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityUnleashEvent;
+// CraftBukkit end
+
public abstract class EntityCreature extends EntityInsentient {
protected static final float DEFAULT_WALK_TARGET_VALUE = 0.0F;

View File

@@ -0,0 +1,143 @@
--- a/net/minecraft/world/entity/EntityExperienceOrb.java
+++ b/net/minecraft/world/entity/EntityExperienceOrb.java
@@ -25,6 +25,14 @@
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.player.PlayerExpCooldownChangeEvent;
+// CraftBukkit end
+
public class EntityExperienceOrb extends Entity {
private static final int LIFETIME = 6000;
@@ -68,6 +76,7 @@
@Override
public void tick() {
super.tick();
+ EntityHuman prevTarget = this.followingPlayer;// CraftBukkit - store old target
this.xo = this.getX();
this.yo = this.getY();
this.zo = this.getZ();
@@ -93,7 +102,22 @@
this.followingPlayer = null;
}
- if (this.followingPlayer != null) {
+ // CraftBukkit start
+ boolean cancelled = false;
+ if (this.followingPlayer != prevTarget) {
+ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this, followingPlayer, (followingPlayer != null) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.FORGOT_TARGET);
+ EntityLiving target = (event.getTarget() == null) ? null : ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle();
+ cancelled = event.isCancelled();
+
+ if (cancelled) {
+ followingPlayer = prevTarget;
+ } else {
+ followingPlayer = (target instanceof EntityHuman) ? (EntityHuman) target : null;
+ }
+ }
+
+ if (this.followingPlayer != null && !cancelled) {
+ // CraftBukkit end
Vec3D vec3d = new Vec3D(this.followingPlayer.getX() - this.getX(), this.followingPlayer.getY() + (double) this.followingPlayer.getEyeHeight() / 2.0D - this.getY(), this.followingPlayer.getZ() - this.getZ());
double d0 = vec3d.lengthSqr();
@@ -121,7 +145,7 @@
++this.age;
if (this.age >= 6000) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
}
}
@@ -190,7 +214,7 @@
private void merge(EntityExperienceOrb entityexperienceorb) {
this.count += entityexperienceorb.count;
this.age = Math.min(this.age, entityexperienceorb.age);
- entityexperienceorb.discard();
+ entityexperienceorb.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause
}
private void setUnderwaterMovement() {
@@ -215,7 +239,7 @@
this.markHurt();
this.health = (int) ((float) this.health - f);
if (this.health <= 0) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
}
return true;
@@ -242,17 +266,17 @@
public void playerTouch(EntityHuman entityhuman) {
if (entityhuman instanceof EntityPlayer entityplayer) {
if (entityhuman.takeXpDelay == 0) {
- entityhuman.takeXpDelay = 2;
+ entityhuman.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(entityhuman, 2, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2;
entityhuman.take(this, 1);
int i = this.repairPlayerItems(entityplayer, this.value);
if (i > 0) {
- entityhuman.giveExperiencePoints(i);
+ entityhuman.giveExperiencePoints(CraftEventFactory.callPlayerExpChangeEvent(entityhuman, i).getAmount()); // CraftBukkit - this.value -> event.getAmount()
}
--this.count;
if (this.count == 0) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
}
}
@@ -266,12 +290,20 @@
ItemStack itemstack = ((EnchantedItemInUse) optional.get()).itemStack();
int j = EnchantmentManager.modifyDurabilityToRepairFromXp(entityplayer.serverLevel(), itemstack, i);
int k = Math.min(j, itemstack.getDamageValue());
+ // CraftBukkit start
+ org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(entityplayer, this, itemstack, optional.get().inSlot(), k);
+ k = event.getRepairAmount();
+ if (event.isCancelled()) {
+ return i;
+ }
+ // CraftBukkit end
itemstack.setDamageValue(itemstack.getDamageValue() - k);
if (k > 0) {
int l = i - k * i / j;
if (l > 0) {
+ this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls
return this.repairPlayerItems(entityplayer, l);
}
}
@@ -291,6 +323,24 @@
}
public static int getExperienceValue(int i) {
+ // CraftBukkit start
+ if (i > 162670129) return i - 100000;
+ if (i > 81335063) return 81335063;
+ if (i > 40667527) return 40667527;
+ if (i > 20333759) return 20333759;
+ if (i > 10166857) return 10166857;
+ if (i > 5083423) return 5083423;
+ if (i > 2541701) return 2541701;
+ if (i > 1270849) return 1270849;
+ if (i > 635413) return 635413;
+ if (i > 317701) return 317701;
+ if (i > 158849) return 158849;
+ if (i > 79423) return 79423;
+ if (i > 39709) return 39709;
+ if (i > 19853) return 19853;
+ if (i > 9923) return 9923;
+ if (i > 4957) return 4957;
+ // CraftBukkit end
return i >= 2477 ? 2477 : (i >= 1237 ? 1237 : (i >= 617 ? 617 : (i >= 307 ? 307 : (i >= 149 ? 149 : (i >= 73 ? 73 : (i >= 37 ? 37 : (i >= 17 ? 17 : (i >= 7 ? 7 : (i >= 3 ? 3 : 1)))))))));
}

View File

@@ -0,0 +1,314 @@
--- a/net/minecraft/world/entity/EntityInsentient.java
+++ b/net/minecraft/world/entity/EntityInsentient.java
@@ -85,6 +85,18 @@
import net.minecraft.world.level.storage.loot.parameters.LootContextParameters;
import net.minecraft.world.phys.AxisAlignedBB;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+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 EquipmentUser, Leashable, Targeting {
private static final DataWatcherObject<Byte> DATA_MOB_FLAGS_ID = DataWatcher.defineId(EntityInsentient.class, DataWatcherRegistry.BYTE);
@@ -132,6 +144,8 @@
private BlockPosition restrictCenter;
private float restrictRadius;
+ public boolean aware = true; // CraftBukkit
+
protected EntityInsentient(EntityTypes<? extends EntityInsentient> entitytypes, World world) {
super(entitytypes, world);
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
@@ -160,6 +174,12 @@
}
+ // CraftBukkit start
+ public void setPersistenceRequired(boolean persistenceRequired) {
+ this.persistenceRequired = persistenceRequired;
+ }
+ // CraftBukkit end
+
protected void registerGoals() {}
public static AttributeProvider.Builder createMobAttributes() {
@@ -264,11 +284,42 @@
@Nullable
protected final EntityLiving getTargetFromBrain() {
- return (EntityLiving) this.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse((Object) null);
+ return (EntityLiving) this.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null); // CraftBukkit - decompile error
}
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
@@ -399,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);
@@ -473,13 +530,25 @@
nbttagcompound.putBoolean("NoAI", this.isNoAi());
}
+ nbttagcompound.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
}
@Override
public void readAdditionalSaveData(NBTTagCompound nbttagcompound) {
super.readAdditionalSaveData(nbttagcompound);
- this.setCanPickUpLoot(nbttagcompound.getBoolean("CanPickUpLoot"));
- this.persistenceRequired = nbttagcompound.getBoolean("PersistenceRequired");
+ // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
+ if (nbttagcompound.contains("CanPickUpLoot", 99)) {
+ boolean data = nbttagcompound.getBoolean("CanPickUpLoot");
+ if (isLevelAtLeast(nbttagcompound, 1) || data) {
+ this.setCanPickUpLoot(data);
+ }
+ }
+
+ boolean data = nbttagcompound.getBoolean("PersistenceRequired");
+ if (isLevelAtLeast(nbttagcompound, 1) || data) {
+ this.persistenceRequired = data;
+ }
+ // CraftBukkit end
NBTTagList nbttaglist;
NBTTagCompound nbttagcompound1;
int i;
@@ -547,6 +616,11 @@
this.lootTableSeed = nbttagcompound.getLong("DeathLootTableSeed");
this.setNoAi(nbttagcompound.getBoolean("NoAI"));
+ // CraftBukkit start
+ if (nbttagcompound.contains("Bukkit.Aware")) {
+ this.aware = nbttagcompound.getBoolean("Bukkit.Aware");
+ }
+ // CraftBukkit end
}
@Override
@@ -623,20 +697,26 @@
protected void pickUpItem(WorldServer worldserver, EntityItem entityitem) {
ItemStack itemstack = entityitem.getItem();
- ItemStack itemstack1 = this.equipItemIfPossible(worldserver, itemstack.copy());
+ ItemStack itemstack1 = this.equipItemIfPossible(worldserver, itemstack.copy(), entityitem); // CraftBukkit - add item
if (!itemstack1.isEmpty()) {
this.onItemPickup(entityitem);
this.take(entityitem, itemstack1.getCount());
itemstack.shrink(itemstack1.getCount());
if (itemstack.isEmpty()) {
- entityitem.discard();
+ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
}
}
}
public ItemStack equipItemIfPossible(WorldServer worldserver, ItemStack itemstack) {
+ // CraftBukkit start - add item
+ return this.equipItemIfPossible(worldserver, itemstack, null);
+ }
+
+ public ItemStack equipItemIfPossible(WorldServer worldserver, ItemStack itemstack, EntityItem entityitem) {
+ // CraftBukkit end
EnumItemSlot enumitemslot = this.getEquipmentSlotForItem(itemstack);
ItemStack itemstack1 = this.getItemBySlot(enumitemslot);
boolean flag = this.canReplaceCurrentItem(itemstack, itemstack1, enumitemslot);
@@ -647,11 +727,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(worldserver, itemstack1);
+ this.forceDrops = false; // CraftBukkit
}
ItemStack itemstack2 = enumitemslot.limit(itemstack);
@@ -768,7 +856,7 @@
@Override
public void checkDespawn() {
if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) {
EntityHuman entityhuman = this.level().getNearestPlayer(this, -1.0D);
@@ -778,14 +866,14 @@
int j = i * i;
if (d0 > (double) j && this.removeWhenFarAway(d0)) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
}
int k = this.getType().getCategory().getNoDespawnDistance();
int l = k * k;
if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && d0 > (double) l && this.removeWhenFarAway(d0)) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else if (d0 < (double) l) {
this.noActionTime = 0;
}
@@ -799,6 +887,7 @@
@Override
protected final void serverAiStep() {
++this.noActionTime;
+ if (!this.aware) return; // CraftBukkit
GameProfilerFiller gameprofilerfiller = Profiler.get();
gameprofilerfiller.push("sensing");
@@ -1338,7 +1427,7 @@
if (itemstack.getItem() instanceof ItemMonsterEgg) {
if (this.level() instanceof WorldServer) {
ItemMonsterEgg itemmonsteregg = (ItemMonsterEgg) itemstack.getItem();
- Optional<EntityInsentient> optional = itemmonsteregg.spawnOffspringFromSpawnEgg(entityhuman, this, this.getType(), (WorldServer) this.level(), this.position(), itemstack);
+ Optional<EntityInsentient> optional = itemmonsteregg.spawnOffspringFromSpawnEgg(entityhuman, this, (EntityTypes<? extends EntityInsentient>) this.getType(), (WorldServer) this.level(), this.position(), itemstack); // CraftBukkit - decompile error
optional.ifPresent((entityinsentient) -> {
this.onOffspringSpawnedFromEgg(entityhuman, entityinsentient);
@@ -1389,12 +1478,19 @@
return this.restrictRadius != -1.0F;
}
+ // CraftBukkit start
@Nullable
public <T extends EntityInsentient> T convertTo(EntityTypes<T> entitytypes, ConversionParams conversionparams, EntitySpawnReason entityspawnreason, ConversionParams.a<T> conversionparams_a) {
+ return this.convertTo(entitytypes, conversionparams, entityspawnreason, conversionparams_a, EntityTransformEvent.TransformReason.UNKNOWN, CreatureSpawnEvent.SpawnReason.DEFAULT);
+ }
+
+ @Nullable
+ public <T extends EntityInsentient> T convertTo(EntityTypes<T> entitytypes, ConversionParams conversionparams, EntitySpawnReason entityspawnreason, ConversionParams.a<T> conversionparams_a, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) {
+ // CraftBukkit end
if (this.isRemoved()) {
return null;
} else {
- T t0 = (EntityInsentient) entitytypes.create(this.level(), entityspawnreason);
+ T t0 = entitytypes.create(this.level(), EntitySpawnReason.CONVERSION); // CraftBukkit - decompile error
if (t0 == null) {
return null;
@@ -1403,14 +1499,24 @@
conversionparams_a.finalizeConversion(t0);
World world = this.level();
+ // CraftBukkit start
+ if (transformReason == null) {
+ // Special handling for slime split and pig lightning
+ return t0;
+ }
+
+ if (CraftEventFactory.callEntityTransformEvent(this, t0, transformReason).isCancelled()) {
+ return null;
+ }
+ // CraftBukkit end
if (world instanceof WorldServer) {
WorldServer worldserver = (WorldServer) world;
- worldserver.addFreshEntity(t0);
+ worldserver.addFreshEntity(t0, spawnReason); // CraftBukkit
}
if (conversionparams.type().shouldDiscardAfterConversion()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause
}
return t0;
@@ -1420,7 +1526,14 @@
@Nullable
public <T extends EntityInsentient> T convertTo(EntityTypes<T> entitytypes, ConversionParams conversionparams, ConversionParams.a<T> conversionparams_a) {
- return this.convertTo(entitytypes, conversionparams, EntitySpawnReason.CONVERSION, conversionparams_a);
+ // CraftBukkit start
+ return this.convertTo(entitytypes, conversionparams, conversionparams_a, EntityTransformEvent.TransformReason.UNKNOWN, CreatureSpawnEvent.SpawnReason.DEFAULT);
+ }
+
+ @Nullable
+ public <T extends EntityInsentient> T convertTo(EntityTypes<T> entitytypes, ConversionParams conversionparams, ConversionParams.a<T> conversionparams_a, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) {
+ return this.convertTo(entitytypes, conversionparams, EntitySpawnReason.CONVERSION, conversionparams_a, transformReason, spawnReason);
+ // CraftBukkit end
}
@Nullable
@@ -1458,6 +1571,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();
}
@@ -1542,7 +1656,7 @@
if (f1 > 0.0F && entity instanceof EntityLiving) {
entityliving = (EntityLiving) entity;
- entityliving.knockback((double) (f1 * 0.5F), (double) MathHelper.sin(this.getYRot() * 0.017453292F), (double) (-MathHelper.cos(this.getYRot() * 0.017453292F)));
+ entityliving.knockback((double) (f1 * 0.5F), (double) MathHelper.sin(this.getYRot() * 0.017453292F), (double) (-MathHelper.cos(this.getYRot() * 0.017453292F)), this, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
}

View File

@@ -0,0 +1,73 @@
--- a/net/minecraft/world/entity/EntityLightning.java
+++ b/net/minecraft/world/entity/EntityLightning.java
@@ -31,6 +31,11 @@
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityLightning extends Entity {
private static final int START_LIFE = 2;
@@ -120,7 +125,7 @@
}
}
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else if (this.life < -this.random.nextInt(10)) {
--this.flashes;
this.life = 1;
@@ -129,7 +134,7 @@
}
}
- if (this.life >= 0) {
+ if (this.life >= 0 && !this.visualOnly) { // CraftBukkit - add !this.visualOnly
if (!(this.level() instanceof WorldServer)) {
this.level().setSkyFlashTime(2);
} else if (!this.visualOnly) {
@@ -169,8 +174,12 @@
IBlockData iblockdata = BlockFireAbstract.getState(this.level(), blockposition);
if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) {
- this.level().setBlockAndUpdate(blockposition, iblockdata);
- ++this.blocksSetOnFire;
+ // CraftBukkit start - add "!visualOnly"
+ if (!visualOnly && !CraftEventFactory.callBlockIgniteEvent(this.level(), blockposition, this).isCancelled()) {
+ this.level().setBlockAndUpdate(blockposition, iblockdata);
+ ++this.blocksSetOnFire;
+ }
+ // CraftBukkit end
}
for (int j = 0; j < i; ++j) {
@@ -178,8 +187,12 @@
iblockdata = BlockFireAbstract.getState(this.level(), blockposition1);
if (this.level().getBlockState(blockposition1).isAir() && iblockdata.canSurvive(this.level(), blockposition1)) {
- this.level().setBlockAndUpdate(blockposition1, iblockdata);
- ++this.blocksSetOnFire;
+ // CraftBukkit start - add "!visualOnly"
+ if (!visualOnly && !CraftEventFactory.callBlockIgniteEvent(this.level(), blockposition1, this).isCancelled()) {
+ this.level().setBlockAndUpdate(blockposition1, iblockdata);
+ ++this.blocksSetOnFire;
+ }
+ // CraftBukkit end
}
}
@@ -247,8 +260,9 @@
iblockdata = world.getBlockState(blockposition1);
} while (!(iblockdata.getBlock() instanceof WeatheringCopper));
+ BlockPosition blockposition1Final = blockposition1; // CraftBukkit - decompile error
WeatheringCopper.getPrevious(iblockdata).ifPresent((iblockdata1) -> {
- world.setBlockAndUpdate(blockposition1, iblockdata1);
+ world.setBlockAndUpdate(blockposition1Final, iblockdata1); // CraftBukkit - decompile error
});
world.levelEvent(3002, blockposition1, -1);
return Optional.of(blockposition1);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/EntityTameableAnimal.java
+++ b/net/minecraft/world/entity/EntityTameableAnimal.java
@@ -28,6 +28,12 @@
import net.minecraft.world.level.pathfinder.PathfinderNormal;
import net.minecraft.world.scores.ScoreboardTeam;
+// CraftBukkit start
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTeleportEvent;
+// CraftBukkit end
+
public abstract class EntityTameableAnimal extends EntityAnimal implements OwnableEntity {
public static final int TELEPORT_WHEN_DISTANCE_IS_SQ = 144;
@@ -295,7 +301,14 @@
if (!this.canTeleportTo(new BlockPosition(i, j, k))) {
return false;
} else {
- this.moveTo((double) i + 0.5D, (double) j, (double) k + 0.5D, this.getYRot(), this.getXRot());
+ // CraftBukkit start
+ EntityTeleportEvent event = CraftEventFactory.callEntityTeleportEvent(this, (double) i + 0.5D, (double) j, (double) k + 0.5D);
+ if (event.isCancelled()) {
+ return false;
+ }
+ Location to = event.getTo();
+ this.moveTo(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
+ // CraftBukkit end
this.navigation.stop();
return true;
}

View File

@@ -0,0 +1,124 @@
--- a/net/minecraft/world/entity/EntityTypes.java
+++ b/net/minecraft/world/entity/EntityTypes.java
@@ -176,6 +176,7 @@
import net.minecraft.world.phys.Vec3D;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.phys.shapes.VoxelShapes;
+import org.bukkit.event.entity.CreatureSpawnEvent;
import org.slf4j.Logger;
public class EntityTypes<T extends Entity> implements FeatureElement, EntityTypeTest<Entity, T> {
@@ -191,7 +192,7 @@
return Items.ACACIA_CHEST_BOAT;
}), EnumCreatureType.MISC).noLootTable().sized(1.375F, 0.5625F).eyeHeight(0.5625F).clientTrackingRange(10));
public static final EntityTypes<Allay> ALLAY = register("allay", EntityTypes.Builder.of(Allay::new, EnumCreatureType.CREATURE).sized(0.35F, 0.6F).eyeHeight(0.36F).ridingOffset(0.04F).clientTrackingRange(8).updateInterval(2));
- public static final EntityTypes<EntityAreaEffectCloud> AREA_EFFECT_CLOUD = register("area_effect_cloud", EntityTypes.Builder.of(EntityAreaEffectCloud::new, EnumCreatureType.MISC).noLootTable().fireImmune().sized(6.0F, 0.5F).clientTrackingRange(10).updateInterval(Integer.MAX_VALUE));
+ public static final EntityTypes<EntityAreaEffectCloud> AREA_EFFECT_CLOUD = register("area_effect_cloud", EntityTypes.Builder.of(EntityAreaEffectCloud::new, EnumCreatureType.MISC).noLootTable().fireImmune().sized(6.0F, 0.5F).clientTrackingRange(10).updateInterval(10)); // CraftBukkit - SPIGOT-3729: track area effect clouds
public static final EntityTypes<Armadillo> ARMADILLO = register("armadillo", EntityTypes.Builder.of(Armadillo::new, EnumCreatureType.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10));
public static final EntityTypes<EntityArmorStand> ARMOR_STAND = register("armor_stand", EntityTypes.Builder.of(EntityArmorStand::new, EnumCreatureType.MISC).sized(0.5F, 1.975F).eyeHeight(1.7775F).clientTrackingRange(10));
public static final EntityTypes<EntityTippedArrow> ARROW = register("arrow", EntityTypes.Builder.of(EntityTippedArrow::new, EnumCreatureType.MISC).noLootTable().sized(0.5F, 0.5F).eyeHeight(0.13F).clientTrackingRange(4).updateInterval(20));
@@ -399,7 +400,7 @@
return ResourceKey.create(Registries.ENTITY_TYPE, MinecraftKey.withDefaultNamespace(s));
}
- private static <T extends Entity> EntityTypes<T> register(String s, EntityTypes.Builder<T> entitytypes_builder) {
+ private static <T extends Entity> EntityTypes<T> register(String s, EntityTypes.Builder entitytypes_builder) { // CraftBukkit - decompile error
return register(vanillaEntityId(s), entitytypes_builder);
}
@@ -431,7 +432,14 @@
@Nullable
public T spawn(WorldServer worldserver, @Nullable ItemStack itemstack, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1) {
- Consumer consumer;
+ // CraftBukkit start
+ return this.spawn(worldserver, itemstack, entityhuman, blockposition, entityspawnreason, flag, flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG);
+ }
+
+ @Nullable
+ public T spawn(WorldServer worldserver, @Nullable ItemStack itemstack, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ // CraftBukkit end
+ Consumer<T> consumer; // CraftBukkit - decompile error
if (itemstack != null) {
consumer = createDefaultStackConfig(worldserver, itemstack, entityhuman);
@@ -440,7 +448,7 @@
};
}
- return this.spawn(worldserver, consumer, blockposition, entityspawnreason, flag, flag1);
+ return this.spawn(worldserver, consumer, blockposition, entityspawnreason, flag, flag1, spawnReason); // CraftBukkit
}
public static <T extends Entity> Consumer<T> createDefaultStackConfig(World world, ItemStack itemstack, @Nullable EntityHuman entityhuman) {
@@ -464,21 +472,40 @@
CustomData customdata = (CustomData) itemstack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
return !customdata.isEmpty() ? consumer.andThen((entity) -> {
- updateCustomEntityTag(world, entityhuman, entity, customdata);
+ try { updateCustomEntityTag(world, entityhuman, entity, customdata); } catch (Throwable t) { LOGGER.warn("Error loading spawn egg NBT", t); } // CraftBukkit - SPIGOT-5665
}) : consumer;
}
@Nullable
public T spawn(WorldServer worldserver, BlockPosition blockposition, EntitySpawnReason entityspawnreason) {
- return this.spawn(worldserver, (Consumer) null, blockposition, entityspawnreason, false, false);
+ // CraftBukkit start
+ return this.spawn(worldserver, blockposition, entityspawnreason, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
+ }
+
+ @Nullable
+ public T spawn(WorldServer worldserver, BlockPosition blockposition, EntitySpawnReason entityspawnreason, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ return this.spawn(worldserver, (Consumer<T>) null, blockposition, entityspawnreason, false, false, spawnReason); // CraftBukkit - decompile error
+ // CraftBukkit end
}
@Nullable
public T spawn(WorldServer worldserver, @Nullable Consumer<T> consumer, BlockPosition blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1) {
+ // CraftBukkit start
+ return this.spawn(worldserver, consumer, blockposition, entityspawnreason, flag, flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
+ }
+
+ @Nullable
+ public T spawn(WorldServer worldserver, @Nullable Consumer<T> consumer, BlockPosition blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ // CraftBukkit end
T t0 = this.create(worldserver, consumer, blockposition, entityspawnreason, flag, flag1);
if (t0 != null) {
- worldserver.addFreshEntityWithPassengers(t0);
+ // CraftBukkit start
+ worldserver.addFreshEntityWithPassengers(t0, spawnReason);
+ if (t0.isRemoved()) {
+ return null; // Don't return an entity when CreatureSpawnEvent is canceled
+ }
+ // CraftBukkit end
if (t0 instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) t0;
@@ -657,7 +684,7 @@
}
return entity;
- }).orElse((Object) null);
+ }).orElse(null); // CraftBukkit - decompile error
}
public static Stream<Entity> loadEntitiesRecursive(final List<? extends NBTBase> list, final World world, final EntitySpawnReason entityspawnreason) {
@@ -718,7 +745,7 @@
@Nullable
public T tryCast(Entity entity) {
- return entity.getType() == this ? entity : null;
+ return entity.getType() == this ? (T) entity : null; // CraftBukkit - decompile error
}
@Override
@@ -791,7 +818,7 @@
this.canSpawnFarFromPlayer = enumcreaturetype == EnumCreatureType.CREATURE || enumcreaturetype == EnumCreatureType.MISC;
}
- public static <T extends Entity> EntityTypes.Builder<T> of(EntityTypes.b<T> entitytypes_b, EnumCreatureType enumcreaturetype) {
+ public static <T extends Entity> EntityTypes.Builder<T> of(EntityTypes.b entitytypes_b, EnumCreatureType enumcreaturetype) { // CraftBukkit - decompile error
return new EntityTypes.Builder<>(entitytypes_b, enumcreaturetype);
}

View File

@@ -0,0 +1,48 @@
--- a/net/minecraft/world/entity/IEntityAngerable.java
+++ b/net/minecraft/world/entity/IEntityAngerable.java
@@ -9,6 +9,10 @@
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.World;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public interface IEntityAngerable {
String TAG_ANGER_TIME = "AngerTime";
@@ -48,14 +52,14 @@
if (entity instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) entity;
- this.setTarget(entityinsentient);
+ this.setTarget(entityinsentient, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
this.setLastHurtByMob(entityinsentient);
}
if (entity instanceof EntityHuman) {
EntityHuman entityhuman = (EntityHuman) entity;
- this.setTarget(entityhuman);
+ this.setTarget(entityhuman, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
this.setLastHurtByPlayer(entityhuman);
}
@@ -114,7 +118,7 @@
default void stopBeingAngry() {
this.setLastHurtByMob((EntityLiving) null);
this.setPersistentAngerTarget((UUID) null);
- this.setTarget((EntityLiving) null);
+ this.setTarget((EntityLiving) null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit
this.setRemainingPersistentAngerTime(0);
}
@@ -127,6 +131,8 @@
void setTarget(@Nullable EntityLiving entityliving);
+ boolean setTarget(@Nullable EntityLiving entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fireEvent); // CraftBukkit
+
boolean canAttack(EntityLiving entityliving);
@Nullable

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/IEntitySelector.java
+++ b/net/minecraft/world/entity/IEntitySelector.java
@@ -43,7 +43,7 @@
ScoreboardTeamBase.EnumTeamPush scoreboardteambase_enumteampush = scoreboardteam == null ? ScoreboardTeamBase.EnumTeamPush.ALWAYS : scoreboardteam.getCollisionRule();
return (Predicate) (scoreboardteambase_enumteampush == ScoreboardTeamBase.EnumTeamPush.NEVER ? Predicates.alwaysFalse() : IEntitySelector.NO_SPECTATORS.and((entity1) -> {
- if (!entity1.isPushable()) {
+ if (!entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API
return false;
} else if (entity.level().isClientSide && (!(entity1 instanceof EntityHuman) || !((EntityHuman) entity1).isLocalPlayer())) {
return false;

View File

@@ -0,0 +1,42 @@
--- a/net/minecraft/world/entity/Interaction.java
+++ b/net/minecraft/world/entity/Interaction.java
@@ -27,6 +27,12 @@
import net.minecraft.world.phys.Vec3D;
import org.slf4j.Logger;
+// CraftBukkit start
+import net.minecraft.world.damagesource.DamageSource;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityDamageEvent;
+// CraftBukkit end
+
public class Interaction extends Entity implements Attackable, Targeting {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -65,7 +71,7 @@
this.setHeight(nbttagcompound.getFloat("height"));
}
- DataResult dataresult;
+ DataResult<com.mojang.datafixers.util.Pair<Interaction.PlayerAction, net.minecraft.nbt.NBTBase>> dataresult; // CraftBukkit - decompile error
Logger logger;
if (nbttagcompound.contains("attack")) {
@@ -145,9 +151,16 @@
@Override
public boolean skipAttackInteraction(Entity entity) {
if (entity instanceof EntityHuman entityhuman) {
+ // CraftBukkit start
+ DamageSource source = entityhuman.damageSources().playerAttack(entityhuman);
+ EntityDamageEvent event = CraftEventFactory.callNonLivingEntityDamageEvent(this, source, 1.0F, false);
+ if (event.isCancelled()) {
+ return true;
+ }
+ // CraftBukkit end
this.attack = new Interaction.PlayerAction(entityhuman.getUUID(), this.level().getGameTime());
if (entityhuman instanceof EntityPlayer entityplayer) {
- CriterionTriggers.PLAYER_HURT_ENTITY.trigger(entityplayer, this, entityhuman.damageSources().generic(), 1.0F, 1.0F, false);
+ CriterionTriggers.PLAYER_HURT_ENTITY.trigger(entityplayer, this, source, (float) event.getFinalDamage(), 1.0F, false); // CraftBukkit
}
return !this.getResponse();

View File

@@ -0,0 +1,126 @@
--- a/net/minecraft/world/entity/Leashable.java
+++ b/net/minecraft/world/entity/Leashable.java
@@ -16,6 +16,11 @@
import net.minecraft.world.level.IMaterial;
import net.minecraft.world.level.World;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityUnleashEvent;
+import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
+// CraftBukkit end
+
public interface Leashable {
String LEASH_TAG = "leash";
@@ -45,7 +50,7 @@
default void setDelayedLeashHolderId(int i) {
this.setLeashData(new Leashable.a(i));
- dropLeash((Entity) this, false, false);
+ dropLeash((Entity & Leashable) this, false, false); // CraftBukkit - decompile error
}
default void readLeashData(NBTTagCompound nbttagcompound) {
@@ -64,7 +69,7 @@
return new Leashable.a(Either.left(nbttagcompound.getCompound("leash").getUUID("UUID")));
} else {
if (nbttagcompound.contains("leash", 11)) {
- Either<UUID, BlockPosition> either = (Either) GameProfileSerializer.readBlockPos(nbttagcompound, "leash").map(Either::right).orElse((Object) null);
+ Either<UUID, BlockPosition> either = (Either) GameProfileSerializer.readBlockPos(nbttagcompound, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error
if (either != null) {
return new Leashable.a(either);
@@ -79,6 +84,11 @@
if (leashable_a != null) {
Either<UUID, BlockPosition> either = leashable_a.delayedLeashInfo;
Entity entity = leashable_a.leashHolder;
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
+ if (entity != null && entity.pluginRemoved) {
+ return;
+ }
+ // CraftBukkit end
if (entity instanceof EntityLeash) {
EntityLeash entityleash = (EntityLeash) entity;
@@ -121,7 +131,9 @@
}
if (e0.tickCount > 100) {
+ e0.forceDrops = true; // CraftBukkit
e0.spawnAtLocation(worldserver, (IMaterial) Items.LEAD);
+ e0.forceDrops = false; // CraftBukkit
((Leashable) e0).setLeashData((Leashable.a) null);
}
}
@@ -130,11 +142,11 @@
}
default void dropLeash() {
- dropLeash((Entity) this, true, true);
+ dropLeash((Entity & Leashable) this, true, true); // CraftBukkit - decompile error
}
default void removeLeash() {
- dropLeash((Entity) this, true, false);
+ dropLeash((Entity & Leashable) this, true, false); // CraftBukkit - decompile error
}
default void onLeashRemoved() {}
@@ -151,7 +163,9 @@
WorldServer worldserver = (WorldServer) world;
if (flag1) {
+ e0.forceDrops = true; // CraftBukkit
e0.spawnAtLocation(worldserver, (IMaterial) Items.LEAD);
+ e0.forceDrops = false; // CraftBukkit
}
if (flag) {
@@ -171,7 +185,8 @@
if (leashable_a != null && leashable_a.leashHolder != null) {
if (!e0.isAlive() || !leashable_a.leashHolder.isAlive()) {
- if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
+ worldserver.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(e0.getBukkitEntity(), (!e0.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit
+ if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !e0.pluginRemoved) { // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin
((Leashable) e0).dropLeash();
} else {
((Leashable) e0).removeLeash();
@@ -205,13 +220,18 @@
}
default void leashTooFarBehaviour() {
+ // CraftBukkit start
+ if (this instanceof Entity entity) {
+ entity.level().getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(entity.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE));
+ }
+ // CraftBukkit end
this.dropLeash();
}
default void closeRangeLeashBehaviour(Entity entity) {}
default void elasticRangeLeashBehaviour(Entity entity, float f) {
- legacyElasticRangeLeashBehaviour((Entity) this, entity, f);
+ legacyElasticRangeLeashBehaviour((Entity & Leashable) this, entity, f); // CraftBukkit - decompile error
}
private static <E extends Entity & Leashable> void legacyElasticRangeLeashBehaviour(E e0, Entity entity, float f) {
@@ -223,7 +243,7 @@
}
default void setLeashedTo(Entity entity, boolean flag) {
- setLeashedTo((Entity) this, entity, flag);
+ setLeashedTo((Entity & Leashable) this, entity, flag); // CraftBukkit - decompile error
}
private static <E extends Entity & Leashable> void setLeashedTo(E e0, Entity entity, boolean flag) {
@@ -254,7 +274,7 @@
@Nullable
default Entity getLeashHolder() {
- return getLeashHolder((Entity) this);
+ return getLeashHolder((Entity & Leashable) this); // CraftBukkit - decompile error
}
@Nullable

View File

@@ -0,0 +1,17 @@
--- a/net/minecraft/world/entity/SaddleStorage.java
+++ b/net/minecraft/world/entity/SaddleStorage.java
@@ -53,6 +53,14 @@
return (Integer) this.entityData.get(this.boostTimeAccessor);
}
+ // CraftBukkit add setBoostTicks(int)
+ public void setBoostTicks(int ticks) {
+ this.boosting = true;
+ this.boostTime = 0;
+ this.entityData.set(this.boostTimeAccessor, ticks);
+ }
+ // CraftBukkit end
+
public void addAdditionalSaveData(NBTTagCompound nbttagcompound) {
nbttagcompound.putBoolean("Saddle", this.hasSaddle());
}

View File

@@ -0,0 +1,7 @@
--- a/net/minecraft/world/entity/ai/attributes/GenericAttributes.java
+++ b/net/minecraft/world/entity/ai/attributes/GenericAttributes.java
@@ -1,3 +1,4 @@
+// mc-dev import
package net.minecraft.world.entity.ai.attributes;
import net.minecraft.core.Holder;

View File

@@ -0,0 +1,33 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorAttackTargetForget.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorAttackTargetForget.java
@@ -7,6 +7,12 @@
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public class BehaviorAttackTargetForget {
private static final int TIMEOUT_TO_GET_WITHIN_ATTACK_RANGE = 200;
@@ -40,6 +46,17 @@
if (entityinsentient.canAttack(entityliving) && (!flag || !isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) && entityliving.isAlive() && entityliving.level() == entityinsentient.level() && !behaviorattacktargetforget_a.test(worldserver, entityliving)) {
return true;
} else {
+ // CraftBukkit start
+ EntityLiving old = entityinsentient.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null);
+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityinsentient, null, (old != null && !old.isAlive()) ? EntityTargetEvent.TargetReason.TARGET_DIED : EntityTargetEvent.TargetReason.FORGOT_TARGET);
+ if (event.isCancelled()) {
+ return false;
+ }
+ if (event.getTarget() != null) {
+ entityinsentient.getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, ((CraftLivingEntity) event.getTarget()).getHandle());
+ return true;
+ }
+ // CraftBukkit end
behaviorattacktargetforget_b.accept(worldserver, entityinsentient, entityliving);
memoryaccessor.erase();
return true;

View File

@@ -0,0 +1,34 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorAttackTargetSet.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorAttackTargetSet.java
@@ -7,6 +7,13 @@
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
+// CraftBukkit start
+import net.minecraft.server.level.EntityPlayer;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public class BehaviorAttackTargetSet {
public BehaviorAttackTargetSet() {}
@@ -34,6 +41,17 @@
if (!entityinsentient.canAttack(entityliving)) {
return false;
} else {
+ // CraftBukkit start
+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityinsentient, entityliving, (entityliving instanceof EntityPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY);
+ if (event.isCancelled()) {
+ return false;
+ }
+ if (event.getTarget() == null) {
+ memoryaccessor.erase();
+ return true;
+ }
+ entityliving = ((CraftLivingEntity) event.getTarget()).getHandle();
+ // CraftBukkit end
memoryaccessor.set(entityliving);
memoryaccessor1.erase();
return true;

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorCareer.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorCareer.java
@@ -9,6 +9,12 @@
import net.minecraft.world.entity.npc.EntityVillager;
import net.minecraft.world.entity.npc.VillagerProfession;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftVillager;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.VillagerCareerChangeEvent;
+// CraftBukkit end
+
public class BehaviorCareer {
public BehaviorCareer() {}
@@ -37,7 +43,14 @@
return villagerprofession.heldJobSite().test(holder);
}).findFirst();
}).ifPresent((villagerprofession) -> {
- entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(villagerprofession));
+ // CraftBukkit start - Fire VillagerCareerChangeEvent where Villager gets employed
+ VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityvillager, CraftVillager.CraftProfession.minecraftToBukkit(villagerprofession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED);
+ if (event.isCancelled()) {
+ return;
+ }
+
+ entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession())));
+ // CraftBukkit end
entityvillager.refreshBrain(worldserver);
});
return true;

View File

@@ -0,0 +1,58 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorFarm.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorFarm.java
@@ -27,6 +27,11 @@
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.gameevent.GameEvent;
+// CraftBukkit start
+import net.minecraft.world.level.block.Blocks;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class BehaviorFarm extends Behavior<EntityVillager> {
private static final int HARVEST_DURATION = 200;
@@ -82,8 +87,8 @@
protected void start(WorldServer worldserver, EntityVillager entityvillager, long i) {
if (i > this.nextOkStartTime && this.aboveFarmlandPos != null) {
- entityvillager.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new BehaviorTarget(this.aboveFarmlandPos)));
- entityvillager.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(new BehaviorTarget(this.aboveFarmlandPos), 0.5F, 1)));
+ entityvillager.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorTarget(this.aboveFarmlandPos))); // CraftBukkit - decompile error
+ entityvillager.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(new BehaviorTarget(this.aboveFarmlandPos), 0.5F, 1))); // CraftBukkit - decompile error
}
}
@@ -103,7 +108,9 @@
Block block1 = worldserver.getBlockState(this.aboveFarmlandPos.below()).getBlock();
if (block instanceof BlockCrops && ((BlockCrops) block).isMaxAge(iblockdata)) {
+ if (CraftEventFactory.callEntityChangeBlockEvent(entityvillager, this.aboveFarmlandPos, Blocks.AIR.defaultBlockState())) { // CraftBukkit
worldserver.destroyBlock(this.aboveFarmlandPos, true, entityvillager);
+ } // CraftBukkit
}
if (iblockdata.isAir() && block1 instanceof BlockSoil && entityvillager.hasFarmSeeds()) {
@@ -120,9 +127,11 @@
ItemBlock itemblock = (ItemBlock) item;
IBlockData iblockdata1 = itemblock.getBlock().defaultBlockState();
+ if (CraftEventFactory.callEntityChangeBlockEvent(entityvillager, this.aboveFarmlandPos, iblockdata1)) { // CraftBukkit
worldserver.setBlockAndUpdate(this.aboveFarmlandPos, iblockdata1);
worldserver.gameEvent((Holder) GameEvent.BLOCK_PLACE, this.aboveFarmlandPos, GameEvent.a.of(entityvillager, iblockdata1));
flag = true;
+ } // CraftBukkit
}
}
@@ -142,8 +151,8 @@
this.aboveFarmlandPos = this.getValidFarmland(worldserver);
if (this.aboveFarmlandPos != null) {
this.nextOkStartTime = i + 20L;
- entityvillager.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(new BehaviorTarget(this.aboveFarmlandPos), 0.5F, 1)));
- entityvillager.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new BehaviorTarget(this.aboveFarmlandPos)));
+ entityvillager.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(new BehaviorTarget(this.aboveFarmlandPos), 0.5F, 1))); // CraftBukkit - decompile error
+ entityvillager.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorTarget(this.aboveFarmlandPos))); // CraftBukkit - decompile error
}
}
}

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorFindAdmirableItem.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorFindAdmirableItem.java
@@ -28,6 +28,20 @@
EntityItem entityitem = (EntityItem) behaviorbuilder_b.get(memoryaccessor2);
if (behaviorbuilder_b.tryGet(memoryaccessor3).isEmpty() && predicate.test(entityliving) && entityitem.closerThan(entityliving, (double) i) && entityliving.level().getWorldBorder().isWithinBounds(entityitem.blockPosition()) && entityliving.canPickUpLoot()) {
+ // CraftBukkit start
+ if (entityliving instanceof net.minecraft.world.entity.animal.allay.Allay) {
+ org.bukkit.event.entity.EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetEvent(entityliving, entityitem, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY);
+
+ if (event.isCancelled()) {
+ return false;
+ }
+ if (!(event.getTarget() instanceof EntityItem)) {
+ memoryaccessor2.erase();
+ }
+
+ entityitem = (EntityItem) ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle();
+ }
+ // CraftBukkit end
MemoryTarget memorytarget = new MemoryTarget(new BehaviorPositionEntity(entityitem, false), f, 0);
memoryaccessor.set(new BehaviorPositionEntity(entityitem, true));

View File

@@ -0,0 +1,38 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorFollowAdult.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorFollowAdult.java
@@ -8,6 +8,13 @@
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.MemoryTarget;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
+// CraftBukkit end
+
public class BehaviorFollowAdult {
public BehaviorFollowAdult() {}
@@ -25,9 +32,20 @@
if (!entityageable.isBaby()) {
return false;
} else {
- EntityAgeable entityageable1 = (EntityAgeable) behaviorbuilder_b.get(memoryaccessor);
+ EntityLiving entityageable1 = (EntityAgeable) behaviorbuilder_b.get(memoryaccessor); // CraftBukkit - type
if (entityageable.closerThan(entityageable1, (double) (uniformint.getMaxValue() + 1)) && !entityageable.closerThan(entityageable1, (double) uniformint.getMinValue())) {
+ // CraftBukkit start
+ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(entityageable, entityageable1, EntityTargetEvent.TargetReason.FOLLOW_LEADER);
+ if (event.isCancelled()) {
+ return false;
+ }
+ if (event.getTarget() == null) {
+ memoryaccessor.erase();
+ return true;
+ }
+ entityageable1 = ((CraftLivingEntity) event.getTarget()).getHandle();
+ // CraftBukkit end
MemoryTarget memorytarget = new MemoryTarget(new BehaviorPositionEntity(entityageable1, false), (Float) function.apply(entityageable), uniformint.getMinValue() - 1);
memoryaccessor1.set(new BehaviorPositionEntity(entityageable1, true));

View File

@@ -0,0 +1,39 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorInteractDoor.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorInteractDoor.java
@@ -61,6 +61,13 @@
BlockDoor blockdoor = (BlockDoor) iblockdata.getBlock();
if (!blockdoor.isOpen(iblockdata)) {
+ // CraftBukkit start - entities opening doors
+ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.level(), blockposition));
+ entityliving.level().getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return false;
+ }
+ // CraftBukkit end
blockdoor.setOpen(entityliving, worldserver, iblockdata, blockposition, true);
}
@@ -76,6 +83,13 @@
BlockDoor blockdoor1 = (BlockDoor) iblockdata1.getBlock();
if (!blockdoor1.isOpen(iblockdata1)) {
+ // CraftBukkit start - entities opening doors
+ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.level(), blockposition1));
+ entityliving.level().getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return false;
+ }
+ // CraftBukkit end
blockdoor1.setOpen(entityliving, worldserver, iblockdata1, blockposition1, true);
optional = rememberDoorToClose(memoryaccessor1, optional, worldserver, blockposition1);
}
@@ -129,7 +143,7 @@
}
private static boolean areOtherMobsComingThroughDoor(EntityLiving entityliving, BlockPosition blockposition, Optional<List<EntityLiving>> optional) {
- return optional.isEmpty() ? false : ((List) optional.get()).stream().filter((entityliving1) -> {
+ return optional.isEmpty() ? false : (optional.get()).stream().filter((entityliving1) -> { // CraftBukkit - decompile error
return entityliving1.getType() == entityliving.getType();
}).filter((entityliving1) -> {
return blockposition.closerToCenterThan(entityliving1.position(), 2.0D);

View File

@@ -0,0 +1,43 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorMakeLove.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorMakeLove.java
@@ -18,6 +18,11 @@
import net.minecraft.world.entity.npc.EntityVillager;
import net.minecraft.world.level.pathfinder.PathEntity;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+// CraftBukkit end
+
public class BehaviorMakeLove extends Behavior<EntityVillager> {
private long birthTimestamp;
@@ -114,11 +119,17 @@
if (entityvillager2 == null) {
return Optional.empty();
} else {
- entityvillager.setAge(6000);
- entityvillager1.setAge(6000);
entityvillager2.setAge(-24000);
entityvillager2.moveTo(entityvillager.getX(), entityvillager.getY(), entityvillager.getZ(), 0.0F, 0.0F);
- worldserver.addFreshEntityWithPassengers(entityvillager2);
+ // CraftBukkit start - call EntityBreedEvent
+ if (CraftEventFactory.callEntityBreedEvent(entityvillager2, entityvillager, entityvillager1, null, null, 0).isCancelled()) {
+ return Optional.empty();
+ }
+ // Move age setting down
+ entityvillager.setAge(6000);
+ entityvillager1.setAge(6000);
+ worldserver.addFreshEntityWithPassengers(entityvillager2, CreatureSpawnEvent.SpawnReason.BREEDING);
+ // CraftBukkit end
worldserver.broadcastEntityEvent(entityvillager2, (byte) 12);
return Optional.of(entityvillager2);
}
@@ -127,6 +138,6 @@
private void giveBedToChild(WorldServer worldserver, EntityVillager entityvillager, BlockPosition blockposition) {
GlobalPos globalpos = GlobalPos.of(worldserver.dimension(), blockposition);
- entityvillager.getBrain().setMemory(MemoryModuleType.HOME, (Object) globalpos);
+ entityvillager.getBrain().setMemory(MemoryModuleType.HOME, globalpos); // CraftBukkit - decompile error
}
}

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorProfession.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorProfession.java
@@ -6,6 +6,12 @@
import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.world.entity.npc.VillagerProfession;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftVillager;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.VillagerCareerChangeEvent;
+// CraftBukkit end
+
public class BehaviorProfession {
public BehaviorProfession() {}
@@ -17,7 +23,14 @@
VillagerData villagerdata = entityvillager.getVillagerData();
if (villagerdata.getProfession() != VillagerProfession.NONE && villagerdata.getProfession() != VillagerProfession.NITWIT && entityvillager.getVillagerXp() == 0 && villagerdata.getLevel() <= 1) {
- entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(VillagerProfession.NONE));
+ // CraftBukkit start
+ VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityvillager, CraftVillager.CraftProfession.minecraftToBukkit(VillagerProfession.NONE), VillagerCareerChangeEvent.ChangeReason.LOSING_JOB);
+ if (event.isCancelled()) {
+ return false;
+ }
+
+ entityvillager.setVillagerData(entityvillager.getVillagerData().setProfession(CraftVillager.CraftProfession.bukkitToMinecraft(event.getProfession())));
+ // CraftBukkit end
entityvillager.refreshBrain(worldserver);
return true;
} else {

View File

@@ -0,0 +1,51 @@
--- a/net/minecraft/world/entity/ai/behavior/BehaviorUtil.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorUtil.java
@@ -60,7 +60,7 @@
}
public static void lookAtEntity(EntityLiving entityliving, EntityLiving entityliving1) {
- entityliving.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new BehaviorPositionEntity(entityliving1, true)));
+ entityliving.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorPositionEntity(entityliving1, true))); // CraftBukkit - decompile error
}
private static void setWalkAndLookTargetMemoriesToEachOther(EntityLiving entityliving, EntityLiving entityliving1, float f, int i) {
@@ -79,8 +79,8 @@
public static void setWalkAndLookTargetMemories(EntityLiving entityliving, BehaviorPosition behaviorposition, float f, int i) {
MemoryTarget memorytarget = new MemoryTarget(behaviorposition, f, i);
- entityliving.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) behaviorposition);
- entityliving.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) memorytarget);
+ entityliving.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, behaviorposition); // CraftBukkit - decompile error
+ entityliving.getBrain().setMemory(MemoryModuleType.WALK_TARGET, memorytarget); // CraftBukkit - decompile error
}
public static void throwItem(EntityLiving entityliving, ItemStack itemstack, Vec3D vec3d) {
@@ -90,6 +90,7 @@
}
public static void throwItem(EntityLiving entityliving, ItemStack itemstack, Vec3D vec3d, Vec3D vec3d1, float f) {
+ if (itemstack.isEmpty()) return; // CraftBukkit - SPIGOT-4940: no empty loot
double d0 = entityliving.getEyeY() - (double) f;
EntityItem entityitem = new EntityItem(entityliving.level(), entityliving.getX(), d0, entityliving.getZ(), itemstack);
@@ -99,12 +100,19 @@
vec3d2 = vec3d2.normalize().multiply(vec3d1.x, vec3d1.y, vec3d1.z);
entityitem.setDeltaMovement(vec3d2);
entityitem.setDefaultPickUpDelay();
+ // CraftBukkit start
+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(entityliving.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
+ entityitem.level().getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
entityliving.level().addFreshEntity(entityitem);
}
public static SectionPosition findSectionClosestToVillage(WorldServer worldserver, SectionPosition sectionposition, int i) {
int j = worldserver.sectionsToVillage(sectionposition);
- Stream stream = SectionPosition.cube(sectionposition, i).filter((sectionposition1) -> {
+ Stream<SectionPosition> stream = SectionPosition.cube(sectionposition, i).filter((sectionposition1) -> { // CraftBukkit - decompile error
return worldserver.sectionsToVillage(sectionposition1) < j;
});

View File

@@ -0,0 +1,68 @@
--- a/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java
+++ b/net/minecraft/world/entity/ai/behavior/PrepareRamNearestTarget.java
@@ -31,6 +31,13 @@
import net.minecraft.world.level.pathfinder.PathfinderNormal;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import net.minecraft.server.level.EntityPlayer;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public class PrepareRamNearestTarget<E extends EntityCreature> extends Behavior<E> {
public static final int TIME_OUT_DURATION = 160;
@@ -63,6 +70,13 @@
return this.ramTargeting.test(worldserver, entitycreature, entityliving);
});
}).ifPresent((entityliving) -> {
+ // CraftBukkit start
+ EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(entitycreature, entityliving, (entityliving instanceof EntityPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY);
+ if (event.isCancelled() || event.getTarget() == null) {
+ return;
+ }
+ entityliving = ((CraftLivingEntity) event.getTarget()).getHandle();
+ // CraftBukkit end
this.chooseRamPosition(entitycreature, entityliving);
});
}
@@ -72,7 +86,7 @@
if (!behaviorcontroller.hasMemoryValue(MemoryModuleType.RAM_TARGET)) {
worldserver.broadcastEntityEvent(e0, (byte) 59);
- behaviorcontroller.setMemory(MemoryModuleType.RAM_COOLDOWN_TICKS, (Object) this.getCooldownOnFail.applyAsInt(e0));
+ behaviorcontroller.setMemory(MemoryModuleType.RAM_COOLDOWN_TICKS, this.getCooldownOnFail.applyAsInt(e0)); // CraftBukkit - decompile error
}
}
@@ -83,8 +97,8 @@
protected void tick(WorldServer worldserver, E e0, long i) {
if (!this.ramCandidate.isEmpty()) {
- e0.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(((PrepareRamNearestTarget.a) this.ramCandidate.get()).getStartPosition(), this.walkSpeed, 0)));
- e0.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (Object) (new BehaviorPositionEntity(((PrepareRamNearestTarget.a) this.ramCandidate.get()).getTarget(), true)));
+ e0.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(((PrepareRamNearestTarget.a) this.ramCandidate.get()).getStartPosition(), this.walkSpeed, 0))); // CraftBukkit - decompile error
+ e0.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorPositionEntity(((PrepareRamNearestTarget.a) this.ramCandidate.get()).getTarget(), true))); // CraftBukkit - decompile error
boolean flag = !((PrepareRamNearestTarget.a) this.ramCandidate.get()).getTarget().blockPosition().equals(((PrepareRamNearestTarget.a) this.ramCandidate.get()).getTargetPosition());
if (flag) {
@@ -101,7 +115,7 @@
}
if (i - (Long) this.reachedRamPositionTimestamp.get() >= (long) this.ramPrepareTime) {
- e0.getBrain().setMemory(MemoryModuleType.RAM_TARGET, (Object) this.getEdgeOfBlock(blockposition, ((PrepareRamNearestTarget.a) this.ramCandidate.get()).getTargetPosition()));
+ e0.getBrain().setMemory(MemoryModuleType.RAM_TARGET, this.getEdgeOfBlock(blockposition, ((PrepareRamNearestTarget.a) this.ramCandidate.get()).getTargetPosition())); // CraftBukkit - decompile error
worldserver.playSound((EntityHuman) null, (Entity) e0, (SoundEffect) this.getPrepareRamSound.apply(e0), SoundCategory.NEUTRAL, 1.0F, e0.getVoicePitch());
this.ramCandidate = Optional.empty();
}
@@ -153,7 +167,7 @@
}
NavigationAbstract navigationabstract = entitycreature.getNavigation();
- Stream stream = list.stream();
+ Stream<BlockPosition> stream = list.stream(); // CraftBukkit - decompile error
BlockPosition blockposition1 = entitycreature.blockPosition();
Objects.requireNonNull(blockposition1);

View File

@@ -0,0 +1,15 @@
--- a/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java
+++ b/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java
@@ -39,6 +39,12 @@
if (worldserver.getBlockState(blockposition2).isAir()) {
IBlockData iblockdata = block.defaultBlockState();
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityliving, blockposition2, iblockdata)) {
+ memoryaccessor2.erase();
+ return true;
+ }
+ // CraftBukkit end
worldserver.setBlock(blockposition2, iblockdata, 3);
worldserver.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition2, GameEvent.a.of(entityliving, iblockdata));
worldserver.playSound((EntityHuman) null, (Entity) entityliving, SoundEffects.FROG_LAY_SPAWN, SoundCategory.BLOCKS, 1.0F, 1.0F);

View File

@@ -0,0 +1,22 @@
--- a/net/minecraft/world/entity/ai/behavior/warden/Digging.java
+++ b/net/minecraft/world/entity/ai/behavior/warden/Digging.java
@@ -10,6 +10,10 @@
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.monster.warden.Warden;
+// CraftBukkit start - imports
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class Digging<E extends Warden> extends Behavior<E> {
public Digging(int i) {
@@ -37,7 +41,7 @@
protected void stop(WorldServer worldserver, E e0, long i) {
if (e0.getRemovalReason() == null) {
- e0.remove(Entity.RemovalReason.DISCARDED);
+ e0.remove(Entity.RemovalReason.DISCARDED, EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause
}
}

View File

@@ -0,0 +1,15 @@
--- a/net/minecraft/world/entity/ai/goal/PathfinderGoalBreakDoor.java
+++ b/net/minecraft/world/entity/ai/goal/PathfinderGoalBreakDoor.java
@@ -72,6 +72,12 @@
}
if (this.breakTime == this.getDoorBreakTime() && this.isValidDifficulty(this.mob.level().getDifficulty())) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.mob, this.doorPos).isCancelled()) {
+ this.start();
+ return;
+ }
+ // CraftBukkit end
this.mob.level().removeBlock(this.doorPos, false);
this.mob.level().levelEvent(1021, this.doorPos, 0);
this.mob.level().levelEvent(2001, this.doorPos, Block.getId(this.mob.level().getBlockState(this.doorPos)));

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/ai/goal/PathfinderGoalEatTile.java
+++ b/net/minecraft/world/entity/ai/goal/PathfinderGoalEatTile.java
@@ -11,6 +11,10 @@
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.block.state.predicate.BlockStatePredicate;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class PathfinderGoalEatTile extends PathfinderGoal {
private static final int EAT_ANIMATION_TICKS = 40;
@@ -64,7 +68,7 @@
BlockPosition blockposition = this.mob.blockPosition();
if (PathfinderGoalEatTile.IS_TALL_GRASS.test(this.level.getBlockState(blockposition))) {
- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, Blocks.AIR.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
this.level.destroyBlock(blockposition, false);
}
@@ -73,7 +77,7 @@
BlockPosition blockposition1 = blockposition.below();
if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) {
- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.AIR.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2);
}

View File

@@ -0,0 +1,26 @@
--- a/net/minecraft/world/entity/ai/goal/PathfinderGoalRemoveBlock.java
+++ b/net/minecraft/world/entity/ai/goal/PathfinderGoalRemoveBlock.java
@@ -22,6 +22,11 @@
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.block.CraftBlock;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget {
private final Block blockToRemove;
@@ -97,6 +102,11 @@
}
if (this.ticksSinceReachedGoal > 60) {
+ // CraftBukkit start - Step on eggs
+ if (!CraftEventFactory.callEntityInteractEvent(this.removerMob, CraftBlock.at(world, blockposition1))) {
+ return;
+ }
+ // CraftBukkit end
world.removeBlock(blockposition1, false);
if (!world.isClientSide) {
for (int i = 0; i < 20; ++i) {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/PathfinderGoalSit.java
+++ b/net/minecraft/world/entity/ai/goal/PathfinderGoalSit.java
@@ -22,7 +22,7 @@
@Override
public boolean canUse() {
if (!this.mob.isTame()) {
- return false;
+ return this.mob.isOrderedToSit() && this.mob.getTarget() == null; // CraftBukkit - Allow sitting for wild animals
} else if (this.mob.isInWaterOrBubble()) {
return false;
} else if (!this.mob.onGround()) {

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/world/entity/ai/goal/PathfinderGoalTame.java
+++ b/net/minecraft/world/entity/ai/goal/PathfinderGoalTame.java
@@ -7,6 +7,11 @@
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class PathfinderGoalTame extends PathfinderGoal {
private final EntityHorseAbstract horse;
@@ -63,7 +68,7 @@
int i = this.horse.getTemper();
int j = this.horse.getMaxTemper();
- if (j > 0 && this.horse.getRandom().nextInt(j) < i) {
+ if (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { // CraftBukkit - fire EntityTameEvent
this.horse.tameWithName(entityhuman);
return;
}

View File

@@ -0,0 +1,41 @@
--- a/net/minecraft/world/entity/ai/goal/PathfinderGoalTempt.java
+++ b/net/minecraft/world/entity/ai/goal/PathfinderGoalTempt.java
@@ -11,6 +11,13 @@
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.ItemStack;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
+// CraftBukkit end
+
public class PathfinderGoalTempt extends PathfinderGoal {
private static final PathfinderTargetCondition TEMPT_TARGETING = PathfinderTargetCondition.forNonCombat().ignoreLineOfSight();
@@ -23,7 +30,7 @@
private double pRotX;
private double pRotY;
@Nullable
- protected EntityHuman player;
+ protected EntityLiving player; // CraftBukkit
private int calmDown;
private boolean isRunning;
private final Predicate<ItemStack> items;
@@ -47,6 +54,15 @@
return false;
} else {
this.player = getServerLevel((Entity) this.mob).getNearestPlayer(this.targetingConditions.range(this.mob.getAttributeValue(GenericAttributes.TEMPT_RANGE)), this.mob);
+ // CraftBukkit start
+ if (this.player != null) {
+ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this.mob, this.player, EntityTargetEvent.TargetReason.TEMPT);
+ if (event.isCancelled()) {
+ return false;
+ }
+ this.player = (event.getTarget() == null) ? null : ((CraftLivingEntity) event.getTarget()).getHandle();
+ }
+ // CraftBukkit end
return this.player != null;
}
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/target/PathfinderGoalDefendVillage.java
+++ b/net/minecraft/world/entity/ai/goal/target/PathfinderGoalDefendVillage.java
@@ -61,7 +61,7 @@
@Override
public void start() {
- this.golem.setTarget(this.potentialTarget);
+ this.golem.setTarget(this.potentialTarget, org.bukkit.event.entity.EntityTargetEvent.TargetReason.DEFEND_VILLAGE, true); // CraftBukkit - reason
super.start();
}
}

View File

@@ -0,0 +1,19 @@
--- a/net/minecraft/world/entity/ai/goal/target/PathfinderGoalHurtByTarget.java
+++ b/net/minecraft/world/entity/ai/goal/target/PathfinderGoalHurtByTarget.java
@@ -67,7 +67,7 @@
@Override
public void start() {
- this.mob.setTarget(this.mob.getLastHurtByMob());
+ this.mob.setTarget(this.mob.getLastHurtByMob(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason
this.targetMob = this.mob.getTarget();
this.timestamp = this.mob.getLastHurtByMobTimestamp();
this.unseenMemoryTicks = 300;
@@ -114,6 +114,6 @@
}
protected void alertOther(EntityInsentient entityinsentient, EntityLiving entityliving) {
- entityinsentient.setTarget(entityliving);
+ entityinsentient.setTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit - reason
}
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/target/PathfinderGoalNearestAttackableTarget.java
+++ b/net/minecraft/world/entity/ai/goal/target/PathfinderGoalNearestAttackableTarget.java
@@ -70,7 +70,7 @@
@Override
public void start() {
- this.mob.setTarget(this.target);
+ this.mob.setTarget(this.target, target instanceof EntityPlayer ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // CraftBukkit - reason
super.start();
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/target/PathfinderGoalOwnerHurtByTarget.java
+++ b/net/minecraft/world/entity/ai/goal/target/PathfinderGoalOwnerHurtByTarget.java
@@ -38,7 +38,7 @@
@Override
public void start() {
- this.mob.setTarget(this.ownerLastHurtBy);
+ this.mob.setTarget(this.ownerLastHurtBy, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit - reason
EntityLiving entityliving = this.tameAnimal.getOwner();
if (entityliving != null) {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/goal/target/PathfinderGoalOwnerHurtTarget.java
+++ b/net/minecraft/world/entity/ai/goal/target/PathfinderGoalOwnerHurtTarget.java
@@ -38,7 +38,7 @@
@Override
public void start() {
- this.mob.setTarget(this.ownerLastHurt);
+ this.mob.setTarget(this.ownerLastHurt, org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true); // CraftBukkit - reason
EntityLiving entityliving = this.tameAnimal.getOwner();
if (entityliving != null) {

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/ai/goal/target/PathfinderGoalTarget.java
+++ b/net/minecraft/world/entity/ai/goal/target/PathfinderGoalTarget.java
@@ -11,6 +11,10 @@
import net.minecraft.world.level.pathfinder.PathPoint;
import net.minecraft.world.scores.ScoreboardTeam;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public abstract class PathfinderGoalTarget extends PathfinderGoal {
private static final int EMPTY_REACH_CACHE = 0;
@@ -69,7 +73,7 @@
}
}
- this.mob.setTarget(entityliving);
+ this.mob.setTarget(entityliving, EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // CraftBukkit
return true;
}
}
@@ -89,7 +93,7 @@
@Override
public void stop() {
- this.mob.setTarget((EntityLiving) null);
+ this.mob.setTarget((EntityLiving) null, EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit
this.targetMob = null;
}

View File

@@ -0,0 +1,45 @@
--- a/net/minecraft/world/entity/ai/sensing/TemptingSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/TemptingSensor.java
@@ -19,6 +19,14 @@
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.ItemStack;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
+// CraftBukkit end
+
public class TemptingSensor extends Sensor<EntityCreature> {
private static final PathfinderTargetCondition TEMPT_TARGETING = PathfinderTargetCondition.forNonCombat().ignoreLineOfSight();
@@ -31,7 +39,7 @@
protected void doTick(WorldServer worldserver, EntityCreature entitycreature) {
BehaviorController<?> behaviorcontroller = entitycreature.getBrain();
PathfinderTargetCondition pathfindertargetcondition = TemptingSensor.TEMPT_TARGETING.copy().range((double) ((float) entitycreature.getAttributeValue(GenericAttributes.TEMPT_RANGE)));
- Stream stream = worldserver.players().stream().filter(IEntitySelector.NO_SPECTATORS).filter((entityplayer) -> {
+ Stream<net.minecraft.server.level.EntityPlayer> stream = worldserver.players().stream().filter(IEntitySelector.NO_SPECTATORS).filter((entityplayer) -> { // CraftBukkit - decompile error
return pathfindertargetcondition.test(worldserver, entitycreature, entityplayer);
}).filter(this::playerHoldingTemptation).filter((entityplayer) -> {
return !entitycreature.hasPassenger((Entity) entityplayer);
@@ -43,7 +51,17 @@
if (!list.isEmpty()) {
EntityHuman entityhuman = (EntityHuman) list.get(0);
- behaviorcontroller.setMemory(MemoryModuleType.TEMPTING_PLAYER, (Object) entityhuman);
+ // CraftBukkit start
+ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(entitycreature, entityhuman, EntityTargetEvent.TargetReason.TEMPT);
+ if (event.isCancelled()) {
+ return;
+ }
+ if (event.getTarget() instanceof HumanEntity) {
+ behaviorcontroller.setMemory(MemoryModuleType.TEMPTING_PLAYER, ((CraftHumanEntity) event.getTarget()).getHandle());
+ } else {
+ behaviorcontroller.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
+ }
+ // CraftBukkit end
} else {
behaviorcontroller.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ai/village/VillageSiege.java
+++ b/net/minecraft/world/entity/ai/village/VillageSiege.java
@@ -121,7 +121,7 @@
}
entityzombie.moveTo(vec3d.x, vec3d.y, vec3d.z, worldserver.random.nextFloat() * 360.0F, 0.0F);
- worldserver.addFreshEntityWithPassengers(entityzombie);
+ worldserver.addFreshEntityWithPassengers(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_INVASION); // CraftBukkit
}
}

View File

@@ -0,0 +1,47 @@
--- a/net/minecraft/world/entity/ambient/EntityBat.java
+++ b/net/minecraft/world/entity/ambient/EntityBat.java
@@ -30,6 +30,10 @@
import net.minecraft.world.level.levelgen.HeightMap;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class EntityBat extends EntityAmbient {
public static final float FLAP_LENGTH_SECONDS = 0.5F;
@@ -144,13 +148,13 @@
this.yHeadRot = (float) this.random.nextInt(360);
}
- if (worldserver.getNearestPlayer(EntityBat.BAT_RESTING_TARGETING, this) != null) {
+ if (worldserver.getNearestPlayer(EntityBat.BAT_RESTING_TARGETING, this) != null && CraftEventFactory.handleBatToggleSleepEvent(this, true)) { // CraftBukkit - Call BatToggleSleepEvent
this.setResting(false);
if (!flag) {
worldserver.levelEvent((EntityHuman) null, 1025, blockposition, 0);
}
}
- } else {
+ } else if (CraftEventFactory.handleBatToggleSleepEvent(this, true)) { // CraftBukkit - Call BatToggleSleepEvent
this.setResting(false);
if (!flag) {
worldserver.levelEvent((EntityHuman) null, 1025, blockposition, 0);
@@ -177,7 +181,7 @@
this.zza = 0.5F;
this.setYRot(this.getYRot() + f1);
- if (this.random.nextInt(100) == 0 && worldserver.getBlockState(blockposition1).isRedstoneConductor(worldserver, blockposition1)) {
+ if (this.random.nextInt(100) == 0 && worldserver.getBlockState(blockposition1).isRedstoneConductor(worldserver, blockposition1) && CraftEventFactory.handleBatToggleSleepEvent(this, false)) { // CraftBukkit - Call BatToggleSleepEvent
this.setResting(true);
}
}
@@ -202,7 +206,7 @@
if (this.isInvulnerableTo(worldserver, damagesource)) {
return false;
} else {
- if (this.isResting()) {
+ if (this.isResting() && CraftEventFactory.handleBatToggleSleepEvent(this, true)) { // CraftBukkit - Call BatToggleSleepEvent
this.setResting(false);
}

View File

@@ -0,0 +1,50 @@
--- a/net/minecraft/world/entity/animal/Bucketable.java
+++ b/net/minecraft/world/entity/animal/Bucketable.java
@@ -17,6 +17,14 @@
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.World;
+// CraftBukkit start
+import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.player.PlayerBucketEntityEvent;
+// CraftBukkit end
+
public interface Bucketable {
boolean fromBucket();
@@ -93,10 +101,22 @@
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.WATER_BUCKET && t0.isAlive()) {
- t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F);
+ // CraftBukkit start
+ // t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F); // CraftBukkit - moved down
ItemStack itemstack1 = ((Bucketable) t0).getBucketItemStack();
((Bucketable) t0).saveToBucketTag(itemstack1);
+
+ PlayerBucketEntityEvent playerBucketFishEvent = CraftEventFactory.callPlayerFishBucketEvent(t0, entityhuman, itemstack, itemstack1, enumhand);
+ itemstack1 = CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket());
+ if (playerBucketFishEvent.isCancelled()) {
+ ((EntityPlayer) entityhuman).containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket
+ t0.getBukkitEntity().update((EntityPlayer) entityhuman); // We need to play out these packets as the client assumes the fish is gone
+ t0.refreshEntityData((EntityPlayer) entityhuman); // Need to send data such as the display name to client
+ return Optional.of(EnumInteractionResult.FAIL);
+ }
+ t0.playSound(((Bucketable) t0).getPickupSound(), 1.0F, 1.0F);
+ // CraftBukkit end
ItemStack itemstack2 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, itemstack1, false);
entityhuman.setItemInHand(enumhand, itemstack2);
@@ -106,7 +126,7 @@
CriterionTriggers.FILLED_BUCKET.trigger((EntityPlayer) entityhuman, itemstack1);
}
- t0.discard();
+ t0.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
return Optional.of(EnumInteractionResult.SUCCESS);
} else {
return Optional.empty();

View File

@@ -0,0 +1,105 @@
--- a/net/minecraft/world/entity/animal/EntityAnimal.java
+++ b/net/minecraft/world/entity/animal/EntityAnimal.java
@@ -35,12 +35,20 @@
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.pathfinder.PathType;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityBreedEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.EntityEnterLoveModeEvent;
+// CraftBukkit end
+
public abstract class EntityAnimal extends EntityAgeable {
protected static final int PARENT_AGE_AFTER_BREEDING = 6000;
public int inLove;
@Nullable
public UUID loveCause;
+ public ItemStack breedItem; // CraftBukkit - Add breedItem variable
protected EntityAnimal(EntityTypes<? extends EntityAnimal> entitytypes, World world) {
super(entitytypes, world);
@@ -82,9 +90,15 @@
}
@Override
- protected void actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f) {
+ // CraftBukkit start - void -> boolean
+ public boolean actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f, EntityDamageEvent event) {
+ boolean damageResult = super.actuallyHurt(worldserver, damagesource, f, event);
+ if (!damageResult) {
+ return false;
+ }
this.resetLove();
- super.actuallyHurt(worldserver, damagesource, f);
+ return true;
+ // CraftBukkit end
}
@Override
@@ -188,10 +202,17 @@
}
public void setInLove(@Nullable EntityHuman entityhuman) {
- this.inLove = 600;
+ // CraftBukkit start
+ EntityEnterLoveModeEvent entityEnterLoveModeEvent = CraftEventFactory.callEntityEnterLoveModeEvent(entityhuman, this, 600);
+ if (entityEnterLoveModeEvent.isCancelled()) {
+ return;
+ }
+ this.inLove = entityEnterLoveModeEvent.getTicksInLove();
+ // CraftBukkit end
if (entityhuman != null) {
this.loveCause = entityhuman.getUUID();
}
+ this.breedItem = entityhuman.getInventory().getSelected(); // CraftBukkit
this.level().broadcastEntityEvent(this, (byte) 18);
}
@@ -233,12 +254,29 @@
if (entityageable != null) {
entityageable.setBaby(true);
entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F);
- this.finalizeSpawnChildFromBreeding(worldserver, entityanimal, entityageable);
- worldserver.addFreshEntityWithPassengers(entityageable);
+ // CraftBukkit start - call EntityBreedEvent
+ EntityPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> {
+ return Optional.ofNullable(entityanimal.getLoveCause());
+ }).orElse(null);
+ int experience = this.getRandom().nextInt(7) + 1;
+ EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, entityanimal, breeder, this.breedItem, experience);
+ if (entityBreedEvent.isCancelled()) {
+ return;
+ }
+ experience = entityBreedEvent.getExperience();
+ this.finalizeSpawnChildFromBreeding(worldserver, entityanimal, entityageable, experience);
+ worldserver.addFreshEntityWithPassengers(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING);
+ // CraftBukkit end
}
}
public void finalizeSpawnChildFromBreeding(WorldServer worldserver, EntityAnimal entityanimal, @Nullable EntityAgeable entityageable) {
+ // CraftBukkit start
+ this.finalizeSpawnChildFromBreeding(worldserver, entityanimal, entityageable, this.getRandom().nextInt(7) + 1);
+ }
+
+ public void finalizeSpawnChildFromBreeding(WorldServer worldserver, EntityAnimal entityanimal, @Nullable EntityAgeable entityageable, int experience) {
+ // CraftBukkit end
Optional.ofNullable(this.getLoveCause()).or(() -> {
return Optional.ofNullable(entityanimal.getLoveCause());
}).ifPresent((entityplayer) -> {
@@ -251,7 +289,11 @@
entityanimal.resetLove();
worldserver.broadcastEntityEvent(this, (byte) 18);
if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
- worldserver.addFreshEntity(new EntityExperienceOrb(worldserver, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1));
+ // CraftBukkit start - use event experience
+ if (experience > 0) {
+ worldserver.addFreshEntity(new EntityExperienceOrb(worldserver, this.getX(), this.getY(), this.getZ(), experience));
+ }
+ // CraftBukkit end
}
}

View File

@@ -0,0 +1,127 @@
--- a/net/minecraft/world/entity/animal/EntityBee.java
+++ b/net/minecraft/world/entity/animal/EntityBee.java
@@ -93,6 +93,12 @@
import net.minecraft.world.level.pathfinder.PathType;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityPotionEffectEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityBird {
public static final float FLAP_DEGREES_PER_TICK = 120.32113F;
@@ -198,12 +204,19 @@
@Override
public void addAdditionalSaveData(NBTTagCompound nbttagcompound) {
+ // CraftBukkit start - selectively save data
+ addAdditionalSaveData(nbttagcompound, true);
+ }
+
+ @Override
+ public void addAdditionalSaveData(NBTTagCompound nbttagcompound, boolean includeAll) {
+ // CraftBukkit end
super.addAdditionalSaveData(nbttagcompound);
- if (this.hasHive()) {
+ if (includeAll && this.hasHive()) { // CraftBukkit - selectively save hive
nbttagcompound.put("hive_pos", GameProfileSerializer.writeBlockPos(this.getHivePos()));
}
- if (this.hasSavedFlowerPos()) {
+ if (includeAll && this.hasSavedFlowerPos()) { // CraftBukkit - selectively save flower
nbttagcompound.put("flower_pos", GameProfileSerializer.writeBlockPos(this.getSavedFlowerPos()));
}
@@ -223,8 +236,8 @@
this.ticksWithoutNectarSinceExitingHive = nbttagcompound.getInt("TicksSincePollination");
this.stayOutOfHiveCountdown = nbttagcompound.getInt("CannotEnterHiveTicks");
this.numCropsGrownSincePollination = nbttagcompound.getInt("CropsGrownSincePollination");
- this.hivePos = (BlockPosition) GameProfileSerializer.readBlockPos(nbttagcompound, "hive_pos").orElse((Object) null);
- this.savedFlowerPos = (BlockPosition) GameProfileSerializer.readBlockPos(nbttagcompound, "flower_pos").orElse((Object) null);
+ this.hivePos = (BlockPosition) GameProfileSerializer.readBlockPos(nbttagcompound, "hive_pos").orElse(null); // CraftBukkit - decompile error
+ this.savedFlowerPos = (BlockPosition) GameProfileSerializer.readBlockPos(nbttagcompound, "flower_pos").orElse(null); // CraftBukkit - decompile error
this.readPersistentAngerSaveData(this.level(), nbttagcompound);
}
@@ -248,7 +261,7 @@
}
if (b0 > 0) {
- entityliving.addEffect(new MobEffect(MobEffects.POISON, b0 * 20, 0), this);
+ entityliving.addEffect(new MobEffect(MobEffects.POISON, b0 * 20, 0), this, EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
}
}
@@ -506,7 +519,7 @@
@Nullable
TileEntityBeehive getBeehiveBlockEntity() {
- return this.hivePos == null ? null : (this.isTooFarAway(this.hivePos) ? null : (TileEntityBeehive) this.level().getBlockEntity(this.hivePos, TileEntityTypes.BEEHIVE).orElse((Object) null));
+ return this.hivePos == null ? null : (this.isTooFarAway(this.hivePos) ? null : (TileEntityBeehive) this.level().getBlockEntity(this.hivePos, TileEntityTypes.BEEHIVE).orElse(null)); // CraftBukkit - decompile error
}
boolean isHiveValid() {
@@ -671,8 +684,14 @@
if (this.isInvulnerableTo(worldserver, damagesource)) {
return false;
} else {
+ // CraftBukkit start - Only stop pollinating if entity was damaged
+ boolean result = super.hurtServer(worldserver, damagesource, f);
+ if (!result) {
+ return result;
+ }
+ // CraftBukkit end
this.beePollinateGoal.stopPollinating();
- return super.hurtServer(worldserver, damagesource, f);
+ return result; // CraftBukkit
}
}
@@ -1082,7 +1101,7 @@
e() {
super();
- this.travellingTicks = EntityBee.this.level().random.nextInt(10);
+ this.travellingTicks = EntityBee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues
this.blacklistedTargets = Lists.newArrayList();
this.setFlags(EnumSet.of(PathfinderGoal.Type.MOVE));
}
@@ -1196,7 +1215,7 @@
f() {
super();
- this.travellingTicks = EntityBee.this.level().random.nextInt(10);
+ this.travellingTicks = EntityBee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues
this.setFlags(EnumSet.of(PathfinderGoal.Type.MOVE));
}
@@ -1301,7 +1320,7 @@
}
}
- if (iblockdata1 != null) {
+ if (iblockdata1 != null && CraftEventFactory.callEntityChangeBlockEvent(EntityBee.this, blockposition, iblockdata1)) { // CraftBukkit
EntityBee.this.level().levelEvent(2011, blockposition, 15);
EntityBee.this.level().setBlockAndUpdate(blockposition, iblockdata1);
EntityBee.this.incrementNumCropsGrownSincePollination();
@@ -1378,7 +1397,7 @@
@Override
protected void alertOther(EntityInsentient entityinsentient, EntityLiving entityliving) {
if (entityinsentient instanceof EntityBee && this.mob.hasLineOfSight(entityliving)) {
- entityinsentient.setTarget(entityliving);
+ entityinsentient.setTarget(entityliving, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason
}
}
@@ -1387,7 +1406,7 @@
private static class c extends PathfinderGoalNearestAttackableTarget<EntityHuman> {
c(EntityBee entitybee) {
- Objects.requireNonNull(entitybee);
+ // Objects.requireNonNull(entitybee); // CraftBukkit - decompile error
super(entitybee, EntityHuman.class, 10, true, false, entitybee::isAngryAt);
}

View File

@@ -0,0 +1,64 @@
--- a/net/minecraft/world/entity/animal/EntityCat.java
+++ b/net/minecraft/world/entity/animal/EntityCat.java
@@ -174,10 +174,10 @@
@Override
public void readAdditionalSaveData(NBTTagCompound nbttagcompound) {
super.readAdditionalSaveData(nbttagcompound);
- Optional optional = Optional.ofNullable(MinecraftKey.tryParse(nbttagcompound.getString("variant"))).map((minecraftkey) -> {
+ Optional<ResourceKey<CatVariant>> optional = Optional.ofNullable(MinecraftKey.tryParse(nbttagcompound.getString("variant"))).map((minecraftkey) -> { // CraftBukkit - decompile error
return ResourceKey.create(Registries.CAT_VARIANT, minecraftkey);
});
- IRegistry iregistry = BuiltInRegistries.CAT_VARIANT;
+ IRegistry<CatVariant> iregistry = BuiltInRegistries.CAT_VARIANT; // CraftBukkit - decompile error
Objects.requireNonNull(iregistry);
optional.flatMap(iregistry::get).ifPresent(this::setVariant);
@@ -462,7 +462,7 @@
}
private void tryToTame(EntityHuman entityhuman) {
- if (this.random.nextInt(3) == 0) {
+ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit
this.tame(entityhuman);
this.setOrderedToSit(true);
this.level().broadcastEntityEvent(this, (byte) 7);
@@ -480,7 +480,7 @@
private static class PathfinderGoalTemptChance extends PathfinderGoalTempt {
@Nullable
- private EntityHuman selectedPlayer;
+ private EntityLiving selectedPlayer; // CraftBukkit
private final EntityCat cat;
public PathfinderGoalTemptChance(EntityCat entitycat, double d0, Predicate<ItemStack> predicate, boolean flag) {
@@ -614,7 +614,15 @@
this.cat.randomTeleport((double) (blockposition_mutableblockposition.getX() + randomsource.nextInt(11) - 5), (double) (blockposition_mutableblockposition.getY() + randomsource.nextInt(5) - 2), (double) (blockposition_mutableblockposition.getZ() + randomsource.nextInt(11) - 5), false);
blockposition_mutableblockposition.set(this.cat.blockPosition());
this.cat.dropFromGiftLootTable(getServerLevel((Entity) this.cat), LootTables.CAT_MORNING_GIFT, (worldserver, itemstack) -> {
- worldserver.addFreshEntity(new EntityItem(worldserver, (double) blockposition_mutableblockposition.getX() - (double) MathHelper.sin(this.cat.yBodyRot * 0.017453292F), (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + (double) MathHelper.cos(this.cat.yBodyRot * 0.017453292F), itemstack));
+ // CraftBukkit start
+ EntityItem entityitem = new EntityItem(worldserver, (double) blockposition_mutableblockposition.getX() - (double) MathHelper.sin(this.cat.yBodyRot * 0.017453292F), (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + (double) MathHelper.cos(this.cat.yBodyRot * 0.017453292F), itemstack);
+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.cat.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
+ entityitem.level().getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ worldserver.addFreshEntity(entityitem);
+ // CraftBukkit end
});
}
@@ -645,10 +653,10 @@
private final EntityCat cat;
public a(EntityCat entitycat, Class<T> oclass, float f, double d0, double d1) {
- Predicate predicate = IEntitySelector.NO_CREATIVE_OR_SPECTATOR;
+ // Predicate predicate = IEntitySelector.NO_CREATIVE_OR_SPECTATOR; // CraftBukkit - decompile error
- Objects.requireNonNull(predicate);
- super(entitycat, oclass, f, d0, d1, predicate::test);
+ // Objects.requireNonNull(predicate); // CraftBukkit - decompile error
+ super(entitycat, oclass, f, d0, d1, IEntitySelector.NO_CREATIVE_OR_SPECTATOR::test); // CraftBukkit - decompile error
this.cat = entitycat;
}

View File

@@ -0,0 +1,15 @@
--- a/net/minecraft/world/entity/animal/EntityChicken.java
+++ b/net/minecraft/world/entity/animal/EntityChicken.java
@@ -99,10 +99,12 @@
if (world instanceof WorldServer worldserver) {
if (this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggTime <= 0) {
+ this.forceDrops = true; // CraftBukkit
if (this.dropFromGiftLootTable(worldserver, LootTables.CHICKEN_LAY, this::spawnAtLocation)) {
this.playSound(SoundEffects.CHICKEN_EGG, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
this.gameEvent(GameEvent.ENTITY_PLACE);
}
+ this.forceDrops = false; // CraftBukkit
this.eggTime = this.random.nextInt(6000) + 6000;
}

View File

@@ -0,0 +1,33 @@
--- a/net/minecraft/world/entity/animal/EntityCow.java
+++ b/net/minecraft/world/entity/animal/EntityCow.java
@@ -31,6 +31,12 @@
import net.minecraft.world.level.World;
import net.minecraft.world.level.block.state.IBlockData;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.player.PlayerBucketFillEvent;
+// CraftBukkit end
+
public class EntityCow extends EntityAnimal {
private static final EntitySize BABY_DIMENSIONS = EntityTypes.COW.getDimensions().scale(0.5F).withEyeHeight(0.665F);
@@ -92,8 +98,16 @@
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
+ // CraftBukkit start - Got milk?
+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) entityhuman.level(), entityhuman, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, enumhand);
+
+ if (event.isCancelled()) {
+ return EnumInteractionResult.PASS;
+ }
+ // CraftBukkit end
+
entityhuman.playSound(SoundEffects.COW_MILK, 1.0F, 1.0F);
- ItemStack itemstack1 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, Items.MILK_BUCKET.getDefaultInstance());
+ ItemStack itemstack1 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit
entityhuman.setItemInHand(enumhand, itemstack1);
return EnumInteractionResult.SUCCESS;

View File

@@ -0,0 +1,69 @@
--- a/net/minecraft/world/entity/animal/EntityDolphin.java
+++ b/net/minecraft/world/entity/animal/EntityDolphin.java
@@ -62,8 +62,20 @@
import net.minecraft.world.level.pathfinder.PathMode;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityPotionEffectEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityDolphin extends AgeableWaterCreature {
+ // CraftBukkit start - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
+ @Override
+ public int getDefaultMaxAirSupply() {
+ return TOTAL_AIR_SUPPLY;
+ }
+ // CraftBukkit end
private static final DataWatcherObject<BlockPosition> TREASURE_POS = DataWatcher.defineId(EntityDolphin.class, DataWatcherRegistry.BLOCK_POS);
private static final DataWatcherObject<Boolean> GOT_FISH = DataWatcher.defineId(EntityDolphin.class, DataWatcherRegistry.BOOLEAN);
private static final DataWatcherObject<Integer> MOISTNESS_LEVEL = DataWatcher.defineId(EntityDolphin.class, DataWatcherRegistry.INT);
@@ -200,7 +212,7 @@
@Override
public int getMaxAirSupply() {
- return 4800;
+ return maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
}
@Override
@@ -234,11 +246,17 @@
ItemStack itemstack = entityitem.getItem();
if (this.canHoldItem(itemstack)) {
+ // CraftBukkit start - call EntityPickupItemEvent
+ if (CraftEventFactory.callEntityPickupItemEvent(this, entityitem, 0, false).isCancelled()) {
+ return;
+ }
+ itemstack = entityitem.getItem(); // CraftBukkit- update ItemStack from event
+ // CraftBukkit start
this.onItemPickup(entityitem);
this.setItemSlot(EnumItemSlot.MAINHAND, itemstack);
this.setGuaranteedDrop(EnumItemSlot.MAINHAND);
this.take(entityitem, itemstack.getCount());
- entityitem.discard();
+ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
}
}
@@ -495,7 +513,7 @@
@Override
public void start() {
- this.player.addEffect(new MobEffect(MobEffects.DOLPHINS_GRACE, 100), this.dolphin);
+ this.player.addEffect(new MobEffect(MobEffects.DOLPHINS_GRACE, 100), this.dolphin, EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit
}
@Override
@@ -514,7 +532,7 @@
}
if (this.player.isSwimming() && this.player.level().random.nextInt(6) == 0) {
- this.player.addEffect(new MobEffect(MobEffects.DOLPHINS_GRACE, 100), this.dolphin);
+ this.player.addEffect(new MobEffect(MobEffects.DOLPHINS_GRACE, 100), this.dolphin, EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit
}
}

View File

@@ -0,0 +1,89 @@
--- a/net/minecraft/world/entity/animal/EntityFox.java
+++ b/net/minecraft/world/entity/animal/EntityFox.java
@@ -91,6 +91,10 @@
import net.minecraft.world.level.pathfinder.PathType;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityFox extends EntityAnimal implements VariantHolder<EntityFox.Type> {
private static final DataWatcherObject<Integer> DATA_TYPE_ID = DataWatcher.defineId(EntityFox.class, DataWatcherRegistry.INT);
@@ -503,7 +507,8 @@
protected void pickUpItem(WorldServer worldserver, EntityItem entityitem) {
ItemStack itemstack = entityitem.getItem();
- if (this.canHoldItem(itemstack)) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entityitem, itemstack.getCount() - 1, !this.canHoldItem(itemstack)).isCancelled()) { // CraftBukkit - call EntityPickupItemEvent
+ itemstack = entityitem.getItem(); // CraftBukkit - update ItemStack from event
int i = itemstack.getCount();
if (i > 1) {
@@ -515,7 +520,7 @@
this.setItemSlot(EnumItemSlot.MAINHAND, itemstack.split(1));
this.setGuaranteedDrop(EnumItemSlot.MAINHAND);
this.take(entityitem, itemstack.getCount());
- entityitem.discard();
+ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
this.ticksSinceEaten = 0;
}
@@ -853,6 +858,16 @@
if (entityplayer1 != null && entityplayer != entityplayer1) {
entityfox.addTrustedUUID(entityplayer1.getUUID());
}
+ // CraftBukkit start - call EntityBreedEvent
+ entityfox.setAge(-24000);
+ entityfox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F);
+ int experience = this.animal.getRandom().nextInt(7) + 1;
+ org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityfox, animal, partner, entityplayer, this.animal.breedItem, experience);
+ if (entityBreedEvent.isCancelled()) {
+ return;
+ }
+ experience = entityBreedEvent.getExperience();
+ // CraftBukkit end
if (entityplayer2 != null) {
entityplayer2.awardStat(StatisticList.ANIMALS_BRED);
@@ -863,12 +878,14 @@
this.partner.setAge(6000);
this.animal.resetLove();
this.partner.resetLove();
- entityfox.setAge(-24000);
- entityfox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F);
- worldserver.addFreshEntityWithPassengers(entityfox);
+ worldserver.addFreshEntityWithPassengers(entityfox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason
this.level.broadcastEntityEvent(this.animal, (byte) 18);
if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
- this.level.addFreshEntity(new EntityExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1));
+ // CraftBukkit start - use event experience
+ if (experience > 0) {
+ this.level.addFreshEntity(new EntityExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience));
+ }
+ // CraftBukkit end
}
}
@@ -1264,6 +1281,11 @@
int i = (Integer) iblockdata.getValue(BlockSweetBerryBush.AGE);
iblockdata.setValue(BlockSweetBerryBush.AGE, 1);
+ // CraftBukkit start - call EntityChangeBlockEvent
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(EntityFox.this, this.blockPos, iblockdata.setValue(BlockSweetBerryBush.AGE, 1))) {
+ return;
+ }
+ // CraftBukkit end
int j = 1 + EntityFox.this.level().random.nextInt(2) + (i == 3 ? 1 : 0);
ItemStack itemstack = EntityFox.this.getItemBySlot(EnumItemSlot.MAINHAND);
@@ -1494,7 +1516,7 @@
}
public static EntityFox.Type byName(String s) {
- return (EntityFox.Type) EntityFox.Type.CODEC.byName(s, (Enum) EntityFox.Type.RED);
+ return (EntityFox.Type) EntityFox.Type.CODEC.byName(s, EntityFox.Type.RED); // CraftBukkit - decompile error
}
public static EntityFox.Type byId(int i) {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/animal/EntityIronGolem.java
+++ b/net/minecraft/world/entity/animal/EntityIronGolem.java
@@ -98,7 +98,7 @@
@Override
protected void doPush(Entity entity) {
if (entity instanceof IMonster && !(entity instanceof EntityCreeper) && this.getRandom().nextInt(20) == 0) {
- this.setTarget((EntityLiving) entity);
+ this.setTarget((EntityLiving) entity, org.bukkit.event.entity.EntityTargetLivingEntityEvent.TargetReason.COLLISION, true); // CraftBukkit - set reason
}
super.doPush(entity);

View File

@@ -0,0 +1,59 @@
--- a/net/minecraft/world/entity/animal/EntityMushroomCow.java
+++ b/net/minecraft/world/entity/animal/EntityMushroomCow.java
@@ -43,6 +43,13 @@
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.storage.loot.LootTables;
+// CraftBukkit start
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityDropItemEvent;
+import org.bukkit.event.entity.EntityTransformEvent;
+// CraftBukkit end
+
public class EntityMushroomCow extends EntityCow implements IShearable, VariantHolder<EntityMushroomCow.Type> {
private static final DataWatcherObject<String> DATA_TYPE = DataWatcher.defineId(EntityMushroomCow.class, DataWatcherRegistry.STRING);
@@ -120,6 +127,11 @@
if (world instanceof WorldServer) {
WorldServer worldserver = (WorldServer) world;
+ // CraftBukkit start
+ if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) {
+ return EnumInteractionResult.PASS;
+ }
+ // CraftBukkit end
this.shear(worldserver, SoundCategory.PLAYERS, itemstack);
this.gameEvent(GameEvent.SHEAR, entityhuman);
itemstack.hurtAndBreak(1, entityhuman, getSlotForHand(enumhand));
@@ -163,11 +175,19 @@
worldserver.sendParticles(Particles.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D);
this.dropFromShearingLootTable(worldserver, LootTables.SHEAR_MOOSHROOM, itemstack, (worldserver1, itemstack1) -> {
for (int i = 0; i < itemstack1.getCount(); ++i) {
- worldserver1.addFreshEntity(new EntityItem(this.level(), this.getX(), this.getY(1.0D), this.getZ(), itemstack1.copyWithCount(1)));
+ // CraftBukkit start
+ EntityItem entityitem = new EntityItem(this.level(), this.getX(), this.getY(1.0D), this.getZ(), itemstack1.copyWithCount(1));
+ EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
+ Bukkit.getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ continue;
+ }
+ worldserver1.addFreshEntity(entityitem);
+ // CraftBukkit end
}
});
- });
+ }, EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit
}
@Override
@@ -263,7 +283,7 @@
}
static EntityMushroomCow.Type byName(String s) {
- return (EntityMushroomCow.Type) EntityMushroomCow.Type.CODEC.byName(s, (Enum) EntityMushroomCow.Type.RED);
+ return (EntityMushroomCow.Type) EntityMushroomCow.Type.CODEC.byName(s, EntityMushroomCow.Type.RED); // CraftBukkit - decompile error
}
}
}

View File

@@ -0,0 +1,25 @@
--- a/net/minecraft/world/entity/animal/EntityOcelot.java
+++ b/net/minecraft/world/entity/animal/EntityOcelot.java
@@ -167,7 +167,7 @@
if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemstack) && entityhuman.distanceToSqr((Entity) this) < 9.0D) {
this.usePlayerItem(entityhuman, enumhand, itemstack);
if (!this.level().isClientSide) {
- if (this.random.nextInt(3) == 0) {
+ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit - added event call and isCancelled check
this.setTrusting(true);
this.spawnTrustingParticles(true);
this.level().broadcastEntityEvent(this, (byte) 41);
@@ -298,10 +298,10 @@
private final EntityOcelot ocelot;
public a(EntityOcelot entityocelot, Class<T> oclass, float f, double d0, double d1) {
- Predicate predicate = IEntitySelector.NO_CREATIVE_OR_SPECTATOR;
+ // Predicate predicate = IEntitySelector.NO_CREATIVE_OR_SPECTATOR; // CraftBukkit - decompile error
- Objects.requireNonNull(predicate);
- super(entityocelot, oclass, f, d0, d1, predicate::test);
+ // Objects.requireNonNull(predicate); // CraftBukkit - decompile error
+ super(entityocelot, oclass, f, d0, d1, IEntitySelector.NO_CREATIVE_OR_SPECTATOR::test); // CraftBukkit - decompile error
this.ocelot = entityocelot;
}

View File

@@ -0,0 +1,64 @@
--- a/net/minecraft/world/entity/animal/EntityPanda.java
+++ b/net/minecraft/world/entity/animal/EntityPanda.java
@@ -69,6 +69,12 @@
import net.minecraft.world.level.storage.loot.LootTables;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public class EntityPanda extends EntityAnimal {
private static final DataWatcherObject<Integer> UNHAPPY_COUNTER = DataWatcher.defineId(EntityPanda.class, DataWatcherRegistry.INT);
@@ -541,14 +547,14 @@
@Override
protected void pickUpItem(WorldServer worldserver, EntityItem entityitem) {
- if (this.getItemBySlot(EnumItemSlot.MAINHAND).isEmpty() && canPickUpAndEat(entityitem)) {
+ if (!CraftEventFactory.callEntityPickupItemEvent(this, entityitem, 0, !(this.getItemBySlot(EnumItemSlot.MAINHAND).isEmpty() && canPickUpAndEat(entityitem))).isCancelled()) { // CraftBukkit
this.onItemPickup(entityitem);
ItemStack itemstack = entityitem.getItem();
this.setItemSlot(EnumItemSlot.MAINHAND, itemstack);
this.setGuaranteedDrop(EnumItemSlot.MAINHAND);
this.take(entityitem, itemstack.getCount());
- entityitem.discard();
+ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
}
}
@@ -772,7 +778,7 @@
}
public static EntityPanda.Gene byName(String s) {
- return (EntityPanda.Gene) EntityPanda.Gene.CODEC.byName(s, (Enum) EntityPanda.Gene.NORMAL);
+ return (EntityPanda.Gene) EntityPanda.Gene.CODEC.byName(s, EntityPanda.Gene.NORMAL); // CraftBukkit - decompile error
}
public static EntityPanda.Gene getRandom(RandomSource randomsource) {
@@ -876,10 +882,10 @@
private final EntityPanda panda;
public c(EntityPanda entitypanda, Class<T> oclass, float f, double d0, double d1) {
- Predicate predicate = IEntitySelector.NO_SPECTATORS;
+ // Predicate predicate = IEntitySelector.NO_SPECTATORS;
- Objects.requireNonNull(predicate);
- super(entitypanda, oclass, f, d0, d1, predicate::test);
+ // Objects.requireNonNull(predicate);
+ super(entitypanda, oclass, f, d0, d1, IEntitySelector.NO_SPECTATORS::test);
this.panda = entitypanda;
}
@@ -1116,7 +1122,7 @@
@Override
protected void alertOther(EntityInsentient entityinsentient, EntityLiving entityliving) {
if (entityinsentient instanceof EntityPanda && entityinsentient.isAggressive()) {
- entityinsentient.setTarget(entityliving);
+ entityinsentient.setTarget(entityliving, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit
}
}

View File

@@ -0,0 +1,45 @@
--- a/net/minecraft/world/entity/animal/EntityParrot.java
+++ b/net/minecraft/world/entity/animal/EntityParrot.java
@@ -248,7 +248,7 @@
}
if (!this.level().isClientSide) {
- if (this.random.nextInt(10) == 0) {
+ if (this.random.nextInt(10) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit
this.tame(entityhuman);
this.level().broadcastEntityEvent(this, (byte) 7);
} else {
@@ -269,7 +269,7 @@
}
} else {
this.usePlayerItem(entityhuman, enumhand, itemstack);
- this.addEffect(new MobEffect(MobEffects.POISON, 900));
+ this.addEffect(new MobEffect(MobEffects.POISON, 900), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // CraftBukkit
if (entityhuman.isCreative() || !this.isInvulnerable()) {
this.hurt(this.damageSources().playerAttack(entityhuman), Float.MAX_VALUE);
}
@@ -363,7 +363,7 @@
@Override
public boolean isPushable() {
- return true;
+ return super.isPushable(); // CraftBukkit - collidable API
}
@Override
@@ -378,8 +378,14 @@
if (this.isInvulnerableTo(worldserver, damagesource)) {
return false;
} else {
+ // CraftBukkit start
+ boolean result = super.hurtServer(worldserver, damagesource, f);
+ if (!result) {
+ return result;
+ }
+ // CraftBukkit end
this.setOrderedToSit(false);
- return super.hurtServer(worldserver, damagesource, f);
+ return result; // CraftBukkit
}
}

View File

@@ -0,0 +1,22 @@
--- a/net/minecraft/world/entity/animal/EntityPerchable.java
+++ b/net/minecraft/world/entity/animal/EntityPerchable.java
@@ -6,6 +6,10 @@
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.level.World;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public abstract class EntityPerchable extends EntityTameableAnimal {
private static final int RIDE_COOLDOWN = 100;
@@ -21,7 +25,7 @@
nbttagcompound.putString("id", this.getEncodeId());
this.saveWithoutId(nbttagcompound);
if (entityplayer.setEntityOnShoulder(nbttagcompound)) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
return true;
} else {
return false;

View File

@@ -0,0 +1,30 @@
--- a/net/minecraft/world/entity/animal/EntityPig.java
+++ b/net/minecraft/world/entity/animal/EntityPig.java
@@ -50,6 +50,11 @@
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable {
private static final DataWatcherObject<Boolean> DATA_SADDLE_ID = DataWatcher.defineId(EntityPig.class, DataWatcherRegistry.BOOLEAN);
@@ -247,7 +252,14 @@
}
entitypigzombie1.setPersistenceRequired();
- });
+ // CraftBukkit start
+ }, null, null);
+ if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) {
+ return;
+ }
+ worldserver.addFreshEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING);
+ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause
+ // CraftBukkit end
if (entitypigzombie == null) {
super.thunderHit(worldserver, entitylightning);

View File

@@ -0,0 +1,20 @@
--- a/net/minecraft/world/entity/animal/EntityPufferFish.java
+++ b/net/minecraft/world/entity/animal/EntityPufferFish.java
@@ -155,7 +155,7 @@
int i = this.getPuffState();
if (entityinsentient.hurtServer(worldserver, this.damageSources().mobAttack(this), (float) (1 + i))) {
- entityinsentient.addEffect(new MobEffect(MobEffects.POISON, 60 * i, 0), this);
+ entityinsentient.addEffect(new MobEffect(MobEffects.POISON, 60 * i, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
this.playSound(SoundEffects.PUFFER_FISH_STING, 1.0F, 1.0F);
}
@@ -171,7 +171,7 @@
entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.PUFFER_FISH_STING, 0.0F));
}
- entityhuman.addEffect(new MobEffect(MobEffects.POISON, 60 * i, 0), this);
+ entityhuman.addEffect(new MobEffect(MobEffects.POISON, 60 * i, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
}
}

View File

@@ -0,0 +1,41 @@
--- a/net/minecraft/world/entity/animal/EntityRabbit.java
+++ b/net/minecraft/world/entity/animal/EntityRabbit.java
@@ -66,6 +66,10 @@
import net.minecraft.world.level.pathfinder.PathEntity;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class EntityRabbit extends EntityAnimal implements VariantHolder<EntityRabbit.Variant> {
public static final double STROLL_SPEED_MOD = 0.6D;
@@ -90,7 +94,6 @@
super(entitytypes, world);
this.jumpControl = new EntityRabbit.ControllerJumpRabbit(this);
this.moveControl = new EntityRabbit.ControllerMoveRabbit(this);
- this.setSpeedModifier(0.0D);
}
@Override
@@ -577,9 +580,19 @@
int i = (Integer) iblockdata.getValue(BlockCarrots.AGE);
if (i == 0) {
+ // CraftBukkit start
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockposition, Blocks.AIR.defaultBlockState())) {
+ return;
+ }
+ // CraftBukkit end
world.setBlock(blockposition, Blocks.AIR.defaultBlockState(), 2);
world.destroyBlock(blockposition, true, this.rabbit);
} else {
+ // CraftBukkit start
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockposition, iblockdata.setValue(BlockCarrots.AGE, i - 1))) {
+ return;
+ }
+ // CraftBukkit end
world.setBlock(blockposition, (IBlockData) iblockdata.setValue(BlockCarrots.AGE, i - 1), 2);
world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.a.of((Entity) this.rabbit));
world.levelEvent(2001, blockposition, Block.getId(iblockdata));

View File

@@ -0,0 +1,50 @@
--- a/net/minecraft/world/entity/animal/EntitySheep.java
+++ b/net/minecraft/world/entity/animal/EntitySheep.java
@@ -50,6 +50,12 @@
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.storage.loot.LootTables;
+// CraftBukkit start
+import net.minecraft.world.item.Item;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.SheepRegrowWoolEvent;
+// CraftBukkit end
+
public class EntitySheep extends EntityAnimal implements IShearable {
private static final int EAT_ANIMATION_TICKS = 40;
@@ -160,6 +166,11 @@
WorldServer worldserver = (WorldServer) world;
if (this.readyForShearing()) {
+ // CraftBukkit start
+ if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) {
+ return EnumInteractionResult.PASS;
+ }
+ // CraftBukkit end
this.shear(worldserver, SoundCategory.PLAYERS, itemstack);
this.gameEvent(GameEvent.SHEAR, entityhuman);
itemstack.hurtAndBreak(1, entityhuman, getSlotForHand(enumhand));
@@ -178,7 +189,9 @@
worldserver.playSound((EntityHuman) null, (Entity) this, SoundEffects.SHEEP_SHEAR, soundcategory, 1.0F, 1.0F);
this.dropFromShearingLootTable(worldserver, LootTables.SHEAR_SHEEP, itemstack, (worldserver1, itemstack1) -> {
for (int i = 0; i < itemstack1.getCount(); ++i) {
+ this.forceDrops = true; // CraftBukkit
EntityItem entityitem = this.spawnAtLocation(worldserver1, itemstack1.copyWithCount(1), 1.0F);
+ this.forceDrops = false; // CraftBukkit
if (entityitem != null) {
entityitem.setDeltaMovement(entityitem.getDeltaMovement().add((double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F), (double) (this.random.nextFloat() * 0.05F), (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F)));
@@ -276,6 +289,12 @@
@Override
public void ate() {
+ // CraftBukkit start
+ SheepRegrowWoolEvent event = new SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity());
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) return;
+ // CraftBukkit end
super.ate();
this.setSheared(false);
if (this.isBaby()) {

View File

@@ -0,0 +1,57 @@
--- a/net/minecraft/world/entity/animal/EntitySnowman.java
+++ b/net/minecraft/world/entity/animal/EntitySnowman.java
@@ -43,6 +43,10 @@
import net.minecraft.world.level.storage.loot.LootTables;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class EntitySnowman extends EntityGolem implements IShearable, IRangedEntity {
private static final DataWatcherObject<Byte> DATA_PUMPKIN_ID = DataWatcher.defineId(EntitySnowman.class, DataWatcherRegistry.BYTE);
@@ -100,7 +104,7 @@
if (world instanceof WorldServer worldserver) {
if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) {
- this.hurtServer(worldserver, this.damageSources().onFire(), 1.0F);
+ this.hurtServer(worldserver, this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING
}
if (!worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
@@ -116,7 +120,11 @@
BlockPosition blockposition = new BlockPosition(j, k, l);
if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) {
- this.level().setBlockAndUpdate(blockposition, iblockdata);
+ // CraftBukkit start
+ if (!CraftEventFactory.handleBlockFormEvent(this.level(), blockposition, iblockdata, this)) {
+ continue;
+ }
+ // CraftBukkit end
this.level().gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition, GameEvent.a.of(this, iblockdata));
}
}
@@ -153,6 +161,11 @@
if (world instanceof WorldServer) {
WorldServer worldserver = (WorldServer) world;
+ // CraftBukkit start
+ if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) {
+ return EnumInteractionResult.PASS;
+ }
+ // CraftBukkit end
this.shear(worldserver, SoundCategory.PLAYERS, itemstack);
this.gameEvent(GameEvent.SHEAR, entityhuman);
itemstack.hurtAndBreak(1, entityhuman, getSlotForHand(enumhand));
@@ -169,7 +182,9 @@
worldserver.playSound((EntityHuman) null, (Entity) this, SoundEffects.SNOW_GOLEM_SHEAR, soundcategory, 1.0F, 1.0F);
this.setPumpkin(false);
this.dropFromShearingLootTable(worldserver, LootTables.SHEAR_SNOW_GOLEM, itemstack, (worldserver1, itemstack1) -> {
+ this.forceDrops = true; // CraftBukkit
this.spawnAtLocation(worldserver1, itemstack1, this.getEyeHeight());
+ this.forceDrops = false; // CraftBukkit
});
}

View File

@@ -0,0 +1,36 @@
--- a/net/minecraft/world/entity/animal/EntityTurtle.java
+++ b/net/minecraft/world/entity/animal/EntityTurtle.java
@@ -310,7 +310,9 @@
WorldServer worldserver = (WorldServer) world;
if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
+ this.forceDrops = true; // CraftBukkit
this.spawnAtLocation(worldserver, Items.TURTLE_SCUTE, 1);
+ this.forceDrops = false; // CraftBukkit
}
}
}
@@ -339,7 +341,7 @@
@Override
public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) {
- this.hurtServer(worldserver, this.damageSources().lightningBolt(), Float.MAX_VALUE);
+ this.hurtServer(worldserver, this.damageSources().lightningBolt().customEntityDamager(entitylightning), Float.MAX_VALUE); // CraftBukkit
}
@Override
@@ -496,12 +498,14 @@
} else if (this.turtle.layEggCounter > this.adjustedTickDelay(200)) {
World world = this.turtle.level();
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), (IBlockData) Blocks.TURTLE_EGG.defaultBlockState().setValue(BlockTurtleEgg.EGGS, this.turtle.random.nextInt(4) + 1))) { // CraftBukkit
world.playSound((EntityHuman) null, blockposition, SoundEffects.TURTLE_LAY_EGG, SoundCategory.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F);
BlockPosition blockposition1 = this.blockPos.above();
IBlockData iblockdata = (IBlockData) Blocks.TURTLE_EGG.defaultBlockState().setValue(BlockTurtleEgg.EGGS, this.turtle.random.nextInt(4) + 1);
world.setBlock(blockposition1, iblockdata, 3);
world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition1, GameEvent.a.of(this.turtle, iblockdata));
+ } // CraftBukkit
this.turtle.setHasEgg(false);
this.turtle.setLayingEgg(false);
this.turtle.setInLoveTime(600);

View File

@@ -0,0 +1,105 @@
--- a/net/minecraft/world/entity/animal/EntityWolf.java
+++ b/net/minecraft/world/entity/animal/EntityWolf.java
@@ -86,6 +86,13 @@
import net.minecraft.world.level.pathfinder.PathType;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.EntityRegainHealthEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable, VariantHolder<Holder<WolfVariant>> {
private static final DataWatcherObject<Boolean> DATA_INTERESTED_ID = DataWatcher.defineId(EntityWolf.class, DataWatcherRegistry.BOOLEAN);
@@ -345,8 +352,14 @@
if (this.isInvulnerableTo(worldserver, damagesource)) {
return false;
} else {
+ // CraftBukkit start
+ boolean result = super.hurtServer(worldserver, damagesource, f);
+ if (!result) {
+ return result;
+ }
+ // CraftBukkit end
this.setOrderedToSit(false);
- return super.hurtServer(worldserver, damagesource, f);
+ return result; // CraftBukkit
}
}
@@ -356,10 +369,15 @@
}
@Override
- protected void actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f) {
+ public boolean actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f, EntityDamageEvent event) { // CraftBukkit - void -> boolean
if (!this.canArmorAbsorb(damagesource)) {
- super.actuallyHurt(worldserver, damagesource, f);
+ return super.actuallyHurt(worldserver, damagesource, f, event); // CraftBukkit
} else {
+ // CraftBukkit start - SPIGOT-7815: if the damage was cancelled, no need to run the wolf armor behaviour
+ if (event.isCancelled()) {
+ return false;
+ }
+ // CraftBukkit end
ItemStack itemstack = this.getBodyArmorItem();
int i = itemstack.getDamageValue();
int j = itemstack.getMaxDamage();
@@ -371,6 +389,7 @@
}
}
+ return false; // CraftBukkit
}
private boolean canArmorAbsorb(DamageSource damagesource) {
@@ -381,7 +400,7 @@
protected void applyTamingSideEffects() {
if (this.isTame()) {
this.getAttribute(GenericAttributes.MAX_HEALTH).setBaseValue(40.0D);
- this.setHealth(40.0F);
+ this.setHealth(this.getMaxHealth()); // CraftBukkit - 40.0 -> getMaxHealth()
} else {
this.getAttribute(GenericAttributes.MAX_HEALTH).setBaseValue(8.0D);
}
@@ -404,7 +423,7 @@
FoodInfo foodinfo = (FoodInfo) itemstack.get(DataComponents.FOOD);
float f = foodinfo != null ? (float) foodinfo.nutrition() : 1.0F;
- this.heal(2.0F * f);
+ this.heal(2.0F * f, EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit
return EnumInteractionResult.SUCCESS;
} else {
if (item instanceof ItemDye) {
@@ -440,7 +459,9 @@
if (world instanceof WorldServer) {
WorldServer worldserver = (WorldServer) world;
+ this.forceDrops = true; // CraftBukkit
this.spawnAtLocation(worldserver, itemstack1);
+ this.forceDrops = false; // CraftBukkit
}
return EnumInteractionResult.SUCCESS;
@@ -459,7 +480,7 @@
this.setOrderedToSit(!this.isOrderedToSit());
this.jumping = false;
this.navigation.stop();
- this.setTarget((EntityLiving) null);
+ this.setTarget((EntityLiving) null, EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
return EnumInteractionResult.SUCCESS.withoutItem();
} else {
return enuminteractionresult;
@@ -477,7 +498,8 @@
}
private void tryToTame(EntityHuman entityhuman) {
- if (this.random.nextInt(3) == 0) {
+ // CraftBukkit - added event call and isCancelled check.
+ if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
this.tame(entityhuman);
this.navigation.stop();
this.setTarget((EntityLiving) null);

View File

@@ -0,0 +1,93 @@
--- a/net/minecraft/world/entity/animal/allay/Allay.java
+++ b/net/minecraft/world/entity/animal/allay/Allay.java
@@ -103,6 +103,7 @@
private float dancingAnimationTicks;
private float spinningAnimationTicks;
private float spinningAnimationTicks0;
+ public boolean forceDancing = false; // CraftBukkit
public Allay(EntityTypes<? extends Allay> entitytypes, World world) {
super(entitytypes, world);
@@ -114,6 +115,12 @@
this.dynamicJukeboxListener = new DynamicGameEventListener<>(new Allay.a(this.vibrationUser.getPositionSource(), ((GameEvent) GameEvent.JUKEBOX_PLAY.value()).notificationRadius()));
}
+ // CraftBukkit start
+ public void setCanDuplicate(boolean canDuplicate) {
+ this.entityData.set(Allay.DATA_CAN_DUPLICATE, canDuplicate);
+ }
+ // CraftBukkit end
+
@Override
protected BehaviorController.b<Allay> brainProvider() {
return BehaviorController.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES);
@@ -126,7 +133,7 @@
@Override
public BehaviorController<Allay> getBrain() {
- return super.getBrain();
+ return (BehaviorController<Allay>) super.getBrain(); // CraftBukkit - decompile error
}
public static AttributeProvider.Builder createAttributes() {
@@ -233,7 +240,7 @@
public void aiStep() {
super.aiStep();
if (!this.level().isClientSide && this.isAlive() && this.tickCount % 10 == 0) {
- this.heal(1.0F);
+ this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
}
if (this.isDancing() && this.shouldStopDancing() && this.tickCount % 20 == 0) {
@@ -303,7 +310,12 @@
ItemStack itemstack1 = this.getItemInHand(EnumHand.MAIN_HAND);
if (this.isDancing() && itemstack.is(TagsItem.DUPLICATES_ALLAYS) && this.canDuplicate()) {
- this.duplicateAllay();
+ // CraftBukkit start - handle cancel duplication
+ Allay allay = this.duplicateAllay();
+ if (allay == null) {
+ return EnumInteractionResult.SUCCESS;
+ }
+ // CraftBukkit end
this.level().broadcastEntityEvent(this, (byte) 18);
this.level().playSound(entityhuman, (Entity) this, SoundEffects.AMETHYST_BLOCK_CHIME, SoundCategory.NEUTRAL, 2.0F, 1.0F);
this.removeInteractionItem(entityhuman, itemstack);
@@ -314,7 +326,7 @@
this.setItemInHand(EnumHand.MAIN_HAND, itemstack2);
this.removeInteractionItem(entityhuman, itemstack);
this.level().playSound(entityhuman, (Entity) this, SoundEffects.ALLAY_ITEM_GIVEN, SoundCategory.NEUTRAL, 2.0F, 1.0F);
- this.getBrain().setMemory(MemoryModuleType.LIKED_PLAYER, (Object) entityhuman.getUUID());
+ this.getBrain().setMemory(MemoryModuleType.LIKED_PLAYER, entityhuman.getUUID()); // CraftBukkit - decompile error
return EnumInteractionResult.SUCCESS;
} else if (!itemstack1.isEmpty() && enumhand == EnumHand.MAIN_HAND && itemstack.isEmpty()) {
this.setItemSlot(EnumItemSlot.MAINHAND, ItemStack.EMPTY);
@@ -415,6 +427,7 @@
}
private boolean shouldStopDancing() {
+ if (this.forceDancing) {return false;} // CraftBukkit
return this.jukeboxPos == null || !this.jukeboxPos.closerToCenterThan(this.position(), (double) ((GameEvent) GameEvent.JUKEBOX_PLAY.value()).notificationRadius()) || !this.level().getBlockState(this.jukeboxPos).is(Blocks.JUKEBOX);
}
@@ -506,7 +519,7 @@
}
- public void duplicateAllay() {
+ public Allay duplicateAllay() { // CraftBukkit - return allay
Allay allay = (Allay) EntityTypes.ALLAY.create(this.level(), EntitySpawnReason.BREEDING);
if (allay != null) {
@@ -514,9 +527,9 @@
allay.setPersistenceRequired();
allay.resetDuplicationCooldown();
this.resetDuplicationCooldown();
- this.level().addFreshEntity(allay);
+ this.level().addFreshEntity(allay, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DUPLICATION); // CraftBukkit - reason for duplicated allay
}
-
+ return allay; // CraftBukkit
}
public void resetDuplicationCooldown() {

View File

@@ -0,0 +1,76 @@
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
@@ -48,6 +48,10 @@
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.storage.loot.LootTables;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityDamageEvent;
+// CraftBukkit end
+
public class Armadillo extends EntityAnimal {
public static final float BABY_SCALE = 0.6F;
@@ -135,16 +139,18 @@
GameProfilerFiller gameprofilerfiller = Profiler.get();
gameprofilerfiller.push("armadilloBrain");
- this.brain.tick(worldserver, this);
+ ((BehaviorController<Armadillo>) this.brain).tick(worldserver, this); // CraftBukkit - decompile error
gameprofilerfiller.pop();
gameprofilerfiller.push("armadilloActivityUpdate");
ArmadilloAi.updateActivity(this);
gameprofilerfiller.pop();
if (this.isAlive() && !this.isBaby() && --this.scuteTime <= 0) {
+ this.forceDrops = true; // CraftBukkit
if (this.dropFromGiftLootTable(worldserver, LootTables.ARMADILLO_SHED, this::spawnAtLocation)) {
this.playSound(SoundEffects.ARMADILLO_SCUTE_DROP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
this.gameEvent(GameEvent.ENTITY_PLACE);
}
+ this.forceDrops = false; // CraftBukkit
this.scuteTime = this.pickNextScuteDropTime();
}
@@ -291,8 +297,13 @@
}
@Override
- protected void actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f) {
- super.actuallyHurt(worldserver, damagesource, f);
+ // CraftBukkit start - void -> boolean
+ public boolean actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f, EntityDamageEvent event) {
+ boolean damageResult = super.actuallyHurt(worldserver, damagesource, f, event);
+ if (!damageResult) {
+ return false;
+ }
+ // CraftBukkit end
if (!this.isNoAi() && !this.isDeadOrDying()) {
if (damagesource.getEntity() instanceof EntityLiving) {
this.getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, 80L);
@@ -304,6 +315,7 @@
}
}
+ return true; // CraftBukkit
}
@Override
@@ -327,7 +339,9 @@
if (world instanceof WorldServer) {
WorldServer worldserver = (WorldServer) world;
+ this.forceDrops = true; // CraftBukkit
this.spawnAtLocation(worldserver, new ItemStack(Items.ARMADILLO_SCUTE));
+ this.forceDrops = false; // CraftBukkit
this.gameEvent(GameEvent.ENTITY_INTERACT);
this.playSound(SoundEffects.ARMADILLO_BRUSH);
}
@@ -431,7 +445,7 @@
}
public static Armadillo.a fromName(String s) {
- return (Armadillo.a) Armadillo.a.CODEC.byName(s, (Enum) Armadillo.a.IDLE);
+ return (Armadillo.a) Armadillo.a.CODEC.byName(s, Armadillo.a.IDLE); // CraftBukkit - decompile error
}
@Override

View File

@@ -0,0 +1,48 @@
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -67,10 +67,17 @@
public class Axolotl extends EntityAnimal implements VariantHolder<Axolotl.Variant>, Bucketable {
+ // CraftBukkit start - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
+ @Override
+ public int getDefaultMaxAirSupply() {
+ return AXOLOTL_TOTAL_AIR_SUPPLY;
+ }
+ // CraftBukkit end
public static final int TOTAL_PLAYDEAD_TIME = 200;
private static final int POSE_ANIMATION_TICKS = 10;
protected static final ImmutableList<? extends SensorType<? extends Sensor<? super Axolotl>>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_ADULT, SensorType.HURT_BY, SensorType.AXOLOTL_ATTACKABLES, SensorType.AXOLOTL_TEMPTATIONS);
- protected static final ImmutableList<? extends MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.BREED_TARGET, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT, new MemoryModuleType[]{MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.PLAY_DEAD_TICKS, MemoryModuleType.NEAREST_ATTACKABLE, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.HAS_HUNTING_COOLDOWN, MemoryModuleType.IS_PANICKING});
+ // CraftBukkit - decompile error
+ protected static final ImmutableList<? extends MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.<MemoryModuleType<?>>of(MemoryModuleType.BREED_TARGET, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT, new MemoryModuleType[]{MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.PLAY_DEAD_TICKS, MemoryModuleType.NEAREST_ATTACKABLE, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.HAS_HUNTING_COOLDOWN, MemoryModuleType.IS_PANICKING});
private static final DataWatcherObject<Integer> DATA_VARIANT = DataWatcher.defineId(Axolotl.class, DataWatcherRegistry.INT);
private static final DataWatcherObject<Boolean> DATA_PLAYING_DEAD = DataWatcher.defineId(Axolotl.class, DataWatcherRegistry.BOOLEAN);
private static final DataWatcherObject<Boolean> FROM_BUCKET = DataWatcher.defineId(Axolotl.class, DataWatcherRegistry.BOOLEAN);
@@ -210,7 +217,7 @@
@Override
public int getMaxAirSupply() {
- return 6000;
+ return maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
}
@Override
@@ -414,7 +421,7 @@
int i = mobeffect != null ? mobeffect.getDuration() : 0;
int j = Math.min(2400, 100 + i);
- entityhuman.addEffect(new MobEffect(MobEffects.REGENERATION, j, 0), this);
+ entityhuman.addEffect(new MobEffect(MobEffects.REGENERATION, j, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // CraftBukkit
}
entityhuman.removeEffect(MobEffects.DIG_SLOWDOWN);
@@ -464,7 +471,7 @@
@Override
public BehaviorController<Axolotl> getBrain() {
- return super.getBrain();
+ return (BehaviorController<Axolotl>) super.getBrain(); // CraftBukkit - decompile error
}
@Override

View File

@@ -0,0 +1,40 @@
--- a/net/minecraft/world/entity/animal/camel/Camel.java
+++ b/net/minecraft/world/entity/animal/camel/Camel.java
@@ -50,6 +50,10 @@
import net.minecraft.world.phys.Vec2F;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityDamageEvent;
+// CraftBukkit end
+
public class Camel extends EntityHorseAbstract {
public static final float BABY_SCALE = 0.45F;
@@ -143,7 +147,7 @@
GameProfilerFiller gameprofilerfiller = Profiler.get();
gameprofilerfiller.push("camelBrain");
- BehaviorController<?> behaviorcontroller = this.getBrain();
+ BehaviorController<Camel> behaviorcontroller = (BehaviorController<Camel>) this.getBrain(); // CraftBukkit - decompile error
behaviorcontroller.tick(worldserver, this);
gameprofilerfiller.pop();
@@ -454,9 +458,15 @@
}
@Override
- protected void actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f) {
+ // CraftBukkit start - void -> boolean
+ public boolean actuallyHurt(WorldServer worldserver, DamageSource damagesource, float f, EntityDamageEvent event) {
+ boolean damageResult = super.actuallyHurt(worldserver, damagesource, f, event);
+ if (!damageResult) {
+ return false;
+ }
+ // CraftBukkit end
this.standUpInstantly();
- super.actuallyHurt(worldserver, damagesource, f);
+ return true; // CraftBukkit
}
@Override

View File

@@ -0,0 +1,40 @@
--- a/net/minecraft/world/entity/animal/frog/ShootTongue.java
+++ b/net/minecraft/world/entity/animal/frog/ShootTongue.java
@@ -20,6 +20,10 @@
import net.minecraft.world.level.pathfinder.PathEntity;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class ShootTongue extends Behavior<Frog> {
public static final int TIME_OUT_DURATION = 100;
@@ -64,7 +68,7 @@
BehaviorUtil.lookAtEntity(frog, entityliving);
frog.setTongueTarget(entityliving);
- frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(entityliving.position(), 2.0F, 0)));
+ frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(entityliving.position(), 2.0F, 0))); // CraftBukkit - decompile error
this.calculatePathCounter = 10;
this.state = ShootTongue.a.MOVE_TO_TARGET;
}
@@ -85,7 +89,7 @@
if (entity.isAlive()) {
frog.doHurtTarget(worldserver, entity);
if (!entity.isAlive()) {
- entity.remove(Entity.RemovalReason.KILLED);
+ entity.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
}
}
}
@@ -106,7 +110,7 @@
this.eatAnimationTimer = 0;
this.state = ShootTongue.a.CATCH_ANIMATION;
} else if (this.calculatePathCounter <= 0) {
- frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(entityliving.position(), 2.0F, 0)));
+ frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(entityliving.position(), 2.0F, 0))); // CraftBukkit - decompile error
this.calculatePathCounter = 10;
} else {
--this.calculatePathCounter;

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -74,7 +74,7 @@
@Override
public BehaviorController<Tadpole> getBrain() {
- return super.getBrain();
+ return (BehaviorController<Tadpole>) super.getBrain(); // CraftBukkit - decompile error
}
@Override
@@ -225,12 +225,17 @@
World world = this.level();
if (world instanceof WorldServer worldserver) {
- this.convertTo(EntityTypes.FROG, ConversionParams.single(this, false, false), (frog) -> {
+ Frog converted = this.convertTo(EntityTypes.FROG, ConversionParams.single(this, false, false), (frog) -> { // CraftBukkit
frog.finalizeSpawn(worldserver, this.level().getCurrentDifficultyAt(frog.blockPosition()), EntitySpawnReason.CONVERSION, (GroupDataEntity) null);
frog.setPersistenceRequired();
frog.fudgePositionAfterSizeChange(this.getDimensions(this.getPose()));
this.playSound(SoundEffects.TADPOLE_GROW_UP, 0.15F, 1.0F);
- });
+ // CraftBukkit start
+ }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.METAMORPHOSIS, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.METAMORPHOSIS);
+ if (converted == null) {
+ this.setAge(0); // Sets the age to 0 for avoid a loop if the event is canceled
+ }
+ // CraftBukkit end
}
}

View File

@@ -0,0 +1,41 @@
--- a/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
@@ -54,6 +54,12 @@
import net.minecraft.world.level.pathfinder.PathType;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.player.PlayerBucketFillEvent;
+// CraftBukkit end
+
public class Goat extends EntityAnimal {
public static final EntitySize LONG_JUMPING_DIMENSIONS = EntitySize.scalable(0.9F, 1.3F).scale(0.7F);
@@ -184,7 +190,7 @@
@Override
public BehaviorController<Goat> getBrain() {
- return super.getBrain();
+ return (BehaviorController<Goat>) super.getBrain(); // CraftBukkit - decompile error
}
@Override
@@ -229,8 +235,15 @@
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
+ // CraftBukkit start - Got milk?
+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) entityhuman.level(), entityhuman, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, enumhand);
+
+ if (event.isCancelled()) {
+ return EnumInteractionResult.PASS;
+ }
+ // CraftBukkit end
entityhuman.playSound(this.getMilkingSound(), 1.0F, 1.0F);
- ItemStack itemstack1 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, Items.MILK_BUCKET.getDefaultInstance());
+ ItemStack itemstack1 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit
entityhuman.setItemInHand(enumhand, itemstack1);
return EnumInteractionResult.SUCCESS;

View File

@@ -0,0 +1,149 @@
--- a/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java
+++ b/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java
@@ -79,6 +79,18 @@
import net.minecraft.world.phys.Vec3D;
import net.minecraft.world.ticks.ContainerSingleItem;
+// CraftBukkit start
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.entity.AbstractHorse;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.event.entity.EntityRegainHealthEvent;
+import org.bukkit.inventory.InventoryHolder;
+// CraftBukkit end
+
public abstract class EntityHorseAbstract extends EntityAnimal implements IInventoryListener, HasCustomInventoryScreen, OwnableEntity, IJumpable, ISaddleable {
public static final int EQUIPMENT_SLOT_OFFSET = 400;
@@ -167,7 +179,53 @@
public boolean stillValid(EntityHuman entityhuman) {
return entityhuman.getVehicle() == EntityHorseAbstract.this || entityhuman.canInteractWithEntity((Entity) EntityHorseAbstract.this, 4.0D);
}
+
+ // CraftBukkit start - add fields and methods
+ public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
+ private int maxStack = MAX_STACK;
+
+ @Override
+ public List<ItemStack> getContents() {
+ return Arrays.asList(this.getTheItem());
+ }
+
+ @Override
+ public void onOpen(CraftHumanEntity who) {
+ transaction.add(who);
+ }
+
+ @Override
+ public void onClose(CraftHumanEntity who) {
+ transaction.remove(who);
+ }
+
+ @Override
+ public List<HumanEntity> getViewers() {
+ return transaction;
+ }
+
+ @Override
+ public int getMaxStackSize() {
+ return maxStack;
+ }
+
+ @Override
+ public void setMaxStackSize(int size) {
+ maxStack = size;
+ }
+
+ @Override
+ public InventoryHolder getOwner() {
+ return (AbstractHorse) EntityHorseAbstract.this.getBukkitEntity();
+ }
+
+ @Override
+ public Location getLocation() {
+ return EntityHorseAbstract.this.getBukkitEntity().getLocation();
+ }
+ // CraftBukkit end
};
+ public int maxDomestication = 100; // CraftBukkit - store max domestication value
protected EntityHorseAbstract(EntityTypes<? extends EntityHorseAbstract> entitytypes, World world) {
super(entitytypes, world);
@@ -366,7 +424,7 @@
public void createInventory() {
InventorySubcontainer inventorysubcontainer = this.inventory;
- this.inventory = new InventorySubcontainer(this.getInventorySize());
+ this.inventory = new InventorySubcontainer(this.getInventorySize(), (AbstractHorse) this.getBukkitEntity()); // CraftBukkit
if (inventorysubcontainer != null) {
inventorysubcontainer.removeListener(this);
int i = Math.min(inventorysubcontainer.getContainerSize(), this.inventory.getContainerSize());
@@ -470,7 +528,7 @@
}
public int getMaxTemper() {
- return 100;
+ return this.maxDomestication; // CraftBukkit - return stored max domestication instead of 100
}
@Override
@@ -541,7 +599,7 @@
}
if (this.getHealth() < this.getMaxHealth() && f > 0.0F) {
- this.heal(f);
+ this.heal(f, EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit
flag = true;
}
@@ -618,7 +676,7 @@
if (world instanceof WorldServer worldserver) {
if (this.isAlive()) {
if (this.random.nextInt(900) == 0 && this.deathTime == 0) {
- this.heal(1.0F);
+ this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
}
if (this.canEatGrass()) {
@@ -883,6 +941,7 @@
if (this.getOwnerUUID() != null) {
nbttagcompound.putUUID("Owner", this.getOwnerUUID());
}
+ nbttagcompound.putInt("Bukkit.MaxDomestication", this.maxDomestication); // CraftBukkit
if (!this.inventory.getItem(0).isEmpty()) {
nbttagcompound.put("SaddleItem", this.inventory.getItem(0).save(this.registryAccess()));
@@ -910,6 +969,11 @@
if (uuid != null) {
this.setOwnerUUID(uuid);
}
+ // CraftBukkit start
+ if (nbttagcompound.contains("Bukkit.MaxDomestication")) {
+ this.maxDomestication = nbttagcompound.getInt("Bukkit.MaxDomestication");
+ }
+ // CraftBukkit end
if (nbttagcompound.contains("SaddleItem", 10)) {
ItemStack itemstack = (ItemStack) ItemStack.parse(this.registryAccess(), nbttagcompound.getCompound("SaddleItem")).orElse(ItemStack.EMPTY);
@@ -1012,6 +1076,17 @@
@Override
public void handleStartJump(int i) {
+ // CraftBukkit start
+ float power;
+ if (i >= 90) {
+ power = 1.0F;
+ } else {
+ power = 0.4F + 0.4F * (float) i / 90.0F;
+ }
+ if (!CraftEventFactory.callHorseJumpEvent(this, power)) {
+ return;
+ }
+ // CraftBukkit end
this.allowStandSliding = true;
this.standIfPossible();
this.playJumpSound();

View File

@@ -0,0 +1,22 @@
--- a/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java
+++ b/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java
@@ -27,6 +27,10 @@
import net.minecraft.world.level.GeneratorAccess;
import net.minecraft.world.level.World;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityHorseSkeleton extends EntityHorseAbstract {
private final PathfinderGoalHorseTrap skeletonTrapGoal = new PathfinderGoalHorseTrap(this);
@@ -122,7 +126,7 @@
public void aiStep() {
super.aiStep();
if (this.isTrap() && this.trapTime++ >= 18000) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
}
}

View File

@@ -0,0 +1,14 @@
--- a/net/minecraft/world/entity/animal/horse/EntityLlama.java
+++ b/net/minecraft/world/entity/animal/horse/EntityLlama.java
@@ -82,6 +82,11 @@
return false;
}
+ // CraftBukkit start
+ public void setStrengthPublic(int i) {
+ this.setStrength(i);
+ }
+ // CraftBukkit end
private void setStrength(int i) {
this.entityData.set(EntityLlama.DATA_STRENGTH_ID, Math.max(1, Math.min(5, i)));
}

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java
+++ b/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java
@@ -22,6 +22,10 @@
import net.minecraft.world.level.World;
import net.minecraft.world.level.WorldAccess;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityLlamaTrader extends EntityLlama {
private int despawnDelay = 47999;
@@ -94,7 +98,7 @@
this.despawnDelay = this.isLeashedToWanderingTrader() ? ((EntityVillagerTrader) this.getLeashHolder()).getDespawnDelay() - 1 : this.despawnDelay - 1;
if (this.despawnDelay <= 0) {
this.removeLeash();
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
}
}
@@ -160,7 +164,7 @@
@Override
public void start() {
- this.mob.setTarget(this.ownerLastHurtBy);
+ this.mob.setTarget(this.ownerLastHurtBy, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit
Entity entity = this.llama.getLeashHolder();
if (entity instanceof EntityVillagerTrader) {

View File

@@ -0,0 +1,26 @@
--- a/net/minecraft/world/entity/animal/horse/PathfinderGoalHorseTrap.java
+++ b/net/minecraft/world/entity/animal/horse/PathfinderGoalHorseTrap.java
@@ -43,12 +43,12 @@
if (entitylightning != null) {
entitylightning.moveTo(this.horse.getX(), this.horse.getY(), this.horse.getZ());
entitylightning.setVisualOnly(true);
- worldserver.addFreshEntity(entitylightning);
+ worldserver.strikeLightning(entitylightning, org.bukkit.event.weather.LightningStrikeEvent.Cause.TRAP); // CraftBukkit
EntitySkeleton entityskeleton = this.createSkeleton(difficultydamagescaler, this.horse);
if (entityskeleton != null) {
entityskeleton.startRiding(this.horse);
- worldserver.addFreshEntityWithPassengers(entityskeleton);
+ worldserver.addFreshEntityWithPassengers(entityskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRAP); // CraftBukkit
for (int i = 0; i < 3; ++i) {
EntityHorseAbstract entityhorseabstract = this.createHorse(difficultydamagescaler);
@@ -59,7 +59,7 @@
if (entityskeleton1 != null) {
entityskeleton1.startRiding(entityhorseabstract);
entityhorseabstract.push(this.horse.getRandom().triangle(0.0D, 1.1485D), 0.0D, this.horse.getRandom().triangle(0.0D, 1.1485D));
- worldserver.addFreshEntityWithPassengers(entityhorseabstract);
+ worldserver.addFreshEntityWithPassengers(entityhorseabstract, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.JOCKEY); // CraftBukkit
}
}
}

View File

@@ -0,0 +1,34 @@
--- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -267,6 +267,13 @@
this.dropFromGiftLootTable(worldserver, LootTables.SNIFFER_DIGGING, (worldserver1, itemstack) -> {
EntityItem entityitem = new EntityItem(this.level(), (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), itemstack);
+ // CraftBukkit start - handle EntityDropItemEvent
+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
+ org.bukkit.Bukkit.getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
entityitem.setDefaultPickUpDelay();
worldserver1.addFreshEntity(entityitem);
});
@@ -308,7 +315,7 @@
List<GlobalPos> list = (List) this.getExploredPositions().limit(20L).collect(Collectors.toList());
list.add(0, GlobalPos.of(this.level().dimension(), blockposition));
- this.getBrain().setMemory(MemoryModuleType.SNIFFER_EXPLORED_POSITIONS, (Object) list);
+ this.getBrain().setMemory(MemoryModuleType.SNIFFER_EXPLORED_POSITIONS, list); // CraftBukkit - decompile error
return this;
}
@@ -444,7 +451,7 @@
@Override
public BehaviorController<Sniffer> getBrain() {
- return super.getBrain();
+ return (BehaviorController<Sniffer>) super.getBrain(); // CraftBukkit - decompile error
}
@Override

View File

@@ -0,0 +1,57 @@
--- a/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java
+++ b/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java
@@ -20,6 +20,12 @@
import net.minecraft.world.level.block.BlockFireAbstract;
import net.minecraft.world.level.dimension.end.EnderDragonBattle;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.ExplosionPrimeEvent;
+// CraftBukkit end
+
public class EntityEnderCrystal extends Entity {
private static final DataWatcherObject<Optional<BlockPosition>> DATA_BEAM_TARGET = DataWatcher.defineId(EntityEnderCrystal.class, DataWatcherRegistry.OPTIONAL_BLOCK_POS);
@@ -57,7 +63,11 @@
BlockPosition blockposition = this.blockPosition();
if (((WorldServer) this.level()).getDragonFight() != null && this.level().getBlockState(blockposition).isAir()) {
- this.level().setBlockAndUpdate(blockposition, BlockFireAbstract.getState(this.level(), blockposition));
+ // CraftBukkit start
+ if (!CraftEventFactory.callBlockIgniteEvent(this.level(), blockposition, this).isCancelled()) {
+ this.level().setBlockAndUpdate(blockposition, BlockFireAbstract.getState(this.level(), blockposition));
+ }
+ // CraftBukkit end
}
}
@@ -99,12 +109,26 @@
return false;
} else {
if (!this.isRemoved()) {
- this.remove(Entity.RemovalReason.KILLED);
+ // CraftBukkit start - All non-living entities need this
+ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, false)) {
+ return false;
+ }
+ // CraftBukkit end
if (!damagesource.is(DamageTypeTags.IS_EXPLOSION)) {
DamageSource damagesource1 = damagesource.getEntity() != null ? this.damageSources().explosion(this, damagesource.getEntity()) : null;
- worldserver.explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), 6.0F, false, World.a.BLOCK);
+ // CraftBukkit start
+ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false);
+ if (event.isCancelled()) {
+ return false;
+ }
+
+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
+ worldserver.explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.BLOCK);
+ } else {
+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
}
+ // CraftBukkit end
this.onDestroyedBy(worldserver, damagesource);
}

View File

@@ -0,0 +1,231 @@
--- a/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java
+++ b/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java
@@ -52,6 +52,22 @@
import net.minecraft.world.phys.Vec3D;
import org.slf4j.Logger;
+// CraftBukkit start
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Explosion;
+import net.minecraft.world.level.ServerExplosion;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.entity.TileEntity;
+import net.minecraft.world.level.storage.loot.LootParams;
+import net.minecraft.world.level.storage.loot.LootTableInfo;
+import net.minecraft.world.level.storage.loot.parameters.LootContextParameters;
+import org.bukkit.craftbukkit.block.CraftBlock;
+import org.bukkit.event.entity.EntityExplodeEvent;
+import org.bukkit.event.entity.EntityRegainHealthEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
public class EntityEnderDragon extends EntityInsentient implements IMonster {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -88,6 +104,7 @@
private final PathPoint[] nodes;
private final int[] nodeAdjacency;
private final Path openSet;
+ private final Explosion explosionSource; // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
public EntityEnderDragon(EntityTypes<? extends EntityEnderDragon> entitytypes, World world) {
super(EntityTypes.ENDER_DRAGON, world);
@@ -108,6 +125,7 @@
this.setHealth(this.getMaxHealth());
this.noPhysics = true;
this.phaseManager = new DragonControllerManager(this);
+ this.explosionSource = new ServerExplosion(world.getMinecraftWorld(), this, null, null, new Vec3D(Double.NaN, Double.NaN, Double.NaN), Float.NaN, true, Explosion.Effect.DESTROY); // CraftBukkit
}
public void setDragonFight(EnderDragonBattle enderdragonbattle) {
@@ -218,7 +236,7 @@
Vec3D vec3d1 = idragoncontroller.getFlyTargetLocation();
- if (vec3d1 != null) {
+ if (vec3d1 != null && idragoncontroller.getPhase() != DragonControllerPhase.HOVERING) { // CraftBukkit - Don't move when hovering
double d0 = vec3d1.x - this.getX();
double d1 = vec3d1.y - this.getY();
double d2 = vec3d1.z - this.getZ();
@@ -379,7 +397,14 @@
if (this.nearestCrystal.isRemoved()) {
this.nearestCrystal = null;
} else if (this.tickCount % 10 == 0 && this.getHealth() < this.getMaxHealth()) {
- this.setHealth(this.getHealth() + 1.0F);
+ // CraftBukkit start
+ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), 1.0F, EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL);
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ this.setHealth((float) (this.getHealth() + event.getAmount()));
+ }
+ // CraftBukkit end
}
}
@@ -458,6 +483,9 @@
int j1 = MathHelper.floor(axisalignedbb.maxZ);
boolean flag = false;
boolean flag1 = false;
+ // CraftBukkit start - Create a list to hold all the destroyed blocks
+ List<org.bukkit.block.Block> destroyedBlocks = new java.util.ArrayList<org.bukkit.block.Block>();
+ // CraftBukkit end
for (int k1 = i; k1 <= l; ++k1) {
for (int l1 = j; l1 <= i1; ++l1) {
@@ -467,7 +495,11 @@
if (!iblockdata.isAir() && !iblockdata.is(TagsBlock.DRAGON_TRANSPARENT)) {
if (worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !iblockdata.is(TagsBlock.DRAGON_IMMUNE)) {
- flag1 = worldserver.removeBlock(blockposition, false) || flag1;
+ // CraftBukkit start - Add blocks to list rather than destroying them
+ // flag1 = worldserver.removeBlock(blockposition, false) || flag1;
+ flag1 = true;
+ destroyedBlocks.add(CraftBlock.at(worldserver, blockposition));
+ // CraftBukkit end
} else {
flag = true;
}
@@ -476,6 +508,49 @@
}
}
+ // CraftBukkit start - Set off an EntityExplodeEvent for the dragon exploding all these blocks
+ // SPIGOT-4882: don't fire event if nothing hit
+ if (!flag1) {
+ return flag;
+ }
+
+ EntityExplodeEvent event = CraftEventFactory.callEntityExplodeEvent(this, destroyedBlocks, 0F, explosionSource.getBlockInteraction());
+ if (event.isCancelled()) {
+ // This flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down.
+ // We should consider adding an event extension for it, or perhaps returning true if the event is cancelled.
+ return flag;
+ } else if (event.getYield() == 0F) {
+ // Yield zero ==> no drops
+ for (org.bukkit.block.Block block : event.blockList()) {
+ this.level().removeBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()), false);
+ }
+ } else {
+ for (org.bukkit.block.Block block : event.blockList()) {
+ org.bukkit.Material blockId = block.getType();
+ if (blockId.isAir()) {
+ continue;
+ }
+
+ CraftBlock craftBlock = ((CraftBlock) block);
+ BlockPosition blockposition = craftBlock.getPosition();
+
+ Block nmsBlock = craftBlock.getNMS().getBlock();
+ if (nmsBlock.dropFromExplosion(explosionSource)) {
+ TileEntity tileentity = craftBlock.getNMS().hasBlockEntity() ? this.level().getBlockEntity(blockposition) : null;
+ LootParams.a loottableinfo_builder = (new LootParams.a((WorldServer) this.level())).withParameter(LootContextParameters.ORIGIN, Vec3D.atCenterOf(blockposition)).withParameter(LootContextParameters.TOOL, ItemStack.EMPTY).withParameter(LootContextParameters.EXPLOSION_RADIUS, 1.0F / event.getYield()).withOptionalParameter(LootContextParameters.BLOCK_ENTITY, tileentity);
+
+ craftBlock.getNMS().getDrops(loottableinfo_builder).forEach((itemstack) -> {
+ Block.popResource(this.level(), blockposition, itemstack);
+ });
+ craftBlock.getNMS().spawnAfterBreak((WorldServer) this.level(), blockposition, ItemStack.EMPTY, false);
+ }
+ nmsBlock.wasExploded((WorldServer) this.level(), blockposition, explosionSource);
+
+ this.level().removeBlock(blockposition, false);
+ }
+ }
+ // CraftBukkit end
+
if (flag1) {
BlockPosition blockposition1 = new BlockPosition(i + this.random.nextInt(l - i + 1), j + this.random.nextInt(i1 - j + 1), k + this.random.nextInt(j1 - k + 1));
@@ -531,7 +606,7 @@
@Override
public void kill(WorldServer worldserver) {
- this.remove(Entity.RemovalReason.KILLED);
+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
this.gameEvent(GameEvent.ENTITY_DIE);
if (this.dragonFight != null) {
this.dragonFight.updateDragon(this);
@@ -540,6 +615,21 @@
}
+ // CraftBukkit start - SPIGOT-2420: Special case, the ender dragon drops 12000 xp for the first kill and 500 xp for every other kill and this over time.
+ @Override
+ public int getExpReward(WorldServer worldserver, Entity entity) {
+ // CraftBukkit - Moved from #tickDeath method
+ boolean flag = worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT);
+ short short0 = 500;
+
+ if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) {
+ short0 = 12000;
+ }
+
+ return flag ? short0 : 0;
+ }
+ // CraftBukkit end
+
@Override
protected void tickDeath() {
if (this.dragonFight != null) {
@@ -555,16 +645,21 @@
this.level().addParticle(Particles.EXPLOSION_EMITTER, this.getX() + (double) f, this.getY() + 2.0D + (double) f1, this.getZ() + (double) f2, 0.0D, 0.0D, 0.0D);
}
+ // CraftBukkit start - SPIGOT-2420: Moved up to #getExpReward method
+ /*
short short0 = 500;
if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) {
short0 = 12000;
}
+ */
+ int short0 = expToDrop;
+ // CraftBukkit end
World world = this.level();
if (world instanceof WorldServer worldserver) {
- if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
+ if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp
EntityExperienceOrb.award(worldserver, this.position(), MathHelper.floor((float) short0 * 0.08F));
}
@@ -592,7 +687,7 @@
if (world1 instanceof WorldServer) {
WorldServer worldserver1 = (WorldServer) world1;
- if (worldserver1.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
+ if (true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp
EntityExperienceOrb.award(worldserver1, this.position(), MathHelper.floor((float) short0 * 0.2F));
}
@@ -600,7 +695,7 @@
this.dragonFight.setDragonKilled(this);
}
- this.remove(Entity.RemovalReason.KILLED);
+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
this.gameEvent(GameEvent.ENTITY_DIE);
}
}
@@ -814,6 +909,7 @@
super.addAdditionalSaveData(nbttagcompound);
nbttagcompound.putInt("DragonPhase", this.phaseManager.getCurrentPhase().getPhase().getId());
nbttagcompound.putInt("DragonDeathTime", this.dragonDeathTime);
+ nbttagcompound.putInt("Bukkit.expToDrop", expToDrop); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts
}
@Override
@@ -827,6 +923,11 @@
this.dragonDeathTime = nbttagcompound.getInt("DragonDeathTime");
}
+ // CraftBukkit start - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts
+ if (nbttagcompound.contains("Bukkit.expToDrop")) {
+ this.expToDrop = nbttagcompound.getInt("Bukkit.expToDrop");
+ }
+ // CraftBukkit end
}
@Override

View File

@@ -0,0 +1,22 @@
--- a/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.java
+++ b/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.java
@@ -11,6 +11,10 @@
import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class DragonControllerLandedFlame extends AbstractDragonControllerLanded {
private static final int FLAME_DURATION = 200;
@@ -100,7 +104,7 @@
@Override
public void end() {
if (this.flame != null) {
- this.flame.discard();
+ this.flame.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
this.flame = null;
}

View File

@@ -0,0 +1,42 @@
--- a/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerManager.java
+++ b/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerManager.java
@@ -5,6 +5,11 @@
import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
import org.slf4j.Logger;
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftEnderDragon;
+import org.bukkit.event.entity.EnderDragonChangePhaseEvent;
+// CraftBukkit end
+
public class DragonControllerManager {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -24,6 +29,19 @@
this.currentPhase.end();
}
+ // CraftBukkit start - Call EnderDragonChangePhaseEvent
+ EnderDragonChangePhaseEvent event = new EnderDragonChangePhaseEvent(
+ (CraftEnderDragon) this.dragon.getBukkitEntity(),
+ (this.currentPhase == null) ? null : CraftEnderDragon.getBukkitPhase(this.currentPhase.getPhase()),
+ CraftEnderDragon.getBukkitPhase(dragoncontrollerphase)
+ );
+ this.dragon.level().getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ dragoncontrollerphase = CraftEnderDragon.getMinecraftPhase(event.getNewPhase());
+ // CraftBukkit end
+
this.currentPhase = this.getPhase(dragoncontrollerphase);
if (!this.dragon.level().isClientSide) {
this.dragon.getEntityData().set(EntityEnderDragon.DATA_PHASE, dragoncontrollerphase.getId());
@@ -45,6 +63,6 @@
this.phases[i] = dragoncontrollerphase.createInstance(this.dragon);
}
- return this.phases[i];
+ return (T) this.phases[i]; // CraftBukkit - decompile error
}
}

View File

@@ -0,0 +1,103 @@
--- a/net/minecraft/world/entity/boss/wither/EntityWither.java
+++ b/net/minecraft/world/entity/boss/wither/EntityWither.java
@@ -57,6 +57,18 @@
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import net.minecraft.network.protocol.game.PacketPlayOutWorldEvent;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.WorldServer;
+import net.minecraft.world.level.block.Blocks;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRegainHealthEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.entity.ExplosionPrimeEvent;
+// CraftBukkit end
+
public class EntityWither extends EntityMonster implements IRangedEntity {
private static final DataWatcherObject<Integer> DATA_TARGET_A = DataWatcher.defineId(EntityWither.class, DataWatcherRegistry.INT);
@@ -252,15 +264,40 @@
i = this.getInvulnerableTicks() - 1;
this.bossEvent.setProgress(1.0F - (float) i / 220.0F);
if (i <= 0) {
- worldserver.explode(this, this.getX(), this.getEyeY(), this.getZ(), 7.0F, false, World.a.MOB);
+ // CraftBukkit start
+ // worldserver.explode(this, this.getX(), this.getEyeY(), this.getZ(), 7.0F, false, World.a.MOB);
+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false);
+ worldserver.getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ worldserver.explode(this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB);
+ }
+ // CraftBukkit end
+
if (!this.isSilent()) {
- worldserver.globalLevelEvent(1023, this.blockPosition(), 0);
+ // CraftBukkit start - Use relative location for far away sounds
+ // worldserver.globalLevelEvent(1023, new BlockPosition(this), 0);
+ int viewDistance = worldserver.getCraftServer().getViewDistance() * 16;
+ for (EntityPlayer player : (List<EntityPlayer>) MinecraftServer.getServer().getPlayerList().players) {
+ double deltaX = this.getX() - player.getX();
+ double deltaZ = this.getZ() - player.getZ();
+ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
+ if (distanceSquared > viewDistance * viewDistance) {
+ double deltaLength = Math.sqrt(distanceSquared);
+ double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance;
+ double relativeZ = player.getZ() + (deltaZ / deltaLength) * viewDistance;
+ player.connection.send(new PacketPlayOutWorldEvent(1023, new BlockPosition((int) relativeX, (int) this.getY(), (int) relativeZ), 0, true));
+ } else {
+ player.connection.send(new PacketPlayOutWorldEvent(1023, this.blockPosition(), 0, true));
+ }
+ }
+ // CraftBukkit end
}
}
this.setInvulnerableTicks(i);
if (this.tickCount % 10 == 0) {
- this.heal(10.0F);
+ this.heal(10.0F, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit
}
} else {
@@ -305,6 +342,7 @@
if (!list.isEmpty()) {
EntityLiving entityliving1 = (EntityLiving) list.get(this.random.nextInt(list.size()));
+ if (CraftEventFactory.callEntityTargetLivingEvent(this, entityliving1, EntityTargetEvent.TargetReason.CLOSEST_ENTITY).isCancelled()) continue; // CraftBukkit
this.setAlternativeTarget(i, entityliving1.getId());
}
}
@@ -331,6 +369,11 @@
IBlockData iblockdata = worldserver.getBlockState(blockposition);
if (canDestroy(iblockdata)) {
+ // CraftBukkit start
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.defaultBlockState())) {
+ continue;
+ }
+ // CraftBukkit end
flag = worldserver.destroyBlock(blockposition, true, this) || flag;
}
}
@@ -342,7 +385,7 @@
}
if (this.tickCount % 20 == 0) {
- this.heal(1.0F);
+ this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
}
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
@@ -499,7 +542,7 @@
@Override
public void checkDespawn() {
if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
this.noActionTime = 0;
}

View File

@@ -0,0 +1,110 @@
--- a/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
+++ b/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
@@ -18,6 +18,15 @@
import net.minecraft.world.phys.Vec3D;
import org.slf4j.Logger;
+// CraftBukkit start
+import net.minecraft.tags.DamageTypeTags;
+import net.minecraft.world.level.block.state.IBlockData;
+import org.bukkit.entity.Hanging;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.hanging.HangingBreakByEntityEvent;
+import org.bukkit.event.hanging.HangingBreakEvent;
+// CraftBukkit end
+
public abstract class BlockAttachedEntity extends Entity {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -44,7 +53,25 @@
if (this.checkInterval++ == 100) {
this.checkInterval = 0;
if (!this.isRemoved() && !this.survives()) {
- this.discard();
+ // CraftBukkit start - fire break events
+ IBlockData material = this.level().getBlockState(this.blockPosition());
+ HangingBreakEvent.RemoveCause cause;
+
+ if (!material.isAir()) {
+ // TODO: This feels insufficient to catch 100% of suffocation cases
+ cause = HangingBreakEvent.RemoveCause.OBSTRUCTION;
+ } else {
+ cause = HangingBreakEvent.RemoveCause.PHYSICS;
+ }
+
+ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), cause);
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (this.isRemoved() || event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
this.dropItem(worldserver, (Entity) null);
}
}
@@ -81,6 +108,22 @@
return false;
} else {
if (!this.isRemoved()) {
+ // CraftBukkit start - fire break events
+ Entity damager = (damagesource.isDirect()) ? damagesource.getDirectEntity() : damagesource.getEntity();
+ HangingBreakEvent event;
+ if (damager != null) {
+ event = new HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damager.getBukkitEntity(), damagesource.is(DamageTypeTags.IS_EXPLOSION) ? HangingBreakEvent.RemoveCause.EXPLOSION : HangingBreakEvent.RemoveCause.ENTITY);
+ } else {
+ event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), damagesource.is(DamageTypeTags.IS_EXPLOSION) ? HangingBreakEvent.RemoveCause.EXPLOSION : HangingBreakEvent.RemoveCause.DEFAULT);
+ }
+
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (this.isRemoved() || event.isCancelled()) {
+ return true;
+ }
+ // CraftBukkit end
+
this.kill(worldserver);
this.markHurt();
this.dropItem(worldserver, damagesource.getEntity());
@@ -101,6 +144,16 @@
if (world instanceof WorldServer worldserver) {
if (!this.isRemoved() && vec3d.lengthSqr() > 0.0D) {
+ // CraftBukkit start - fire break events
+ // TODO - Does this need its own cause? Seems to only be triggered by pistons
+ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS);
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (this.isRemoved() || event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
+
this.kill(worldserver);
this.dropItem(worldserver, (Entity) null);
}
@@ -113,7 +166,7 @@
World world = this.level();
if (world instanceof WorldServer worldserver) {
- if (!this.isRemoved() && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) {
+ if (false && !this.isRemoved() && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed
this.kill(worldserver);
this.dropItem(worldserver, (Entity) null);
}
@@ -121,6 +174,15 @@
}
+ // CraftBukkit start - selectively save tile position
+ @Override
+ public void addAdditionalSaveData(NBTTagCompound nbttagcompound, boolean includeAll) {
+ if (includeAll) {
+ addAdditionalSaveData(nbttagcompound);
+ }
+ }
+ // CraftBukkit end
+
@Override
public void addAdditionalSaveData(NBTTagCompound nbttagcompound) {
BlockPosition blockposition = this.getPos();

View File

@@ -0,0 +1,207 @@
--- a/net/minecraft/world/entity/decoration/EntityArmorStand.java
+++ b/net/minecraft/world/entity/decoration/EntityArmorStand.java
@@ -48,6 +48,16 @@
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.craftbukkit.CraftEquipmentSlot;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.entity.ArmorStand;
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
+// CraftBukkit end
+
public class EntityArmorStand extends EntityLiving {
public static final int WOBBLE_TIME = 5;
@@ -123,6 +133,13 @@
return createLivingAttributes().add(GenericAttributes.STEP_HEIGHT, 0.0D);
}
+ // CraftBukkit start - SPIGOT-3607, SPIGOT-3637
+ @Override
+ public float getBukkitYaw() {
+ return this.getYRot();
+ }
+ // CraftBukkit end
+
@Override
public void refreshDimensions() {
double d0 = this.getX();
@@ -183,13 +200,20 @@
@Override
public void setItemSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
+ // CraftBukkit start
+ this.setItemSlot(enumitemslot, itemstack, false);
+ }
+
+ @Override
+ public void setItemSlot(EnumItemSlot enumitemslot, ItemStack itemstack, boolean silent) {
+ // CraftBukkit end
this.verifyEquippedItem(itemstack);
switch (enumitemslot.getType()) {
case HAND:
- this.onEquipItem(enumitemslot, (ItemStack) this.handItems.set(enumitemslot.getIndex(), itemstack), itemstack);
+ this.onEquipItem(enumitemslot, (ItemStack) this.handItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit
break;
case HUMANOID_ARMOR:
- this.onEquipItem(enumitemslot, (ItemStack) this.armorItems.set(enumitemslot.getIndex(), itemstack), itemstack);
+ this.onEquipItem(enumitemslot, (ItemStack) this.armorItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit
}
}
@@ -412,7 +436,25 @@
return false;
} else if (itemstack1.isEmpty() && (this.disabledSlots & 1 << enumitemslot.getFilterBit(16)) != 0) {
return false;
- } else if (entityhuman.hasInfiniteMaterials() && itemstack1.isEmpty() && !itemstack.isEmpty()) {
+ // CraftBukkit start
+ } else {
+ org.bukkit.inventory.ItemStack armorStandItem = CraftItemStack.asCraftMirror(itemstack1);
+ org.bukkit.inventory.ItemStack playerHeldItem = CraftItemStack.asCraftMirror(itemstack);
+
+ Player player = (Player) entityhuman.getBukkitEntity();
+ ArmorStand self = (ArmorStand) this.getBukkitEntity();
+
+ EquipmentSlot slot = CraftEquipmentSlot.getSlot(enumitemslot);
+ EquipmentSlot hand = CraftEquipmentSlot.getHand(enumhand);
+ PlayerArmorStandManipulateEvent armorStandManipulateEvent = new PlayerArmorStandManipulateEvent(player, self, playerHeldItem, armorStandItem, slot, hand);
+ this.level().getCraftServer().getPluginManager().callEvent(armorStandManipulateEvent);
+
+ if (armorStandManipulateEvent.isCancelled()) {
+ return true;
+ }
+
+ if (entityhuman.hasInfiniteMaterials() && itemstack1.isEmpty() && !itemstack.isEmpty()) {
+ // CraftBukkit end
this.setItemSlot(enumitemslot, itemstack.copyWithCount(1));
return true;
} else if (!itemstack.isEmpty() && itemstack.getCount() > 1) {
@@ -427,6 +469,7 @@
entityhuman.setItemInHand(enumhand, itemstack1);
return true;
}
+ } // CraftBukkit
}
@Override
@@ -436,12 +479,22 @@
} else if (!worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && damagesource.getEntity() instanceof EntityInsentient) {
return false;
} else if (damagesource.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
- this.kill(worldserver);
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) {
+ return false;
+ }
+ this.kill(worldserver, damagesource); // CraftBukkit
+ // CraftBukkit end
return false;
- } else if (!this.isInvulnerableTo(worldserver, damagesource) && !this.invisible && !this.isMarker()) {
+ } else if (!this.isInvulnerableTo(worldserver, damagesource) && (true || !this.invisible) && !this.isMarker()) { // CraftBukkit
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, true, this.invisible)) {
+ return false;
+ }
+ // CraftBukkit end
if (damagesource.is(DamageTypeTags.IS_EXPLOSION)) {
this.brokenByAnything(worldserver, damagesource);
- this.kill(worldserver);
+ this.kill(worldserver, damagesource); // CraftBukkit
return false;
} else if (damagesource.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
if (this.isOnFire()) {
@@ -474,7 +527,7 @@
if (damagesource.isCreativePlayer()) {
this.playBrokenSound();
this.showBreakingParticles();
- this.kill(worldserver);
+ this.kill(worldserver, damagesource); // CraftBukkit
return true;
} else {
long i = worldserver.getGameTime();
@@ -486,7 +539,7 @@
} else {
this.brokenByPlayer(worldserver, damagesource);
this.showBreakingParticles();
- this.kill(worldserver);
+ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event
}
return true;
@@ -536,7 +589,7 @@
f1 -= f;
if (f1 <= 0.5F) {
this.brokenByAnything(worldserver, damagesource);
- this.kill(worldserver);
+ this.kill(worldserver, damagesource); // CraftBukkit
} else {
this.setHealth(f1);
this.gameEvent(GameEvent.ENTITY_DAMAGE, damagesource.getEntity());
@@ -548,13 +601,13 @@
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
- Block.popResource(this.level(), this.blockPosition(), itemstack);
+ drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
this.brokenByAnything(worldserver, damagesource);
}
private void brokenByAnything(WorldServer worldserver, DamageSource damagesource) {
this.playBrokenSound();
- this.dropAllDeathLoot(worldserver, damagesource);
+ // this.dropAllDeathLoot(worldserver, damagesource); // CraftBukkit - moved down
ItemStack itemstack;
int i;
@@ -562,7 +615,7 @@
for (i = 0; i < this.handItems.size(); ++i) {
itemstack = (ItemStack) this.handItems.get(i);
if (!itemstack.isEmpty()) {
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
+ drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
this.handItems.set(i, ItemStack.EMPTY);
}
}
@@ -570,10 +623,11 @@
for (i = 0; i < this.armorItems.size(); ++i) {
itemstack = (ItemStack) this.armorItems.get(i);
if (!itemstack.isEmpty()) {
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
+ drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
this.armorItems.set(i, ItemStack.EMPTY);
}
}
+ this.dropAllDeathLoot(worldserver, damagesource); // CraftBukkit - moved from above
}
@@ -664,9 +718,23 @@
return this.isSmall();
}
+ // CraftBukkit start
+ @Override
+ public boolean shouldDropExperience() {
+ return true; // MC-157395, SPIGOT-5193 even baby (small) armor stands should drop
+ }
+ // CraftBukkit end
+
@Override
public void kill(WorldServer worldserver) {
- this.remove(Entity.RemovalReason.KILLED);
+ // CraftBukkit start - pass DamageSource for kill
+ this.kill(worldserver, null);
+ }
+
+ public void kill(WorldServer worldserver, DamageSource damageSource) {
+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), drops); // CraftBukkit - call event
+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
+ // CraftBukkit end
this.gameEvent(GameEvent.ENTITY_DIE);
}

View File

@@ -0,0 +1,48 @@
--- a/net/minecraft/world/entity/decoration/EntityItemFrame.java
+++ b/net/minecraft/world/entity/decoration/EntityItemFrame.java
@@ -91,6 +91,12 @@
@Override
protected AxisAlignedBB calculateBoundingBox(BlockPosition blockposition, EnumDirection enumdirection) {
+ // CraftBukkit start - break out BB calc into own method
+ return calculateBoundingBoxStatic(blockposition, enumdirection);
+ }
+
+ public static AxisAlignedBB calculateBoundingBoxStatic(BlockPosition blockposition, EnumDirection enumdirection) {
+ // CraftBukkit end
float f = 0.46875F;
Vec3D vec3d = Vec3D.atCenterOf(blockposition).relative(enumdirection, -0.46875D);
EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.getAxis();
@@ -155,6 +161,11 @@
if (this.isInvulnerableToBase(damagesource)) {
return false;
} else if (this.shouldDamageDropItem(damagesource)) {
+ // CraftBukkit start - fire EntityDamageEvent
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, false) || this.isRemoved()) {
+ return true;
+ }
+ // CraftBukkit end
this.dropItem(worldserver, damagesource.getEntity(), false);
this.gameEvent(GameEvent.BLOCK_CHANGE, damagesource.getEntity());
this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F);
@@ -267,13 +278,19 @@
}
public void setItem(ItemStack itemstack, boolean flag) {
+ // CraftBukkit start
+ this.setItem(itemstack, flag, true);
+ }
+
+ public void setItem(ItemStack itemstack, boolean flag, boolean playSound) {
+ // CraftBukkit end
if (!itemstack.isEmpty()) {
itemstack = itemstack.copyWithCount(1);
}
this.onItemChanged(itemstack);
this.getEntityData().set(EntityItemFrame.DATA_ITEM, itemstack);
- if (!itemstack.isEmpty()) {
+ if (!itemstack.isEmpty() && playSound) { // CraftBukkit
this.playSound(this.getAddItemSound(), 1.0F, 1.0F);
}

View File

@@ -0,0 +1,74 @@
--- a/net/minecraft/world/entity/decoration/EntityLeash.java
+++ b/net/minecraft/world/entity/decoration/EntityLeash.java
@@ -27,6 +27,13 @@
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import net.minecraft.network.protocol.game.PacketPlayOutAttachEntity;
+import net.minecraft.server.level.EntityPlayer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityLeash extends BlockAttachedEntity {
public static final double OFFSET_Y = 0.375D;
@@ -85,6 +92,15 @@
Leashable leashable = (Leashable) iterator.next();
if (leashable.getLeashHolder() == entityhuman) {
+ // CraftBukkit start
+ if (leashable instanceof Entity leashed) {
+ if (CraftEventFactory.callPlayerLeashEntityEvent(leashed, this, entityhuman, enumhand).isCancelled()) {
+ ((EntityPlayer) entityhuman).connection.send(new PacketPlayOutAttachEntity(leashed, leashable.getLeashHolder()));
+ flag = true; // Also set true when the event is cancelled otherwise it tries to unleash the entities
+ continue;
+ }
+ }
+ // CraftBukkit end
leashable.setLeashedTo(this, true);
flag = true;
}
@@ -93,18 +109,38 @@
boolean flag1 = false;
if (!flag) {
- this.discard();
- if (entityhuman.getAbilities().instabuild) {
+ // CraftBukkit start - Move below
+ // this.discard();
+ boolean die = true;
+ // CraftBukkit end
+ if (true || entityhuman.getAbilities().instabuild) { // CraftBukkit - Process for non-creative as well
Iterator iterator1 = list.iterator();
while (iterator1.hasNext()) {
Leashable leashable1 = (Leashable) iterator1.next();
if (leashable1.isLeashed() && leashable1.getLeashHolder() == this) {
- leashable1.removeLeash();
+ // CraftBukkit start
+ if (leashable1 instanceof Entity leashed) {
+ if (CraftEventFactory.callPlayerUnleashEntityEvent(leashed, entityhuman, enumhand).isCancelled()) {
+ die = false;
+ continue;
+ }
+ }
+ if (entityhuman.getAbilities().instabuild){
+ leashable1.removeLeash();
+ } else {
+ leashable1.dropLeash();
+ }
+ // CraftBukkit end
flag1 = true;
}
}
+ // CraftBukkit start
+ if (die) {
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
+ }
+ // CraftBukkit end
}
}

View File

@@ -0,0 +1,51 @@
--- a/net/minecraft/world/entity/decoration/EntityPainting.java
+++ b/net/minecraft/world/entity/decoration/EntityPainting.java
@@ -72,7 +72,7 @@
public static Optional<EntityPainting> create(World world, BlockPosition blockposition, EnumDirection enumdirection) {
EntityPainting entitypainting = new EntityPainting(world, blockposition);
List<Holder<PaintingVariant>> list = new ArrayList();
- Iterable iterable = world.registryAccess().lookupOrThrow(Registries.PAINTING_VARIANT).getTagOrEmpty(PaintingVariantTags.PLACEABLE);
+ Iterable<Holder<PaintingVariant>> iterable = world.registryAccess().lookupOrThrow(Registries.PAINTING_VARIANT).getTagOrEmpty(PaintingVariantTags.PLACEABLE); // CraftBukkit - decompile error
Objects.requireNonNull(list);
iterable.forEach(list::add);
@@ -138,22 +138,32 @@
@Override
protected AxisAlignedBB calculateBoundingBox(BlockPosition blockposition, EnumDirection enumdirection) {
+ // CraftBukkit start
+ PaintingVariant paintingvariant = (PaintingVariant) this.getVariant().value();
+ return calculateBoundingBoxStatic(blockposition, enumdirection, paintingvariant.width(), paintingvariant.height());
+ }
+
+ public static AxisAlignedBB calculateBoundingBoxStatic(BlockPosition blockposition, EnumDirection enumdirection, int width, int height) {
+ // CraftBukkit end
float f = 0.46875F;
Vec3D vec3d = Vec3D.atCenterOf(blockposition).relative(enumdirection, -0.46875D);
- PaintingVariant paintingvariant = (PaintingVariant) this.getVariant().value();
- double d0 = this.offsetForPaintingSize(paintingvariant.width());
- double d1 = this.offsetForPaintingSize(paintingvariant.height());
+ // CraftBukkit start
+ double d0 = offsetForPaintingSize(width);
+ double d1 = offsetForPaintingSize(height);
+ // CraftBukkit end
EnumDirection enumdirection1 = enumdirection.getCounterClockWise();
Vec3D vec3d1 = vec3d.relative(enumdirection1, d0).relative(EnumDirection.UP, d1);
EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.getAxis();
- double d2 = enumdirection_enumaxis == EnumDirection.EnumAxis.X ? 0.0625D : (double) paintingvariant.width();
- double d3 = (double) paintingvariant.height();
- double d4 = enumdirection_enumaxis == EnumDirection.EnumAxis.Z ? 0.0625D : (double) paintingvariant.width();
+ // CraftBukkit start
+ double d2 = enumdirection_enumaxis == EnumDirection.EnumAxis.X ? 0.0625D : (double) width;
+ double d3 = (double) height;
+ double d4 = enumdirection_enumaxis == EnumDirection.EnumAxis.Z ? 0.0625D : (double) width;
+ // CraftBukkit end
return AxisAlignedBB.ofSize(vec3d1, d2, d3, d4);
}
- private double offsetForPaintingSize(int i) {
+ private static double offsetForPaintingSize(int i) { // CraftBukkit - static
return i % 2 == 0 ? 0.5D : 0.0D;
}

View File

@@ -0,0 +1,91 @@
--- a/net/minecraft/world/entity/item/EntityFallingBlock.java
+++ b/net/minecraft/world/entity/item/EntityFallingBlock.java
@@ -52,6 +52,11 @@
import net.minecraft.world.phys.Vec3D;
import org.slf4j.Logger;
+// CraftBukkit start;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityFallingBlock extends Entity {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -87,10 +92,17 @@
}
public static EntityFallingBlock fall(World world, BlockPosition blockposition, IBlockData iblockdata) {
+ // CraftBukkit start
+ return fall(world, blockposition, iblockdata, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
+ }
+
+ public static EntityFallingBlock fall(World world, BlockPosition blockposition, IBlockData iblockdata, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ // CraftBukkit end
EntityFallingBlock entityfallingblock = new EntityFallingBlock(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, iblockdata.hasProperty(BlockProperties.WATERLOGGED) ? (IBlockData) iblockdata.setValue(BlockProperties.WATERLOGGED, false) : iblockdata);
+ if (!CraftEventFactory.callEntityChangeBlockEvent(entityfallingblock, blockposition, iblockdata.getFluidState().createLegacyBlock())) return entityfallingblock; // CraftBukkit
world.setBlock(blockposition, iblockdata.getFluidState().createLegacyBlock(), 3);
- world.addFreshEntity(entityfallingblock);
+ world.addFreshEntity(entityfallingblock, spawnReason); // CraftBukkit
return entityfallingblock;
}
@@ -139,7 +151,7 @@
@Override
public void tick() {
if (this.blockState.isAir()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
Block block = this.blockState.getBlock();
@@ -174,7 +186,7 @@
this.spawnAtLocation(worldserver, (IMaterial) block);
}
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
}
} else {
IBlockData iblockdata = this.level().getBlockState(blockposition);
@@ -191,9 +203,15 @@
this.blockState = (IBlockData) this.blockState.setValue(BlockProperties.WATERLOGGED, true);
}
+ // CraftBukkit start
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, this.blockState)) {
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // SPIGOT-6586 called before the event in previous versions
+ return;
+ }
+ // CraftBukkit end
if (this.level().setBlock(blockposition, this.blockState, 3)) {
((WorldServer) this.level()).getChunkSource().chunkMap.broadcast(this, new PacketPlayOutBlockChange(blockposition, this.level().getBlockState(blockposition)));
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
if (block instanceof Fallable) {
((Fallable) block).onLand(this.level(), blockposition, this.blockState, iblockdata, this);
}
@@ -221,19 +239,19 @@
}
}
} else if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
this.callOnBrokenAfterFall(block, blockposition);
this.spawnAtLocation(worldserver, (IMaterial) block);
}
} else {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
this.callOnBrokenAfterFall(block, blockposition);
this.spawnAtLocation(worldserver, (IMaterial) block);
}
}
} else {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
this.callOnBrokenAfterFall(block, blockposition);
}
}

View File

@@ -0,0 +1,171 @@
--- a/net/minecraft/world/entity/item/EntityItem.java
+++ b/net/minecraft/world/entity/item/EntityItem.java
@@ -34,6 +34,15 @@
import net.minecraft.world.level.portal.TeleportTransition;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.entity.Player;
+import org.bukkit.event.entity.EntityPickupItemEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.player.PlayerPickupItemEvent;
+// CraftBukkit end
+
public class EntityItem extends Entity implements TraceableEntity {
private static final DataWatcherObject<ItemStack> DATA_ITEM = DataWatcher.defineId(EntityItem.class, DataWatcherRegistry.ITEM_STACK);
@@ -52,6 +61,7 @@
@Nullable
public UUID target;
public final float bobOffs;
+ private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
public EntityItem(EntityTypes<? extends EntityItem> entitytypes, World world) {
super(entitytypes, world);
@@ -133,12 +143,15 @@
@Override
public void tick() {
if (this.getItem().isEmpty()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
super.tick();
- if (this.pickupDelay > 0 && this.pickupDelay != 32767) {
- --this.pickupDelay;
- }
+ // CraftBukkit start - Use wall time for pickup and despawn timers
+ int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
+ if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks;
+ if (this.age != -32768) this.age += elapsedTicks;
+ this.lastTick = MinecraftServer.currentTick;
+ // CraftBukkit end
this.xo = this.getX();
this.yo = this.getY();
@@ -188,9 +201,11 @@
this.mergeWithNeighbours();
}
+ /* CraftBukkit start - moved up
if (this.age != -32768) {
++this.age;
}
+ // CraftBukkit end */
this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing();
if (!this.level().isClientSide) {
@@ -202,7 +217,13 @@
}
if (!this.level().isClientSide && this.age >= 6000) {
- this.discard();
+ // CraftBukkit start - fire ItemDespawnEvent
+ if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
+ this.age = 0;
+ return;
+ }
+ // CraftBukkit end
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
}
}
@@ -287,11 +308,16 @@
}
private static void merge(EntityItem entityitem, ItemStack itemstack, EntityItem entityitem1, ItemStack itemstack1) {
+ // CraftBukkit start
+ if (!CraftEventFactory.callItemMergeEvent(entityitem1, entityitem)) {
+ return;
+ }
+ // CraftBukkit end
merge(entityitem, itemstack, itemstack1);
entityitem.pickupDelay = Math.max(entityitem.pickupDelay, entityitem1.pickupDelay);
entityitem.age = Math.min(entityitem.age, entityitem1.age);
if (itemstack1.isEmpty()) {
- entityitem1.discard();
+ entityitem1.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause);
}
}
@@ -320,12 +346,17 @@
} else if (!this.getItem().canBeHurtBy(damagesource)) {
return false;
} else {
+ // CraftBukkit start
+ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) {
+ return false;
+ }
+ // CraftBukkit end
this.markHurt();
this.health = (int) ((float) this.health - f);
this.gameEvent(GameEvent.ENTITY_DAMAGE, damagesource.getEntity());
if (this.health <= 0) {
this.getItem().onDestroyed(this);
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
}
return true;
@@ -382,7 +413,7 @@
}
if (this.getItem().isEmpty()) {
- this.discard();
+ this.discard(null); // CraftBukkit - add Bukkit remove cause
}
}
@@ -394,10 +425,50 @@
Item item = itemstack.getItem();
int i = itemstack.getCount();
+ // CraftBukkit start - fire PlayerPickupItemEvent
+ int canHold = entityhuman.getInventory().canHold(itemstack);
+ int remaining = i - canHold;
+
+ if (this.pickupDelay <= 0 && canHold > 0) {
+ itemstack.setCount(canHold);
+ // Call legacy event
+ PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
+ playerEvent.setCancelled(!playerEvent.getPlayer().getCanPickupItems());
+ this.level().getCraftServer().getPluginManager().callEvent(playerEvent);
+ if (playerEvent.isCancelled()) {
+ itemstack.setCount(i); // SPIGOT-5294 - restore count
+ return;
+ }
+
+ // Call newer event afterwards
+ EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
+ entityEvent.setCancelled(!entityEvent.getEntity().getCanPickupItems());
+ this.level().getCraftServer().getPluginManager().callEvent(entityEvent);
+ if (entityEvent.isCancelled()) {
+ itemstack.setCount(i); // SPIGOT-5294 - restore count
+ return;
+ }
+
+ // Update the ItemStack if it was changed in the event
+ ItemStack current = this.getItem();
+ if (!itemstack.equals(current)) {
+ itemstack = current;
+ } else {
+ itemstack.setCount(canHold + remaining); // = i
+ }
+
+ // Possibly < 0; fix here so we do not have to modify code below
+ this.pickupDelay = 0;
+ } else if (this.pickupDelay == 0) {
+ // ensure that the code below isn't triggered if canHold says we can't pick the items up
+ this.pickupDelay = -1;
+ }
+ // CraftBukkit end
+
if (this.pickupDelay == 0 && (this.target == null || this.target.equals(entityhuman.getUUID())) && entityhuman.getInventory().add(itemstack)) {
entityhuman.take(this, i);
if (itemstack.isEmpty()) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
itemstack.setCount(i);
}

View File

@@ -0,0 +1,53 @@
--- a/net/minecraft/world/entity/item/EntityTNTPrimed.java
+++ b/net/minecraft/world/entity/item/EntityTNTPrimed.java
@@ -27,6 +27,12 @@
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.portal.TeleportTransition;
+// CraftBukkit start;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.ExplosionPrimeEvent;
+// CraftBukkit end
+
public class EntityTNTPrimed extends Entity implements TraceableEntity {
private static final DataWatcherObject<Integer> DATA_FUSE_ID = DataWatcher.defineId(EntityTNTPrimed.class, DataWatcherRegistry.INT);
@@ -51,6 +57,7 @@
public EntityLiving owner;
private boolean usedPortal;
public float explosionPower;
+ public boolean isIncendiary = false; // CraftBukkit - add field
public EntityTNTPrimed(EntityTypes<? extends EntityTNTPrimed> entitytypes, World world) {
super(entitytypes, world);
@@ -107,10 +114,13 @@
this.setFuse(i);
if (i <= 0) {
- this.discard();
+ // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event
+ // this.discard();
if (!this.level().isClientSide) {
this.explode();
}
+ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
+ // CraftBukkit end
} else {
this.updateInWaterStateAndDoFluidPushing();
if (this.level().isClientSide) {
@@ -121,7 +131,13 @@
}
private void explode() {
- this.level().explode(this, Explosion.getDefaultDamageSource(this.level(), this), this.usedPortal ? EntityTNTPrimed.USED_PORTAL_DAMAGE_CALCULATOR : null, this.getX(), this.getY(0.0625D), this.getZ(), this.explosionPower, false, World.a.TNT);
+ // CraftBukkit start
+ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
+ if (event.isCancelled()) {
+ return;
+ }
+ this.level().explode(this, Explosion.getDefaultDamageSource(this.level(), this), this.usedPortal ? EntityTNTPrimed.USED_PORTAL_DAMAGE_CALCULATOR : null, this.getX(), this.getY(0.0625D), this.getZ(), event.getRadius(), event.getFire(), World.a.TNT);
+ // CraftBukkit end
}
@Override

View File

@@ -0,0 +1,15 @@
--- a/net/minecraft/world/entity/monster/Bogged.java
+++ b/net/minecraft/world/entity/monster/Bogged.java
@@ -79,6 +79,12 @@
if (world instanceof WorldServer) {
WorldServer worldserver = (WorldServer) world;
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) {
+ this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients
+ return EnumInteractionResult.PASS;
+ }
+ // CraftBukkit end
this.shear(worldserver, SoundCategory.PLAYERS, itemstack);
this.gameEvent(GameEvent.SHEAR, entityhuman);
itemstack.hurtAndBreak(1, entityhuman, getSlotForHand(enumhand));

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/monster/EntityCaveSpider.java
+++ b/net/minecraft/world/entity/monster/EntityCaveSpider.java
@@ -40,7 +40,7 @@
}
if (b0 > 0) {
- ((EntityLiving) entity).addEffect(new MobEffect(MobEffects.POISON, b0 * 20, 0), this);
+ ((EntityLiving) entity).addEffect(new MobEffect(MobEffects.POISON, b0 * 20, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
}
}

View File

@@ -0,0 +1,96 @@
--- a/net/minecraft/world/entity/monster/EntityCreeper.java
+++ b/net/minecraft/world/entity/monster/EntityCreeper.java
@@ -42,6 +42,13 @@
import net.minecraft.world.level.World;
import net.minecraft.world.level.gameevent.GameEvent;
+// CraftBukkit start;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.ExplosionPrimeEvent;
+// CraftBukkit end
+
public class EntityCreeper extends EntityMonster {
private static final DataWatcherObject<Integer> DATA_SWELL_DIR = DataWatcher.defineId(EntityCreeper.class, DataWatcherRegistry.INT);
@@ -52,6 +59,7 @@
public int maxSwell = 30;
public int explosionRadius = 3;
private int droppedSkulls;
+ public Entity entityIgniter; // CraftBukkit
public EntityCreeper(EntityTypes<? extends EntityCreeper> entitytypes, World world) {
super(entitytypes, world);
@@ -214,9 +222,20 @@
@Override
public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) {
super.thunderHit(worldserver, entitylightning);
+ // CraftBukkit start
+ if (CraftEventFactory.callCreeperPowerEvent(this, entitylightning, org.bukkit.event.entity.CreeperPowerEvent.PowerCause.LIGHTNING).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
this.entityData.set(EntityCreeper.DATA_IS_POWERED, true);
}
+ // CraftBukkit start
+ public void setPowered(boolean powered) {
+ this.entityData.set(EntityCreeper.DATA_IS_POWERED, powered);
+ }
+ // CraftBukkit end
+
@Override
protected EnumInteractionResult mobInteract(EntityHuman entityhuman, EnumHand enumhand) {
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
@@ -226,8 +245,9 @@
this.level().playSound(entityhuman, this.getX(), this.getY(), this.getZ(), soundeffect, this.getSoundSource(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F);
if (!this.level().isClientSide) {
+ this.entityIgniter = entityhuman; // CraftBukkit
this.ignite();
- if (!itemstack.isDamageableItem()) {
+ if (itemstack.getMaxDamage() == 0) { // CraftBukkit - fix MC-264285: unbreakable flint and steels are completely consumed when igniting a creeper
itemstack.shrink(1);
} else {
itemstack.hurtAndBreak(1, entityhuman, getSlotForHand(enumhand));
@@ -246,11 +266,20 @@
if (world instanceof WorldServer worldserver) {
float f = this.isPowered() ? 2.0F : 1.0F;
+ // CraftBukkit start
+ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, this.explosionRadius * f, false);
+ if (!event.isCancelled()) {
+ // CraftBukkit end
this.dead = true;
- worldserver.explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionRadius * f, World.a.MOB);
+ worldserver.explode(this, net.minecraft.world.level.Explosion.getDefaultDamageSource(this.level(), this).customCausingEntityDamager(this.entityIgniter), null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB); // CraftBukkit
this.spawnLingeringCloud();
this.triggerOnDeathMobEffects(worldserver, Entity.RemovalReason.KILLED);
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
+ // CraftBukkit start
+ } else {
+ swell = 0;
+ }
+ // CraftBukkit end
}
}
@@ -261,6 +290,7 @@
if (!collection.isEmpty()) {
EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
+ entityareaeffectcloud.setOwner(this); // CraftBukkit
entityareaeffectcloud.setRadius(2.5F);
entityareaeffectcloud.setRadiusOnUse(-0.5F);
entityareaeffectcloud.setWaitTime(10);
@@ -274,7 +304,7 @@
entityareaeffectcloud.addEffect(new MobEffect(mobeffect));
}
- this.level().addFreshEntity(entityareaeffectcloud);
+ this.level().addFreshEntity(entityareaeffectcloud, CreatureSpawnEvent.SpawnReason.EXPLOSION); // CraftBukkit
}
}

View File

@@ -0,0 +1,65 @@
--- a/net/minecraft/world/entity/monster/EntityEnderman.java
+++ b/net/minecraft/world/entity/monster/EntityEnderman.java
@@ -69,6 +69,11 @@
import net.minecraft.world.phys.MovingObjectPositionBlock;
import net.minecraft.world.phys.Vec3D;
+// CraftBukkit start;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
+
public class EntityEnderman extends EntityMonster implements IEntityAngerable {
private static final MinecraftKey SPEED_MODIFIER_ATTACKING_ID = MinecraftKey.withDefaultNamespace("attacking");
@@ -112,7 +117,17 @@
@Override
public void setTarget(@Nullable EntityLiving entityliving) {
- super.setTarget(entityliving);
+ // CraftBukkit start - fire event
+ setTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true);
+ }
+
+ @Override
+ public boolean setTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) {
+ if (!super.setTarget(entityliving, reason, fireEvent)) {
+ return false;
+ }
+ entityliving = getTarget();
+ // CraftBukkit end
AttributeModifiable attributemodifiable = this.getAttribute(GenericAttributes.MOVEMENT_SPEED);
if (entityliving == null) {
@@ -127,6 +142,7 @@
attributemodifiable.addTransientModifier(EntityEnderman.SPEED_MODIFIER_ATTACKING);
}
}
+ return true;
}
@@ -465,9 +481,11 @@
if (iblockdata2 != null) {
iblockdata2 = Block.updateFromNeighbourShapes(iblockdata2, this.enderman.level(), blockposition);
if (this.canPlaceBlock(world, blockposition, iblockdata2, iblockdata, iblockdata1, blockposition1)) {
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockposition, iblockdata2)) { // CraftBukkit - Place event
world.setBlock(blockposition, iblockdata2, 3);
world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition, GameEvent.a.of(this.enderman, iblockdata2));
this.enderman.setCarriedBlock((IBlockData) null);
+ } // CraftBukkit
}
}
@@ -506,9 +524,11 @@
boolean flag = movingobjectpositionblock.getBlockPos().equals(blockposition);
if (iblockdata.is(TagsBlock.ENDERMAN_HOLDABLE) && flag) {
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockposition, Blocks.AIR.defaultBlockState())) { // CraftBukkit - Place event
world.removeBlock(blockposition, false);
world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition, GameEvent.a.of(this.enderman, iblockdata));
this.enderman.setCarriedBlock(iblockdata.getBlock().defaultBlockState());
+ } // CraftBukkit
}
}

View File

@@ -0,0 +1,22 @@
--- a/net/minecraft/world/entity/monster/EntityEndermite.java
+++ b/net/minecraft/world/entity/monster/EntityEndermite.java
@@ -25,6 +25,10 @@
import net.minecraft.world.level.World;
import net.minecraft.world.level.block.state.IBlockData;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
+
public class EntityEndermite extends EntityMonster {
private static final int MAX_LIFE = 2400;
@@ -113,7 +117,7 @@
}
if (this.life >= 2400) {
- this.discard();
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
}
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/monster/EntityEvoker.java
+++ b/net/minecraft/world/entity/monster/EntityEvoker.java
@@ -212,7 +212,7 @@
worldserver.getScoreboard().addPlayerToTeam(entityvex.getScoreboardName(), scoreboardteam);
}
- worldserver.addFreshEntityWithPassengers(entityvex);
+ worldserver.addFreshEntityWithPassengers(entityvex, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPELL); // CraftBukkit - Add SpawnReason
worldserver.gameEvent((Holder) GameEvent.ENTITY_PLACE, blockposition, GameEvent.a.of((Entity) EntityEvoker.this));
}
}

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/monster/EntityGhast.java
+++ b/net/minecraft/world/entity/monster/EntityGhast.java
@@ -333,6 +333,8 @@
EntityLargeFireball entitylargefireball = new EntityLargeFireball(world, this.ghast, vec3d1.normalize(), this.ghast.getExplosionPower());
+ // CraftBukkit - set bukkitYield when setting explosionpower
+ entitylargefireball.bukkitYield = entitylargefireball.explosionPower = this.ghast.getExplosionPower();
entitylargefireball.setPos(this.ghast.getX() + vec3d.x * 4.0D, this.ghast.getY(0.5D) + 0.5D, entitylargefireball.getZ() + vec3d.z * 4.0D);
world.addFreshEntity(entitylargefireball);
this.chargeTime = -40;

View File

@@ -0,0 +1,19 @@
--- a/net/minecraft/world/entity/monster/EntityGuardian.java
+++ b/net/minecraft/world/entity/monster/EntityGuardian.java
@@ -60,6 +60,7 @@
private boolean clientSideTouchedGround;
@Nullable
public PathfinderGoalRandomStroll randomStrollGoal;
+ public EntityGuardian.PathfinderGoalGuardianAttack guardianAttackGoal; // CraftBukkit - add field
public EntityGuardian(EntityTypes<? extends EntityGuardian> entitytypes, World world) {
super(entitytypes, world);
@@ -75,7 +76,7 @@
PathfinderGoalMoveTowardsRestriction pathfindergoalmovetowardsrestriction = new PathfinderGoalMoveTowardsRestriction(this, 1.0D);
this.randomStrollGoal = new PathfinderGoalRandomStroll(this, 1.0D, 80);
- this.goalSelector.addGoal(4, new EntityGuardian.PathfinderGoalGuardianAttack(this));
+ this.goalSelector.addGoal(4, guardianAttackGoal = new EntityGuardian.PathfinderGoalGuardianAttack(this)); // CraftBukkit - assign field
this.goalSelector.addGoal(5, pathfindergoalmovetowardsrestriction);
this.goalSelector.addGoal(7, this.randomStrollGoal);
this.goalSelector.addGoal(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));

Some files were not shown because too many files have changed in this diff Show More