1.21.6 dev

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Bjarne Koll
2025-05-28 13:23:32 +02:00
committed by Nassim Jahnke
parent 39203a65e0
commit a24f9b204c
788 changed files with 41006 additions and 6324 deletions

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/AgeableMob.java
+++ b/net/minecraft/world/entity/AgeableMob.java
@@ -22,6 +_,7 @@
@@ -23,6 +_,7 @@
protected int age = 0;
protected int forcedAge = 0;
protected int forcedAgeTimer;
@@ -8,40 +8,31 @@
protected AgeableMob(EntityType<? extends AgeableMob> entityType, Level level) {
super(entityType, level);
@@ -68,13 +_,15 @@
@@ -69,6 +_,7 @@
}
public void ageUp(int amount, boolean forced) {
+ if (this.ageLocked) return; // Paper - Honor ageLock
int age = this.getAge();
+ int previousAge = age; // Paper - Decompile fix: lvt reassignment lost
int previousAge = age;
age += amount * 20;
if (age > 0) {
age = 0;
}
- int i1 = age - age;
+ int i1 = age - previousAge; // Paper - Decompile fix
this.setAge(age);
if (forced) {
this.forcedAge += i1;
@@ -106,6 +_,7 @@
super.addAdditionalSaveData(compound);
compound.putInt("Age", this.getAge());
compound.putInt("ForcedAge", this.forcedAge);
+ compound.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit
@@ -108,6 +_,7 @@
super.addAdditionalSaveData(output);
output.putInt("Age", this.getAge());
output.putInt("ForcedAge", this.forcedAge);
+ output.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit
}
@Override
@@ -113,6 +_,7 @@
super.readAdditionalSaveData(compound);
this.setAge(compound.getIntOr("Age", 0));
this.forcedAge = compound.getIntOr("ForcedAge", 0);
+ this.ageLocked = compound.getBooleanOr("AgeLocked", false); // CraftBukkit
@@ -115,6 +_,7 @@
super.readAdditionalSaveData(input);
this.setAge(input.getIntOr("Age", 0));
this.forcedAge = input.getIntOr("ForcedAge", 0);
+ this.ageLocked = input.getBooleanOr("AgeLocked", false); // CraftBukkit
}
@Override
@@ -127,7 +_,7 @@
@@ -129,7 +_,7 @@
@Override
public void aiStep() {
super.aiStep();

View File

@@ -1,24 +1,15 @@
--- a/net/minecraft/world/entity/AreaEffectCloud.java
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
@@ -59,7 +_,7 @@
public float radiusOnUse = 0.0F;
public float radiusPerTick = 0.0F;
@Nullable
- private LivingEntity owner;
+ private net.minecraft.world.entity.LivingEntity owner;
@Nullable
public UUID ownerUUID;
@@ -193,7 +_,7 @@
@@ -191,7 +_,7 @@
private void serverTick(ServerLevel level) {
if (this.duration != -1 && this.tickCount >= this.waitTime + this.duration) {
if (this.duration != -1 && this.tickCount - this.waitTime >= this.duration) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
boolean isWaiting = this.isWaiting();
boolean flag = this.tickCount < this.waitTime;
@@ -206,7 +_,7 @@
@@ -204,7 +_,7 @@
if (this.radiusPerTick != 0.0F) {
radius += this.radiusPerTick;
if (radius < 0.5F) {
@@ -27,7 +18,7 @@
return;
}
@@ -222,6 +_,7 @@
@@ -220,6 +_,7 @@
this.potionContents.forEachEffect(list::add, this.potionDurationScale);
List<LivingEntity> entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox());
if (!entitiesOfClass.isEmpty()) {
@@ -35,7 +26,7 @@
for (LivingEntity livingEntity : entitiesOfClass) {
if (!this.victims.containsKey(livingEntity)
&& livingEntity.isAffectedByPotions()
@@ -230,6 +_,17 @@
@@ -228,6 +_,17 @@
double d1 = livingEntity.getZ() - this.getZ();
double d2 = d * d + d1 * d1;
if (d2 <= radius * radius) {
@@ -53,7 +44,7 @@
this.victims.put(livingEntity, this.tickCount + this.reapplicationDelay);
for (MobEffectInstance mobEffectInstance : list) {
@@ -238,14 +_,14 @@
@@ -236,14 +_,14 @@
.value()
.applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), 0.5);
} else {
@@ -70,7 +61,7 @@
return;
}
@@ -255,7 +_,7 @@
@@ -253,7 +_,7 @@
if (this.durationOnUse != 0 && this.duration != -1) {
this.duration = this.duration + this.durationOnUse;
if (this.duration <= 0) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ConversionType.java
+++ b/net/minecraft/world/entity/ConversionType.java
@@ -21,7 +_,7 @@
@@ -24,7 +_,7 @@
for (Entity entity : newMob.getPassengers()) {
entity.stopRiding();
@@ -9,7 +9,7 @@
}
firstPassenger.startRiding(newMob);
@@ -70,6 +_,7 @@
@@ -73,6 +_,7 @@
if (leashHolder != null) {
oldMob.dropLeash();
}

View File

@@ -2,7 +2,7 @@
+++ b/net/minecraft/world/entity/EntitySelector.java
@@ -17,6 +_,22 @@
public static final Predicate<Entity> NO_SPECTATORS = entity -> !entity.isSpectator();
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(Entity::canBeCollidedWith);
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(entity -> entity.canBeCollidedWith(null));
public static final Predicate<Entity> CAN_BE_PICKED = NO_SPECTATORS.and(Entity::isPickable);
+ // Paper start - Ability to control player's insomnia and phantoms
+ public static Predicate<Player> IS_INSOMNIAC = (player) -> {
@@ -38,12 +38,13 @@
return (Predicate<Entity>)(collisionRule == Team.CollisionRule.NEVER
? Predicates.alwaysFalse()
: NO_SPECTATORS.and(
pushedEntity -> {
- if (!pushedEntity.isPushable()) {
- entity1 -> {
- if (!entity1.isPushable()) {
+ entity1 -> { final Entity pushedEntity = entity1; // Paper - OBFHELPER
+ if (!pushedEntity.isCollidable(ignoreClimbing) || !pushedEntity.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(pushedEntity)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
return false;
} else if (!entity.level().isClientSide || pushedEntity instanceof Player player && player.isLocalPlayer()) {
Team team1 = pushedEntity.getTeam();
} else if (!entity.level().isClientSide || entity1 instanceof Player player && player.isLocalPlayer()) {
Team team1 = entity1.getTeam();
Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule();
- if (collisionRule1 == Team.CollisionRule.NEVER) {
+ if (collisionRule1 == Team.CollisionRule.NEVER || (pushedEntity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions)) { // Paper - Configurable player collision

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/EntityType.java
+++ b/net/minecraft/world/entity/EntityType.java
@@ -216,7 +_,7 @@
@@ -217,7 +_,7 @@
.fireImmune()
.sized(6.0F, 0.5F)
.clientTrackingRange(10)
@@ -9,7 +9,7 @@
);
public static final EntityType<Armadillo> ARMADILLO = register(
"armadillo", EntityType.Builder.of(Armadillo::new, MobCategory.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10)
@@ -1145,6 +_,22 @@
@@ -1155,6 +_,22 @@
boolean shouldOffsetY,
boolean shouldOffsetYMore
) {
@@ -32,7 +32,7 @@
Consumer<T> consumer;
if (spawnedFrom != null) {
consumer = createDefaultStackConfig(level, spawnedFrom, owner);
@@ -1152,7 +_,7 @@
@@ -1162,7 +_,7 @@
consumer = entity -> {};
}
@@ -41,7 +41,7 @@
}
public static <T extends Entity> Consumer<T> createDefaultStackConfig(Level level, ItemStack stack, @Nullable LivingEntity owner) {
@@ -1169,19 +_,56 @@
@@ -1179,19 +_,56 @@
public static <T extends Entity> Consumer<T> appendCustomEntityStackConfig(Consumer<T> consumer, Level level, ItemStack stack, @Nullable LivingEntity owner) {
CustomData customData = stack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
@@ -101,7 +101,7 @@
if (entity instanceof Mob mob) {
mob.playAmbientSound();
}
@@ -1237,6 +_,15 @@
@@ -1247,6 +_,15 @@
if (level.isClientSide
|| !entity.getType().onlyOpCanSetNbt()
|| owner instanceof Player player && server.getPlayerList().isOp(player.getGameProfile())) {
@@ -117,25 +117,25 @@
customData.loadInto(entity);
}
}
@@ -1308,9 +_,20 @@
@@ -1318,9 +_,20 @@
}
public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason) {
public static Optional<Entity> create(ValueInput input, Level level, EntitySpawnReason spawnReason) {
+ // Paper start - Don't fire sync event during generation
+ return create(tag, level, spawnReason, false);
+ return create(input, level, spawnReason, false);
+ }
+
+ public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason, boolean generation) {
+ public static Optional<Entity> create(ValueInput input, Level level, EntitySpawnReason spawnReason, boolean generation) {
+ // Paper end - Don't fire sync event during generation
return Util.ifElse(
by(tag).map(entityType -> entityType.create(level, spawnReason)),
- entity -> entity.load(tag),
+ // Paper start - Don't fire sync event during generation
+ entity -> {
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
+ entity.load(tag);
+ },
+ // Paper end - Don't fire sync event during generation
() -> LOGGER.warn("Skipping Entity with id {}", tag.getStringOr("id", "[invalid]"))
by(input).map(entityType -> entityType.create(level, spawnReason)),
- entity -> entity.load(input),
+ // Paper start - Don't fire sync event during generation
+ entity -> {
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
+ entity.load(input);
+ },
+ // Paper end - Don't fire sync event during generation
() -> LOGGER.warn("Skipping Entity with id {}", input.getStringOr("id", "[invalid]"))
);
}

View File

@@ -1,62 +1,67 @@
--- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -41,9 +_,54 @@
@@ -44,13 +_,59 @@
@Nullable
private Player followingPlayer;
private final InterpolationHandler interpolation = new InterpolationHandler(this);
-
+ // Paper start
+ @Nullable
+ public java.util.UUID sourceEntityId;
+ @Nullable
+ public java.util.UUID triggerEntityId;
+ public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+
+ private void loadPaperNBT(CompoundTag tag) {
+ CompoundTag expData = tag.getCompoundOrEmpty("Paper.ExpData");
+ if (expData.isEmpty()) {
+ return;
+ }
+
+ this.sourceEntityId = expData.read("source", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
+ this.triggerEntityId = expData.read("trigger", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
+ expData.getString("reason").ifPresent(reason -> {
+ try {
+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
+ } catch (Exception e) {
+ this.level().getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
+ }
+ private void loadPaperNBT(ValueInput input) {
+ input.read("Paper.ExpData", net.minecraft.nbt.CompoundTag.CODEC).ifPresent(expData -> {
+ this.sourceEntityId = expData.read("source", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
+ this.triggerEntityId = expData.read("trigger", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
+ expData.getString("reason").ifPresent(reason -> {
+ try {
+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
+ } catch (Exception e) {
+ this.level().getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
+ }
+ });
+ });
+ }
+ private void savePaperNBT(CompoundTag tag) {
+ CompoundTag expData = new CompoundTag();
+ private void savePaperNBT(ValueOutput output) {
+ net.minecraft.nbt.CompoundTag expData = new net.minecraft.nbt.CompoundTag();
+ expData.storeNullable("source", net.minecraft.core.UUIDUtil.CODEC, this.sourceEntityId);
+ expData.storeNullable("trigger", net.minecraft.core.UUIDUtil.CODEC, this.triggerEntityId);
+ if (this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) {
+ expData.putString("reason", this.spawnReason.name());
+ }
+ tag.put("Paper.ExpData", expData);
+ output.store("Paper.ExpData", net.minecraft.nbt.CompoundTag.CODEC, expData);
+ }
+
+ @Deprecated @io.papermc.paper.annotation.DoNotUse
+ // Paper end
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor
public ExperienceOrb(Level level, double x, double y, double z, int value) {
+ this(level, x, y, z, value, null, null);
- this(level, new Vec3(x, y, z), Vec3.ZERO, value);
+ // Paper start - add reasons for orbs
+ this(level, x, y, z, value, null, null, null);
+ }
+
+ public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId) {
+ this(level, x, y, z, value, reason, triggerId, null);
+ }
+
+ public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
+ this(level, new Vec3(x, y, z), Vec3.ZERO, value, reason, triggerId, sourceId);
+ // Paper end - add reasons for orbs
}
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor
public ExperienceOrb(Level level, Vec3 pos, Vec3 direction, int value) {
+ // Paper start - add reasons for orbs
+ this(level, pos, direction, value, null, null, null);
+ }
+ public ExperienceOrb(Level level, Vec3 pos, Vec3 direction, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
+ // Paper end - add reasons for orbs
this(EntityType.EXPERIENCE_ORB, level);
+ // Paper start - add reasons for orbs
+ this.sourceEntityId = sourceId != null ? sourceId.getUUID() : null;
+ this.triggerEntityId = triggerId != null ? triggerId.getUUID() : null;
+ this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+ // Paper end
this.setPos(x, y, z);
if (!this.level().isClientSide) {
this.setYRot((float)(this.random.nextDouble() * 360.0));
@@ -119,12 +_,13 @@
+ // Paper end - add reasons for orbs
this.setPos(pos);
if (!level.isClientSide) {
this.setYRot(this.random.nextFloat() * 360.0F);
@@ -147,12 +_,13 @@
this.age++;
if (this.age >= 6000) {
@@ -71,7 +76,7 @@
if (this.followingPlayer == null || this.followingPlayer.isSpectator() || this.followingPlayer.distanceToSqr(this) > 64.0) {
Player nearestPlayer = this.level().getNearestPlayer(this, 8.0);
if (nearestPlayer != null && !nearestPlayer.isSpectator() && !nearestPlayer.isDeadOrDying()) {
@@ -134,7 +_,24 @@
@@ -162,7 +_,24 @@
}
}
@@ -97,26 +102,21 @@
Vec3 vec3 = new Vec3(
this.followingPlayer.getX() - this.getX(),
this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(),
@@ -161,18 +_,29 @@
@@ -193,18 +_,24 @@
}
public static void award(ServerLevel level, Vec3 pos, int amount) {
+ // Paper start - add reasons for orbs
+ award(level, pos, amount, null, null, null);
public static void awardWithDirection(ServerLevel level, Vec3 pos, Vec3 direction, int amount) {
+ // Paper start - add reason to orbs
+ awardWithDirection(level, pos, direction, amount, null, null, null);
+ }
+
+ public static void award(ServerLevel level, Vec3 pos, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId) {
+ award(level, pos, amount, reason, triggerId, null);
+ }
+
+ public static void award(ServerLevel level, Vec3 pos, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
+ // Paper end - add reasons for orbs
+ public static void awardWithDirection(ServerLevel level, Vec3 pos, Vec3 direction, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) {
+ // Paper end - add reason to orbs
while (amount > 0) {
int experienceValue = getExperienceValue(amount);
amount -= experienceValue;
if (!tryMergeToExisting(level, pos, experienceValue)) {
- level.addFreshEntity(new ExperienceOrb(level, pos.x(), pos.y(), pos.z(), experienceValue));
+ level.addFreshEntity(new ExperienceOrb(level, pos.x(), pos.y(), pos.z(), experienceValue, reason, triggerId, sourceId)); // Paper - add reason
- level.addFreshEntity(new ExperienceOrb(level, pos, direction, experienceValue));
+ level.addFreshEntity(new ExperienceOrb(level, pos, direction, experienceValue, reason, triggerId, sourceId)); // Paper - add reason to orbs
}
}
}
@@ -126,10 +126,10 @@
AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0);
- int randomInt = level.getRandom().nextInt(40);
+ int randomInt = level.getRandom().nextInt(io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA)); // Paper - Configure how many orb groups per area
List<ExperienceOrb> entities = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aabb, orb -> canMerge(orb, randomInt, amount));
if (!entities.isEmpty()) {
ExperienceOrb experienceOrb = entities.get(0);
@@ -189,13 +_,18 @@
List<ExperienceOrb> entities = level.getEntities(
EntityTypeTest.forClass(ExperienceOrb.class), aabb, experienceOrb1 -> canMerge(experienceOrb1, randomInt, amount)
);
@@ -223,13 +_,18 @@
}
private static boolean canMerge(ExperienceOrb orb, int amount, int other) {
@@ -150,7 +150,7 @@
}
private void setUnderwaterMovement() {
@@ -220,7 +_,7 @@
@@ -254,7 +_,7 @@
this.markHurt();
this.health = (int)(this.health - amount);
if (this.health <= 0) {
@@ -159,24 +159,24 @@
}
return true;
@@ -231,32 +_,34 @@
public void addAdditionalSaveData(CompoundTag compound) {
compound.putShort("Health", (short)this.health);
compound.putShort("Age", (short)this.age);
- compound.putShort("Value", (short)this.getValue());
+ compound.putInt("Value", this.getValue()); // Paper - save as Integer
compound.putInt("Count", this.count);
+ this.savePaperNBT(compound); // Paper
@@ -265,32 +_,34 @@
protected void addAdditionalSaveData(ValueOutput output) {
output.putShort("Health", (short)this.health);
output.putShort("Age", (short)this.age);
- output.putShort("Value", (short)this.getValue());
+ output.putInt("Value", this.getValue()); // Paper - save as Integer
output.putInt("Count", this.count);
+ this.savePaperNBT(output); // Paper
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
this.health = compound.getShortOr("Health", (short)5);
this.age = compound.getShortOr("Age", (short)0);
- this.setValue(compound.getShortOr("Value", (short)0));
+ this.setValue(compound.getIntOr("Value", 0)); // Paper - load as Integer
this.count = compound.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1);
+ this.loadPaperNBT(compound); // Paper
protected void readAdditionalSaveData(ValueInput input) {
this.health = input.getShortOr("Health", (short)5);
this.age = input.getShortOr("Age", (short)0);
- this.setValue(input.getShortOr("Value", (short)0));
+ this.setValue(input.getIntOr("Value", 0)); // Paper - load as Integer
this.count = input.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1);
+ this.loadPaperNBT(input); // Paper
}
@Override
@@ -200,9 +200,9 @@
}
}
}
@@ -270,9 +_,19 @@
@@ -304,9 +_,19 @@
ItemStack itemStack = randomItemWith.get().itemStack();
int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemStack, value);
int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.level(), itemStack, value);
int min = Math.min(i, itemStack.getDamageValue());
+ // CraftBukkit start
+ // Paper start - mending event
@@ -221,7 +221,7 @@
if (i1 > 0) {
return this.repairPlayerItems(player, i1);
}
@@ -318,6 +_,24 @@
@@ -352,6 +_,24 @@
}
public static int getExperienceValue(int expValue) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/Interaction.java
+++ b/net/minecraft/world/entity/Interaction.java
@@ -100,9 +_,16 @@
@@ -101,9 +_,16 @@
@Override
public boolean skipAttackInteraction(Entity entity) {
if (entity instanceof Player player) {

View File

@@ -1,18 +1,18 @@
--- a/net/minecraft/world/entity/Leashable.java
+++ b/net/minecraft/world/entity/Leashable.java
@@ -56,6 +_,11 @@
@@ -80,6 +_,11 @@
}
default void writeLeashData(CompoundTag tag, @Nullable Leashable.LeashData leashData) {
default void writeLeashData(ValueOutput output, @Nullable Leashable.LeashData leashData) {
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
+ if (leashData != null && leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) {
+ return;
+ }
+ // CraftBukkit end
tag.storeNullable("leash", Leashable.LeashData.CODEC, leashData);
output.storeNullable("leash", Leashable.LeashData.CODEC, leashData);
}
@@ -75,7 +_,9 @@
@@ -99,7 +_,9 @@
}
if (entity.tickCount > 100) {
@@ -22,7 +22,7 @@
entity.setLeashData(null);
}
}
@@ -99,7 +_,9 @@
@@ -123,7 +_,9 @@
entity.onLeashRemoved();
if (entity.level() instanceof ServerLevel serverLevel) {
if (dropItem) {
@@ -32,7 +32,7 @@
}
if (broadcastPacket) {
@@ -117,7 +_,15 @@
@@ -143,7 +_,15 @@
if (leashData != null && leashData.leashHolder != null) {
if (!entity.isAlive() || !leashData.leashHolder.isAlive()) {
@@ -49,16 +49,29 @@
entity.dropLeash();
} else {
entity.removeLeash();
@@ -131,7 +_,7 @@
return;
}
- if (f > 10.0) {
+ if (f > entity.level().paperConfig().misc.maxLeashDistance.or(LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance
@@ -154,7 +_,7 @@
if (leashHolder != null && leashHolder.level() == entity.level()) {
double d = entity.leashDistanceTo(leashHolder);
entity.whenLeashedTo(leashHolder);
- if (d > entity.leashSnapDistance()) {
+ if (d > entity.leashSnapDistanceOrConfig()) { // Paper - Configurable max leash distance
level.playSound(null, leashHolder.getX(), leashHolder.getY(), leashHolder.getZ(), SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F);
entity.leashTooFarBehaviour();
} else if (f > 6.0) {
entity.elasticRangeLeashBehaviour(leashHolder, f);
@@ -148,7 +_,21 @@
} else if (d > entity.leashElasticDistance() - leashHolder.getBbWidth() - entity.getBbWidth()
@@ -175,6 +_,12 @@
entity.checkFallDistanceAccumulation();
}
+ // Paper start - Configurable max leash distance
+ default double leashSnapDistanceOrConfig() {
+ if (!(this instanceof final Entity entity)) return leashSnapDistance();
+ return entity.level().paperConfig().misc.maxLeashDistance.or(leashSnapDistance());
+ }
+ // Paper end - Configurable max leash distance
default double leashSnapDistance() {
return 12.0;
}
@@ -196,7 +_,21 @@
}
default void leashTooFarBehaviour() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/LightningBolt.java
+++ b/net/minecraft/world/entity/LightningBolt.java
@@ -39,6 +_,7 @@
@@ -40,6 +_,7 @@
private ServerPlayer cause;
private final Set<Entity> hitEntities = Sets.newHashSet();
private int blocksSetOnFire;
@@ -8,7 +8,7 @@
public LightningBolt(EntityType<? extends LightningBolt> entityType, Level level) {
super(entityType, level);
@@ -76,7 +_,7 @@
@@ -77,7 +_,7 @@
@Override
public void tick() {
super.tick();
@@ -17,7 +17,7 @@
if (this.level().isClientSide()) {
this.level()
.playLocalSound(
@@ -107,7 +_,7 @@
@@ -108,7 +_,7 @@
}
this.powerLightningRod();
@@ -26,7 +26,7 @@
this.gameEvent(GameEvent.LIGHTNING_STRIKE);
}
}
@@ -130,7 +_,7 @@
@@ -131,7 +_,7 @@
}
}
@@ -35,7 +35,7 @@
} else if (this.life < -this.random.nextInt(10)) {
this.flashes--;
this.life = 1;
@@ -139,10 +_,10 @@
@@ -140,10 +_,10 @@
}
}
@@ -48,7 +48,7 @@
List<Entity> entities = this.level()
.getEntities(
this,
@@ -168,26 +_,34 @@
@@ -169,26 +_,34 @@
}
private void spawnFire(int extraIgnitions) {
@@ -89,7 +89,7 @@
BlockState blockState = level.getBlockState(pos);
BlockPos blockPos;
BlockState blockState1;
@@ -200,22 +_,27 @@
@@ -201,22 +_,27 @@
}
if (blockState1.getBlock() instanceof WeatheringCopper) {
@@ -121,7 +121,7 @@
if (optional.isEmpty()) {
break;
}
@@ -224,11 +_,17 @@
@@ -225,11 +_,17 @@
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -135,6 +_,17 @@
@@ -138,6 +_,17 @@
import org.jetbrains.annotations.Contract;
import org.slf4j.Logger;
@@ -15,13 +15,13 @@
+import org.bukkit.event.entity.EntityResurrectEvent;
+// CraftBukkit end
+
public abstract class LivingEntity extends Entity implements Attackable {
public abstract class LivingEntity extends Entity implements Attackable, WaypointTransmitter {
private static final Logger LOGGER = LogUtils.getLogger();
private static final String TAG_ACTIVE_EFFECTS = "active_effects";
@@ -251,11 +_,25 @@
EquipmentSlot.class
@@ -264,11 +_,25 @@
);
protected final EntityEquipment equipment;
private Waypoint.Icon locatorBarIcon = new Waypoint.Icon();
+ // CraftBukkit start
+ public int expToDrop;
+ public List<DefaultDrop> drops = new java.util.ArrayList<>(); // Paper - Restore vanilla drops behavior
@@ -45,7 +45,7 @@
this.equipment = this.createEquipment();
this.blocksBuilding = true;
this.reapplyPosition();
@@ -350,7 +_,13 @@
@@ -364,7 +_,13 @@
double d1 = Math.min(0.2F + d / 15.0, 2.5);
int i = (int)(150.0 * d1);
@@ -60,7 +60,7 @@
}
}
@@ -535,7 +_,7 @@
@@ -549,7 +_,7 @@
this.deathTime++;
if (this.deathTime >= 20 && !this.level().isClientSide() && !this.isRemoved()) {
this.level().broadcastEntityEvent(this, (byte)60);
@@ -69,7 +69,7 @@
}
}
@@ -640,7 +_,7 @@
@@ -654,7 +_,7 @@
}
public boolean shouldDiscardFriction() {
@@ -78,7 +78,7 @@
}
public void setDiscardFriction(boolean discardFriction) {
@@ -652,10 +_,15 @@
@@ -666,10 +_,15 @@
}
public void onEquipItem(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem) {
@@ -95,7 +95,7 @@
this.level()
.playSeededSound(
null,
@@ -682,12 +_,12 @@
@@ -696,12 +_,12 @@
}
@Override
@@ -110,7 +110,7 @@
this.brain.clearMemories();
}
@@ -696,11 +_,17 @@
@@ -718,11 +_,17 @@
mobEffectInstance.onMobRemoved(level, this, removalReason);
}
@@ -119,16 +119,16 @@
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
protected void addAdditionalSaveData(ValueOutput output) {
+ // Paper start - Friction API
+ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) {
+ compound.putString("Paper.FrictionState", this.frictionState.toString());
+ output.putString("Paper.FrictionState", this.frictionState.toString());
+ }
+ // Paper end - Friction API
compound.putFloat("Health", this.getHealth());
compound.putShort("HurtTime", (short)this.hurtTime);
compound.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp);
@@ -731,8 +_,15 @@
output.putFloat("Health", this.getHealth());
output.putShort("HurtTime", (short)this.hurtTime);
output.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp);
@@ -756,8 +_,15 @@
}
}
@@ -146,7 +146,7 @@
if (stack.isEmpty()) {
return null;
} else if (this.level().isClientSide) {
@@ -741,6 +_,31 @@
@@ -766,6 +_,31 @@
} else {
ItemEntity itemEntity = this.createItemStackToDrop(stack, randomizeMotion, includeThrower);
if (itemEntity != null) {
@@ -178,20 +178,20 @@
this.level().addFreshEntity(itemEntity);
}
@@ -750,7 +_,22 @@
@@ -775,7 +_,22 @@
@Override
public void readAdditionalSaveData(CompoundTag compound) {
- this.internalSetAbsorptionAmount(compound.getFloatOr("AbsorptionAmount", 0.0F));
protected void readAdditionalSaveData(ValueInput input) {
- this.internalSetAbsorptionAmount(input.getFloatOr("AbsorptionAmount", 0.0F));
+ // Paper start - Check for NaN
+ float absorptionAmount = compound.getFloatOr("AbsorptionAmount", 0.0F);
+ float absorptionAmount = input.getFloatOr("AbsorptionAmount", 0.0F);
+ if (Float.isNaN(absorptionAmount)) {
+ absorptionAmount = 0;
+ }
+ this.internalSetAbsorptionAmount(absorptionAmount);
+ // Paper end - Check for NaN
+ // Paper start - Friction API
+ compound.getString("Paper.FrictionState").ifPresent(frictionState -> {
+ input.getString("Paper.FrictionState").ifPresent(frictionState -> {
+ try {
+ this.frictionState = net.kyori.adventure.util.TriState.valueOf(frictionState);
+ } catch (Exception ignored) {
@@ -200,32 +200,32 @@
+ });
+ // Paper end - Friction API
if (this.level() != null && !this.level().isClientSide) {
compound.getList("attributes").ifPresent(this.getAttributes()::load);
input.read("attributes", AttributeInstance.Packed.LIST_CODEC).ifPresent(this.getAttributes()::apply);
}
@@ -763,6 +_,11 @@
@@ -787,6 +_,11 @@
this.activeEffects.put(mobEffectInstance.getEffect(), mobEffectInstance);
}
+ // CraftBukkit start
+ compound.getDouble("Bukkit.MaxHealth").ifPresent(maxHealth -> {
+ input.read("Bukkit.MaxHealth", com.mojang.serialization.Codec.DOUBLE).ifPresent(maxHealth -> {
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(maxHealth);
+ });
+ // CraftBukkit end
this.setHealth(compound.getFloatOr("Health", this.getMaxHealth()));
this.hurtTime = compound.getShortOr("HurtTime", (short)0);
this.deathTime = compound.getShortOr("DeathTime", (short)0);
@@ -770,6 +_,7 @@
compound.getString("Team").ifPresent(string -> {
this.setHealth(input.getFloatOr("Health", this.getMaxHealth()));
this.hurtTime = input.getShortOr("HurtTime", (short)0);
this.deathTime = input.getShortOr("DeathTime", (short)0);
@@ -794,6 +_,7 @@
input.getString("Team").ifPresent(string -> {
Scoreboard scoreboard = this.level().getScoreboard();
PlayerTeam playerTeam = scoreboard.getPlayerTeam(string);
+ if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { playerTeam = null; } // Paper - Perf: Disable Scoreboards for non players by default
boolean flag = playerTeam != null && scoreboard.addPlayerToTeam(this.getStringUUID(), playerTeam);
if (!flag) {
LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", string);
@@ -777,11 +_,13 @@
@@ -801,11 +_,13 @@
});
this.setSharedFlag(7, compound.getBooleanOr("FallFlying", false));
compound.read("sleeping_pos", BlockPos.CODEC).ifPresentOrElse(blockPos -> {
this.setSharedFlag(7, input.getBooleanOr("FallFlying", false));
input.read("sleeping_pos", BlockPos.CODEC).ifPresentOrElse(blockPos -> {
+ if (this.position().distanceToSqr(blockPos.getX(), blockPos.getY(), blockPos.getZ()) < Mth.square(16)) { // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
this.setSleepingPos(blockPos);
this.entityData.set(DATA_POSE, Pose.SLEEPING);
@@ -234,10 +234,10 @@
}
+ } // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
}, this::clearSleepingPos);
compound.getCompound("Brain").ifPresent(compoundTag -> this.brain = this.makeBrain(new Dynamic<>(NbtOps.INSTANCE, compoundTag)));
this.lastHurtByPlayer = EntityReference.read(compound, "last_hurt_by_player");
@@ -791,15 +_,44 @@
this.equipment.setAll(compound.read("equipment", EntityEquipment.CODEC, registryOps).orElseGet(EntityEquipment::new));
input.read("Brain", Codec.PASSTHROUGH).ifPresent(dynamic -> this.brain = this.makeBrain((Dynamic<?>)dynamic));
this.lastHurtByPlayer = EntityReference.read(input, "last_hurt_by_player");
@@ -816,15 +_,44 @@
this.locatorBarIcon = input.read("locator_bar_icon", Waypoint.Icon.CODEC).orElseGet(Waypoint.Icon::new);
}
+ // CraftBukkit start
@@ -281,7 +281,7 @@
iterator.remove();
this.onEffectsRemoved(List.of(mobEffectInstance));
} else if (mobEffectInstance.getDuration() % 600 == 0) {
@@ -809,6 +_,17 @@
@@ -834,6 +_,17 @@
} catch (ConcurrentModificationException var6) {
}
@@ -299,7 +299,7 @@
if (this.effectsDirty) {
this.updateInvisibilityStatus();
this.updateGlowingStatus();
@@ -916,15 +_,33 @@
@@ -941,15 +_,33 @@
}
public boolean removeAllEffects() {
@@ -337,7 +337,7 @@
}
}
@@ -951,21 +_,57 @@
@@ -976,21 +_,57 @@
}
public final boolean addEffect(MobEffectInstance effectInstance) {
@@ -397,7 +397,7 @@
this.onEffectUpdated(mobEffectInstance, true, entity);
flag = true;
}
@@ -1004,11 +_,37 @@
@@ -1029,11 +_,37 @@
@Nullable
public final MobEffectInstance removeEffectNoUpdate(Holder<MobEffect> effect) {
@@ -436,7 +436,7 @@
if (mobEffectInstance != null) {
this.onEffectsRemoved(List.of(mobEffectInstance));
return true;
@@ -1092,17 +_,62 @@
@@ -1124,17 +_,62 @@
}
public void heal(float healAmount) {
@@ -500,7 +500,7 @@
this.entityData.set(DATA_HEALTH_ID, Mth.clamp(health, 0.0F, this.getMaxHealth()));
}
@@ -1114,7 +_,7 @@
@@ -1146,7 +_,7 @@
public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
if (this.isInvulnerableTo(level, damageSource)) {
return false;
@@ -509,15 +509,14 @@
return false;
} else if (damageSource.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) {
return false;
@@ -1128,35 +_,59 @@
amount = 0.0F;
@@ -1161,35 +_,58 @@
}
float originAmount = amount;
- float f1 = this.applyItemBlocking(level, damageSource, amount);
- amount -= f1;
+ final float originalAmount = amount; // Paper - revert to vanilla #hurt - OBFHELPER
+ float f1 = this.applyItemBlocking(level, damageSource, amount, true); // Paper
+ // Paper end
+ // amount -= f1; // CraftBukkit - Moved into handleEntityDamage(DamageSource, float) to allow modification
boolean flag = f1 > 0.0F;
- if (damageSource.is(DamageTypeTags.IS_FREEZING) && this.getType().is(EntityTypeTags.FREEZE_HURTS_EXTRA_TYPES)) {
+ // CraftBukkit - Moved into handleEntityDamage(DamageSource, float) to get amount
@@ -554,7 +553,7 @@
+ if (!this.actuallyHurt(level, damageSource, (float) event.getFinalDamage(), event)) { // Paper - fix invulnerability reduction in EntityDamageEvent - no longer subtract lastHurt, that is part of the damage event calc now
+ return false;
+ }
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
+ // CraftBukkit end
this.lastHurt = amount;
flag1 = false;
@@ -567,7 +566,7 @@
+ if (!this.actuallyHurt(level, damageSource, (float) event.getFinalDamage(), event)) {
+ return false;
+ }
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event.
this.lastHurt = amount;
- this.invulnerableTime = 20;
- this.actuallyHurt(level, damageSource, amount);
@@ -577,7 +576,7 @@
this.hurtDuration = 10;
this.hurtTime = this.hurtDuration;
}
@@ -1171,7 +_,7 @@
@@ -1204,7 +_,7 @@
level.broadcastDamageEvent(this, damageSource);
}
@@ -586,7 +585,7 @@
this.markHurt();
}
@@ -1186,8 +_,16 @@
@@ -1219,8 +_,16 @@
d = damageSource.getSourcePosition().x() - this.getX();
d1 = damageSource.getSourcePosition().z() - this.getZ();
}
@@ -604,7 +603,7 @@
if (!flag) {
this.indicateDamage(d, d1);
}
@@ -1196,19 +_,19 @@
@@ -1229,19 +_,19 @@
if (this.isDeadOrDying()) {
if (!this.checkTotemDeathProtection(damageSource)) {
@@ -629,7 +628,7 @@
if (flag2) {
this.lastDamageSource = damageSource;
this.lastDamageStamp = this.level().getGameTime();
@@ -1234,6 +_,12 @@
@@ -1267,6 +_,12 @@
}
public float applyItemBlocking(ServerLevel level, DamageSource damageSource, float damageAmount) {
@@ -642,7 +641,7 @@
if (damageAmount <= 0.0F) {
return 0.0F;
} else {
@@ -1258,10 +_,12 @@
@@ -1291,10 +_,12 @@
}
float f = blocksAttacks.resolveBlockedDamage(damageSource, damageAmount, acos);
@@ -656,7 +655,7 @@
return f;
}
@@ -1272,6 +_,59 @@
@@ -1305,6 +_,59 @@
}
}
@@ -716,7 +715,7 @@
public void playSecondaryHurtSound(DamageSource damageSource) {
if (damageSource.is(DamageTypes.THORNS)) {
SoundSource soundSource = this instanceof Player ? SoundSource.PLAYERS : SoundSource.HOSTILE;
@@ -1304,12 +_,24 @@
@@ -1337,12 +_,24 @@
return EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class);
}
@@ -742,7 +741,7 @@
}
private boolean checkTotemDeathProtection(DamageSource damageSource) {
@@ -1319,18 +_,39 @@
@@ -1352,18 +_,39 @@
ItemStack itemStack = null;
DeathProtection deathProtection = null;
@@ -789,7 +788,7 @@
serverPlayer.awardStat(Stats.ITEM_USED.get(itemStack.getItem()));
CriteriaTriggers.USED_TOTEM.trigger(serverPlayer, itemStack);
this.gameEvent(GameEvent.ITEM_INTERACT_FINISH);
@@ -1389,6 +_,7 @@
@@ -1422,6 +_,7 @@
if (!this.isRemoved() && !this.dead) {
Entity entity = damageSource.getEntity();
LivingEntity killCredit = this.getKillCredit();
@@ -797,7 +796,7 @@
if (killCredit != null) {
killCredit.awardKillScore(this, damageSource);
}
@@ -1398,68 +_,141 @@
@@ -1431,68 +_,141 @@
}
if (!this.level().isClientSide && this.hasCustomName()) {
@@ -945,14 +944,14 @@
+ protected void dropExperience(ServerLevel level, @Nullable Entity entity) {
+ // CraftBukkit start - Update getExpReward() above if the removed if() changes!
+ if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time
+ ExperienceOrb.award(level, this.position(), this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, entity, this); // Paper
+ ExperienceOrb.awardWithDirection(level, this.position(), net.minecraft.world.phys.Vec3.ZERO, this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, entity, this); // Paper
+ this.expToDrop = 0;
+ }
+ // CraftBukkit end
}
protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) {
@@ -1539,9 +_,14 @@
@@ -1572,9 +_,14 @@
}
public void knockback(double strength, double x, double z) {
@@ -969,7 +968,7 @@
Vec3 deltaMovement = this.getDeltaMovement();
while (x * x + z * z < 1.0E-5F) {
@@ -1550,11 +_,22 @@
@@ -1583,11 +_,22 @@
}
Vec3 vec3 = new Vec3(x, 0.0, z).normalize().scale(strength);
@@ -993,7 +992,7 @@
}
}
@@ -1639,7 +_,7 @@
@@ -1672,7 +_,7 @@
@Override
public boolean isAlive() {
@@ -1002,7 +1001,7 @@
}
public boolean isLookingAtMe(LivingEntity entity, double tolerance, boolean scaleByDistance, boolean visual, double... yValues) {
@@ -1673,9 +_,14 @@
@@ -1706,9 +_,14 @@
boolean flag = super.causeFallDamage(fallDistance, damageMultiplier, damageSource);
int i = this.calculateFallDamage(fallDistance, damageMultiplier);
if (i > 0) {
@@ -1018,7 +1017,7 @@
return true;
} else {
return flag;
@@ -1740,7 +_,7 @@
@@ -1773,7 +_,7 @@
protected float getDamageAfterArmorAbsorb(DamageSource damageSource, float damageAmount) {
if (!damageSource.is(DamageTypeTags.BYPASSES_ARMOR)) {
@@ -1027,7 +1026,7 @@
damageAmount = CombatRules.getDamageAfterAbsorb(
this, damageAmount, damageSource, this.getArmorValue(), (float)this.getAttributeValue(Attributes.ARMOR_TOUGHNESS)
);
@@ -1753,7 +_,8 @@
@@ -1786,7 +_,8 @@
if (damageSource.is(DamageTypeTags.BYPASSES_EFFECTS)) {
return damageAmount;
} else {
@@ -1037,7 +1036,7 @@
int i = (this.getEffect(MobEffects.RESISTANCE).getAmplifier() + 1) * 5;
int i1 = 25 - i;
float f = damageAmount * i1;
@@ -1790,24 +_,201 @@
@@ -1823,24 +_,201 @@
}
}
@@ -1249,7 +1248,7 @@
}
public CombatTracker getCombatTracker() {
@@ -1836,7 +_,17 @@
@@ -1869,7 +_,17 @@
}
public final void setArrowCount(int count) {
@@ -1268,7 +1267,7 @@
}
public final int getStingerCount() {
@@ -1991,7 +_,7 @@
@@ -2024,7 +_,7 @@
@Override
protected void onBelowWorld() {
@@ -1277,7 +1276,7 @@
}
protected void updateSwingTime() {
@@ -2087,8 +_,15 @@
@@ -2120,8 +_,15 @@
}
public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
@@ -1295,7 +1294,7 @@
public float getArmorCoverPercentage() {
int i = 0;
@@ -2180,14 +_,27 @@
@@ -2213,14 +_,27 @@
return this.hasEffect(MobEffects.JUMP_BOOST) ? 0.1F * (this.getEffect(MobEffects.JUMP_BOOST).getAmplifier() + 1.0F) : 0.0F;
}
@@ -1323,7 +1322,7 @@
this.addDeltaMovement(new Vec3(-Mth.sin(f) * 0.2, 0.0, Mth.cos(f) * 0.2));
}
@@ -2327,8 +_,10 @@
@@ -2380,8 +_,10 @@
}
public void stopFallFlying() {
@@ -1334,7 +1333,7 @@
}
private Vec3 updateFallFlyingMovement(Vec3 deltaMovement) {
@@ -2454,7 +_,7 @@
@@ -2507,7 +_,7 @@
}
protected float getFlyingSpeed() {
@@ -1343,7 +1342,7 @@
}
public float getSpeed() {
@@ -2538,37 +_,15 @@
@@ -2591,37 +_,15 @@
profilerFiller.pop();
profilerFiller.push("rangeChecks");
@@ -1390,7 +1389,7 @@
profilerFiller.pop();
if (this.isFallFlying()) {
@@ -2598,16 +_,39 @@
@@ -2651,16 +_,39 @@
@Nullable
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
Map<EquipmentSlot, ItemStack> map = null;
@@ -1430,7 +1429,7 @@
AttributeMap attributes = this.getAttributes();
if (!itemStack.isEmpty()) {
this.stopLocationBasedEffects(itemStack, equipmentSlot, attributes);
@@ -2632,6 +_,8 @@
@@ -2685,6 +_,8 @@
}
}
}
@@ -1439,7 +1438,7 @@
}
return map;
@@ -2663,7 +_,7 @@
@@ -2716,7 +_,7 @@
list.add(Pair.of(equipmentSlot, itemStack1));
this.lastEquipmentItems.put(equipmentSlot, itemStack1);
});
@@ -1448,7 +1447,7 @@
}
protected void tickHeadTurn(float yBodyRot) {
@@ -2749,8 +_,10 @@
@@ -2802,8 +_,10 @@
if (!flag || this.onGround() && !(fluidHeight > fluidJumpThreshold)) {
if (!this.isInLava() || this.onGround() && !(fluidHeight > fluidJumpThreshold)) {
if ((this.onGround() || flag && fluidHeight <= fluidJumpThreshold) && this.noJumpDelay == 0) {
@@ -1459,7 +1458,7 @@
}
} else {
this.jumpInLiquid(FluidTags.LAVA);
@@ -2791,7 +_,7 @@
@@ -2844,7 +_,7 @@
profilerFiller.pop();
if (this.level() instanceof ServerLevel serverLevel) {
profilerFiller.push("freezing");
@@ -1468,7 +1467,7 @@
this.setTicksFrozen(Math.max(0, this.getTicksFrozen() - 2));
}
@@ -2812,6 +_,20 @@
@@ -2865,6 +_,20 @@
this.pushEntities();
profilerFiller.pop();
@@ -1489,15 +1488,15 @@
if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterOrRain()) {
this.hurtServer(serverLevel, this.damageSources().drown(), 1.0F);
}
@@ -2830,6 +_,7 @@
this.checkSlowFallDistance();
@@ -2887,6 +_,7 @@
this.checkFallDistanceAccumulation();
if (!this.level().isClientSide) {
if (!this.canGlide()) {
+ if (this.getSharedFlag(7) != false && !CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) // CraftBukkit
this.setSharedFlag(7, false);
return;
}
@@ -2869,10 +_,25 @@
@@ -2926,10 +_,25 @@
}
protected void pushEntities() {
@@ -1524,7 +1523,7 @@
if (_int > 0 && pushableEntities.size() > _int - 1 && this.random.nextInt(4) == 0) {
int i = 0;
@@ -2888,7 +_,16 @@
@@ -2945,7 +_,16 @@
}
}
@@ -1541,7 +1540,7 @@
this.doPush(entity1);
}
}
@@ -2930,9 +_,16 @@
@@ -2987,9 +_,16 @@
@Override
public void stopRiding() {
@@ -1560,16 +1559,16 @@
this.dismountVehicle(vehicle);
}
}
@@ -2959,7 +_,7 @@
@@ -3016,7 +_,7 @@
}
public void onItemPickup(ItemEntity itemEntity) {
- Entity owner = itemEntity.getOwner();
+ Entity owner = itemEntity.thrower != null ? this.level().getGlobalPlayerByUUID(itemEntity.thrower) : null; // Paper - check global player list where appropriate
+ Entity owner = EntityReference.get(itemEntity.thrower, this.level()::getGlobalPlayerByUUID, Entity.class); // Paper - check global player list where appropriate
if (owner instanceof ServerPlayer) {
CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.trigger((ServerPlayer)owner, itemEntity.getItem(), this);
}
@@ -2969,7 +_,7 @@
@@ -3026,7 +_,7 @@
if (!entity.isRemoved()
&& !this.level().isClientSide
&& (entity instanceof ItemEntity || entity instanceof AbstractArrow || entity instanceof ExperienceOrb)) {
@@ -1578,7 +1577,7 @@
}
}
@@ -2983,7 +_,8 @@
@@ -3040,7 +_,8 @@
} else {
Vec3 vec3 = new Vec3(this.getX(), this.getEyeY(), this.getZ());
Vec3 vec31 = new Vec3(entity.getX(), y, entity.getZ());
@@ -1588,7 +1587,7 @@
}
}
@@ -3003,13 +_,27 @@
@@ -3060,13 +_,27 @@
@Override
public boolean isPickable() {
@@ -1619,7 +1618,7 @@
@Override
public float getYHeadRot() {
@@ -3040,7 +_,7 @@
@@ -3097,7 +_,7 @@
}
public final void setAbsorptionAmount(float absorptionAmount) {
@@ -1628,7 +1627,7 @@
}
protected void internalSetAbsorptionAmount(float absorptionAmount) {
@@ -3067,6 +_,15 @@
@@ -3124,6 +_,15 @@
return (this.entityData.get(DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
}
@@ -1644,7 +1643,7 @@
private void updatingUsingItem() {
if (this.isUsingItem()) {
if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {
@@ -3084,6 +_,11 @@
@@ -3141,6 +_,11 @@
return null;
} else {
double d = this.getEyeY() - 0.3F;
@@ -1656,7 +1655,7 @@
ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), stack);
itemEntity.setPickUpDelay(40);
if (includeThrower) {
@@ -3115,7 +_,12 @@
@@ -3172,7 +_,12 @@
protected void updateUsingItem(ItemStack usingItem) {
usingItem.onUseTick(this.level(), this, this.getUseItemRemainingTicks());
@@ -1670,7 +1669,7 @@
this.completeUsingItem();
}
}
@@ -3141,10 +_,19 @@
@@ -3198,10 +_,19 @@
}
public void startUsingItem(InteractionHand hand) {
@@ -1692,7 +1691,7 @@
if (!this.level().isClientSide) {
this.setLivingEntityFlag(1, true);
this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND);
@@ -3168,7 +_,10 @@
@@ -3225,7 +_,10 @@
}
} else if (!this.isUsingItem() && !this.useItem.isEmpty()) {
this.useItem = ItemStack.EMPTY;
@@ -1704,7 +1703,7 @@
}
}
}
@@ -3207,12 +_,49 @@
@@ -3264,12 +_,49 @@
this.releaseUsingItem();
} else {
if (!this.useItem.isEmpty() && this.isUsingItem()) {
@@ -1755,7 +1754,7 @@
}
}
}
@@ -3237,6 +_,7 @@
@@ -3294,6 +_,7 @@
ItemStack itemInHand = this.getItemInHand(this.getUsedItemHand());
if (!this.useItem.isEmpty() && ItemStack.isSameItem(itemInHand, this.useItem)) {
this.useItem = itemInHand;
@@ -1763,7 +1762,7 @@
this.useItem.releaseUsing(this.level(), this, this.getUseItemRemainingTicks());
if (this.useItem.useOnRelease()) {
this.updatingUsingItem();
@@ -3256,7 +_,10 @@
@@ -3313,7 +_,10 @@
}
this.useItem = ItemStack.EMPTY;
@@ -1775,7 +1774,7 @@
}
public boolean isBlocking() {
@@ -3280,6 +_,60 @@
@@ -3337,6 +_,60 @@
}
}
@@ -1836,7 +1835,7 @@
public boolean isSuppressingSlidingDownLadder() {
return this.isShiftKeyDown();
}
@@ -3298,6 +_,12 @@
@@ -3355,6 +_,12 @@
}
public boolean randomTeleport(double x, double y, double z, boolean broadcastTeleport) {
@@ -1849,7 +1848,7 @@
double x1 = this.getX();
double y1 = this.getY();
double z1 = this.getZ();
@@ -3320,16 +_,39 @@
@@ -3377,16 +_,39 @@
}
if (flag1) {
@@ -1892,7 +1891,7 @@
} else {
if (broadcastTeleport) {
level.broadcastEntityEvent(this, (byte)46);
@@ -3339,7 +_,7 @@
@@ -3396,7 +_,7 @@
pathfinderMob.getNavigation().stop();
}

View File

@@ -1,7 +1,7 @@
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -83,6 +_,14 @@
import net.minecraft.world.phys.AABB;
@@ -82,6 +_,14 @@
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.ticks.ContainerSingleItem;
+// CraftBukkit start
@@ -15,7 +15,7 @@
public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting {
private static final EntityDataAccessor<Byte> DATA_MOB_FLAGS_ID = SynchedEntityData.defineId(Mob.class, EntityDataSerializers.BYTE);
private static final int MOB_FLAG_NO_AI = 1;
@@ -112,6 +_,7 @@
@@ -115,6 +_,7 @@
private final BodyRotationControl bodyRotationControl;
protected PathNavigation navigation;
public GoalSelector goalSelector;
@@ -23,15 +23,15 @@
public GoalSelector targetSelector;
@Nullable
private LivingEntity target;
@@ -126,6 +_,7 @@
@@ -129,6 +_,7 @@
private Leashable.LeashData leashData;
private BlockPos restrictCenter = BlockPos.ZERO;
private float restrictRadius = -1.0F;
private BlockPos homePosition = BlockPos.ZERO;
private int homeRadius = -1;
+ public boolean aware = true; // CraftBukkit
protected Mob(EntityType<? extends Mob> entityType, Level level) {
super(entityType, level);
@@ -142,6 +_,12 @@
@@ -145,6 +_,12 @@
}
}
@@ -44,7 +44,7 @@
protected void registerGoals() {
}
@@ -222,7 +_,39 @@
@@ -225,7 +_,39 @@
}
public void setTarget(@Nullable LivingEntity target) {
@@ -84,40 +84,40 @@
}
@Override
@@ -358,13 +_,22 @@
@@ -365,13 +_,22 @@
if (this.isNoAi()) {
compound.putBoolean("NoAI", this.isNoAi());
output.putBoolean("NoAI", this.isNoAi());
}
+ compound.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
+ output.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
- this.setCanPickUpLoot(compound.getBooleanOr("CanPickUpLoot", false));
- this.persistenceRequired = compound.getBooleanOr("PersistenceRequired", false);
protected void readAdditionalSaveData(ValueInput input) {
super.readAdditionalSaveData(input);
- this.setCanPickUpLoot(input.getBooleanOr("CanPickUpLoot", false));
- this.persistenceRequired = input.getBooleanOr("PersistenceRequired", false);
+ // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
+ boolean canPickUpLoot = compound.getBooleanOr("CanPickUpLoot", false);
+ if (isLevelAtLeast(compound, 1) || canPickUpLoot) {
+ boolean canPickUpLoot = input.getBooleanOr("CanPickUpLoot", false);
+ if (isLevelAtLeast(input, 1) || canPickUpLoot) {
+ this.setCanPickUpLoot(canPickUpLoot);
+ }
+ boolean persistenceRequired = compound.getBooleanOr("PersistenceRequired", false);
+ if (isLevelAtLeast(compound, 1) || persistenceRequired) {
+ boolean persistenceRequired = input.getBooleanOr("PersistenceRequired", false);
+ if (isLevelAtLeast(input, 1) || persistenceRequired) {
+ this.persistenceRequired = persistenceRequired;
+ }
+ // CraftBukkit end
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
this.dropChances = compound.read("drop_chances", DropChances.CODEC, registryOps).orElse(DropChances.DEFAULT);
this.readLeashData(compound);
@@ -372,6 +_,7 @@
this.lootTable = compound.read("DeathLootTable", LootTable.KEY_CODEC);
this.lootTableSeed = compound.getLongOr("DeathLootTableSeed", 0L);
this.setNoAi(compound.getBooleanOr("NoAI", false));
+ this.aware = compound.getBooleanOr("Bukkit.Aware", true); // CraftBukkit
this.dropChances = input.read("drop_chances", DropChances.CODEC).orElse(DropChances.DEFAULT);
this.readLeashData(input);
this.homeRadius = input.getIntOr("home_radius", -1);
@@ -383,6 +_,7 @@
this.lootTable = input.read("DeathLootTable", LootTable.KEY_CODEC);
this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L);
this.setNoAi(input.getBooleanOr("NoAI", false));
+ this.aware = input.getBooleanOr("Bukkit.Aware", true); // CraftBukkit
}
@Override
@@ -433,6 +_,11 @@
@@ -446,6 +_,11 @@
&& !itemEntity.getItem().isEmpty()
&& !itemEntity.hasPickUpDelay()
&& this.wantsToPickUp(serverLevel, itemEntity.getItem())) {
@@ -129,7 +129,7 @@
this.pickUpItem(serverLevel, itemEntity);
}
}
@@ -447,18 +_,24 @@
@@ -460,18 +_,24 @@
protected void pickUpItem(ServerLevel level, ItemEntity entity) {
ItemStack item = entity.getItem();
@@ -156,7 +156,7 @@
EquipmentSlot equipmentSlotForItem = this.getEquipmentSlotForItem(stack);
if (!this.isEquippableInSlot(stack, equipmentSlotForItem)) {
return ItemStack.EMPTY;
@@ -471,10 +_,18 @@
@@ -484,10 +_,18 @@
canReplaceCurrentItem = itemBySlot.isEmpty();
}
@@ -176,7 +176,7 @@
}
ItemStack itemStack = equipmentSlotForItem.limit(stack);
@@ -591,22 +_,29 @@
@@ -608,22 +_,29 @@
@Override
public void checkDespawn() {
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
@@ -219,7 +219,7 @@
this.noActionTime = 0;
}
}
@@ -618,6 +_,15 @@
@@ -635,6 +_,15 @@
@Override
protected final void serverAiStep() {
this.noActionTime++;
@@ -235,7 +235,7 @@
ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("sensing");
this.sensing.tick();
@@ -793,14 +_,69 @@
@@ -814,14 +_,69 @@
public boolean stillValid(Player player) {
return player.getVehicle() == Mob.this || player.canInteractWithEntity(Mob.this, 4.0);
}
@@ -305,7 +305,7 @@
ItemStack itemBySlot = this.getItemBySlot(equipmentSlot);
float f = this.dropChances.byEquipment(equipmentSlot);
if (f != 0.0F) {
@@ -820,7 +_,13 @@
@@ -841,7 +_,13 @@
}
this.spawnAtLocation(level, itemBySlot);
@@ -319,7 +319,7 @@
}
}
}
@@ -844,7 +_,9 @@
@@ -865,7 +_,9 @@
set.add(equipmentSlot);
} else if (this.dropChances.isPreserved(equipmentSlot)) {
this.setItemSlot(equipmentSlot, ItemStack.EMPTY);
@@ -329,7 +329,7 @@
}
}
}
@@ -1122,6 +_,21 @@
@@ -1147,6 +_,21 @@
public <T extends Mob> T convertTo(
EntityType<T> entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion<T> afterConversion
) {
@@ -351,7 +351,7 @@
if (this.isRemoved()) {
return null;
} else {
@@ -1130,13 +_,23 @@
@@ -1155,13 +_,23 @@
return null;
} else {
conversionParams.type().convert(this, mob, conversionParams);
@@ -378,7 +378,7 @@
}
return mob;
@@ -1146,7 +_,18 @@
@@ -1171,7 +_,18 @@
@Nullable
public <T extends Mob> T convertTo(EntityType<T> entityType, ConversionParams coversionParams, ConversionParams.AfterConversion<T> afterConversion) {
@@ -398,7 +398,7 @@
}
@Nullable
@@ -1182,7 +_,17 @@
@@ -1213,7 +_,17 @@
public boolean startRiding(Entity entity, boolean force) {
boolean flag = super.startRiding(entity, force);
if (flag && this.isLeashed()) {
@@ -417,7 +417,7 @@
}
return flag;
@@ -1270,7 +_,7 @@
@@ -1296,7 +_,7 @@
float knockback = this.getKnockback(source, damageSource);
if (knockback > 0.0F && source instanceof LivingEntity livingEntity) {
livingEntity.knockback(

View File

@@ -1,8 +1,8 @@
--- a/net/minecraft/world/entity/NeutralMob.java
+++ b/net/minecraft/world/entity/NeutralMob.java
@@ -35,9 +_,11 @@
@@ -36,9 +_,11 @@
if (level instanceof ServerLevel serverLevel) {
UUID uuid = tag.read("AngryAt", UUIDUtil.CODEC).orElse(null);
UUID uuid = input.read("AngryAt", UUIDUtil.CODEC).orElse(null);
this.setPersistentAngerTarget(uuid);
- if ((uuid != null ? serverLevel.getEntity(uuid) : null) instanceof LivingEntity livingEntity) {
- this.setTarget(livingEntity);
@@ -15,7 +15,7 @@
}
}
@@ -90,7 +_,7 @@
@@ -91,7 +_,7 @@
default void stopBeingAngry() {
this.setLastHurtByMob(null);
this.setPersistentAngerTarget(null);
@@ -24,7 +24,7 @@
this.setRemainingPersistentAngerTime(0);
}
@@ -101,8 +_,24 @@
@@ -102,8 +_,24 @@
void setTarget(@Nullable LivingEntity livingEntity);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/OminousItemSpawner.java
+++ b/net/minecraft/world/entity/OminousItemSpawner.java
@@ -79,7 +_,7 @@
@@ -77,7 +_,7 @@
entity = this.spawnProjectile(serverLevel, projectileItem, item);
} else {
entity = new ItemEntity(serverLevel, this.getX(), this.getY(), this.getZ(), item);
@@ -9,7 +9,7 @@
}
serverLevel.levelEvent(3021, this.blockPosition(), 1);
@@ -93,7 +_,7 @@
@@ -91,7 +_,7 @@
ProjectileItem.DispenseConfig dispenseConfig = projectileItem.createDispenseConfig();
dispenseConfig.overrideDispenseEvent().ifPresent(i -> level.levelEvent(i, this.blockPosition(), 0));
Direction direction = Direction.DOWN;
@@ -18,7 +18,7 @@
projectileItem.asProjectile(level, this.position(), stack, direction),
level,
stack,
@@ -102,7 +_,7 @@
@@ -100,7 +_,7 @@
direction.getStepZ(),
dispenseConfig.power(),
dispenseConfig.uncertainty()

View File

@@ -1,34 +1,15 @@
--- a/net/minecraft/world/entity/TamableAnimal.java
+++ b/net/minecraft/world/entity/TamableAnimal.java
@@ -77,7 +_,7 @@
@@ -75,7 +_,7 @@
}
this.orderedToSit = compound.getBooleanOr("Sitting", false);
this.orderedToSit = input.getBooleanOr("Sitting", false);
- this.setInSittingPose(this.orderedToSit);
+ this.setInSittingPose(this.orderedToSit, false); // Paper - Add EntityToggleSitEvent
}
@Override
@@ -88,8 +_,16 @@
@Override
public boolean handleLeashAtDistance(Entity leashHolder, float distance) {
if (this.isInSittingPose()) {
- if (distance > 10.0F) {
- this.dropLeash();
+ if (distance > (float) this.level().paperConfig().misc.maxLeashDistance.or(Leashable.LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance
+ // Paper start - Expand EntityUnleashEvent
+ org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(this.getBukkitEntity(), org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.DISTANCE, true);
+ if (!event.callEvent()) return false;
+ if (event.isDropLeash()) {
+ this.dropLeash();
+ } else {
+ this.removeLeash();
+ }
+ // Paper end - Expand EntityUnleashEvent
}
return false;
@@ -148,6 +_,13 @@
@@ -133,6 +_,13 @@
}
public void setInSittingPose(boolean sitting) {
@@ -42,7 +23,7 @@
byte b = this.entityData.get(DATA_FLAGS_ID);
if (sitting) {
this.entityData.set(DATA_FLAGS_ID, (byte)(b | 1));
@@ -230,7 +_,12 @@
@@ -215,7 +_,12 @@
if (this.level() instanceof ServerLevel serverLevel
&& serverLevel.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES)
&& this.getOwner() instanceof ServerPlayer serverPlayer) {
@@ -56,7 +37,7 @@
}
super.die(cause);
@@ -273,7 +_,14 @@
@@ -258,7 +_,14 @@
if (!this.canTeleportTo(new BlockPos(x, y, z))) {
return false;
} else {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
@@ -155,20 +_,20 @@
@@ -151,20 +_,20 @@
double baseValue = this.getBaseValue();
for (AttributeModifier attributeModifier : this.getModifiersOrEmpty(AttributeModifier.Operation.ADD_VALUE)) {

View File

@@ -1,7 +1,7 @@
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -148,4 +_,12 @@
.ifPresent(attributeInstance -> attributeInstance.load(compoundOrEmpty));
}
}
}
+

View File

@@ -9,7 +9,7 @@
public static final Holder<Attribute> ATTACK_KNOCKBACK = register("attack_knockback", new RangedAttribute("attribute.name.attack_knockback", 0.0, 0.0, 5.0));
public static final Holder<Attribute> ATTACK_SPEED = register(
"attack_speed", new RangedAttribute("attribute.name.attack_speed", 4.0, 0.0, 1024.0).setSyncable(true)
@@ -49,10 +_,10 @@
@@ -52,10 +_,10 @@
);
public static final Holder<Attribute> LUCK = register("luck", new RangedAttribute("attribute.name.luck", 0.0, -1024.0, 1024.0).setSyncable(true));
public static final Holder<Attribute> MAX_ABSORPTION = register(
@@ -22,7 +22,7 @@
);
public static final Holder<Attribute> MINING_EFFICIENCY = register(
"mining_efficiency", new RangedAttribute("attribute.name.mining_efficiency", 0.0, 0.0, 1024.0).setSyncable(true)
@@ -61,7 +_,7 @@
@@ -64,7 +_,7 @@
"movement_efficiency", new RangedAttribute("attribute.name.movement_efficiency", 0.0, 0.0, 1.0).setSyncable(true)
);
public static final Holder<Attribute> MOVEMENT_SPEED = register(

View File

@@ -1,23 +1,20 @@
--- a/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java
+++ b/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java
@@ -24,8 +_,19 @@
if (!mob.isBaby()) {
return false;
} else {
- AgeableMob ageableMob = instance.get(nearestVisibleAdult);
+ LivingEntity ageableMob = instance.get(nearestVisibleAdult); // CraftBukkit - type
if (mob.closerThan(ageableMob, followRange.getMaxValue() + 1) && !mob.closerThan(ageableMob, followRange.getMinValue())) {
+ // CraftBukkit start
+ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(mob, ageableMob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER);
+ if (event.isCancelled()) {
+ return false;
+ }
+ if (event.getTarget() == null) {
+ nearestVisibleAdult.erase();
+ return true;
+ }
+ ageableMob = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle();
+ // CraftBukkit end
WalkTarget walkTarget1 = new WalkTarget(
new EntityTracker(ageableMob, false), speedModifier.apply(mob), followRange.getMinValue() - 1
);
@@ -30,6 +_,17 @@
} else {
LivingEntity livingEntity = instance.get(memoryAccessor);
if (entity.closerThan(livingEntity, followRange.getMaxValue() + 1) && !entity.closerThan(livingEntity, followRange.getMinValue())) {
+ // CraftBukkit start
+ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(entity, livingEntity, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER);
+ if (event.isCancelled()) {
+ return false;
+ }
+ if (event.getTarget() == null) {
+ memoryAccessor.erase();
+ return true;
+ }
+ livingEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle();
+ // CraftBukkit end
WalkTarget walkTarget = new WalkTarget(
new EntityTracker(livingEntity, targetEyeHeight, targetEyeHeight),
speedModifier.apply(entity),

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/goal/TemptGoal.java
+++ b/net/minecraft/world/entity/ai/goal/TemptGoal.java
@@ -21,7 +_,7 @@
@@ -24,7 +_,7 @@
private double pRotX;
private double pRotY;
@Nullable
@@ -9,7 +9,7 @@
private int calmDown;
private boolean isRunning;
private final Predicate<ItemStack> items;
@@ -44,6 +_,15 @@
@@ -57,6 +_,15 @@
} else {
this.player = getServerLevel(this.mob)
.getNearestPlayer(this.targetingConditions.range(this.mob.getAttributeValue(Attributes.TEMPT_RANGE)), this.mob);
@@ -25,3 +25,21 @@
return this.player != null;
}
}
@@ -123,7 +_,7 @@
this.mob.getNavigation().stop();
}
- protected void navigateTowards(Player player) {
+ protected void navigateTowards(LivingEntity player) { // Paper
this.mob.getNavigation().moveTo(player, this.speedModifier);
}
@@ -142,7 +_,7 @@
}
@Override
- protected void navigateTowards(Player player) {
+ protected void navigateTowards(LivingEntity player) { // Paper
Vec3 vec3 = player.getEyePosition().subtract(this.mob.position()).scale(this.mob.getRandom().nextDouble()).add(this.mob.position());
this.mob.getMoveControl().setWantedPosition(vec3.x, vec3.y, vec3.z, this.speedModifier);
}

View File

@@ -12,7 +12,7 @@
@@ -54,7 +_,7 @@
}
if (mutableBlockPos.getY() > this.level.getMinY()) {
if (mutableBlockPos.getY() >= this.level.getMinY()) {
- return super.createPath(mutableBlockPos.above(), accuracy);
+ return super.createPath(mutableBlockPos.above(), entity, accuracy); // Paper - EntityPathfindEvent
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ambient/Bat.java
+++ b/net/minecraft/world/entity/ambient/Bat.java
@@ -86,7 +_,7 @@
@@ -87,7 +_,7 @@
}
@Override
@@ -9,7 +9,7 @@
return false;
}
@@ -140,13 +_,13 @@
@@ -141,13 +_,13 @@
this.yHeadRot = this.random.nextInt(360);
}
@@ -25,7 +25,7 @@
this.setResting(false);
if (!isSilent) {
level.levelEvent(null, 1025, blockPos, 0);
@@ -179,7 +_,7 @@
@@ -180,7 +_,7 @@
float f1 = Mth.wrapDegrees(f - this.getYRot());
this.zza = 0.5F;
this.setYRot(this.getYRot() + f1);
@@ -34,7 +34,7 @@
this.setResting(true);
}
}
@@ -204,7 +_,7 @@
@@ -205,7 +_,7 @@
if (this.isInvulnerableTo(level, damageSource)) {
return false;
} else {

View File

@@ -1,14 +1,14 @@
--- a/net/minecraft/world/entity/animal/Animal.java
+++ b/net/minecraft/world/entity/animal/Animal.java
@@ -41,6 +_,7 @@
@@ -42,6 +_,7 @@
public int inLove = 0;
@Nullable
public UUID loveCause;
public EntityReference<ServerPlayer> loveCause;
+ public @Nullable ItemStack breedItem; // CraftBukkit - Add breedItem variable
protected Animal(EntityType<? extends Animal> entityType, Level level) {
super(entityType, level);
@@ -80,9 +_,13 @@
@@ -81,9 +_,13 @@
}
@Override
@@ -24,18 +24,18 @@
}
@Override
@@ -138,8 +_,9 @@
@@ -139,8 +_,9 @@
if (this.isFood(itemInHand)) {
int age = this.getAge();
if (!this.level().isClientSide && age == 0 && this.canFallInLove()) {
if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove()) {
+ final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying
this.usePlayerItem(player, hand, itemInHand);
- this.setInLove(player);
+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
- this.setInLove(serverPlayer);
+ this.setInLove(serverPlayer, breedCopy); // Paper - Fix EntityBreedEvent copying
this.playEatingSound();
return InteractionResult.SUCCESS_SERVER;
}
@@ -176,8 +_,23 @@
@@ -177,8 +_,23 @@
return this.inLove <= 0;
}
@@ -57,10 +57,10 @@
+ }
+ this.inLove = entityEnterLoveModeEvent.getTicksInLove();
+ // CraftBukkit end
if (player != null) {
this.loveCause = player.getUUID();
if (player instanceof ServerPlayer serverPlayer) {
this.loveCause = new EntityReference<>(serverPlayer);
}
@@ -220,23 +_,45 @@
@@ -216,23 +_,45 @@
if (breedOffspring != null) {
breedOffspring.setBaby(true);
breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F);
@@ -108,7 +108,7 @@
- if (level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
- level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1));
+ if (experience > 0 && level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - Call EntityBreedEvent
+ level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, player, baby)); // Paper - Call EntityBreedEvent, add spawn context
+ level.addFreshEntity(new ExperienceOrb(level, this.position(), net.minecraft.world.phys.Vec3.ZERO, experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, player, baby)); // Paper - Call EntityBreedEvent, add spawn context
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Bee.java
+++ b/net/minecraft/world/entity/animal/Bee.java
@@ -145,10 +_,26 @@
@@ -146,10 +_,26 @@
Bee.BeeGoToHiveGoal goToHiveGoal;
private Bee.BeeGoToKnownFlowerGoal goToKnownFlowerGoal;
private int underWaterTicks;
@@ -28,26 +28,26 @@
this.lookControl = new Bee.BeeLookControl(this);
this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
this.setPathfindingMalus(PathType.WATER, -1.0F);
@@ -195,9 +_,18 @@
@@ -196,9 +_,18 @@
@Override
public void addAdditionalSaveData(CompoundTag compound) {
protected void addAdditionalSaveData(ValueOutput output) {
+ // CraftBukkit start - selectively save data
+ this.addAdditionalSaveData(compound, true);
+ this.addAdditionalSaveData(output, true);
+ }
+
+ @Override
+ public void addAdditionalSaveData(CompoundTag compound, boolean saveAll) {
+ public void addAdditionalSaveData(ValueOutput output, boolean saveAll) {
+ // CraftBukkit end
super.addAdditionalSaveData(compound);
super.addAdditionalSaveData(output);
+ if (saveAll) { // Paper
compound.storeNullable("hive_pos", BlockPos.CODEC, this.hivePos);
compound.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
output.storeNullable("hive_pos", BlockPos.CODEC, this.hivePos);
output.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
+ } // Paper
compound.putBoolean("HasNectar", this.hasNectar());
compound.putBoolean("HasStung", this.hasStung());
compound.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive);
@@ -235,7 +_,7 @@
output.putBoolean("HasNectar", this.hasNectar());
output.putBoolean("HasStung", this.hasStung());
output.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive);
@@ -236,7 +_,7 @@
}
if (i > 0) {
@@ -56,7 +56,7 @@
}
}
@@ -490,7 +_,11 @@
@@ -491,7 +_,11 @@
if (this.hivePos == null) {
return null;
} else {
@@ -69,7 +69,7 @@
}
}
@@ -523,6 +_,7 @@
@@ -524,6 +_,7 @@
}
public void setRolling(boolean isRolling) {
@@ -77,7 +77,7 @@
this.setFlag(2, isRolling);
}
@@ -579,7 +_,7 @@
@@ -580,7 +_,7 @@
if (beeInteractionEffect != null) {
this.usePlayerItem(player, hand, itemInHand);
if (!this.level().isClientSide) {
@@ -86,7 +86,7 @@
}
return InteractionResult.SUCCESS;
@@ -648,8 +_,9 @@
@@ -649,8 +_,9 @@
if (this.isInvulnerableTo(level, damageSource)) {
return false;
} else {
@@ -97,25 +97,7 @@
}
}
@@ -770,7 +_,7 @@
@VisibleForDebug
public class BeeGoToHiveGoal extends Bee.BaseBeeGoal {
public static final int MAX_TRAVELLING_TICKS = 2400;
- int travellingTicks = Bee.this.level().random.nextInt(10);
+ int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues
private static final int MAX_BLACKLISTED_TARGETS = 3;
final List<BlockPos> blacklistedTargets = Lists.newArrayList();
@Nullable
@@ -886,7 +_,7 @@
public class BeeGoToKnownFlowerGoal extends Bee.BaseBeeGoal {
private static final int MAX_TRAVELLING_TICKS = 2400;
- int travellingTicks = Bee.this.level().random.nextInt(10);
+ int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues
BeeGoToKnownFlowerGoal() {
this.setFlags(EnumSet.of(Goal.Flag.MOVE));
@@ -983,7 +_,7 @@
@@ -981,7 +_,7 @@
}
}
@@ -124,7 +106,7 @@
Bee.this.level().levelEvent(2011, blockPos, 15);
Bee.this.level().setBlockAndUpdate(blockPos, blockState1);
Bee.this.incrementNumCropsGrownSincePollination();
@@ -1007,7 +_,7 @@
@@ -1005,7 +_,7 @@
@Override
protected void alertOther(Mob mob, LivingEntity target) {
if (mob instanceof Bee && this.mob.hasLineOfSight(target)) {
@@ -133,7 +115,7 @@
}
}
}
@@ -1165,7 +_,7 @@
@@ -1163,7 +_,7 @@
Bee.this.dropFlower();
this.pollinating = false;
Bee.this.remainingCooldownBeforeLocatingNewFlower = 200;

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Cat.java
+++ b/net/minecraft/world/entity/animal/Cat.java
@@ -372,6 +_,11 @@
@@ -373,6 +_,11 @@
if (item instanceof DyeItem dyeItem) {
DyeColor dyeColor = dyeItem.getDyeColor();
if (dyeColor != this.getCollarColor()) {
@@ -12,7 +12,7 @@
if (!this.level().isClientSide()) {
this.setCollarColor(dyeColor);
itemInHand.consume(1, player);
@@ -384,7 +_,7 @@
@@ -385,7 +_,7 @@
if (!this.level().isClientSide()) {
this.usePlayerItem(player, hand, itemInHand);
FoodProperties foodProperties = itemInHand.get(DataComponents.FOOD);
@@ -21,7 +21,7 @@
this.playEatingSound();
}
@@ -446,7 +_,7 @@
@@ -447,7 +_,7 @@
}
private void tryToTame(Player player) {
@@ -30,7 +30,7 @@
this.tame(player);
this.setOrderedToSit(true);
this.level().broadcastEntityEvent(this, (byte)7);
@@ -580,15 +_,20 @@
@@ -581,15 +_,20 @@
.dropFromGiftLootTable(
getServerLevel(this.cat),
BuiltInLootTables.CAT_MORNING_GIFT,
@@ -55,7 +55,7 @@
);
}
@@ -615,7 +_,7 @@
@@ -616,7 +_,7 @@
static class CatTemptGoal extends TemptGoal {
@Nullable

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Chicken.java
+++ b/net/minecraft/world/entity/animal/Chicken.java
@@ -111,10 +_,12 @@
@@ -112,10 +_,12 @@
this.flap = this.flap + this.flapping * 2.0F;
if (this.level() instanceof ServerLevel serverLevel && this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggTime <= 0) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Dolphin.java
+++ b/net/minecraft/world/entity/animal/Dolphin.java
@@ -98,6 +_,13 @@
@@ -99,6 +_,13 @@
return EntityType.DOLPHIN.create(level, EntitySpawnReason.BREEDING);
}
@@ -14,7 +14,7 @@
@Override
public float getAgeScale() {
return this.isBaby() ? 0.65F : 1.0F;
@@ -182,7 +_,7 @@
@@ -183,7 +_,7 @@
@Override
public int getMaxAirSupply() {
@@ -23,7 +23,7 @@
}
@Override
@@ -215,11 +_,15 @@
@@ -216,11 +_,15 @@
if (this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty()) {
ItemStack item = entity.getItem();
if (this.canHoldItem(item)) {
@@ -40,7 +40,7 @@
}
}
}
@@ -486,7 +_,7 @@
@@ -487,7 +_,7 @@
@Override
public void start() {
@@ -49,7 +49,7 @@
}
@Override
@@ -505,7 +_,7 @@
@@ -506,7 +_,7 @@
}
if (this.player.isSwimming() && this.player.level().random.nextInt(6) == 0) {
@@ -58,7 +58,7 @@
}
}
}
@@ -575,7 +_,7 @@
@@ -576,7 +_,7 @@
0.3F * Mth.cos(Dolphin.this.getYRot() * (float) (Math.PI / 180.0)) * Mth.cos(Dolphin.this.getXRot() * (float) (Math.PI / 180.0))
+ Mth.sin(f1) * f2
);

View File

@@ -1,15 +1,15 @@
--- a/net/minecraft/world/entity/animal/Fox.java
+++ b/net/minecraft/world/entity/animal/Fox.java
@@ -429,7 +_,7 @@
compound.read("Trusted", TRUSTED_LIST_CODEC).orElse(List.of()).forEach(this::addTrustedEntity);
this.setSleeping(compound.getBooleanOr("Sleeping", false));
this.setVariant(compound.read("Type", Fox.Variant.CODEC).orElse(Fox.Variant.DEFAULT));
- this.setSitting(compound.getBooleanOr("Sitting", false));
+ this.setSitting(compound.getBooleanOr("Sitting", false), false); // Paper - Add EntityToggleSitEvent
this.setIsCrouching(compound.getBooleanOr("Crouching", false));
@@ -430,7 +_,7 @@
input.read("Trusted", TRUSTED_LIST_CODEC).orElse(List.of()).forEach(this::addTrustedEntity);
this.setSleeping(input.getBooleanOr("Sleeping", false));
this.setVariant(input.read("Type", Fox.Variant.CODEC).orElse(Fox.Variant.DEFAULT));
- this.setSitting(input.getBooleanOr("Sitting", false));
+ this.setSitting(input.getBooleanOr("Sitting", false), false); // Paper - Add EntityToggleSitEvent
this.setIsCrouching(input.getBooleanOr("Crouching", false));
if (this.level() instanceof ServerLevel) {
this.setTargetGoals();
@@ -446,6 +_,12 @@
@@ -447,6 +_,12 @@
}
public void setSitting(boolean sitting) {
@@ -22,7 +22,7 @@
this.setFlag(1, sitting);
}
@@ -505,19 +_,20 @@
@@ -506,19 +_,20 @@
itemEntity.setPickUpDelay(40);
itemEntity.setThrower(this);
this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F);
@@ -46,7 +46,7 @@
int count = item.getCount();
if (count > 1) {
this.dropItemStack(item.split(count - 1));
@@ -528,7 +_,7 @@
@@ -529,7 +_,7 @@
this.setItemSlot(EquipmentSlot.MAINHAND, item.split(1));
this.setGuaranteedDrop(EquipmentSlot.MAINHAND);
this.take(entity, item.getCount());
@@ -55,7 +55,7 @@
this.ticksSinceEaten = 0;
}
}
@@ -623,12 +_,12 @@
@@ -620,12 +_,12 @@
}
@Override
@@ -70,7 +70,7 @@
}
void wakeUp() {
@@ -692,15 +_,33 @@
@@ -689,15 +_,33 @@
return this.getTrustedEntities().anyMatch(entityReference -> entityReference.matches(entity));
}
@@ -108,7 +108,7 @@
}
public static boolean isPathClear(Fox fox, LivingEntity livingEntity) {
@@ -876,6 +_,19 @@
@@ -873,6 +_,19 @@
fox.addTrustedEntity(loveCause1);
}
@@ -128,7 +128,7 @@
if (serverPlayer != null) {
serverPlayer.awardStat(Stats.ANIMALS_BRED);
CriteriaTriggers.BRED_ANIMALS.trigger(serverPlayer, this.animal, this.partner, fox);
@@ -885,14 +_,12 @@
@@ -882,14 +_,12 @@
this.partner.setAge(6000);
this.animal.resetLove();
this.partner.resetLove();
@@ -142,11 +142,11 @@
this.level
.addFreshEntity(
- new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1)
+ new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper - call EntityBreedEvent, add spawn context
+ new ExperienceOrb(this.level, this.animal.position(), net.minecraft.world.phys.Vec3.ZERO, experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper - call EntityBreedEvent, add spawn context
);
}
}
@@ -956,6 +_,7 @@
@@ -953,6 +_,7 @@
private void pickSweetBerries(BlockState state) {
int ageValue = state.getValue(SweetBerryBushBlock.AGE);
state.setValue(SweetBerryBushBlock.AGE, 1);

View File

@@ -0,0 +1,25 @@
--- a/net/minecraft/world/entity/animal/HappyGhast.java
+++ b/net/minecraft/world/entity/animal/HappyGhast.java
@@ -296,8 +_,12 @@
}
@Override
- protected void removePassenger(Entity passenger) {
- super.removePassenger(passenger);
+ // Paper start - cancellable passengers
+ protected boolean removePassenger(Entity passenger, boolean suppressCancellation) {
+ if (!super.removePassenger(passenger, suppressCancellation)) {
+ return false;
+ }
+ // Paper end - cancellable passengers
if (!this.level().isClientSide) {
this.setServerStillTimeout(10);
}
@@ -306,6 +_,7 @@
this.clearHome();
this.level().playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.HARNESS_GOGGLES_UP, this.getSoundSource(), 1.0F, 1.0F);
}
+ return true; // Paper - cancellable passengers
}
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/IronGolem.java
+++ b/net/minecraft/world/entity/animal/IronGolem.java
@@ -105,7 +_,7 @@
@@ -106,7 +_,7 @@
@Override
protected void doPush(Entity entity) {
if (entity instanceof Enemy && !(entity instanceof Creeper) && this.getRandom().nextInt(20) == 0) {
@@ -9,7 +9,7 @@
}
super.doPush(entity);
@@ -304,7 +_,7 @@
@@ -305,7 +_,7 @@
BlockPos blockPos = this.blockPosition();
BlockPos blockPos1 = blockPos.below();
BlockState blockState = level.getBlockState(blockPos1);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/net/minecraft/world/entity/animal/MushroomCow.java
@@ -116,7 +_,17 @@
@@ -117,7 +_,17 @@
return InteractionResult.SUCCESS;
} else if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) {
if (this.level() instanceof ServerLevel serverLevel) {
@@ -19,7 +19,7 @@
this.gameEvent(GameEvent.SHEAR, player);
itemInHand.hurtAndBreak(1, player, getSlotForHand(hand));
}
@@ -169,15 +_,31 @@
@@ -170,15 +_,31 @@
@Override
public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Ocelot.java
+++ b/net/minecraft/world/entity/animal/Ocelot.java
@@ -126,7 +_,7 @@
@@ -127,7 +_,7 @@
@Override
public boolean removeWhenFarAway(double distanceToClosestPlayer) {
@@ -9,7 +9,7 @@
}
public static AttributeSupplier.Builder createAttributes() {
@@ -160,7 +_,7 @@
@@ -161,7 +_,7 @@
if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemInHand) && player.distanceToSqr(this) < 9.0) {
this.usePlayerItem(player, hand, itemInHand);
if (!this.level().isClientSide) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Panda.java
+++ b/net/minecraft/world/entity/animal/Panda.java
@@ -128,6 +_,7 @@
@@ -129,6 +_,7 @@
}
public void sit(boolean sitting) {
@@ -8,7 +8,7 @@
this.setFlag(8, sitting);
}
@@ -517,24 +_,28 @@
@@ -518,24 +_,28 @@
for (Panda panda : level.getEntitiesOfClass(Panda.class, this.getBoundingBox().inflate(10.0))) {
if (!panda.isBaby() && panda.onGround() && !panda.isInWater() && panda.canPerformAction()) {
@@ -39,7 +39,7 @@
}
}
@@ -625,8 +_,9 @@
@@ -626,8 +_,9 @@
this.usePlayerItem(player, hand, itemInHand);
this.ageUp((int)(-this.getAge() / 20 * 0.1F), true);
} else if (!this.level().isClientSide && this.getAge() == 0 && this.canFallInLove()) {
@@ -50,7 +50,7 @@
} else {
if (!(this.level() instanceof ServerLevel serverLevel) || this.isSitting() || this.isInWater()) {
return InteractionResult.PASS;
@@ -636,7 +_,9 @@
@@ -637,7 +_,9 @@
this.eat(true);
ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemBySlot.isEmpty() && !player.hasInfiniteMaterials()) {
@@ -60,7 +60,7 @@
}
this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemInHand.getItem(), 1));
@@ -858,7 +_,7 @@
@@ -859,7 +_,7 @@
@Override
protected void alertOther(Mob mob, LivingEntity target) {
if (mob instanceof Panda && mob.isAggressive()) {
@@ -69,7 +69,7 @@
}
}
}
@@ -1087,7 +_,9 @@
@@ -1088,7 +_,9 @@
public void stop() {
ItemStack itemBySlot = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemBySlot.isEmpty()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Parrot.java
+++ b/net/minecraft/world/entity/animal/Parrot.java
@@ -262,7 +_,7 @@
@@ -264,7 +_,7 @@
}
if (!this.level().isClientSide) {
@@ -9,7 +9,7 @@
this.tame(player);
this.level().broadcastEntityEvent(this, (byte)7);
} else {
@@ -283,7 +_,7 @@
@@ -285,7 +_,7 @@
}
} else {
this.usePlayerItem(player, hand, itemInHand);
@@ -18,7 +18,7 @@
if (player.isCreative() || !this.isInvulnerable()) {
this.hurt(this.damageSources().playerAttack(player), Float.MAX_VALUE);
}
@@ -378,8 +_,8 @@
@@ -380,8 +_,8 @@
}
@Override
@@ -29,7 +29,7 @@
}
@Override
@@ -394,8 +_,13 @@
@@ -396,8 +_,13 @@
if (this.isInvulnerableTo(level, damageSource)) {
return false;
} else {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Pig.java
+++ b/net/minecraft/world/entity/animal/Pig.java
@@ -214,7 +_,14 @@
@@ -215,7 +_,14 @@
}
mob.setPersistenceRequired();

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Pufferfish.java
+++ b/net/minecraft/world/entity/animal/Pufferfish.java
@@ -96,24 +_,36 @@
@@ -97,24 +_,36 @@
public void tick() {
if (!this.level().isClientSide && this.isAlive() && this.isEffectiveAi()) {
if (this.inflateCounter > 0) {
@@ -37,7 +37,7 @@
this.deflateTimer++;
}
}
@@ -137,7 +_,7 @@
@@ -138,7 +_,7 @@
private void touch(ServerLevel level, Mob mob) {
int puffState = this.getPuffState();
if (mob.hurtServer(level, this.damageSources().mobAttack(this), 1 + puffState)) {
@@ -46,7 +46,7 @@
this.playSound(SoundEvents.PUFFER_FISH_STING, 1.0F, 1.0F);
}
}
@@ -152,7 +_,7 @@
@@ -153,7 +_,7 @@
serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.PUFFER_FISH_STING, 0.0F));
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Rabbit.java
+++ b/net/minecraft/world/entity/animal/Rabbit.java
@@ -95,7 +_,7 @@
@@ -96,7 +_,7 @@
super(entityType, level);
this.jumpControl = new Rabbit.RabbitJumpControl(this);
this.moveControl = new Rabbit.RabbitMoveControl(this);
@@ -9,7 +9,7 @@
}
@Override
@@ -588,9 +_,11 @@
@@ -589,9 +_,11 @@
if (this.canRaid && block instanceof CarrotBlock) {
int ageValue = blockState.getValue(CarrotBlock.AGE);
if (ageValue == 0) {

View File

@@ -1,11 +1,11 @@
--- a/net/minecraft/world/entity/animal/ShoulderRidingEntity.java
+++ b/net/minecraft/world/entity/animal/ShoulderRidingEntity.java
@@ -19,7 +_,7 @@
compoundTag.putString("id", this.getEncodeId());
this.saveWithoutId(compoundTag);
if (player.setEntityOnShoulder(compoundTag)) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
return true;
} else {
return false;
@@ -24,7 +_,7 @@
this.saveWithoutId(tagValueOutput);
tagValueOutput.putString("id", this.getEncodeId());
if (player.setEntityOnShoulder(tagValueOutput.buildResult())) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
return true;
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/net/minecraft/world/entity/animal/SnowGolem.java
@@ -91,7 +_,7 @@
@@ -92,7 +_,7 @@
super.aiStep();
if (this.level() instanceof ServerLevel serverLevel) {
if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) {
@@ -9,7 +9,7 @@
}
if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
@@ -106,7 +_,7 @@
@@ -107,7 +_,7 @@
int floor2 = Mth.floor(this.getZ() + (i / 2 % 2 * 2 - 1) * 0.25F);
BlockPos blockPos = new BlockPos(floor, floor1, floor2);
if (this.level().getBlockState(blockPos).isAir() && blockState.canSurvive(this.level(), blockPos)) {
@@ -18,7 +18,7 @@
this.level().gameEvent(GameEvent.BLOCK_PLACE, blockPos, GameEvent.Context.of(this, blockState));
}
}
@@ -134,7 +_,19 @@
@@ -135,7 +_,19 @@
ItemStack itemInHand = player.getItemInHand(hand);
if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) {
if (this.level() instanceof ServerLevel serverLevel) {
@@ -39,7 +39,7 @@
this.gameEvent(GameEvent.SHEAR, player);
itemInHand.hurtAndBreak(1, player, getSlotForHand(hand));
}
@@ -147,11 +_,29 @@
@@ -148,11 +_,29 @@
@Override
public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/Turtle.java
+++ b/net/minecraft/world/entity/animal/Turtle.java
@@ -259,7 +_,9 @@
@@ -260,7 +_,9 @@
protected void ageBoundaryReached() {
super.ageBoundaryReached();
if (!this.isBaby() && this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
@@ -10,7 +10,7 @@
}
}
@@ -284,7 +_,7 @@
@@ -285,7 +_,7 @@
@Override
public void thunderHit(ServerLevel level, LightningBolt lightning) {
@@ -19,7 +19,7 @@
}
@Override
@@ -311,6 +_,10 @@
@@ -312,6 +_,10 @@
if (loveCause == null && this.partner.getLoveCause() != null) {
loveCause = this.partner.getLoveCause();
}
@@ -30,16 +30,16 @@
if (loveCause != null) {
loveCause.awardStat(Stats.ANIMALS_BRED);
@@ -324,7 +_,7 @@
@@ -325,7 +_,7 @@
this.partner.resetLove();
RandomSource random = this.animal.getRandom();
if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), random.nextInt(7) + 1));
+ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause)); // Paper - Add EntityFertilizeEggEvent event
+ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.position(), Vec3.ZERO, event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, this.turtle)); // Paper - Add EntityFertilizeEggEvent event
}
}
}
@@ -347,7 +_,7 @@
@@ -348,7 +_,7 @@
&& (
this.turtle.hasEgg()
|| this.turtle.getRandom().nextInt(reducedTickDelay(700)) == 0 && !this.turtle.homePos.closerToCenterThan(this.turtle.position(), 64.0)
@@ -48,7 +48,7 @@
}
@Override
@@ -455,14 +_,20 @@
@@ -456,14 +_,20 @@
BlockPos blockPos = this.turtle.blockPosition();
if (!this.turtle.isInWater() && this.isReachedTarget()) {
if (this.turtle.layEggCounter < 1) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/allay/Allay.java
+++ b/net/minecraft/world/entity/animal/allay/Allay.java
@@ -116,6 +_,7 @@
@@ -113,6 +_,7 @@
private float dancingAnimationTicks;
private float spinningAnimationTicks;
private float spinningAnimationTicks0;
@@ -8,7 +8,7 @@
public Allay(EntityType<? extends Allay> entityType, Level level) {
super(entityType, level);
@@ -129,6 +_,12 @@
@@ -126,6 +_,12 @@
);
}
@@ -21,7 +21,7 @@
@Override
protected Brain.Provider<Allay> brainProvider() {
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
@@ -248,7 +_,7 @@
@@ -233,7 +_,7 @@
public void aiStep() {
super.aiStep();
if (!this.level().isClientSide && this.isAlive() && this.tickCount % 10 == 0) {
@@ -30,7 +30,7 @@
}
if (this.isDancing() && this.shouldStopDancing() && this.tickCount % 20 == 0) {
@@ -316,7 +_,12 @@
@@ -301,7 +_,12 @@
ItemStack itemInHand = player.getItemInHand(hand);
ItemStack itemInHand1 = this.getItemInHand(InteractionHand.MAIN_HAND);
if (this.isDancing() && itemInHand.is(ItemTags.DUPLICATES_ALLAYS) && this.canDuplicate()) {
@@ -44,7 +44,7 @@
this.level().broadcastEntityEvent(this, (byte)18);
this.level().playSound(player, this, SoundEvents.AMETHYST_BLOCK_CHIME, SoundSource.NEUTRAL, 2.0F, 1.0F);
this.removeInteractionItem(player, itemInHand);
@@ -421,6 +_,7 @@
@@ -406,6 +_,7 @@
}
private boolean shouldStopDancing() {
@@ -52,16 +52,16 @@
return this.jukeboxPos == null
|| !this.jukeboxPos.closerToCenterThan(this.position(), GameEvent.JUKEBOX_PLAY.value().notificationRadius())
|| !this.level().getBlockState(this.jukeboxPos).is(Blocks.JUKEBOX);
@@ -475,7 +_,7 @@
this.readInventoryFromTag(compound, this.registryAccess());
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
this.vibrationData = compound.read("listener", VibrationSystem.Data.CODEC, registryOps).orElseGet(VibrationSystem.Data::new);
- this.setDuplicationCooldown(compound.getIntOr("DuplicationCooldown", 0));
+ this.setDuplicationCooldown(compound.getLongOr("DuplicationCooldown", 0)); // Paper - Load as long
@@ -458,7 +_,7 @@
super.readAdditionalSaveData(input);
this.readInventoryFromTag(input);
this.vibrationData = input.read("listener", VibrationSystem.Data.CODEC).orElseGet(VibrationSystem.Data::new);
- this.setDuplicationCooldown(input.getIntOr("DuplicationCooldown", 0));
+ this.setDuplicationCooldown(input.getLongOr("DuplicationCooldown", 0)); // Paper - Load as long
}
@Override
@@ -494,15 +_,17 @@
@@ -477,15 +_,17 @@
this.entityData.set(DATA_CAN_DUPLICATE, duplicationCooldown == 0L);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
@@ -142,10 +_,12 @@
@@ -143,10 +_,12 @@
ArmadilloAi.updateActivity(this);
profilerFiller.pop();
if (this.isAlive() && !this.isBaby() && --this.scuteTime <= 0) {
@@ -13,7 +13,7 @@
this.scuteTime = this.pickNextScuteDropTime();
}
@@ -282,8 +_,11 @@
@@ -283,8 +_,11 @@
}
@Override
@@ -27,7 +27,7 @@
if (!this.isNoAi() && !this.isDeadOrDying()) {
if (damageSource.getEntity() instanceof LivingEntity) {
this.getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, 80L);
@@ -294,6 +_,7 @@
@@ -295,6 +_,7 @@
this.rollOut();
}
}
@@ -35,7 +35,7 @@
}
@Override
@@ -312,7 +_,9 @@
@@ -313,7 +_,9 @@
return false;
} else {
if (this.level() instanceof ServerLevel serverLevel) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -231,7 +_,7 @@
@@ -233,7 +_,7 @@
@Override
public int getMaxAirSupply() {
@@ -9,7 +9,7 @@
}
public Axolotl.Variant getVariant() {
@@ -449,10 +_,10 @@
@@ -451,10 +_,10 @@
if (effect == null || effect.endsWithin(2399)) {
int i = effect != null ? effect.getDuration() : 0;
int min = Math.min(2400, 100 + i);
@@ -22,7 +22,7 @@
}
@Override
@@ -544,6 +_,13 @@
@@ -546,6 +_,13 @@
) {
return level.getBlockState(pos.below()).is(BlockTags.AXOLOTLS_SPAWNABLE_ON);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/camel/Camel.java
+++ b/net/minecraft/world/entity/animal/camel/Camel.java
@@ -398,12 +_,12 @@
@@ -404,12 +_,12 @@
} else {
boolean flag = this.getHealth() < this.getMaxHealth();
if (flag) {
@@ -15,7 +15,7 @@
}
boolean isBaby = this.isBaby();
@@ -463,9 +_,13 @@
@@ -469,9 +_,13 @@
}
@Override
@@ -31,7 +31,7 @@
}
@Override
@@ -566,7 +_,7 @@
@@ -572,7 +_,7 @@
}
public void sitDown() {
@@ -40,7 +40,7 @@
this.makeSound(SoundEvents.CAMEL_SIT);
this.setPose(Pose.SITTING);
this.gameEvent(GameEvent.ENTITY_ACTION);
@@ -575,7 +_,7 @@
@@ -581,7 +_,7 @@
}
public void standUp() {
@@ -49,7 +49,7 @@
this.makeSound(SoundEvents.CAMEL_STAND);
this.setPose(Pose.STANDING);
this.gameEvent(GameEvent.ENTITY_ACTION);
@@ -584,6 +_,7 @@
@@ -590,6 +_,7 @@
}
public void standUpInstantly() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -287,7 +_,12 @@
@@ -288,7 +_,12 @@
@Override
public void spawnChildFromBreeding(ServerLevel level, Animal mate) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -63,6 +_,7 @@
@@ -65,6 +_,7 @@
MemoryModuleType.BREED_TARGET,
MemoryModuleType.IS_PANICKING
);
@@ -8,7 +8,7 @@
public Tadpole(EntityType<? extends AbstractFish> entityType, Level level) {
super(entityType, level);
@@ -114,7 +_,7 @@
@@ -116,7 +_,7 @@
@Override
public void aiStep() {
super.aiStep();
@@ -17,22 +17,22 @@
this.setAge(this.age + 1);
}
}
@@ -123,12 +_,14 @@
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
compound.putInt("Age", this.age);
+ compound.putBoolean("AgeLocked", this.ageLocked); // Paper
@@ -125,12 +_,14 @@
protected void addAdditionalSaveData(ValueOutput output) {
super.addAdditionalSaveData(output);
output.putInt("Age", this.age);
+ output.putBoolean("AgeLocked", this.ageLocked); // Paper
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
this.setAge(compound.getIntOr("Age", 0));
+ this.ageLocked = compound.getBooleanOr("AgeLocked", false); // Paper
protected void readAdditionalSaveData(ValueInput input) {
super.readAdditionalSaveData(input);
this.setAge(input.getIntOr("Age", 0));
+ this.ageLocked = input.getBooleanOr("AgeLocked", false); // Paper
}
@Nullable
@@ -178,13 +_,19 @@
@@ -180,13 +_,19 @@
@Override
public void saveToBucketTag(ItemStack stack) {
Bucketable.saveDefaultDataToBucketTag(this, stack);
@@ -53,7 +53,7 @@
}
@Override
@@ -216,6 +_,7 @@
@@ -218,6 +_,7 @@
}
private void ageUp(int offset) {
@@ -61,7 +61,7 @@
this.setAge(this.age + offset * 20);
}
@@ -228,12 +_,17 @@
@@ -230,12 +_,17 @@
private void ageUp() {
if (this.level() instanceof ServerLevel serverLevel) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
@@ -234,13 +_,22 @@
@@ -235,13 +_,22 @@
public InteractionResult mobInteract(Player player, InteractionHand hand) {
ItemStack itemInHand = player.getItemInHand(hand);
if (itemInHand.is(Items.BUCKET) && !this.isBaby()) {
@@ -25,7 +25,7 @@
this.playEatingSound();
}
@@ -352,8 +_,7 @@
@@ -353,8 +_,7 @@
double d1 = Mth.randomBetween(this.random, 0.3F, 0.7F);
double d2 = Mth.randomBetween(this.random, -0.2F, 0.2F);
ItemEntity itemEntity = new ItemEntity(this.level(), vec3.x(), vec3.y(), vec3.z(), itemStack, d, d1, d2);
@@ -35,7 +35,7 @@
}
}
@@ -384,4 +_,15 @@
@@ -385,4 +_,15 @@
) {
return level.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(level, pos);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
+++ b/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
@@ -70,6 +_,12 @@
@@ -73,6 +_,12 @@
super.dropEquipment(level);
if (this.hasChest()) {
this.spawnAtLocation(level, Blocks.CHEST);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/net/minecraft/world/entity/animal/horse/AbstractHorse.java
@@ -122,6 +_,7 @@
@@ -123,6 +_,7 @@
protected int gallopSoundCounter;
@Nullable
public EntityReference<LivingEntity> owner;
@@ -8,7 +8,7 @@
protected AbstractHorse(EntityType<? extends AbstractHorse> entityType, Level level) {
super(entityType, level);
@@ -250,7 +_,7 @@
@@ -252,7 +_,7 @@
}
@Override
@@ -17,7 +17,7 @@
return !this.isVehicle();
}
@@ -301,7 +_,7 @@
@@ -303,7 +_,7 @@
public void createInventory() {
SimpleContainer simpleContainer = this.inventory;
@@ -26,7 +26,7 @@
if (simpleContainer != null) {
int min = Math.min(simpleContainer.getContainerSize(), this.inventory.getContainerSize());
@@ -395,7 +_,7 @@
@@ -397,7 +_,7 @@
}
public int getMaxTemper() {
@@ -35,7 +35,7 @@
}
@Override
@@ -450,7 +_,7 @@
@@ -456,7 +_,7 @@
i1 = 5;
if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) {
flag = true;
@@ -44,7 +44,7 @@
}
} else if (stack.is(Items.GOLDEN_APPLE) || stack.is(Items.ENCHANTED_GOLDEN_APPLE)) {
f = 10.0F;
@@ -458,12 +_,12 @@
@@ -464,12 +_,12 @@
i1 = 10;
if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) {
flag = true;
@@ -59,7 +59,7 @@
flag = true;
}
@@ -534,7 +_,7 @@
@@ -540,7 +_,7 @@
super.aiStep();
if (this.level() instanceof ServerLevel serverLevel && this.isAlive()) {
if (this.random.nextInt(900) == 0 && this.deathTime == 0) {
@@ -68,7 +68,7 @@
}
if (this.canEatGrass()) {
@@ -637,6 +_,16 @@
@@ -642,6 +_,16 @@
}
}
@@ -85,36 +85,23 @@
@Override
public InteractionResult mobInteract(Player player, InteractionHand hand) {
if (this.isVehicle() || this.isBaby()) {
@@ -674,6 +_,12 @@
this.setFlag(16, eating);
}
+ // Paper start - Horse API
+ public void setForceStanding(boolean standing) {
+ this.setFlag(FLAG_STANDING, standing);
+ }
+ // Paper end - Horse API
+
public void setStanding(boolean standing) {
if (standing) {
this.setEating(false);
@@ -785,6 +_,7 @@
if (this.owner != null) {
this.owner.store(compound, "Owner");
}
+ compound.putInt("Bukkit.MaxDomestication", this.maxDomestication); // Paper - max domestication
@@ -788,6 +_,7 @@
output.putInt("Temper", this.getTemper());
output.putBoolean("Tame", this.isTamed());
EntityReference.store(this.owner, output, "Owner");
+ output.putInt("Bukkit.MaxDomestication", this.maxDomestication); // Paper - max domestication
}
@Override
@@ -795,6 +_,7 @@
this.setTemper(compound.getIntOr("Temper", 0));
this.setTamed(compound.getBooleanOr("Tame", false));
this.owner = EntityReference.readWithOldOwnerConversion(compound, "Owner", this.level());
+ this.maxDomestication = compound.getIntOr("Bukkit.MaxDomestication", this instanceof Llama ? 30 : 100); // Paper - max domestication
@@ -798,6 +_,7 @@
this.setTemper(input.getIntOr("Temper", 0));
this.setTamed(input.getBooleanOr("Tame", false));
this.owner = EntityReference.readWithOldOwnerConversion(input, "Owner", this.level());
+ this.maxDomestication = input.getIntOr("Bukkit.MaxDomestication", this instanceof Llama ? 30 : 100); // Paper - max domestication
}
@Override
@@ -883,6 +_,17 @@
@@ -886,6 +_,17 @@
@Override
public void handleStartJump(int jumpPower) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/horse/Llama.java
+++ b/net/minecraft/world/entity/animal/horse/Llama.java
@@ -76,17 +_,23 @@
@@ -77,17 +_,23 @@
@Nullable
private Llama caravanHead;
@Nullable
@@ -25,7 +25,7 @@
private void setStrength(int strength) {
this.entityData.set(DATA_STRENGTH_ID, Math.max(1, Math.min(5, strength)));
}
@@ -193,12 +_,12 @@
@@ -194,12 +_,12 @@
f = 10.0F;
if (this.isTamed() && this.getAge() == 0 && this.canFallInLove()) {
flag = true;
@@ -40,7 +40,7 @@
flag = true;
}
@@ -312,7 +_,7 @@
@@ -313,7 +_,7 @@
@Override
public int getMaxTemper() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
+++ b/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
@@ -124,7 +_,7 @@
@@ -125,7 +_,7 @@
public void aiStep() {
super.aiStep();
if (this.isTrap() && this.trapTime++ >= 18000) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/horse/TraderLlama.java
+++ b/net/minecraft/world/entity/animal/horse/TraderLlama.java
@@ -88,7 +_,7 @@
@@ -89,7 +_,7 @@
this.despawnDelay = this.isLeashedToWanderingTrader() ? ((WanderingTrader)this.getLeashHolder()).getDespawnDelay() - 1 : this.despawnDelay - 1;
if (this.despawnDelay <= 0) {
this.removeLeash();
@@ -9,7 +9,7 @@
}
}
}
@@ -147,7 +_,7 @@
@@ -148,7 +_,7 @@
@Override
public void start() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/sheep/Sheep.java
+++ b/net/minecraft/world/entity/animal/sheep/Sheep.java
@@ -161,7 +_,19 @@
@@ -139,7 +_,19 @@
ItemStack itemInHand = player.getItemInHand(hand);
if (itemInHand.is(Items.SHEARS)) {
if (this.level() instanceof ServerLevel serverLevel && this.readyForShearing()) {
@@ -21,7 +21,7 @@
this.gameEvent(GameEvent.SHEAR, player);
itemInHand.hurtAndBreak(1, player, getSlotForHand(hand));
return InteractionResult.SUCCESS_SERVER;
@@ -175,14 +_,28 @@
@@ -153,14 +_,28 @@
@Override
public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) {
@@ -57,7 +57,7 @@
if (itemEntity != null) {
itemEntity.setDeltaMovement(
itemEntity.getDeltaMovement()
@@ -302,6 +_,7 @@
@@ -280,6 +_,7 @@
@Override
public void ate() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -267,6 +_,13 @@
@@ -278,6 +_,13 @@
this.dropFromGiftLootTable(serverLevel, BuiltInLootTables.SNIFFER_DIGGING, (serverLevel1, itemStack) -> {
ItemEntity itemEntity = new ItemEntity(this.level(), headBlock.getX(), headBlock.getY(), headBlock.getZ(), itemStack);
itemEntity.setDefaultPickUpDelay();
@@ -14,7 +14,7 @@
serverLevel1.addFreshEntity(itemEntity);
});
this.playSound(SoundEvents.SNIFFER_DROP_SEED, 1.0F, 1.0F);
@@ -325,12 +_,17 @@
@@ -336,12 +_,17 @@
@Override
public void spawnChildFromBreeding(ServerLevel level, Animal mate) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/animal/wolf/Wolf.java
+++ b/net/minecraft/world/entity/animal/wolf/Wolf.java
@@ -400,16 +_,18 @@
@@ -399,16 +_,18 @@
if (this.isInvulnerableTo(level, damageSource)) {
return false;
} else {
@@ -22,7 +22,7 @@
ItemStack bodyArmorItem = this.getBodyArmorItem();
int damageValue = bodyArmorItem.getDamageValue();
int maxDamage = bodyArmorItem.getMaxDamage();
@@ -429,6 +_,7 @@
@@ -428,6 +_,7 @@
);
}
}
@@ -30,7 +30,7 @@
}
private boolean canArmorAbsorb(DamageSource damageSource) {
@@ -439,7 +_,7 @@
@@ -438,7 +_,7 @@
protected void applyTamingSideEffects() {
if (this.isTame()) {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(40.0);
@@ -39,7 +39,7 @@
} else {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(8.0);
}
@@ -459,7 +_,7 @@
@@ -463,7 +_,7 @@
this.usePlayerItem(player, hand, itemInHand);
FoodProperties foodProperties = itemInHand.get(DataComponents.FOOD);
float f = foodProperties != null ? foodProperties.nutrition() : 1.0F;
@@ -49,25 +49,15 @@
}
@@ -492,7 +_,7 @@
this.setOrderedToSit(!this.isOrderedToSit());
this.jumping = false;
this.navigation.stop();
- this.setTarget(null);
+ this.setTarget(null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET); // CraftBukkit - reason
return InteractionResult.SUCCESS.withoutItem();
}
@@ -504,7 +_,9 @@
ItemStack bodyArmorItem = this.getBodyArmorItem();
this.setBodyArmorItem(ItemStack.EMPTY);
if (this.level() instanceof ServerLevel serverLevel) {
+ this.forceDrops = true; // CraftBukkit
this.spawnAtLocation(serverLevel, bodyArmorItem);
+ this.forceDrops = false; // CraftBukkit
this.setOrderedToSit(!this.isOrderedToSit());
this.jumping = false;
this.navigation.stop();
- this.setTarget(null);
+ this.setTarget(null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET); // CraftBukkit - reason
return InteractionResult.SUCCESS.withoutItem();
}
return InteractionResult.SUCCESS;
@@ -512,6 +_,13 @@
@@ -501,6 +_,13 @@
DyeColor dyeColor = dyeItem.getDyeColor();
if (dyeColor != this.getCollarColor()) {
@@ -81,7 +71,7 @@
this.setCollarColor(dyeColor);
itemInHand.consume(1, player);
return InteractionResult.SUCCESS;
@@ -526,7 +_,7 @@
@@ -515,7 +_,7 @@
}
private void tryToTame(Player player) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -25,6 +_,7 @@
@@ -26,6 +_,7 @@
private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
private static final boolean DEFAULT_SHOW_BOTTOM = true;
public int time;
@@ -8,7 +8,7 @@
public EndCrystal(EntityType<? extends EndCrystal> entityType, Level level) {
super(entityType, level);
@@ -56,21 +_,37 @@
@@ -57,21 +_,37 @@
if (this.level() instanceof ServerLevel) {
BlockPos blockPos = this.blockPosition();
if (((ServerLevel)this.level()).getDragonFight() != null && this.level().getBlockState(blockPos).isAir()) {
@@ -34,21 +34,21 @@
}
@Override
protected void addAdditionalSaveData(CompoundTag compound) {
compound.storeNullable("beam_target", BlockPos.CODEC, this.getBeamTarget());
compound.putBoolean("ShowBottom", this.showsBottom());
+ compound.putBoolean("Paper.GeneratedByDragonFight", this.generatedByDragonFight); // Paper - Fix invulnerable end crystals
protected void addAdditionalSaveData(ValueOutput output) {
output.storeNullable("beam_target", BlockPos.CODEC, this.getBeamTarget());
output.putBoolean("ShowBottom", this.showsBottom());
+ output.putBoolean("Paper.GeneratedByDragonFight", this.generatedByDragonFight); // Paper - Fix invulnerable end crystals
}
@Override
protected void readAdditionalSaveData(CompoundTag compound) {
this.setBeamTarget(compound.read("beam_target", BlockPos.CODEC).orElse(null));
this.setShowBottom(compound.getBooleanOr("ShowBottom", true));
+ this.generatedByDragonFight = compound.getBooleanOr("Paper.GeneratedByDragonFight", false); // Paper - Fix invulnerable end crystals
protected void readAdditionalSaveData(ValueInput input) {
this.setBeamTarget(input.read("beam_target", BlockPos.CODEC).orElse(null));
this.setShowBottom(input.getBooleanOr("ShowBottom", true));
+ this.generatedByDragonFight = input.getBooleanOr("Paper.GeneratedByDragonFight", false); // Paper - Fix invulnerable end crystals
}
@Override
@@ -91,10 +_,24 @@
@@ -92,10 +_,24 @@
return false;
} else {
if (!this.isRemoved()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -87,6 +_,10 @@
@@ -88,6 +_,10 @@
private final Node[] nodes = new Node[24];
private final int[] nodeAdjacency = new int[24];
private final BinaryHeap openSet = new BinaryHeap();
@@ -11,7 +11,7 @@
public EnderDragon(EntityType<? extends EnderDragon> entityType, Level level) {
super(EntityType.ENDER_DRAGON, level);
@@ -102,6 +_,7 @@
@@ -103,6 +_,7 @@
this.setHealth(this.getMaxHealth());
this.noPhysics = true;
this.phaseManager = new EnderDragonPhaseManager(this);
@@ -19,8 +19,8 @@
}
public void setDragonFight(EndDragonFight dragonFight) {
@@ -120,6 +_,19 @@
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0);
@@ -121,6 +_,19 @@
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0).add(Attributes.CAMERA_DISTANCE, 16.0);
}
+ // Paper start - Allow changing the EnderDragon podium
@@ -39,7 +39,7 @@
@Override
public boolean isFlapping() {
float cos = Mth.cos(this.flapTime * (float) (Math.PI * 2));
@@ -211,7 +_,7 @@
@@ -212,7 +_,7 @@
}
Vec3 flyTargetLocation = currentPhase.getFlyTargetLocation();
@@ -48,7 +48,7 @@
double d = flyTargetLocation.x - this.getX();
double d1 = flyTargetLocation.y - this.getY();
double d2 = flyTargetLocation.z - this.getZ();
@@ -366,7 +_,12 @@
@@ -367,7 +_,12 @@
if (this.nearestCrystal.isRemoved()) {
this.nearestCrystal = null;
} else if (this.tickCount % 10 == 0 && this.getHealth() < this.getMaxHealth()) {
@@ -62,7 +62,7 @@
}
}
@@ -396,7 +_,7 @@
@@ -397,7 +_,7 @@
double d2 = entity.getX() - d;
double d3 = entity.getZ() - d1;
double max = Math.max(d2 * d2 + d3 * d3, 0.1);
@@ -71,7 +71,7 @@
if (!this.phaseManager.getCurrentPhase().isSitting() && livingEntity.getLastHurtByMobTimestamp() < entity.tickCount - 2) {
DamageSource damageSource = this.damageSources().mobAttack(this);
entity.hurtServer(level, damageSource, 5.0F);
@@ -429,6 +_,7 @@
@@ -430,6 +_,7 @@
int floor5 = Mth.floor(box.maxZ);
boolean flag = false;
boolean flag1 = false;
@@ -79,7 +79,7 @@
for (int i = floor; i <= floor3; i++) {
for (int i1 = floor1; i1 <= floor4; i1++) {
@@ -437,7 +_,11 @@
@@ -438,7 +_,11 @@
BlockState blockState = level.getBlockState(blockPos);
if (!blockState.isAir() && !blockState.is(BlockTags.DRAGON_TRANSPARENT)) {
if (level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !blockState.is(BlockTags.DRAGON_IMMUNE)) {
@@ -92,7 +92,7 @@
} else {
flag = true;
}
@@ -446,6 +_,58 @@
@@ -447,6 +_,58 @@
}
}
@@ -151,7 +151,7 @@
if (flag1) {
BlockPos blockPos1 = new BlockPos(
floor + this.random.nextInt(floor3 - floor + 1),
@@ -503,7 +_,15 @@
@@ -504,7 +_,15 @@
@Override
public void kill(ServerLevel level) {
@@ -168,7 +168,7 @@
this.gameEvent(GameEvent.ENTITY_DIE);
if (this.dragonFight != null) {
this.dragonFight.updateDragon(this);
@@ -525,18 +_,41 @@
@@ -526,18 +_,41 @@
this.level().addParticle(ParticleTypes.EXPLOSION_EMITTER, this.getX() + f, this.getY() + 2.0 + f1, this.getZ() + f2, 0.0, 0.0, 0.0);
}
@@ -186,7 +186,7 @@
- if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
- ExperienceOrb.award(serverLevel, this.position(), Mth.floor(i * 0.08F));
+ if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp
+ ExperienceOrb.award(serverLevel, this.position(), Mth.floor(i * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.Optionull.map(this.lastHurtByPlayer, lastHurtByPlayer -> lastHurtByPlayer.getEntity(this.level(), Player.class)), this); // Paper
+ ExperienceOrb.awardWithDirection(serverLevel, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.world.entity.EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class), this); // Paper
}
if (this.dragonDeathTime == 1 && !this.isSilent()) {
@@ -213,14 +213,14 @@
}
}
@@ -549,15 +_,15 @@
@@ -550,15 +_,15 @@
}
if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel serverLevel1) {
- if (serverLevel1.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
- ExperienceOrb.award(serverLevel1, this.position(), Mth.floor(i * 0.2F));
+ if (true) { // Paper - SPIGOT-2420: Already checked for the game rule when calculating the xp
+ ExperienceOrb.award(serverLevel1, this.position(), Mth.floor(i * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.Optionull.map(this.lastHurtByPlayer, lastHurtByPlayer -> lastHurtByPlayer.getEntity(this.level(), Player.class)), this); // Paper
+ ExperienceOrb.awardWithDirection(serverLevel1, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.world.entity.EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class), this); // Paper
}
if (this.dragonFight != null) {
@@ -232,23 +232,23 @@
this.gameEvent(GameEvent.ENTITY_DIE);
}
}
@@ -739,6 +_,7 @@
super.addAdditionalSaveData(compound);
compound.putInt("DragonPhase", this.phaseManager.getCurrentPhase().getPhase().getId());
compound.putInt("DragonDeathTime", this.dragonDeathTime);
+ compound.putInt("Bukkit.expToDrop", this.expToDrop); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts
@@ -740,6 +_,7 @@
super.addAdditionalSaveData(output);
output.putInt("DragonPhase", this.phaseManager.getCurrentPhase().getPhase().getId());
output.putInt("DragonDeathTime", this.dragonDeathTime);
+ output.putInt("Bukkit.expToDrop", this.expToDrop); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts
}
@Override
@@ -746,6 +_,7 @@
super.readAdditionalSaveData(compound);
compound.getInt("DragonPhase").ifPresent(integer -> this.phaseManager.setPhase(EnderDragonPhase.getById(integer)));
this.dragonDeathTime = compound.getIntOr("DragonDeathTime", 0);
+ this.expToDrop = compound.getIntOr("Bukkit.expToDrop", 0); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts
@@ -747,6 +_,7 @@
super.readAdditionalSaveData(input);
input.getInt("DragonPhase").ifPresent(integer -> this.phaseManager.setPhase(EnderDragonPhase.getById(integer)));
this.dragonDeathTime = input.getIntOr("DragonDeathTime", 0);
+ this.expToDrop = input.getIntOr("Bukkit.expToDrop", 0); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts
}
@Override
@@ -786,7 +_,7 @@
@@ -787,7 +_,7 @@
EnderDragonPhase<? extends DragonPhaseInstance> phase = currentPhase.getPhase();
Vec3 viewVector;
if (phase == EnderDragonPhase.LANDING || phase == EnderDragonPhase.TAKEOFF) {
@@ -257,7 +257,7 @@
float max = Math.max((float)Math.sqrt(heightmapPos.distToCenterSqr(this.position())) / 4.0F, 1.0F);
float f = 6.0F / max;
float xRot = this.getXRot();
@@ -874,4 +_,19 @@
@@ -875,4 +_,19 @@
protected float sanitizeScale(float scale) {
return 1.0F;
}

View File

@@ -1,7 +1,7 @@
--- a/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
+++ b/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
@@ -83,7 +_,13 @@
this.flame.setParticle(ParticleTypes.DRAGON_BREATH);
this.flame.setCustomParticle(ParticleTypes.DRAGON_BREATH);
this.flame.setPotionDurationScale(0.25F);
this.flame.addEffect(new MobEffectInstance(MobEffects.INSTANT_DAMAGE));
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -70,6 +_,7 @@
@@ -71,6 +_,7 @@
private final int[] nextHeadUpdate = new int[2];
private final int[] idleHeadUpdates = new int[2];
private int destroyBlocksTick;
@@ -8,7 +8,7 @@
public final ServerBossEvent bossEvent = (ServerBossEvent)new ServerBossEvent(
this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS
)
@@ -261,15 +_,40 @@
@@ -262,15 +_,40 @@
int i = this.getInvulnerableTicks() - 1;
this.bossEvent.setProgress(1.0F - i / 220.0F);
if (i <= 0) {
@@ -52,7 +52,7 @@
}
} else {
super.customServerAiStep(level);
@@ -306,6 +_,7 @@
@@ -307,6 +_,7 @@
);
if (!nearbyEntities.isEmpty()) {
LivingEntity livingEntity1 = nearbyEntities.get(this.random.nextInt(nearbyEntities.size()));
@@ -60,7 +60,7 @@
this.setAlternativeTarget(ix, livingEntity1.getId());
}
}
@@ -335,6 +_,11 @@
@@ -336,6 +_,11 @@
)) {
BlockState blockState = level.getBlockState(blockPos);
if (canDestroy(blockState)) {
@@ -72,7 +72,7 @@
flag = level.destroyBlock(blockPos, true, this) || flag;
}
}
@@ -346,7 +_,7 @@
@@ -347,7 +_,7 @@
}
if (this.tickCount % 20 == 0) {
@@ -81,12 +81,12 @@
}
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
@@ -484,16 +_,16 @@
@@ -485,16 +_,16 @@
@Override
protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) {
super.dropCustomDeathLoot(level, damageSource, recentlyHit);
- ItemEntity itemEntity = this.spawnAtLocation(level, Items.NETHER_STAR);
+ ItemEntity itemEntity = this.spawnAtLocation(level, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
+ ItemEntity itemEntity = this.spawnAtLocation(level, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), net.minecraft.world.phys.Vec3.ZERO, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
if (itemEntity != null) {
- itemEntity.setExtendedLifetime();
+ itemEntity.setExtendedLifetime(); // Paper - diff on change
@@ -101,7 +101,7 @@
} else {
this.noActionTime = 0;
}
@@ -548,12 +_,18 @@
@@ -549,12 +_,18 @@
@Override
public boolean canUsePortal(boolean allowPassengers) {

View File

@@ -1,14 +1,13 @@
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -88,9 +_,17 @@
public Rotations rightArmPose = DEFAULT_RIGHT_ARM_POSE;
public Rotations leftLegPose = DEFAULT_LEFT_LEG_POSE;
public Rotations rightLegPose = DEFAULT_RIGHT_LEG_POSE;
@@ -85,9 +_,16 @@
private boolean invisible = false;
public long lastHit;
public int disabledSlots = 0;
+ public boolean canMove = true; // Paper
+ // Paper start - Allow ArmorStands not to tick
+ public boolean canTick = true;
+ public boolean canTickSetByAPI = false;
+ private boolean noTickPoseDirty = false;
+ private boolean noTickEquipmentDirty = false;
+ // Paper end - Allow ArmorStands not to tick
@@ -18,7 +17,7 @@
}
public ArmorStand(Level level, double x, double y, double z) {
@@ -102,6 +_,13 @@
@@ -99,6 +_,13 @@
return createLivingAttributes().add(Attributes.STEP_HEIGHT, 0.0);
}
@@ -32,7 +31,7 @@
@Override
public void refreshDimensions() {
double x = this.getX();
@@ -137,6 +_,14 @@
@@ -134,6 +_,14 @@
return slot != EquipmentSlot.BODY && slot != EquipmentSlot.SADDLE && !this.isDisabled(slot);
}
@@ -45,39 +44,35 @@
+ // Paper - Allow ArmorStands not to tick; Still update equipment
+
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
@@ -150,6 +_,7 @@
protected void addAdditionalSaveData(ValueOutput output) {
super.addAdditionalSaveData(output);
@@ -147,6 +_,7 @@
}
compound.put("Pose", this.writePose());
+ if (this.canTickSetByAPI) compound.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick
output.store("Pose", ArmorStand.ArmorStandPose.CODEC, this.getArmorStandPose());
+ if (this.canTickSetByAPI) output.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick
}
@Override
@@ -163,6 +_,12 @@
this.setMarker(compound.getBooleanOr("Marker", false));
@@ -160,10 +_,16 @@
this.setMarker(input.getBooleanOr("Marker", false));
this.noPhysics = !this.hasPhysics();
this.readPose(compound.getCompoundOrEmpty("Pose"));
input.read("Pose", ArmorStand.ArmorStandPose.CODEC).ifPresent(this::setArmorStandPose);
+ // Paper start - Allow ArmorStands not to tick
+ compound.getBoolean("Paper.CanTickOverride").ifPresent(canTick -> {
+ this.canTick = canTick;
+ if (input.getInt("Paper.CanTickOverride").isPresent()) { // Check if is set
+ this.canTick = input.getBooleanOr("Paper.CanTickOverride", true);
+ this.canTickSetByAPI = true;
+ });
+ }
+ // Paper end - Allow ArmorStands not to tick
}
private void readPose(CompoundTag compound) {
@@ -204,7 +_,7 @@
}
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return false;
}
@@ -214,6 +_,7 @@
@@ -173,6 +_,7 @@
@Override
protected void pushEntities() {
@@ -85,7 +80,7 @@
for (Entity entity : this.level().getEntities(this, this.getBoundingBox(), RIDABLE_MINECARTS)) {
if (this.distanceToSqr(entity) <= 0.2) {
entity.push(this);
@@ -286,7 +_,25 @@
@@ -245,7 +_,25 @@
return false;
} else if (itemBySlot.isEmpty() && (this.disabledSlots & 1 << slot.getFilterBit(16)) != 0) {
return false;
@@ -112,7 +107,7 @@
this.setItemSlot(slot, stack.copyWithCount(1));
return true;
} else if (stack.isEmpty() || stack.getCount() <= 1) {
@@ -299,6 +_,7 @@
@@ -258,6 +_,7 @@
this.setItemSlot(slot, stack.split(1));
return true;
}
@@ -120,7 +115,7 @@
}
@Override
@@ -308,15 +_,32 @@
@@ -267,15 +_,32 @@
} else if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && damageSource.getEntity() instanceof Mob) {
return false;
} else if (damageSource.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
@@ -157,7 +152,7 @@
if (this.isOnFire()) {
this.causeDamage(level, damageSource, 0.15F);
} else {
@@ -325,9 +_,19 @@
@@ -284,9 +_,19 @@
return false;
} else if (damageSource.is(DamageTypeTags.BURNS_ARMOR_STANDS) && this.getHealth() > 0.5F) {
@@ -177,7 +172,7 @@
boolean isCanBreakArmorStand = damageSource.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND);
boolean isAlwaysKillsArmorStands = damageSource.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS);
if (!isCanBreakArmorStand && !isAlwaysKillsArmorStands) {
@@ -337,7 +_,7 @@
@@ -296,7 +_,7 @@
} else if (damageSource.isCreativePlayer()) {
this.playBrokenSound();
this.showBreakingParticles();
@@ -186,7 +181,7 @@
return true;
} else {
long gameTime = level.getGameTime();
@@ -346,9 +_,9 @@
@@ -305,9 +_,9 @@
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
this.lastHit = gameTime;
} else {
@@ -198,7 +193,7 @@
}
return true;
@@ -400,31 +_,42 @@
@@ -359,31 +_,42 @@
float health = this.getHealth();
health -= damageAmount;
if (health <= 0.5F) {
@@ -252,17 +247,14 @@
}
private void playBrokenSound() {
@@ -458,7 +_,28 @@
@@ -431,9 +_,40 @@
return this.isSmall();
}
@Override
public void tick() {
+ // Paper start - Allow ArmorStands not to tick
+ // Paper start - Allow ArmorStands not to tick
+ @Override
+ public void tick() {
+ if (!this.canTick) {
+ if (this.noTickPoseDirty) {
+ this.noTickPoseDirty = false;
+ this.updatePose();
+ }
+
+ if (this.noTickEquipmentDirty) {
+ this.noTickEquipmentDirty = false;
+ this.detectEquipmentUpdates();
@@ -270,27 +262,9 @@
+
+ return;
+ }
+ // Paper end - Allow ArmorStands not to tick
super.tick();
+ // Paper start - Allow ArmorStands not to tick
+ this.updatePose();
+ super.tick();
+ }
+
+ public void updatePose() {
+ // Paper end - Allow ArmorStands not to tick
Rotations rotations = this.entityData.get(DATA_HEAD_POSE);
if (!this.headPose.equals(rotations)) {
this.setHeadPose(rotations);
@@ -506,9 +_,32 @@
return this.isSmall();
}
+ // CraftBukkit start
+ @Override
+ public boolean shouldDropExperience() {
+ return true; // MC-157395, SPIGOT-5193 even small armor stands should drop
+ }
+ // CraftBukkit end
+ // Paper end - Allow ArmorStands not to tick
+
@Override
public void kill(ServerLevel level) {
@@ -315,47 +289,9 @@
this.gameEvent(GameEvent.ENTITY_DIE);
}
@@ -572,31 +_,37 @@
public void setHeadPose(Rotations headPose) {
this.headPose = headPose;
this.entityData.set(DATA_HEAD_POSE, headPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setBodyPose(Rotations bodyPose) {
this.bodyPose = bodyPose;
this.entityData.set(DATA_BODY_POSE, bodyPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftArmPose(Rotations leftArmPose) {
this.leftArmPose = leftArmPose;
this.entityData.set(DATA_LEFT_ARM_POSE, leftArmPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightArmPose(Rotations rightArmPose) {
this.rightArmPose = rightArmPose;
this.entityData.set(DATA_RIGHT_ARM_POSE, rightArmPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftLegPose(Rotations leftLegPose) {
this.leftLegPose = leftLegPose;
this.entityData.set(DATA_LEFT_LEG_POSE, leftLegPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightLegPose(Rotations rightLegPose) {
this.rightLegPose = rightLegPose;
this.entityData.set(DATA_RIGHT_LEG_POSE, rightLegPose);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public Rotations getHeadPose() {
@@ -728,4 +_,13 @@
public boolean canBeSeenByAnyone() {
return !this.isInvisible() && !this.isMarker();
@@ -684,4 +_,13 @@
.apply(instance, ArmorStand.ArmorStandPose::new)
);
}
+
+ // Paper start

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
+++ b/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
@@ -20,7 +_,7 @@
@@ -21,7 +_,7 @@
public abstract class BlockAttachedEntity extends Entity {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -9,7 +9,7 @@
protected BlockPos pos;
protected BlockAttachedEntity(EntityType<? extends BlockAttachedEntity> entityType, Level level) {
@@ -38,10 +_,26 @@
@@ -39,10 +_,26 @@
public void tick() {
if (this.level() instanceof ServerLevel serverLevel) {
this.checkBelowWorld();
@@ -38,7 +38,7 @@
this.dropItem(serverLevel, null);
}
}
@@ -74,6 +_,21 @@
@@ -75,6 +_,21 @@
return false;
} else {
if (!this.isRemoved()) {
@@ -60,7 +60,7 @@
this.kill(level);
this.markHurt();
this.dropItem(level, damageSource.getEntity());
@@ -91,18 +_,36 @@
@@ -93,18 +_,36 @@
@Override
public void move(MoverType type, Vec3 movement) {
if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && movement.lengthSqr() > 0.0) {
@@ -100,12 +100,12 @@
+
+ // CraftBukkit start - selectively save tile position
+ @Override
+ public void addAdditionalSaveData(CompoundTag nbt, boolean includeAll) {
+ protected void addAdditionalSaveData(final net.minecraft.world.level.storage.ValueOutput output, final boolean includeAll) {
+ if (includeAll) {
+ this.addAdditionalSaveData(nbt);
+ this.addAdditionalSaveData(output);
+ }
+ }
+ // CraftBukkit end
@Override
public void addAdditionalSaveData(CompoundTag tag) {
protected void addAdditionalSaveData(ValueOutput output) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/decoration/ItemFrame.java
+++ b/net/minecraft/world/entity/decoration/ItemFrame.java
@@ -56,6 +_,7 @@
@@ -54,6 +_,7 @@
private static final boolean DEFAULT_FIXED = false;
public float dropChance = 1.0F;
public boolean fixed = false;
@@ -8,7 +8,7 @@
public ItemFrame(EntityType<? extends ItemFrame> entityType, Level level) {
super(entityType, level);
@@ -97,6 +_,12 @@
@@ -102,6 +_,12 @@
@Override
protected AABB calculateBoundingBox(BlockPos pos, Direction direction) {
@@ -21,7 +21,7 @@
float f = 0.46875F;
Vec3 vec3 = Vec3.atCenterOf(pos).relative(direction, -0.46875);
Direction.Axis axis = direction.getAxis();
@@ -127,9 +_,9 @@
@@ -132,9 +_,9 @@
}
@Override
@@ -33,7 +33,7 @@
}
}
@@ -158,6 +_,18 @@
@@ -163,6 +_,18 @@
if (this.isInvulnerableToBase(damageSource)) {
return false;
} else if (this.shouldDamageDropItem(damageSource)) {
@@ -52,7 +52,7 @@
this.dropItem(level, damageSource.getEntity(), false);
this.gameEvent(GameEvent.BLOCK_CHANGE, damageSource.getEntity());
this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F);
@@ -243,6 +_,14 @@
@@ -248,6 +_,14 @@
return this.getEntityData().get(DATA_ITEM);
}
@@ -67,7 +67,7 @@
@Nullable
public MapId getFramedMapId(ItemStack stack) {
return stack.get(DataComponents.MAP_ID);
@@ -257,13 +_,19 @@
@@ -262,13 +_,19 @@
}
public void setItem(ItemStack stack, boolean updateNeighbours) {
@@ -88,7 +88,7 @@
this.playSound(this.getAddItemSound(), 1.0F, 1.0F);
}
@@ -289,6 +_,7 @@
@@ -295,6 +_,7 @@
}
private void onItemChanged(ItemStack item) {
@@ -96,7 +96,7 @@
if (!item.isEmpty() && item.getFrame() != this) {
item.setEntityRepresentation(this);
}
@@ -359,7 +_,13 @@
@@ -363,7 +_,13 @@
if (savedData != null && savedData.isTrackedCountOverLimit(256)) {
return InteractionResult.FAIL;
} else {
@@ -111,7 +111,7 @@
this.gameEvent(GameEvent.BLOCK_CHANGE, player);
itemInHand.consume(1, player);
return InteractionResult.SUCCESS;
@@ -368,6 +_,13 @@
@@ -372,6 +_,13 @@
return InteractionResult.PASS;
}
} else {

View File

@@ -1,61 +1,29 @@
--- a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
+++ b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
@@ -81,6 +_,15 @@
@@ -82,7 +_,7 @@
boolean flag = false;
for (Leashable leashable : list) {
if (leashable.getLeashHolder() == player) {
+ // CraftBukkit start
+ if (leashable instanceof Entity leashed) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, this, player, hand).isCancelled()) {
+ ((net.minecraft.server.level.ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(leashed, leashable.getLeashHolder()));
+ flag = true; // Also set true when the event is cancelled otherwise it tries to unleash the entities
+ continue;
+ }
+ }
+ // CraftBukkit end
for (Leashable leashable : Leashable.leashableLeashedTo(player)) {
- if (leashable.canHaveALeashAttachedTo(this)) {
+ if (leashable.canHaveALeashAttachedTo(this) && org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerLeashEntityEvent(leashable, this, player, hand)) { // Paper - leash event
leashable.setLeashedTo(this, true);
flag = true;
}
@@ -88,14 +_,39 @@
@@ -91,7 +_,7 @@
boolean flag1 = false;
if (!flag) {
- this.discard();
- if (player.getAbilities().instabuild) {
+ // CraftBukkit start - Move below
+ // this.discard();
+ boolean die = true;
+ // CraftBukkit end
+ if (true || player.getAbilities().instabuild) { // CraftBukkit - Process for non-creative as well
for (Leashable leashable1 : list) {
if (leashable1.isLeashed() && leashable1.getLeashHolder() == this) {
- leashable1.removeLeash();
+ // CraftBukkit start
+ boolean dropLeash = !player.hasInfiniteMaterials();
+ if (leashable1 instanceof Entity leashed) {
+ // Paper start - Expand EntityUnleashEvent
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(leashed, player, hand, dropLeash);
+ dropLeash = event.isDropLeash();
+ if (event.isCancelled()) {
+ // Paper end - Expand EntityUnleashEvent
+ die = false;
+ continue;
+ }
+ }
+ if (!dropLeash) { // Paper - Expand EntityUnleashEvent
+ leashable1.removeLeash();
+ } else {
+ leashable1.dropLeash();
+ }
+ // CraftBukkit end
flag1 = true;
}
if (!flag && !player.isSecondaryUseActive()) {
for (Leashable leashable1 : Leashable.leashableLeashedTo(this)) {
- if (leashable1.canHaveALeashAttachedTo(player)) {
+ if (leashable1.canHaveALeashAttachedTo(player) && org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerLeashEntityEvent(leashable1, player, player, hand)) { // Paper - leash event
leashable1.setLeashedTo(player, true);
flag1 = true;
}
+ // CraftBukkit start
+ if (die) {
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
+ }
+ // CraftBukkit end
}
}
@@ -111,7 +_,7 @@
@Override
public void notifyLeasheeRemoved(Leashable leashHolder) {
if (Leashable.leashableLeashedTo(this).isEmpty()) {
- this.discard();
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/decoration/Painting.java
+++ b/net/minecraft/world/entity/decoration/Painting.java
@@ -146,21 +_,31 @@
@@ -149,21 +_,31 @@
@Override
protected AABB calculateBoundingBox(BlockPos pos, Direction direction) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/item/FallingBlockEntity.java
+++ b/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -69,6 +_,7 @@
@@ -72,6 +_,7 @@
public CompoundTag blockData;
public boolean forceTickAfterTeleportToDuplicate;
protected static final EntityDataAccessor<BlockPos> DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS);
@@ -8,7 +8,7 @@
public FallingBlockEntity(EntityType<? extends FallingBlockEntity> entityType, Level level) {
super(entityType, level);
@@ -94,6 +_,7 @@
@@ -97,6 +_,7 @@
pos.getZ() + 0.5,
blockState.hasProperty(BlockStateProperties.WATERLOGGED) ? blockState.setValue(BlockStateProperties.WATERLOGGED, false) : blockState
);
@@ -16,7 +16,7 @@
level.setBlock(pos, blockState.getFluidState().createLegacyBlock(), 3);
level.addFreshEntity(fallingBlockEntity);
return fallingBlockEntity;
@@ -144,13 +_,22 @@
@@ -147,13 +_,22 @@
@Override
public void tick() {
if (this.blockState.isAir()) {
@@ -40,7 +40,7 @@
this.handlePortal();
if (this.level() instanceof ServerLevel serverLevel && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) {
BlockPos blockPos = this.blockPosition();
@@ -171,12 +_,12 @@
@@ -174,12 +_,12 @@
}
if (!this.onGround() && !flag1) {
@@ -55,7 +55,7 @@
}
} else {
BlockState blockState = this.level().getBlockState(blockPos);
@@ -194,12 +_,18 @@
@@ -197,12 +_,18 @@
this.blockState = this.blockState.setValue(BlockStateProperties.WATERLOGGED, true);
}
@@ -75,7 +75,7 @@
if (block instanceof Fallable) {
((Fallable)block).onLand(this.level(), blockPos, this.blockState, blockState, this);
}
@@ -220,19 +_,19 @@
@@ -227,19 +_,19 @@
}
}
} else if (this.dropItem && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
@@ -98,26 +98,26 @@
this.callOnBrokenAfterFall(block, blockPos);
}
}
@@ -293,6 +_,7 @@
@@ -299,6 +_,7 @@
}
compound.putBoolean("CancelDrop", this.cancelDrop);
+ if (!this.autoExpire) compound.putBoolean("Paper.AutoExpire", false); // Paper - Expand FallingBlock API
output.putBoolean("CancelDrop", this.cancelDrop);
+ if (!this.autoExpire) output.putBoolean("Paper.AutoExpire", false); // Paper - Expand FallingBlock API
}
@Override
@@ -305,8 +_,9 @@
this.fallDamagePerDistance = compound.getFloatOr("FallHurtAmount", 0.0F);
this.fallDamageMax = compound.getIntOr("FallHurtMax", 40);
this.dropItem = compound.getBooleanOr("DropItem", true);
- this.blockData = compound.getCompound("TileEntityData").map(CompoundTag::copy).orElse(null);
+ this.blockData = compound.getCompound("TileEntityData").map(blockData -> this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock ? null : blockData).map(CompoundTag::copy).orElse(null); // Paper - Filter bad block entity nbt data from falling blocks
this.cancelDrop = compound.getBooleanOr("CancelDrop", false);
+ this.autoExpire = compound.getBooleanOr("Paper.AutoExpire", true); // Paper - Expand FallingBlock API
@@ -310,8 +_,9 @@
this.fallDamagePerDistance = input.getFloatOr("FallHurtAmount", 0.0F);
this.fallDamageMax = input.getIntOr("FallHurtMax", 40);
this.dropItem = input.getBooleanOr("DropItem", true);
- this.blockData = input.read("TileEntityData", CompoundTag.CODEC).orElse(null);
+ this.blockData = input.read("TileEntityData", CompoundTag.CODEC).map(blockData -> this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock ? null : blockData).map(CompoundTag::copy).orElse(null); // Paper - Filter bad block entity nbt data from falling blocks
this.cancelDrop = input.getBooleanOr("CancelDrop", false);
+ this.autoExpire = input.getBooleanOr("Paper.AutoExpire", true); // Paper - Expand FallingBlock API
}
public void setHurtsEntities(float fallDamagePerDistance, int fallDamageMax) {
@@ -363,7 +_,7 @@
@@ -368,7 +_,7 @@
ResourceKey<Level> resourceKey1 = this.level().dimension();
boolean flag = (resourceKey1 == Level.END || resourceKey == Level.END) && resourceKey1 != resourceKey;
Entity entity = super.teleport(teleportTransition);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -56,6 +_,9 @@
@@ -53,6 +_,9 @@
@Nullable
public UUID target;
public final float bobOffs;
@@ -10,7 +10,7 @@
public ItemEntity(EntityType<? extends ItemEntity> entityType, Level level) {
super(entityType, level);
@@ -64,7 +_,12 @@
@@ -61,7 +_,12 @@
}
public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack) {
@@ -24,7 +24,7 @@
}
public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack, double deltaX, double deltaY, double deltaZ) {
@@ -126,7 +_,7 @@
@@ -116,7 +_,7 @@
@Override
public void tick() {
if (this.getItem().isEmpty()) {
@@ -33,7 +33,7 @@
} else {
super.tick();
if (this.pickupDelay > 0 && this.pickupDelay != 32767) {
@@ -154,11 +_,15 @@
@@ -144,11 +_,15 @@
}
}
@@ -51,7 +51,7 @@
f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F;
}
@@ -191,8 +_,14 @@
@@ -181,8 +_,14 @@
}
}
@@ -68,7 +68,7 @@
}
}
}
@@ -217,9 +_,18 @@
@@ -207,9 +_,18 @@
private void mergeWithNeighbours() {
if (this.isMergable()) {
@@ -88,7 +88,7 @@
this.tryToMerge(itemEntity);
if (this.isRemoved()) {
break;
@@ -231,7 +_,7 @@
@@ -221,7 +_,7 @@
private boolean isMergable() {
ItemStack item = this.getItem();
@@ -97,7 +97,7 @@
}
private void tryToMerge(ItemEntity itemEntity) {
@@ -264,11 +_,16 @@
@@ -254,11 +_,16 @@
}
private static void merge(ItemEntity destinationEntity, ItemStack destinationStack, ItemEntity originEntity, ItemStack originStack) {
@@ -115,7 +115,7 @@
}
}
@@ -296,12 +_,17 @@
@@ -286,12 +_,17 @@
} else if (!this.getItem().canBeHurtBy(damageSource)) {
return false;
} else {
@@ -134,25 +134,24 @@
}
return true;
@@ -324,6 +_,11 @@
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
compound.store("Item", ItemStack.CODEC, registryOps, this.getItem());
@@ -313,6 +_,11 @@
if (!this.getItem().isEmpty()) {
output.store("Item", ItemStack.CODEC, this.getItem());
}
+ // Paper start - Friction API
+ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) {
+ compound.putString("Paper.FrictionState", this.frictionState.toString());
+ output.putString("Paper.FrictionState", this.frictionState.toString());
+ }
+ // Paper end - Friction API
}
@Override
@@ -336,8 +_,19 @@
this.cachedThrower = null;
RegistryOps<Tag> registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE);
this.setItem(compound.read("Item", ItemStack.CODEC, registryOps).orElse(ItemStack.EMPTY));
+
@@ -323,8 +_,17 @@
this.target = input.read("Owner", UUIDUtil.CODEC).orElse(null);
this.thrower = EntityReference.read(input, "Thrower");
this.setItem(input.read("Item", ItemStack.CODEC).orElse(ItemStack.EMPTY));
+ // Paper start - Friction API
+ compound.getString("Paper.FrictionState").ifPresent(frictionState -> {
+ input.getString("Paper.FrictionState").ifPresent(frictionState -> {
+ try {
+ this.frictionState = net.kyori.adventure.util.TriState.valueOf(frictionState);
+ } catch (Exception ignored) {
@@ -160,14 +159,13 @@
+ }
+ });
+ // Paper end - Friction API
+
if (this.getItem().isEmpty()) {
- this.discard();
+ this.discard(null); // CraftBukkit - add Bukkit remove cause
}
}
@@ -347,10 +_,73 @@
@@ -334,10 +_,73 @@
ItemStack item = this.getItem();
Item item1 = item.getItem();
int count = item.getCount();
@@ -242,7 +240,7 @@
item.setCount(count);
}
@@ -388,6 +_,7 @@
@@ -375,6 +_,7 @@
public void setItem(ItemStack stack) {
this.getEntityData().set(DATA_ITEM, stack);
@@ -250,7 +248,7 @@
}
@Override
@@ -441,7 +_,7 @@
@@ -427,7 +_,7 @@
public void makeFakeItem() {
this.setNeverPickUp();

View File

@@ -1,8 +1,8 @@
--- a/net/minecraft/world/entity/item/PrimedTnt.java
+++ b/net/minecraft/world/entity/item/PrimedTnt.java
@@ -29,6 +_,12 @@
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.portal.TeleportTransition;
@@ -28,6 +_,12 @@
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
@@ -13,15 +13,15 @@
public class PrimedTnt extends Entity implements TraceableEntity {
private static final EntityDataAccessor<Integer> DATA_FUSE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<BlockState> DATA_BLOCK_STATE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.BLOCK_STATE);
@@ -53,6 +_,7 @@
public LivingEntity owner;
@@ -52,6 +_,7 @@
public EntityReference<LivingEntity> owner;
private boolean usedPortal;
public float explosionPower = 4.0F;
+ public boolean isIncendiary = false; // CraftBukkit
public PrimedTnt(EntityType<? extends PrimedTnt> entityType, Level level) {
super(entityType, level);
@@ -62,7 +_,7 @@
@@ -61,7 +_,7 @@
public PrimedTnt(Level level, double x, double y, double z, @Nullable LivingEntity owner) {
this(EntityType.TNT, level);
this.setPos(x, y, z);
@@ -30,7 +30,7 @@
this.setDeltaMovement(-Math.sin(d) * 0.02, 0.2F, -Math.cos(d) * 0.02);
this.setFuse(80);
this.xo = x;
@@ -94,10 +_,17 @@
@@ -93,10 +_,17 @@
@Override
public void tick() {
@@ -48,7 +48,7 @@
this.setDeltaMovement(this.getDeltaMovement().scale(0.98));
if (this.onGround()) {
this.setDeltaMovement(this.getDeltaMovement().multiply(0.7, -0.5, 0.7));
@@ -106,20 +_,50 @@
@@ -105,20 +_,50 @@
int i = this.getFuse() - 1;
this.setFuse(i);
if (i <= 0) {
@@ -100,7 +100,7 @@
this.level()
.explode(
this,
@@ -128,8 +_,8 @@
@@ -127,8 +_,8 @@
this.getX(),
this.getY(0.0625),
this.getZ(),

View File

@@ -64,22 +64,22 @@
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
@@ -222,11 +_,22 @@
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
protected void readAdditionalSaveData(ValueInput input) {
super.readAdditionalSaveData(input);
this.reassessWeaponGoal();
- }
-
- @Override
- public void onEquipItem(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem) {
- super.onEquipItem(slot, oldItem, newItem);
+ this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API
+ this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API
+ }
+
+ // Paper start - shouldBurnInDay API
+ @Override
+ public void addAdditionalSaveData(final net.minecraft.nbt.CompoundTag nbt) {
+ super.addAdditionalSaveData(nbt);
+ nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ protected void addAdditionalSaveData(final net.minecraft.world.level.storage.ValueOutput output) {
+ super.addAdditionalSaveData(output);
+ output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ }
+ // Paper end - shouldBurnInDay API
+

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Bogged.java
+++ b/net/minecraft/world/entity/monster/Bogged.java
@@ -73,7 +_,19 @@
@@ -74,7 +_,19 @@
ItemStack itemInHand = player.getItemInHand(hand);
if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) {
if (this.level() instanceof ServerLevel serverLevel) {
@@ -21,7 +21,7 @@
this.gameEvent(GameEvent.SHEAR, player);
itemInHand.hurtAndBreak(1, player, getSlotForHand(hand));
}
@@ -126,15 +_,33 @@
@@ -127,15 +_,33 @@
@Override
public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Creeper.java
+++ b/net/minecraft/world/entity/monster/Creeper.java
@@ -53,6 +_,7 @@
@@ -54,6 +_,7 @@
public int maxSwell = 30;
public int explosionRadius = 3;
private int droppedSkulls;
@@ -8,16 +8,16 @@
public Creeper(EntityType<? extends Creeper> entityType, Level level) {
super(entityType, level);
@@ -116,7 +_,7 @@
this.maxSwell = compound.getShortOr("Fuse", (short)30);
this.explosionRadius = compound.getByteOr("ExplosionRadius", (byte)3);
if (compound.getBooleanOr("ignited", false)) {
@@ -117,7 +_,7 @@
this.maxSwell = input.getShortOr("Fuse", (short)30);
this.explosionRadius = input.getByteOr("ExplosionRadius", (byte)3);
if (input.getBooleanOr("ignited", false)) {
- this.ignite();
+ this.entityData.set(DATA_IS_IGNITED, true); // Paper - set directly to avoid firing event
}
}
@@ -149,10 +_,11 @@
@@ -150,10 +_,11 @@
}
@Override
@@ -31,7 +31,7 @@
}
@Override
@@ -199,9 +_,20 @@
@@ -200,9 +_,20 @@
@Override
public void thunderHit(ServerLevel level, LightningBolt lightning) {
super.thunderHit(level, lightning);
@@ -52,7 +52,7 @@
@Override
protected InteractionResult mobInteract(Player player, InteractionHand hand) {
ItemStack itemInHand = player.getItemInHand(hand);
@@ -210,8 +_,9 @@
@@ -211,8 +_,9 @@
this.level()
.playSound(player, this.getX(), this.getY(), this.getZ(), soundEvent, this.getSoundSource(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F);
if (!this.level().isClientSide) {
@@ -63,7 +63,7 @@
itemInHand.shrink(1);
} else {
itemInHand.hurtAndBreak(1, player, getSlotForHand(hand));
@@ -227,18 +_,29 @@
@@ -228,18 +_,29 @@
public void explodeCreeper() {
if (this.level() instanceof ServerLevel serverLevel) {
float f = this.isPowered() ? 2.0F : 1.0F;
@@ -96,7 +96,7 @@
areaEffectCloud.setRadius(2.5F);
areaEffectCloud.setRadiusOnUse(-0.5F);
areaEffectCloud.setWaitTime(10);
@@ -250,16 +_,27 @@
@@ -251,16 +_,27 @@
areaEffectCloud.addEffect(new MobEffectInstance(mobEffectInstance));
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Drowned.java
+++ b/net/minecraft/world/entity/monster/Drowned.java
@@ -85,7 +_,7 @@
@@ -86,7 +_,7 @@
this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> this.okTarget(entity)));

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/EnderMan.java
+++ b/net/minecraft/world/entity/monster/EnderMan.java
@@ -116,9 +_,20 @@
@@ -114,9 +_,20 @@
.add(Attributes.STEP_HEIGHT, 1.0);
}
@@ -23,7 +23,7 @@
AttributeInstance attribute = this.getAttribute(Attributes.MOVEMENT_SPEED);
if (livingEntity == null) {
this.targetChangeTime = 0;
@@ -132,6 +_,7 @@
@@ -130,6 +_,7 @@
attribute.addTransientModifier(SPEED_MODIFIER_ATTACKING);
}
}
@@ -31,7 +31,7 @@
}
@Override
@@ -207,6 +_,15 @@
@@ -203,6 +_,15 @@
}
boolean isBeingStaredBy(Player player) {
@@ -47,7 +47,7 @@
return LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM.test(player) && this.isLookingAtMe(player, 0.025, true, false, new double[]{this.getEyeY()});
}
@@ -246,7 +_,7 @@
@@ -242,7 +_,7 @@
float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue();
if (lightLevelDependentMagicValue > 0.5F
&& level.canSeeSky(this.blockPosition())
@@ -56,7 +56,7 @@
this.setTarget(null);
this.teleport();
}
@@ -359,21 +_,25 @@
@@ -355,21 +_,25 @@
AbstractThrownPotion abstractThrownPotion1 = damageSource.getDirectEntity() instanceof AbstractThrownPotion abstractThrownPotion
? abstractThrownPotion
: null;
@@ -83,7 +83,7 @@
return flag;
}
@@ -398,6 +_,16 @@
@@ -394,6 +_,16 @@
this.entityData.set(DATA_STARED_AT, true);
}
@@ -100,7 +100,7 @@
@Override
public boolean requiresCustomPersistence() {
return super.requiresCustomPersistence() || this.getCarriedBlock() != null;
@@ -457,16 +_,19 @@
@@ -453,16 +_,19 @@
int floor1 = Mth.floor(this.enderman.getY() + random.nextDouble() * 2.0);
int floor2 = Mth.floor(this.enderman.getZ() - 1.0 + random.nextDouble() * 2.0);
BlockPos blockPos = new BlockPos(floor, floor1, floor2);
@@ -121,7 +121,7 @@
}
}
}
@@ -564,7 +_,7 @@
@@ -560,7 +_,7 @@
} else {
if (this.target != null && !this.enderman.isPassenger()) {
if (this.enderman.isBeingStaredBy((Player)this.target)) {
@@ -130,7 +130,7 @@
this.enderman.teleport();
}
@@ -603,15 +_,18 @@
@@ -599,15 +_,18 @@
int floor1 = Mth.floor(this.enderman.getY() + random.nextDouble() * 3.0);
int floor2 = Mth.floor(this.enderman.getZ() - 2.0 + random.nextDouble() * 4.0);
BlockPos blockPos = new BlockPos(floor, floor1, floor2);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Endermite.java
+++ b/net/minecraft/world/entity/monster/Endermite.java
@@ -122,7 +_,7 @@
@@ -123,7 +_,7 @@
}
if (this.life >= 2400) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Evoker.java
+++ b/net/minecraft/world/entity/monster/Evoker.java
@@ -264,7 +_,7 @@
@@ -247,7 +_,7 @@
serverLevel.getScoreboard().addPlayerToTeam(vex.getScoreboardName(), team);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Ghast.java
+++ b/net/minecraft/world/entity/monster/Ghast.java
@@ -64,6 +_,12 @@
@@ -73,6 +_,12 @@
return this.explosionPower;
}
@@ -13,7 +13,7 @@
@Override
protected boolean shouldDespawnInPeaceful() {
return true;
@@ -276,6 +_,7 @@
@@ -372,6 +_,7 @@
}
LargeFireball largeFireball = new LargeFireball(level, this.ghast, vec3.normalize(), this.ghast.getExplosionPower());

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -48,6 +_,11 @@
@@ -49,6 +_,11 @@
@Nullable
public BlockPos anchorPoint;
Phantom.AttackPhase attackPhase = Phantom.AttackPhase.CIRCLE;
@@ -12,7 +12,7 @@
public Phantom(EntityType<? extends Phantom> entityType, Level level) {
super(entityType, level);
@@ -142,7 +_,7 @@
@@ -143,7 +_,7 @@
@Override
public void aiStep() {
@@ -21,29 +21,29 @@
this.igniteForSeconds(8.0F);
}
@@ -163,6 +_,10 @@
super.readAdditionalSaveData(compound);
this.anchorPoint = compound.read("anchor_pos", BlockPos.CODEC).orElse(null);
this.setPhantomSize(compound.getIntOr("size", 0));
@@ -178,6 +_,10 @@
super.readAdditionalSaveData(input);
this.anchorPoint = input.read("anchor_pos", BlockPos.CODEC).orElse(null);
this.setPhantomSize(input.getIntOr("size", 0));
+ // Paper start
+ this.spawningEntity = compound.read("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
+ this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true);
+ this.spawningEntity = input.read("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
+ this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true);
+ // Paper end
}
@Override
@@ -170,6 +_,10 @@
super.addAdditionalSaveData(compound);
compound.storeNullable("anchor_pos", BlockPos.CODEC, this.anchorPoint);
compound.putInt("size", this.getPhantomSize());
@@ -185,6 +_,10 @@
super.addAdditionalSaveData(output);
output.storeNullable("anchor_pos", BlockPos.CODEC, this.anchorPoint);
output.putInt("size", this.getPhantomSize());
+ // Paper start
+ compound.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity);
+ compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ output.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity);
+ output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ // Paper end
}
@Override
@@ -243,7 +_,8 @@
@@ -258,7 +_,8 @@
for (Player player : nearbyPlayers) {
if (Phantom.this.canAttack(serverLevel, player, TargetingConditions.DEFAULT)) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Pillager.java
+++ b/net/minecraft/world/entity/monster/Pillager.java
@@ -214,7 +_,7 @@
@@ -215,7 +_,7 @@
this.onItemPickup(entity);
ItemStack itemStack = this.inventory.addItem(item);
if (itemStack.isEmpty()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Ravager.java
+++ b/net/minecraft/world/entity/monster/Ravager.java
@@ -154,12 +_,19 @@
@@ -155,12 +_,19 @@
BlockState blockState = serverLevel.getBlockState(blockPos);
Block block = blockState.getBlock();
if (block instanceof LeavesBlock) {
@@ -20,7 +20,7 @@
}
}
@@ -260,7 +_,7 @@
@@ -252,7 +_,7 @@
double d = entity.getX() - this.getX();
double d1 = entity.getZ() - this.getZ();
double max = Math.max(d * d + d1 * d1, 0.001);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Shulker.java
+++ b/net/minecraft/world/entity/monster/Shulker.java
@@ -277,7 +_,13 @@
@@ -278,7 +_,13 @@
@Override
public void stopRiding() {
@@ -15,7 +15,7 @@
if (this.level().isClientSide) {
this.clientOldAttachPosition = this.blockPosition();
}
@@ -390,6 +_,14 @@
@@ -391,6 +_,14 @@
&& this.level().getWorldBorder().isWithinBounds(blockPos1)
&& this.level().noCollision(this, new AABB(blockPos1).deflate(1.0E-6))) {
Direction direction = this.findAttachableSurface(blockPos1);
@@ -30,7 +30,7 @@
if (direction != null) {
this.unRide();
this.setAttachFace(direction);
@@ -454,7 +_,12 @@
@@ -455,7 +_,12 @@
if (shulker != null) {
shulker.setVariant(this.getVariant());
shulker.snapTo(vec3);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Skeleton.java
+++ b/net/minecraft/world/entity/monster/Skeleton.java
@@ -93,11 +_,17 @@
@@ -94,11 +_,17 @@
}
protected void doFreezeConversion() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Slime.java
+++ b/net/minecraft/world/entity/monster/Slime.java
@@ -57,6 +_,7 @@
@@ -58,6 +_,7 @@
public float squish;
public float oSquish;
private boolean wasOnGround = false;
@@ -8,23 +8,23 @@
public Slime(EntityType<? extends Slime> entityType, Level level) {
super(entityType, level);
@@ -111,6 +_,7 @@
super.addAdditionalSaveData(compound);
compound.putInt("Size", this.getSize() - 1);
compound.putBoolean("wasOnGround", this.wasOnGround);
+ compound.putBoolean("Paper.canWander", this.canWander); // Paper
@@ -112,6 +_,7 @@
super.addAdditionalSaveData(output);
output.putInt("Size", this.getSize() - 1);
output.putBoolean("wasOnGround", this.wasOnGround);
+ output.putBoolean("Paper.canWander", this.canWander); // Paper
}
@Override
@@ -118,6 +_,7 @@
this.setSize(compound.getIntOr("Size", 0) + 1, false);
super.readAdditionalSaveData(compound);
this.wasOnGround = compound.getBooleanOr("wasOnGround", false);
+ this.canWander = compound.getBooleanOr("Paper.canWander", true); // Paper
@@ -119,6 +_,7 @@
this.setSize(input.getIntOr("Size", 0) + 1, false);
super.readAdditionalSaveData(input);
this.wasOnGround = input.getBooleanOr("wasOnGround", false);
+ this.canWander = input.getBooleanOr("Paper.canWander", true); // Paper
}
public boolean isTiny() {
@@ -197,7 +_,7 @@
@@ -198,7 +_,7 @@
}
@Override
@@ -33,7 +33,7 @@
int size = this.getSize();
if (!this.level().isClientSide && size > 1 && this.isDeadOrDying()) {
float width = this.getDimensions(this.getPose()).width();
@@ -205,18 +_,43 @@
@@ -206,18 +_,43 @@
int i = size / 2;
int i1 = 2 + this.random.nextInt(3);
PlayerTeam team = this.getTeam();
@@ -81,7 +81,7 @@
}
@Override
@@ -282,9 +_,13 @@
@@ -283,9 +_,13 @@
return checkMobSpawnRules(entityType, level, spawnReason, pos, random);
}
@@ -97,7 +97,7 @@
&& random.nextFloat() < 0.5F
&& random.nextFloat() < level.getMoonBrightness()
&& level.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) {
@@ -296,8 +_,11 @@
@@ -297,8 +_,11 @@
}
ChunkPos chunkPos = new ChunkPos(pos);
@@ -111,7 +111,7 @@
return checkMobSpawnRules(entityType, level, spawnReason, pos, random);
}
}
@@ -356,6 +_,16 @@
@@ -357,6 +_,16 @@
return super.getDefaultDimensions(pose).scale(this.getSize());
}
@@ -128,7 +128,7 @@
static class SlimeAttackGoal extends Goal {
private final Slime slime;
private int growTiredTimer;
@@ -368,7 +_,16 @@
@@ -369,7 +_,16 @@
@Override
public boolean canUse() {
LivingEntity target = this.slime.getTarget();
@@ -146,7 +146,7 @@
}
@Override
@@ -380,7 +_,16 @@
@@ -381,7 +_,16 @@
@Override
public boolean canContinueToUse() {
LivingEntity target = this.slime.getTarget();
@@ -164,7 +164,7 @@
}
@Override
@@ -399,6 +_,13 @@
@@ -400,6 +_,13 @@
slimeMoveControl.setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
}
}
@@ -178,7 +178,7 @@
}
static class SlimeFloatGoal extends Goal {
@@ -412,7 +_,7 @@
@@ -413,7 +_,7 @@
@Override
public boolean canUse() {
@@ -187,7 +187,7 @@
}
@Override
@@ -442,7 +_,7 @@
@@ -443,7 +_,7 @@
@Override
public boolean canUse() {
@@ -196,7 +196,7 @@
}
@Override
@@ -520,7 +_,7 @@
@@ -521,7 +_,7 @@
@Override
public boolean canUse() {
@@ -205,7 +205,7 @@
&& (this.slime.onGround() || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION))
&& this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
}
@@ -530,6 +_,11 @@
@@ -531,6 +_,11 @@
if (--this.nextRandomizeTime <= 0) {
this.nextRandomizeTime = this.adjustedTickDelay(40 + this.slime.getRandom().nextInt(60));
this.chosenDegrees = this.slime.getRandom().nextInt(360);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/SpellcasterIllager.java
+++ b/net/minecraft/world/entity/monster/SpellcasterIllager.java
@@ -209,6 +_,11 @@
@@ -210,6 +_,11 @@
public void tick() {
this.attackWarmupDelay--;
if (this.attackWarmupDelay == 0) {

View File

@@ -1,15 +1,15 @@
--- a/net/minecraft/world/entity/monster/Vex.java
+++ b/net/minecraft/world/entity/monster/Vex.java
@@ -286,7 +_,7 @@
@@ -293,7 +_,7 @@
@Override
public void start() {
- Vex.this.setTarget(Vex.this.owner.getTarget());
+ Vex.this.setTarget(Vex.this.owner.getTarget(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET); // CraftBukkit
Mob owner = Vex.this.getOwner();
- Vex.this.setTarget(owner != null ? owner.getTarget() : null);
+ Vex.this.setTarget(owner != null ? owner.getTarget() : null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET); // CraftBukkit
super.start();
}
}
@@ -345,7 +_,10 @@
@@ -352,7 +_,10 @@
for (int i = 0; i < 3; i++) {
BlockPos blockPos = boundOrigin.offset(Vex.this.random.nextInt(15) - 7, Vex.this.random.nextInt(11) - 5, Vex.this.random.nextInt(15) - 7);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Vindicator.java
+++ b/net/minecraft/world/entity/monster/Vindicator.java
@@ -183,7 +_,7 @@
@@ -184,7 +_,7 @@
static class VindicatorBreakDoorGoal extends BreakDoorGoal {
public VindicatorBreakDoorGoal(Mob mob) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -68,9 +_,7 @@
@@ -67,9 +_,7 @@
public class Zombie extends Monster {
private static final ResourceLocation SPEED_MODIFIER_BABY_ID = ResourceLocation.withDefaultNamespace("baby");
@@ -11,7 +11,7 @@
private static final ResourceLocation REINFORCEMENT_CALLER_CHARGE_ID = ResourceLocation.withDefaultNamespace("reinforcement_caller_charge");
private static final AttributeModifier ZOMBIE_REINFORCEMENT_CALLEE_CHARGE = new AttributeModifier(
ResourceLocation.withDefaultNamespace("reinforcement_callee_charge"), -0.05F, AttributeModifier.Operation.ADD_VALUE
@@ -91,13 +_,15 @@
@@ -90,13 +_,15 @@
private static final boolean DEFAULT_BABY = false;
private static final boolean DEFAULT_CAN_BREAK_DOORS = false;
private static final int DEFAULT_IN_WATER_TIME = 0;
@@ -28,7 +28,7 @@
}
public Zombie(Level level) {
@@ -106,7 +_,7 @@
@@ -105,7 +_,7 @@
@Override
protected void registerGoals() {
@@ -37,7 +37,7 @@
this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F));
this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
this.addBehaviourGoals();
@@ -118,7 +_,7 @@
@@ -117,7 +_,7 @@
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers(ZombifiedPiglin.class));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
@@ -46,7 +46,7 @@
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
}
@@ -172,11 +_,16 @@
@@ -171,11 +_,16 @@
@Override
protected int getBaseExperienceReward(ServerLevel level) {
@@ -64,7 +64,7 @@
}
@Override
@@ -184,9 +_,9 @@
@@ -183,9 +_,9 @@
this.getEntityData().set(DATA_BABY_ID, childZombie);
if (this.level() != null && !this.level().isClientSide) {
AttributeInstance attribute = this.getAttribute(Attributes.MOVEMENT_SPEED);
@@ -76,7 +76,7 @@
}
}
}
@@ -255,6 +_,13 @@
@@ -254,6 +_,13 @@
super.aiStep();
}
@@ -90,7 +90,7 @@
public void startUnderWaterConversion(int conversionTime) {
this.conversionTime = conversionTime;
this.getEntityData().set(DATA_DROWNED_CONVERSION_ID, true);
@@ -268,31 +_,50 @@
@@ -267,31 +_,50 @@
}
protected void convertToZombieType(EntityType<? extends Zombie> entityType) {
@@ -150,7 +150,7 @@
@Override
public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
@@ -325,13 +_,13 @@
@@ -324,13 +_,13 @@
if (SpawnPlacements.isSpawnPositionOk(type, level, blockPos)
&& SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.REINFORCEMENT, blockPos, level.random)) {
zombie.setPos(i1, i2, i3);
@@ -167,7 +167,7 @@
AttributeInstance attribute = this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE);
AttributeModifier modifier = attribute.getModifier(REINFORCEMENT_CALLER_CHARGE_ID);
double d = modifier != null ? modifier.amount() : 0.0;
@@ -356,7 +_,12 @@
@@ -355,7 +_,12 @@
if (flag) {
float effectiveDifficulty = this.level().getCurrentDifficultyAt(this.blockPosition()).getEffectiveDifficulty();
if (this.getMainHandItem().isEmpty() && this.isOnFire() && this.random.nextFloat() < effectiveDifficulty * 0.3F) {
@@ -181,19 +181,19 @@
}
}
@@ -416,6 +_,7 @@
compound.putBoolean("CanBreakDoors", this.canBreakDoors());
compound.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
compound.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
+ compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
@@ -415,6 +_,7 @@
output.putBoolean("CanBreakDoors", this.canBreakDoors());
output.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
output.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
+ output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
}
@Override
@@ -430,13 +_,15 @@
@@ -429,13 +_,15 @@
} else {
this.getEntityData().set(DATA_DROWNED_CONVERSION_ID, false);
}
+ this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API
+ this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API
}
@Override
@@ -207,7 +207,7 @@
return flag;
}
@@ -472,7 +_,7 @@
@@ -471,7 +_,7 @@
spawnGroupData = super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData);
float specialMultiplier = difficulty.getSpecialMultiplier();
if (spawnReason != EntitySpawnReason.CONVERSION) {
@@ -216,7 +216,7 @@
}
if (spawnGroupData == null) {
@@ -499,7 +_,7 @@
@@ -498,7 +_,7 @@
chicken1.finalizeSpawn(level, difficulty, EntitySpawnReason.JOCKEY, null);
chicken1.setChickenJockey(true);
this.startRiding(chicken1);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -160,12 +_,20 @@
@@ -159,12 +_,20 @@
}
public void startConverting(@Nullable UUID conversionStarter, int villagerConversionTime) {
@@ -24,7 +24,7 @@
}
@Override
@@ -190,7 +_,7 @@
@@ -189,7 +_,7 @@
}
private void finishConversion(ServerLevel level) {
@@ -32,21 +32,21 @@
+ Villager converted = this.convertTo( // CraftBukkit
EntityType.VILLAGER,
ConversionParams.single(this, false, false),
villager -> {
@@ -214,19 +_,24 @@
villager.finalizeSpawn(level, level.getCurrentDifficultyAt(villager.blockPosition()), EntitySpawnReason.CONVERSION, null);
villager.refreshBrain(level);
mob -> {
@@ -213,19 +_,24 @@
mob.finalizeSpawn(level, level.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.CONVERSION, null);
mob.refreshBrain(level);
if (this.conversionStarter != null) {
- Player playerByUuid = level.getPlayerByUUID(this.conversionStarter);
+ Player playerByUuid = level.getGlobalPlayerByUUID(this.conversionStarter); // Paper - check global player list where appropriate
if (playerByUuid instanceof ServerPlayer) {
CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer)playerByUuid, this, villager);
level.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager);
CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer)playerByUuid, this, mob);
level.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, mob);
}
}
- villager.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0));
+ villager.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit
- mob.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0));
+ mob.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit
if (!this.isSilent()) {
level.levelEvent(null, 1027, this.blockPosition(), 0);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/ZombifiedPiglin.java
+++ b/net/minecraft/world/entity/monster/ZombifiedPiglin.java
@@ -56,6 +_,7 @@
@@ -57,6 +_,7 @@
private static final int ALERT_RANGE_Y = 10;
private static final UniformInt ALERT_INTERVAL = TimeUtil.rangeOfSeconds(4, 6);
private int ticksUntilNextAlert;
@@ -8,7 +8,7 @@
public ZombifiedPiglin(EntityType<? extends ZombifiedPiglin> entityType, Level level) {
super(entityType, level);
@@ -71,7 +_,7 @@
@@ -72,7 +_,7 @@
protected void addBehaviourGoals() {
this.goalSelector.addGoal(2, new ZombieAttackGoal(this, 1.0, false));
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0));
@@ -17,7 +17,7 @@
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt));
this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true));
}
@@ -144,7 +_,7 @@
@@ -145,7 +_,7 @@
.filter(zombifiedPiglin -> zombifiedPiglin != this)
.filter(zombifiedPiglin -> zombifiedPiglin.getTarget() == null)
.filter(zombifiedPiglin -> !zombifiedPiglin.isAlliedTo(this.getTarget()))
@@ -26,7 +26,7 @@
}
private void playAngerSound() {
@@ -152,18 +_,27 @@
@@ -153,18 +_,27 @@
}
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/creaking/Creaking.java
+++ b/net/minecraft/world/entity/monster/creaking/Creaking.java
@@ -191,9 +_,9 @@
@@ -192,9 +_,9 @@
}
@Override
@@ -12,7 +12,7 @@
}
}
@@ -318,7 +_,7 @@
@@ -319,7 +_,7 @@
}
this.makeSound(this.getDeathSound());
@@ -21,7 +21,7 @@
}
public void creakingDeathEffects(DamageSource damageSource) {
@@ -471,9 +_,9 @@
@@ -472,9 +_,9 @@
}
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java
@@ -265,7 +_,12 @@
@@ -266,7 +_,12 @@
}
private void finishConversion() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
+++ b/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
@@ -102,9 +_,14 @@
@@ -101,9 +_,14 @@
}
protected void finishConversion(ServerLevel serverLevel) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -124,6 +_,12 @@
@@ -125,6 +_,12 @@
MemoryModuleType.ATE_RECENTLY,
MemoryModuleType.NEAREST_REPELLENT
);
@@ -13,29 +13,29 @@
public Piglin(EntityType<? extends AbstractPiglin> entityType, Level level) {
super(entityType, level);
@@ -136,6 +_,10 @@
compound.putBoolean("IsBaby", this.isBaby());
compound.putBoolean("CannotHunt", this.cannotHunt);
this.writeInventoryToTag(compound, this.registryAccess());
@@ -137,6 +_,10 @@
output.putBoolean("IsBaby", this.isBaby());
output.putBoolean("CannotHunt", this.cannotHunt);
this.writeInventoryToTag(output);
+ // CraftBukkit start
+ compound.store("Bukkit.BarterList", ITEM_SET_CODEC, this.allowedBarterItems);
+ compound.store("Bukkit.InterestList", ITEM_SET_CODEC, this.interestItems);
+ output.store("Bukkit.BarterList", ITEM_SET_CODEC, this.allowedBarterItems);
+ output.store("Bukkit.InterestList", ITEM_SET_CODEC, this.interestItems);
+ // CraftBukkit end
}
@Override
@@ -144,6 +_,10 @@
this.setBaby(compound.getBooleanOr("IsBaby", false));
this.setCannotHunt(compound.getBooleanOr("CannotHunt", false));
this.readInventoryFromTag(compound, this.registryAccess());
@@ -145,6 +_,10 @@
this.setBaby(input.getBooleanOr("IsBaby", false));
this.setCannotHunt(input.getBooleanOr("CannotHunt", false));
this.readInventoryFromTag(input);
+ // CraftBukkit start
+ this.allowedBarterItems = compound.read("Bukkit.BarterList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new);
+ this.interestItems = compound.read("Bukkit.InterestList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new);
+ this.allowedBarterItems = input.read("Bukkit.BarterList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new);
+ this.interestItems = input.read("Bukkit.InterestList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new);
+ // CraftBukkit end
}
@VisibleForDebug
@@ -321,7 +_,9 @@
@@ -322,7 +_,9 @@
@Override
protected void finishConversion(ServerLevel serverLevel) {
PiglinAi.cancelAdmiring(serverLevel, this);
@@ -45,7 +45,7 @@
super.finishConversion(serverLevel);
}
@@ -397,7 +_,7 @@
@@ -398,7 +_,7 @@
}
protected void holdInOffHand(ItemStack stack) {
@@ -54,7 +54,7 @@
this.setItemSlot(EquipmentSlot.OFFHAND, stack);
this.setGuaranteedDrop(EquipmentSlot.OFFHAND);
} else {
@@ -422,15 +_,15 @@
@@ -423,15 +_,15 @@
return false;
} else {
TagKey<Item> preferredWeaponType = this.getPreferredWeaponType();

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/net/minecraft/world/entity/monster/warden/Warden.java
@@ -404,7 +_,7 @@
@@ -402,7 +_,7 @@
public static void applyDarknessAround(ServerLevel level, Vec3 pos, @Nullable Entity source, int radius) {
MobEffectInstance mobEffectInstance = new MobEffectInstance(MobEffects.DARKNESS, 260, 0, false, false);
@@ -9,7 +9,7 @@
}
@Override
@@ -450,6 +_,15 @@
@@ -446,6 +_,15 @@
@VisibleForTesting
public void increaseAngerAt(@Nullable Entity entity, int offset, boolean playListeningSound) {
if (!this.isNoAi() && this.canTargetEntity(entity)) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/npc/Villager.java
+++ b/net/minecraft/world/entity/npc/Villager.java
@@ -286,7 +_,7 @@
@@ -287,7 +_,7 @@
this.increaseProfessionLevelOnUpdate = false;
}
@@ -9,7 +9,7 @@
}
}
@@ -395,7 +_,12 @@
@@ -396,7 +_,12 @@
this.updateDemand();
for (MerchantOffer merchantOffer : this.getOffers()) {
@@ -23,7 +23,7 @@
}
this.resendOffersToTradingPlayer();
@@ -456,7 +_,12 @@
@@ -457,7 +_,12 @@
int i = 2 - this.numberOfRestocksToday;
if (i > 0) {
for (MerchantOffer merchantOffer : this.getOffers()) {
@@ -37,7 +37,7 @@
}
}
@@ -477,6 +_,7 @@
@@ -478,6 +_,7 @@
int playerReputation = this.getPlayerReputation(player);
if (playerReputation != 0) {
for (MerchantOffer merchantOffer : this.getOffers()) {
@@ -45,7 +45,7 @@
merchantOffer.addToSpecialPriceDiff(-Mth.floor(playerReputation * merchantOffer.getPriceMultiplier()));
}
}
@@ -486,6 +_,7 @@
@@ -487,6 +_,7 @@
int amplifier = effect.getAmplifier();
for (MerchantOffer merchantOffer1 : this.getOffers()) {
@@ -53,7 +53,7 @@
double d = 0.3 + 0.0625 * amplifier;
int i = (int)Math.floor(d * merchantOffer1.getBaseCostA().getCount());
merchantOffer1.addToSpecialPriceDiff(-Math.max(i, 1));
@@ -594,7 +_,7 @@
@@ -595,7 +_,7 @@
}
if (offer.shouldRewardExp()) {
@@ -62,7 +62,7 @@
}
}
@@ -612,7 +_,7 @@
@@ -613,7 +_,7 @@
@Override
public void die(DamageSource cause) {
@@ -71,7 +71,7 @@
Entity entity = cause.getEntity();
if (entity != null) {
this.tellWitnessesThatIWasMurdered(entity);
@@ -780,12 +_,19 @@
@@ -781,12 +_,19 @@
@Override
public void thunderHit(ServerLevel level, LightningBolt lightning) {
if (level.getDifficulty() != Difficulty.PEACEFUL) {
@@ -93,7 +93,7 @@
if (witch == null) {
super.thunderHit(level, lightning);
}
@@ -825,6 +_,12 @@
@@ -826,6 +_,12 @@
@Override
protected void updateTrades() {
@@ -106,7 +106,7 @@
VillagerData villagerData = this.getVillagerData();
ResourceKey<VillagerProfession> resourceKey = villagerData.profession().unwrapKey().orElse(null);
if (resourceKey != null) {
@@ -840,10 +_,12 @@
@@ -841,10 +_,12 @@
VillagerTrades.ItemListing[] itemListings = map1.get(villagerData.level());
if (itemListings != null) {
MerchantOffers offers = this.getOffers();
@@ -120,7 +120,7 @@
}
public void gossip(ServerLevel serverLevel, Villager target, long gameTime) {
@@ -872,7 +_,7 @@
@@ -873,7 +_,7 @@
List<Villager> entitiesOfClass = serverLevel.getEntitiesOfClass(Villager.class, aabb);
List<Villager> list = entitiesOfClass.stream().filter(villager -> villager.wantsToSpawnGolem(gameTime)).limit(5L).toList();
if (list.size() >= minVillagerAmount) {
@@ -129,7 +129,7 @@
EntityType.IRON_GOLEM,
EntitySpawnReason.MOB_SUMMONED,
serverLevel,
@@ -881,9 +_,11 @@
@@ -882,9 +_,11 @@
8,
6,
SpawnUtil.Strategy.LEGACY_IRON_GOLEM,

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/npc/WanderingTrader.java
+++ b/net/minecraft/world/entity/npc/WanderingTrader.java
@@ -45,11 +_,15 @@
@@ -46,11 +_,15 @@
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.tuple.Pair;
@@ -17,7 +17,7 @@
public WanderingTrader(EntityType<? extends WanderingTrader> entityType, Level level) {
super(entityType, level);
@@ -65,7 +_,7 @@
@@ -66,7 +_,7 @@
this,
PotionContents.createItemStack(Items.POTION, Potions.INVISIBILITY),
SoundEvents.WANDERING_TRADER_DISAPPEARED,
@@ -26,7 +26,7 @@
)
);
this.goalSelector
@@ -75,7 +_,7 @@
@@ -76,7 +_,7 @@
this,
new ItemStack(Items.MILK_BUCKET),
SoundEvents.WANDERING_TRADER_REAPPEARED,
@@ -35,7 +35,7 @@
)
);
this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this));
@@ -163,7 +_,7 @@
@@ -164,7 +_,7 @@
protected void rewardTradeXp(MerchantOffer offer) {
if (offer.shouldRewardExp()) {
int i = 3 + this.random.nextInt(4);
@@ -44,7 +44,7 @@
}
}
@@ -215,7 +_,7 @@
@@ -216,7 +_,7 @@
private void maybeDespawn() {
if (this.despawnDelay > 0 && !this.isTrading() && --this.despawnDelay == 0) {

View File

@@ -81,7 +81,7 @@
- wanderingTrader.setDespawnDelay(48000);
+ // wanderingTrader.setDespawnDelay(48000); // Paper - moved above, modifiable by plugins on CreatureSpawnEvent
wanderingTrader.setWanderTarget(blockPos1);
wanderingTrader.restrictTo(blockPos1, 16);
wanderingTrader.setHomeTo(blockPos1, 16);
return true;
@@ -112,7 +_,7 @@
private void tryToSpawnLlamaFor(ServerLevel serverLevel, WanderingTrader trader, int maxDistance) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/player/Inventory.java
+++ b/net/minecraft/world/entity/player/Inventory.java
@@ -49,6 +_,70 @@
@@ -56,6 +_,80 @@
public final Player player;
public final EntityEquipment equipment;
private int timesChanged;
@@ -24,9 +24,19 @@
+ }
+
+ public java.util.List<ItemStack> getArmorContents() {
+ java.util.List<ItemStack> items = new java.util.ArrayList<>(4);
+ for (EquipmentSlot equipmentSlot : EQUIPMENT_SLOTS_SORTED_BY_INDEX) {
+ if (equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
+ items.add(this.equipment.get(equipmentSlot));
+ }
+ }
+ return items;
+ }
+
+ public java.util.List<ItemStack> getExtraContent() {
+ java.util.List<ItemStack> items = new java.util.ArrayList<>();
+ for (EquipmentSlot equipmentSlot : EQUIPMENT_SLOTS_SORTED_BY_INDEX) {
+ if (equipmentSlot.isArmor()) {
+ if (equipmentSlot.getType() != EquipmentSlot.Type.HUMANOID_ARMOR) { // Non humanoid armor is considered extra
+ items.add(this.equipment.get(equipmentSlot));
+ }
+ }
@@ -71,7 +81,7 @@
public Inventory(Player player, EntityEquipment equipment) {
this.player = player;
@@ -85,10 +_,39 @@
@@ -92,10 +_,39 @@
private boolean hasRemainingSpaceForItem(ItemStack destination, ItemStack origin) {
return !destination.isEmpty()
@@ -114,7 +124,7 @@
public int getFreeSlot() {
for (int i = 0; i < this.items.size(); i++) {
@@ -100,8 +_,10 @@
@@ -107,8 +_,10 @@
return -1;
}
@@ -127,7 +137,7 @@
if (!this.items.get(this.selected).isEmpty()) {
int freeSlot = this.getFreeSlot();
if (freeSlot != -1) {
@@ -112,8 +_,10 @@
@@ -119,8 +_,10 @@
this.items.set(this.selected, stack);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -169,7 +_,7 @@
@@ -178,7 +_,7 @@
private static final int DEFAULT_CURRENT_IMPULSE_CONTEXT_RESET_GRACE_TIME = 0;
private long timeEntitySatOnShoulder;
final Inventory inventory;
@@ -9,7 +9,7 @@
public final InventoryMenu inventoryMenu;
public AbstractContainerMenu containerMenu;
protected FoodData foodData = new FoodData();
@@ -208,6 +_,18 @@
@@ -217,6 +_,18 @@
public Entity currentExplosionCause;
private boolean ignoreFallDamageFromCurrentImpulse = false;
private int currentImpulseContextResetGraceTime = 0;
@@ -26,9 +26,9 @@
+ }
+ // CraftBukkit end
public Player(Level level, BlockPos pos, float yRot, GameProfile gameProfile) {
public Player(Level level, GameProfile gameProfile) {
super(EntityType.PLAYER, level);
@@ -276,6 +_,13 @@
@@ -286,6 +_,13 @@
if (this.isSleeping()) {
this.sleepCounter++;
@@ -42,7 +42,7 @@
if (this.sleepCounter > 100) {
this.sleepCounter = 100;
}
@@ -293,7 +_,7 @@
@@ -303,7 +_,7 @@
this.updateIsUnderwater();
super.tick();
if (!this.level().isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) {
@@ -51,7 +51,7 @@
this.containerMenu = this.inventoryMenu;
}
@@ -380,7 +_,7 @@
@@ -390,7 +_,7 @@
}
private void turtleHelmetTick() {
@@ -60,7 +60,7 @@
}
private boolean isEquipped(Item item) {
@@ -527,6 +_,18 @@
@@ -537,6 +_,18 @@
}
}
@@ -79,7 +79,7 @@
public void closeContainer() {
this.containerMenu = this.inventoryMenu;
}
@@ -538,8 +_,14 @@
@@ -548,8 +_,14 @@
public void rideTick() {
if (!this.level().isClientSide && this.wantsToStopRiding() && this.isPassenger()) {
this.stopRiding();
@@ -96,7 +96,7 @@
super.rideTick();
this.oBob = this.bob;
this.bob = 0.0F;
@@ -598,6 +_,7 @@
@@ -608,6 +_,7 @@
this.playShoulderEntityAmbientSound(this.getShoulderEntityLeft());
this.playShoulderEntityAmbientSound(this.getShoulderEntityRight());
if (!this.level().isClientSide && (this.fallDistance > 0.5 || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) {
@@ -104,7 +104,7 @@
this.removeEntitiesOnShoulder();
}
}
@@ -841,10 +_,10 @@
@@ -850,10 +_,10 @@
if (this.isDeadOrDying()) {
return false;
} else {
@@ -117,7 +117,7 @@
}
if (level.getDifficulty() == Difficulty.EASY) {
@@ -856,7 +_,14 @@
@@ -865,7 +_,14 @@
}
}
@@ -133,7 +133,7 @@
}
}
}
@@ -868,7 +_,7 @@
@@ -877,7 +_,7 @@
BlocksAttacks blocksAttacks = itemBlockingWith != null ? itemBlockingWith.get(DataComponents.BLOCKS_ATTACKS) : null;
float secondsToDisableBlocking = entity.getSecondsToDisableBlocking();
if (secondsToDisableBlocking > 0.0F && blocksAttacks != null) {
@@ -142,7 +142,7 @@
}
}
@@ -878,9 +_,29 @@
@@ -887,9 +_,29 @@
}
public boolean canHarmPlayer(Player other) {
@@ -175,7 +175,7 @@
}
@Override
@@ -894,7 +_,12 @@
@@ -903,7 +_,12 @@
}
@Override
@@ -189,7 +189,7 @@
if (!this.isInvulnerableTo(level, damageSource)) {
amount = this.getDamageAfterArmorAbsorb(damageSource, amount);
amount = this.getDamageAfterMagicAbsorb(damageSource, amount);
@@ -906,7 +_,7 @@
@@ -915,7 +_,7 @@
}
if (var8 != 0.0F) {
@@ -198,7 +198,7 @@
this.getCombatTracker().recordDamage(damageSource, var8);
this.setHealth(this.getHealth() - var8);
if (var8 < 3.4028235E37F) {
@@ -916,6 +_,7 @@
@@ -925,6 +_,7 @@
this.gameEvent(GameEvent.ENTITY_DAMAGE);
}
}
@@ -206,7 +206,7 @@
}
public boolean isTextFilteringEnabled() {
@@ -997,13 +_,19 @@
@@ -1009,13 +_,19 @@
@Override
public void removeVehicle() {
@@ -228,7 +228,7 @@
}
@Override
@@ -1082,8 +_,17 @@
@@ -1094,8 +_,17 @@
}
public void attack(Entity target) {
@@ -248,7 +248,7 @@
float f = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE);
ItemStack weaponItem = this.getWeaponItem();
DamageSource damageSource = Optional.ofNullable(weaponItem.getItem().getDamageSource(this)).orElse(this.damageSources().playerAttack(this));
@@ -1091,18 +_,25 @@
@@ -1103,18 +_,25 @@
float attackStrengthScale = this.getAttackStrengthScale(0.5F);
f *= 0.2F + attackStrengthScale * attackStrengthScale * 0.8F;
f1 *= attackStrengthScale;
@@ -281,7 +281,7 @@
flag1 = true;
} else {
flag1 = false;
@@ -1118,7 +_,9 @@
@@ -1130,7 +_,9 @@
&& !this.isPassenger()
&& target instanceof LivingEntity
&& !this.isSprinting();
@@ -291,7 +291,7 @@
f *= 1.5F;
}
@@ -1145,17 +_,23 @@
@@ -1157,17 +_,23 @@
if (target instanceof LivingEntity livingEntity1) {
livingEntity1.knockback(
f4 * 0.5F, Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)), -Mth.cos(this.getYRot() * (float) (Math.PI / 180.0))
@@ -315,7 +315,7 @@
}
if (flag3) {
@@ -1169,42 +_,59 @@
@@ -1181,42 +_,59 @@
&& !(livingEntity2 instanceof ArmorStand armorStand && armorStand.isMarker())
&& this.distanceToSqr(livingEntity2) < 9.0) {
float f6 = this.getEnchantedDamage(livingEntity2, f5, damageSource) * attackStrengthScale;
@@ -386,7 +386,7 @@
);
}
}
@@ -1252,10 +_,11 @@
@@ -1264,10 +_,11 @@
}
}
@@ -401,7 +401,7 @@
}
}
}
@@ -1290,8 +_,8 @@
@@ -1302,8 +_,8 @@
}
@Override
@@ -412,7 +412,7 @@
this.inventoryMenu.removed(this);
if (this.containerMenu != null && this.hasContainerOpen()) {
this.doCloseContainer();
@@ -1355,6 +_,12 @@
@@ -1367,6 +_,12 @@
}
public Either<Player.BedSleepingProblem, Unit> startSleepInBed(BlockPos bedPos) {
@@ -425,7 +425,7 @@
this.startSleeping(bedPos);
this.sleepCounter = 0;
return Either.right(Unit.INSTANCE);
@@ -1466,7 +_,7 @@
@@ -1478,7 +_,7 @@
@Override
public boolean causeFallDamage(double fallDistance, float damageMultiplier, DamageSource damageSource) {
@@ -434,7 +434,7 @@
return false;
} else {
if (fallDistance >= 2.0) {
@@ -1507,7 +_,15 @@
@@ -1519,7 +_,15 @@
}
public void startFallFlying() {
@@ -451,7 +451,7 @@
}
@Override
@@ -1613,15 +_,35 @@
@@ -1625,15 +_,35 @@
public int getXpNeededForNextLevel() {
if (this.experienceLevel >= 30) {
return 112 + (this.experienceLevel - 30) * 9;
@@ -489,7 +489,7 @@
}
}
}
@@ -1715,24 +_,53 @@
@@ -1727,31 +_,60 @@
public void removeEntitiesOnShoulder() {
if (this.timeEntitySatOnShoulder + 20L < this.level().getGameTime()) {
@@ -532,24 +532,32 @@
+ @Nullable
+ private Entity respawnEntityOnShoulder0(CompoundTag entityCompound) { // CraftBukkit void->boolean
+ // Paper end - release entity api - return entity - overload
if (!this.level().isClientSide && !entityCompound.isEmpty()) {
- EntityType.create(entityCompound, this.level(), EntitySpawnReason.LOAD).ifPresent(entity -> {
+ return EntityType.create(entityCompound, this.level(), EntitySpawnReason.LOAD).map((entity) -> { // CraftBukkit
if (entity instanceof TamableAnimal tamableAnimal) {
tamableAnimal.setOwner(this);
}
if (this.level() instanceof ServerLevel serverLevel && !entityCompound.isEmpty()) {
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) {
- EntityType.create(
+ return EntityType.create( // Paper - release entity api
TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), serverLevel.registryAccess(), entityCompound),
serverLevel,
EntitySpawnReason.LOAD
)
- .ifPresent(entity -> {
+ .map(entity -> { // Paper - release entity api
if (entity instanceof TamableAnimal tamableAnimal) {
tamableAnimal.setOwner(this);
}
entity.setPos(this.getX(), this.getY() + 0.7F, this.getZ());
- ((ServerLevel)this.level()).addWithUUID(entity);
- });
+ return ((ServerLevel)this.level()).addWithUUID(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY) ? entity : null; // CraftBukkit // Paper start - release entity api - return entity
+ }).orElse(null); // CraftBukkit // Paper end - release entity api - return entity
entity.setPos(this.getX(), this.getY() + 0.7F, this.getZ());
- serverLevel.addWithUUID(entity);
- });
+ return serverLevel.addWithUUID(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY) ? entity : null; // Paper - spawn reason
+ }).orElse(null); // Paper - release entity api - return entity
}
}
+ return null; // Paper - return null
}
@Nullable
@@ -1926,17 +_,32 @@
@@ -1945,17 +_,32 @@
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
}
@@ -584,7 +592,7 @@
for (int i = 0; i < this.inventory.getContainerSize(); i++) {
ItemStack item = this.inventory.getItem(i);
@@ -1945,6 +_,7 @@
@@ -1964,6 +_,7 @@
}
}
@@ -592,7 +600,7 @@
return this.hasInfiniteMaterials() ? new ItemStack(Items.ARROW) : ItemStack.EMPTY;
}
}
@@ -2027,12 +_,20 @@
@@ -2046,12 +_,20 @@
}
public boolean hasClientLoaded() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -93,7 +_,14 @@
@@ -90,7 +_,14 @@
ItemStack pickupItemStack,
@Nullable ItemStack firedFromWeapon
) {
@@ -15,7 +15,7 @@
this.pickupItemStack = pickupItemStack.copy();
this.applyComponentsFromItemStack(pickupItemStack);
Unit unit = pickupItemStack.remove(DataComponents.INTANGIBLE_PROJECTILE);
@@ -118,8 +_,8 @@
@@ -115,8 +_,8 @@
protected AbstractArrow(
EntityType<? extends AbstractArrow> entityType, LivingEntity owner, Level level, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon
) {
@@ -26,7 +26,7 @@
}
public void setSoundEvent(SoundEvent soundEvent) {
@@ -214,6 +_,7 @@
@@ -211,6 +_,7 @@
this.setSharedFlagOnFire(this.getRemainingFireTicks() > 0);
}
} else {
@@ -34,7 +34,7 @@
this.inGroundTime = 0;
Vec3 vec31 = this.position();
if (this.isInWater()) {
@@ -280,12 +_,12 @@
@@ -277,12 +_,12 @@
if (entityHitResult == null) {
if (this.isAlive() && hitResult.getType() != HitResult.Type.MISS) {
@@ -49,7 +49,7 @@
this.hasImpulse = true;
if (this.getPierceLevel() > 0 && projectileDeflection == ProjectileDeflection.NONE) {
continue;
@@ -318,13 +_,26 @@
@@ -315,13 +_,26 @@
}
}
@@ -77,7 +77,7 @@
}
private void startFalling() {
@@ -357,8 +_,8 @@
@@ -354,8 +_,8 @@
protected void tickDespawn() {
this.life++;
@@ -88,7 +88,7 @@
}
}
@@ -392,9 +_,9 @@
@@ -389,9 +_,9 @@
}
@Override
@@ -100,7 +100,7 @@
}
}
@@ -421,7 +_,7 @@
@@ -418,7 +_,7 @@
}
if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) {
@@ -109,7 +109,7 @@
return;
}
@@ -437,10 +_,16 @@
@@ -434,10 +_,16 @@
livingEntity.setLastHurtMob(entity);
}
@@ -127,7 +127,7 @@
}
if (entity.hurtOrSimulate(damageSource, ceil)) {
@@ -478,7 +_,7 @@
@@ -475,7 +_,7 @@
this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F));
if (this.getPierceLevel() <= 0) {
@@ -136,7 +136,7 @@
}
} else {
entity.setRemainingFireTicks(remainingFireTicks);
@@ -489,7 +_,7 @@
@@ -486,7 +_,7 @@
this.spawnAtLocation(serverLevel2, this.getPickupItem(), 0.1F);
}
@@ -145,7 +145,7 @@
}
}
}
@@ -502,7 +_,7 @@
@@ -499,7 +_,7 @@
double max = Math.max(0.0, 1.0 - entity.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
Vec3 vec3 = this.getDeltaMovement().multiply(1.0, 0.0, 1.0).normalize().scale(d * 0.6 * max);
if (vec3.lengthSqr() > 0.0) {
@@ -154,7 +154,7 @@
}
}
}
@@ -610,7 +_,14 @@
@@ -605,7 +_,14 @@
@Override
public void setOwner(@Nullable Entity entity) {
@@ -169,7 +169,7 @@
this.pickup = switch (entity) {
case Player player when this.pickup == AbstractArrow.Pickup.DISALLOWED -> AbstractArrow.Pickup.ALLOWED;
@@ -622,9 +_,22 @@
@@ -617,9 +_,22 @@
@Override
public void playerTouch(Player entity) {
if (!this.level().isClientSide && (this.isInGround() || this.isNoPhysics()) && this.shakeTime <= 0) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
+++ b/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
@@ -19,6 +_,8 @@
@@ -20,6 +_,8 @@
public static final double INITAL_ACCELERATION_POWER = 0.1;
public static final double DEFLECTION_SCALE = 0.5;
public double accelerationPower = 0.1;
@@ -9,7 +9,7 @@
protected AbstractHurtingProjectile(EntityType<? extends AbstractHurtingProjectile> entityType, Level level) {
super(entityType, level);
@@ -83,12 +_,12 @@
@@ -84,12 +_,12 @@
}
if (hitResultOnMoveVector.getType() != HitResult.Type.MISS && this.isAlive()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/projectile/AbstractThrownPotion.java
+++ b/net/minecraft/world/entity/projectile/AbstractThrownPotion.java
@@ -70,54 +_,95 @@
@@ -67,54 +_,95 @@
@Override
protected void onHit(HitResult result) {
super.onHit(result);
@@ -8,7 +8,7 @@
+ this.splash(result);
+ }
+
+ public void splash(@Nullable HitResult result) {
+ public void splash(HitResult result) {
+ // Paper end - More projectile API
if (this.level() instanceof ServerLevel serverLevel) {
ItemStack item = this.getItem();
@@ -17,10 +17,10 @@
if (potionContents.is(Potions.WATER)) {
- this.onHitAsWater(serverLevel);
- } else if (potionContents.hasEffects()) {
- this.onHitAsPotion(serverLevel, item, result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null);
- this.onHitAsPotion(serverLevel, item, result);
+ showParticles = this.onHitAsWater(serverLevel, result); // Paper - Fix potions splash events
+ } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply
+ showParticles = this.onHitAsPotion(serverLevel, item, result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result); // Paper - pass HitResult
+ showParticles = this.onHitAsPotion(serverLevel, item, result); // Paper - pass HitResult
}
+ if (showParticles) { // Paper - Fix potions splash events
@@ -35,7 +35,7 @@
- private void onHitAsWater(ServerLevel level) {
+ private static final Predicate<LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = AbstractThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
+
+ private boolean onHitAsWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events
+ private boolean onHitAsWater(ServerLevel level, HitResult result) { // Paper - Fix potions splash events
AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0);
- for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, aabb, WATER_SENSITIVE_OR_ON_FIRE)) {
@@ -85,8 +85,8 @@
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
- protected abstract void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity);
+ protected abstract boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable HitResult hitResult); // Paper - Pass HitResult // Paper - Fix potions splash events & More Projectile API
- protected abstract void onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult);
+ protected abstract boolean onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult); // Paper - Fix potions splash events & More Projectile API
private void dowseFire(BlockPos pos) {
BlockState blockState = this.level().getBlockState(pos);

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