From 025651f9db76d478ce7a70991966cf8294d680f4 Mon Sep 17 00:00:00 2001 From: granny Date: Sat, 11 Jan 2025 21:48:31 -0800 Subject: [PATCH] port API for any mob to burn daylight patch --- ...024-API-for-any-mob-to-burn-daylight.patch | 49 --- ...166-API-for-any-mob-to-burn-daylight.patch | 388 ------------------ .../java/org/bukkit/entity/Entity.java.patch | 11 +- .../org/bukkit/entity/LivingEntity.java.patch | 23 ++ .../features/0001-Ridables.patch | 34 +- ...-Configurable-entity-base-attributes.patch | 18 +- ...-Minecart-settings-and-WASD-controls.patch | 4 +- .../0009-Implement-elytra-settings.patch | 8 +- ...mes-from-item-forms-of-entities-to-e.patch | 4 +- ...iefing-bypass-to-everything-affected.patch | 4 +- ...oggle-for-water-sensitive-mob-damage.patch | 16 +- ...019-API-for-any-mob-to-burn-daylight.patch | 344 ++++++++++++++++ ...006-API-for-any-mob-to-burn-daylight.patch | 46 +++ 13 files changed, 468 insertions(+), 481 deletions(-) delete mode 100644 patches/api/0024-API-for-any-mob-to-burn-daylight.patch delete mode 100644 patches/server/0166-API-for-any-mob-to-burn-daylight.patch create mode 100644 purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/LivingEntity.java.patch create mode 100644 purpur-server/minecraft-patches/features/0019-API-for-any-mob-to-burn-daylight.patch create mode 100644 purpur-server/paper-patches/features/0006-API-for-any-mob-to-burn-daylight.patch diff --git a/patches/api/0024-API-for-any-mob-to-burn-daylight.patch b/patches/api/0024-API-for-any-mob-to-burn-daylight.patch deleted file mode 100644 index 2a27a45f4..000000000 --- a/patches/api/0024-API-for-any-mob-to-burn-daylight.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ben Kerllenevich -Date: Tue, 25 May 2021 16:30:30 -0400 -Subject: [PATCH] API for any mob to burn daylight - -Co-authored by: Encode42 - -diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index 5603ecc5d8f6ccf29333e1c47db3af36379a27d6..a4136da96f0759ca137a86f2518af58bccb6b632 100644 ---- a/src/main/java/org/bukkit/entity/Entity.java -+++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1202,5 +1202,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent - * @return True if ridable in water - */ - boolean isRidableInWater(); -+ -+ /** -+ * Checks if the entity is in daylight -+ * -+ * @return True if in daylight -+ */ -+ boolean isInDaylight(); - // Purpur end - } -diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index d21a228bbec0302e75c4db5aa1db54f321143587..a4acc3578e935cd1174474bd1f6ff14db4294fe7 100644 ---- a/src/main/java/org/bukkit/entity/LivingEntity.java -+++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -1468,4 +1468,20 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource - */ - boolean canUseEquipmentSlot(org.bukkit.inventory.@NotNull EquipmentSlot slot); - // Paper end - Expose canUseSlot -+ -+ // Purpur start - API for any mob to burn daylight -+ /** -+ * If this mob will burn in the sunlight -+ * -+ * @return True if mob will burn in sunlight -+ */ -+ boolean shouldBurnInDay(); -+ -+ /** -+ * Set if this mob should burn in the sunlight -+ * -+ * @param shouldBurnInDay True to burn in sunlight -+ */ -+ void setShouldBurnInDay(boolean shouldBurnInDay); -+ // Purpur end - API for any mob to burn daylight - } diff --git a/patches/server/0166-API-for-any-mob-to-burn-daylight.patch b/patches/server/0166-API-for-any-mob-to-burn-daylight.patch deleted file mode 100644 index 07d21912b..000000000 --- a/patches/server/0166-API-for-any-mob-to-burn-daylight.patch +++ /dev/null @@ -1,388 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ben Kerllenevich -Date: Tue, 25 May 2021 16:31:09 -0400 -Subject: [PATCH] API for any mob to burn daylight - -Co-authored by: Encode42 - -diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index a5f4f5d915a864240fd738ca32872829bfcabb41..25a6f228bad7deca7e7301868039d27bf65505c8 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -575,6 +575,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - // Purpur end - Add canSaveToDisk to Entity - -+ // Purpur start - copied from Mob - API for any mob to burn daylight -+ public boolean isSunBurnTick() { -+ if (this.level().isDay() && !this.level().isClientSide) { -+ float f = this.getLightLevelDependentMagicValue(); -+ BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); -+ boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; -+ -+ if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ // Purpur end - copied from Mob - API for any mob to burn daylight -+ - public Entity(EntityType type, Level world) { - this.id = Entity.ENTITY_COUNTER.incrementAndGet(); - this.despawnTime = type == EntityType.PLAYER ? -1 : world.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit -diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 28d3b200ab0c3e8993dfb89a3e48146898c6b85e..ecf8e9742951c144170ce818c14d368011ef99a8 100644 ---- a/net/minecraft/world/entity/LivingEntity.java -+++ b/net/minecraft/world/entity/LivingEntity.java -@@ -295,6 +295,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper - public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event - public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API -+ protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight - - @Override - public float getBukkitYaw() { -@@ -839,6 +840,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> { - nbt.put("Brain", nbtbase); - }); -+ nbt.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight - } - - @Override -@@ -927,6 +929,11 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.brain = this.makeBrain(new Dynamic(NbtOps.INSTANCE, nbt.get("Brain"))); - } - -+ // Purpur start - API for any mob to burn daylight -+ if (nbt.contains("Purpur.ShouldBurnInDay")) { -+ this.shouldBurnInDay = nbt.getBoolean("Purpur.ShouldBurnInDay"); -+ } -+ // Purpur end - API for any mob to burn daylight - } - - // CraftBukkit start -@@ -3788,6 +3795,34 @@ public abstract class LivingEntity extends Entity implements Attackable { - } - } - -+ // Purpur start - copied from Zombie - API for any mob to burn daylight -+ if (this.isAlive()) { -+ boolean flag = this.shouldBurnInDay() && this.isSunBurnTick(); // Paper - shouldBurnInDay API // Purpur - use shouldBurnInDay() method to handle Phantoms properly - API for any mob to burn daylight -+ -+ if (flag) { -+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -+ -+ if (!itemstack.isEmpty()) { -+ if (itemstack.isDamageableItem()) { -+ Item item = itemstack.getItem(); -+ -+ itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2)); -+ if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) { -+ this.onEquippedItemBroken(item, EquipmentSlot.HEAD); -+ this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); -+ } -+ } -+ -+ flag = false; -+ } -+ -+ if (flag) { -+ if (getRider() == null || !this.isControllable()) // Purpur - ignore mobs which are uncontrollable or without rider - API for any mob to burn daylight -+ this.igniteForSeconds(8.0F); -+ } -+ } -+ } -+ // Purpur end - copied from Zombie - API for any mob to burn daylight - } - - public boolean isSensitiveToWater() { -diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 6836f0ddab9d05d146fc03c234b1b58829ec96c0..30213b1917de318989f280aed8735bbe539de100 100644 ---- a/net/minecraft/world/entity/Mob.java -+++ b/net/minecraft/world/entity/Mob.java -@@ -1773,17 +1773,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - protected void playAttackSound() {} - - public boolean isSunBurnTick() { -- if (this.level().isDay() && !this.level().isClientSide) { -- float f = this.getLightLevelDependentMagicValue(); -- BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); -- boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; -- -- if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) { -- return true; -- } -- } -- -- return false; -+ // Purpur - implemented in Entity - API for any mob to burn daylight -+ return super.isSunBurnTick(); - } - - @Override -diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java -index 22b003a23b519bedc50bbcad0706aa2d7d7f4b3a..27bdd3c4e0dc3fbb906689e2390c945bf3d40eea 100644 ---- a/net/minecraft/world/entity/monster/AbstractSkeleton.java -+++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -70,6 +70,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - protected AbstractSkeleton(EntityType type, Level world) { - super(type, world); - this.reassessWeaponGoal(); -+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight - } - - @Override -@@ -100,37 +101,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - abstract SoundEvent getStepSound(); - - // Paper start - shouldBurnInDay API -- private boolean shouldBurnInDay = true; -+ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight - public boolean shouldBurnInDay() { return shouldBurnInDay; } - public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } - // Paper end - shouldBurnInDay API - - @Override - public void aiStep() { -- boolean flag = shouldBurnInDay && this.isSunBurnTick(); // Paper - shouldBurnInDay API -- -- if (flag) { -- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -- -- if (!itemstack.isEmpty()) { -- if (itemstack.isDamageableItem()) { -- Item item = itemstack.getItem(); -- -- itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2)); -- if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) { -- this.onEquippedItemBroken(item, EquipmentSlot.HEAD); -- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); -- } -- } -- -- flag = false; -- } -- -- if (flag) { -- this.igniteForSeconds(8.0F); -- } -- } -- -+ // Purpur - implemented in LivingEntity - API for any mob to burn daylight - super.aiStep(); - } - -@@ -252,7 +230,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - super.readAdditionalSaveData(nbt); - this.reassessWeaponGoal(); - // Paper start - shouldBurnInDay API -- if (nbt.contains("Paper.ShouldBurnInDay")) { -+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight - this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); - } - // Paper end - shouldBurnInDay API -@@ -262,7 +240,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - @Override - public void addAdditionalSaveData(CompoundTag nbt) { - super.addAdditionalSaveData(nbt); -- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); -+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight - } - // Paper end - shouldBurnInDay API - -diff --git a/net/minecraft/world/entity/monster/Husk.java b/net/minecraft/world/entity/monster/Husk.java -index 43887b5aa533d456de5e66da2a3bef82aed58084..9f0b91de19ecdb0f74fe6d93a1e75c27c262ee07 100644 ---- a/net/minecraft/world/entity/monster/Husk.java -+++ b/net/minecraft/world/entity/monster/Husk.java -@@ -21,6 +21,7 @@ public class Husk extends Zombie { - - public Husk(EntityType type, Level world) { - super(type, world); -+ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight - } - - // Purpur start - Ridables -@@ -79,7 +80,7 @@ public class Husk extends Zombie { - - @Override - public boolean isSunSensitive() { -- return false; -+ return this.shouldBurnInDay; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight - } - - @Override -diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index f09830c1c88f4b28f05e1647706a3c96a596ad1e..71bbb3209acc12c9f20b8964770be8666a7e72f8 100644 ---- a/net/minecraft/world/entity/monster/Phantom.java -+++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -60,6 +60,7 @@ public class Phantom extends FlyingMob implements Enemy { - this.xpReward = 5; - this.moveControl = new Phantom.PhantomMoveControl(this); - this.lookControl = new Phantom.PhantomLookControl(this); -+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight - } - - // Purpur start - Ridables -@@ -251,6 +252,7 @@ public class Phantom extends FlyingMob implements Enemy { - - @Override - public void aiStep() { -+ // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight - // Purpur start - Phantoms burn in light - boolean burnFromDaylight = this.shouldBurnInDay && this.isSunBurnTick() && this.level().purpurConfig.phantomBurnInDaylight; - boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight; -@@ -282,7 +284,7 @@ public class Phantom extends FlyingMob implements Enemy { - if (nbt.hasUUID("Paper.SpawningEntity")) { - this.spawningEntity = nbt.getUUID("Paper.SpawningEntity"); - } -- if (nbt.contains("Paper.ShouldBurnInDay")) { -+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight - this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); - } - // Paper end -@@ -299,7 +301,7 @@ public class Phantom extends FlyingMob implements Enemy { - if (this.spawningEntity != null) { - nbt.putUUID("Paper.SpawningEntity", this.spawningEntity); - } -- nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); -+ //nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight - // Paper end - } - -@@ -359,8 +361,14 @@ public class Phantom extends FlyingMob implements Enemy { - return this.spawningEntity; - } - public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; } -- private boolean shouldBurnInDay = true; -- public boolean shouldBurnInDay() { return shouldBurnInDay; } -+ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight -+ // Purpur start - API for any mob to burn daylight -+ public boolean shouldBurnInDay() { -+ boolean burnFromDaylight = this.shouldBurnInDay && this.level().purpurConfig.phantomBurnInDaylight; -+ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight; -+ return burnFromDaylight || burnFromLightSource; -+ } -+ // Purpur end - API for any mob to burn daylight - public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } - // Paper end - -diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java -index 09b21cf02a07e1eb6a0aa2c6880d4106fe9e0d77..d0fcd51e36e7c7e774fcf9b1db42ec7fceb9fc41 100644 ---- a/net/minecraft/world/entity/monster/Zombie.java -+++ b/net/minecraft/world/entity/monster/Zombie.java -@@ -99,11 +99,12 @@ public class Zombie extends Monster { - private int inWaterTime; - public int conversionTime; - // private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field // Paper - remove anti tick skipping measures / wall time -- private boolean shouldBurnInDay = true; // Paper - Add more Zombie API -+ //private boolean shouldBurnInDay = true; // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight - - public Zombie(EntityType type, Level world) { - super(type, world); - this.breakDoorGoal = new BreakDoorGoal(this, com.google.common.base.Predicates.in(world.paperConfig().entities.behavior.doorBreakingDifficulty.getOrDefault(type, world.paperConfig().entities.behavior.doorBreakingDifficulty.get(EntityType.ZOMBIE)))); // Paper - Configurable door breaking difficulty -+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight - } - - public Zombie(Level world) { -@@ -296,32 +297,7 @@ public class Zombie extends Monster { - - @Override - public void aiStep() { -- if (this.isAlive()) { -- boolean flag = this.isSunSensitive() && this.isSunBurnTick(); -- -- if (flag) { -- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -- -- if (!itemstack.isEmpty()) { -- if (itemstack.isDamageableItem()) { -- Item item = itemstack.getItem(); -- -- itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2)); -- if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) { -- this.onEquippedItemBroken(item, EquipmentSlot.HEAD); -- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); -- } -- } -- -- flag = false; -- } -- -- if (flag) { -- this.igniteForSeconds(8.0F); -- } -- } -- } -- -+ // Purpur - implemented in LivingEntity - API for any mob to burn daylight - super.aiStep(); - } - -@@ -381,6 +357,7 @@ public class Zombie extends Monster { - // CraftBukkit end - } - -+ public boolean shouldBurnInDay() { return this.isSunSensitive(); } // Purpur - for ABI compatibility - API for any mob to burn daylight - public boolean isSunSensitive() { - return this.shouldBurnInDay; // Paper - Add more Zombie API - } -@@ -519,7 +496,7 @@ public class Zombie extends Monster { - nbt.putBoolean("CanBreakDoors", this.canBreakDoors()); - nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1); - nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1); -- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API -+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight - } - - @Override -@@ -532,7 +509,7 @@ public class Zombie extends Monster { - this.startUnderWaterConversion(nbt.getInt("DrownedConversionTime")); - } - // Paper start - Add more Zombie API -- if (nbt.contains("Paper.ShouldBurnInDay")) { -+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight - this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); - } - // Paper end - Add more Zombie API -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 51772356a3c64da7b29fa204ffec03a70cd4406a..f9d7f1d317a9534d471a481db8c26f9d3b15bfda 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -87,6 +87,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); - } - -+ // Purpur start - API for any mob to burn daylight -+ @Override -+ public boolean isInDaylight() { -+ return getHandle().isSunBurnTick(); -+ } -+ // Purpur end - API for any mob to burn daylight -+ - public static CraftEntity getEntity(CraftServer server, T entity) { - Preconditions.checkArgument(entity != null, "Unknown entity"); - -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 4f98d138a275a6c34528b7a5148ef265bc38d6b5..7ccc40555964b906be6987532de1f319e38741ce 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1211,4 +1211,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { - return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); - } - // Paper end - Expose canUseSlot -+ -+ // Purpur start - API for any mob to burn daylight -+ @Override -+ public boolean shouldBurnInDay() { -+ return this.getHandle().shouldBurnInDay(); -+ } -+ -+ @Override -+ public void setShouldBurnInDay(final boolean shouldBurnInDay) { -+ this.getHandle().setShouldBurnInDay(shouldBurnInDay); -+ } -+ // Purpur end - API for any mob to burn daylight - } diff --git a/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch b/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch index 2fb28b23c..1ad686669 100644 --- a/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch +++ b/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch @@ -1,6 +1,6 @@ --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1172,4 +_,35 @@ +@@ -1172,4 +_,44 @@ */ void broadcastHurtAnimation(@NotNull java.util.Collection players); // Paper end - broadcast hurt animation @@ -35,4 +35,13 @@ + */ + boolean isRidableInWater(); + // Purpur end - Ridables ++ ++ // Purpur start - API for any mob to burn daylight ++ /** ++ * Checks if the entity is in daylight ++ * ++ * @return True if in daylight ++ */ ++ boolean isInDaylight(); ++ // Purpur end - API for any mob to burn daylight } diff --git a/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/LivingEntity.java.patch b/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/LivingEntity.java.patch new file mode 100644 index 000000000..2ec452396 --- /dev/null +++ b/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/LivingEntity.java.patch @@ -0,0 +1,23 @@ +--- a/src/main/java/org/bukkit/entity/LivingEntity.java ++++ b/src/main/java/org/bukkit/entity/LivingEntity.java +@@ -1468,4 +_,20 @@ + */ + boolean canUseEquipmentSlot(org.bukkit.inventory.@NotNull EquipmentSlot slot); + // Paper end - Expose canUseSlot ++ ++ // Purpur start - API for any mob to burn daylight ++ /** ++ * If this mob will burn in the sunlight ++ * ++ * @return True if mob will burn in sunlight ++ */ ++ boolean shouldBurnInDay(); ++ ++ /** ++ * Set if this mob should burn in the sunlight ++ * ++ * @param shouldBurnInDay True to burn in sunlight ++ */ ++ void setShouldBurnInDay(boolean shouldBurnInDay); ++ // Purpur end - API for any mob to burn daylight + } diff --git a/purpur-server/minecraft-patches/features/0001-Ridables.patch b/purpur-server/minecraft-patches/features/0001-Ridables.patch index 6c74dc927..f2f2a143b 100644 --- a/purpur-server/minecraft-patches/features/0001-Ridables.patch +++ b/purpur-server/minecraft-patches/features/0001-Ridables.patch @@ -42,7 +42,7 @@ index 53a7c465e64920f46ee46d9c71fc595dbfb24021..4daa8dfa6d9e13ffb88ad0c5d4f18f24 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index ed2b443cd1742772637f77bf1b094c2631d0c7df..477e195dfe753869fb3e4bfd4cf98188573f3574 100644 +index c7e49eeccf4fdcb5abc4527bf3efd1e36e150165..a5fc9dcaca63e1b30db2346f64bc49adcd263ec7 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -842,6 +842,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc @@ -75,7 +75,7 @@ index a2832445eab54cc6d93f929ac061949002f1bd4b..6d19faa36b4f824533e1b76e7cda1f32 if ((target instanceof Bucketable && target instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { target.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 0c88c51f870030812fabbe4239bca2bb815fea92..cf3b9cbe7658d85fee387ede1c27fbd71d940631 100644 +index 04b14a3eaf74236d72ea9ea090ae53f692e4b9ab..d22350f58ad29700bdca54f4697110bf4639faf9 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -3136,6 +3136,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -177,7 +177,7 @@ index 95d78dcdb6777df73898694367ee17b1cb76d7a2..d0313fd5368baa53ec511c8c07fc78a1 protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 7de38a23e6c9e702e25d2e970fc741d1c4e934b0..35c0f89b0a2c7c920277e7b85230f787b781564b 100644 +index 56c2c0f35e39489679aef921ba65d264eb12c05d..293be658b1154a09468be16583400e7389acc103 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -250,9 +250,9 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -210,7 +210,7 @@ index 7de38a23e6c9e702e25d2e970fc741d1c4e934b0..35c0f89b0a2c7c920277e7b85230f787 @Override protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) { -@@ -3515,8 +3516,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3526,8 +3527,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); profilerFiller.pop(); // Paper start - Add EntityMoveEvent @@ -223,7 +223,7 @@ index 7de38a23e6c9e702e25d2e970fc741d1c4e934b0..35c0f89b0a2c7c920277e7b85230f787 Location from = new Location(this.level().getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO); Location to = new Location(this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); io.papermc.paper.event.entity.EntityMoveEvent event = new io.papermc.paper.event.entity.EntityMoveEvent(this.getBukkitLivingEntity(), from, to.clone()); -@@ -3526,6 +3529,21 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3537,6 +3540,21 @@ public abstract class LivingEntity extends Entity implements Attackable { this.absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch()); } } @@ -568,7 +568,7 @@ index c0997c8c0f8ee4474d3acdd5938b1879c4e589a2..28ae152125ed83d8917674b6068f227f double d = this.wantedX - this.fish.getX(); double d1 = this.wantedY - this.fish.getY(); diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java -index 94244b148533ef026bf5c56abbc2bb5cfa83c938..474240c0fd68dbfe18b8fce7ae6e7634eea65956 100644 +index d77ae36ffc47d06767066e4ce1c1d21a52e1483c..069444e6de2b587f8df3b87391b1ffcf1ee1c388 100644 --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java @@ -145,6 +145,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1069,10 +1069,10 @@ index ddc252c76cedec0a0e9e268d8a874015a5ad52fe..8b0a813f9dd001c6dd108ba7aac04d13 } } diff --git a/net/minecraft/world/entity/animal/IronGolem.java b/net/minecraft/world/entity/animal/IronGolem.java -index 8e9ba307a0528eb1aef56bdc0f4ded0e71621253..654f5855e1b69f05205e6a132d79ac94b929eeb4 100644 +index ab3a3a2488628e18f71e30eab1639e9a08f63986..37b84f98e269bd28a67636929b200ee709804734 100644 --- a/net/minecraft/world/entity/animal/IronGolem.java +++ b/net/minecraft/world/entity/animal/IronGolem.java -@@ -61,8 +61,27 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -61,9 +61,28 @@ public class IronGolem extends AbstractGolem implements NeutralMob { super(entityType, level); } @@ -1095,12 +1095,13 @@ index 8e9ba307a0528eb1aef56bdc0f4ded0e71621253..654f5855e1b69f05205e6a132d79ac94 + @Override protected void registerGoals() { + if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur - Iron golem calm anger options + if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0, true)); this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9, 32.0F)); this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6, false)); -@@ -70,6 +89,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -71,6 +90,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { this.goalSelector.addGoal(5, new OfferFlowerGoal(this)); this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); @@ -1108,7 +1109,7 @@ index 8e9ba307a0528eb1aef56bdc0f4ded0e71621253..654f5855e1b69f05205e6a132d79ac94 this.targetSelector.addGoal(1, new DefendVillageTargetGoal(this)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); -@@ -256,12 +276,12 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -257,12 +277,12 @@ public class IronGolem extends AbstractGolem implements NeutralMob { protected InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemInHand = player.getItemInHand(hand); if (!itemInHand.is(Items.IRON_INGOT)) { @@ -1296,7 +1297,7 @@ index 283ddf7d13a17c0a6df5a52b7fd26ed7b7a4826b..19aa39af6685a03eb584820853239a3f } } diff --git a/net/minecraft/world/entity/animal/Parrot.java b/net/minecraft/world/entity/animal/Parrot.java -index 9b43cab816c780a78c823f72119c291a8b264ac7..11a19ad96317d2e44ab998e4125596aeac0e999b 100644 +index e682575b6ccee62d22e01ee1c81d1b2a065c236e..6dcb01914b7f2e0cd5d04b78f323bfd609de4ac4 100644 --- a/net/minecraft/world/entity/animal/Parrot.java +++ b/net/minecraft/world/entity/animal/Parrot.java @@ -124,12 +124,68 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder(this, Player.class, true)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this)); } -@@ -311,6 +388,7 @@ public class Creeper extends Monster { +@@ -312,6 +389,7 @@ public class Creeper extends Monster { com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); if (event.callEvent()) { this.entityData.set(DATA_IS_IGNITED, event.isIgnited()); @@ -5039,7 +5041,7 @@ index 99947e9877b79c0d419e1639c2b1379fc1504c6a..7e4d14d30eb3f06c0c7426e09084355a if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur - Add config for villager trading this.setTradingPlayer(player); diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index 6e84f57c90c0747403c4679bc920f9a9aa83594f..fa258b6a1795d18a053843e93349dbf9aadf7e77 100644 +index 7e358600f5013e7ff7050626fa3d17b18d8d1f9b..83a64dcdeb6cb3139db23327e7ce62109ce771fa 100644 --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java @@ -218,6 +218,19 @@ public abstract class Player extends LivingEntity { @@ -5080,7 +5082,7 @@ index 4880db97135d54fa72f64c108b2bd4ded096438b..bc102b049047d6e2a1d29e10f92cdf5a protected double getDefaultGravity() { return 0.06; diff --git a/net/minecraft/world/entity/projectile/WitherSkull.java b/net/minecraft/world/entity/projectile/WitherSkull.java -index 843a359d082ac1eba56f37179a6b28251dbf7c94..db071d4f98513b56bcc83e80fc2e5ee9609888af 100644 +index c7a76d45b5749cf054607808610eb710493f80ea..9af37bd40649f602d700fc7b683c646ae9189eb9 100644 --- a/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/net/minecraft/world/entity/projectile/WitherSkull.java @@ -110,6 +110,14 @@ public class WitherSkull extends AbstractHurtingProjectile { diff --git a/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch b/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch index d919f2d9c..4c1c23253 100644 --- a/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch +++ b/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch @@ -23,7 +23,7 @@ index d0313fd5368baa53ec511c8c07fc78a1f1ecec4e..898b1e01026ec1f44cfe60e9f18a997c protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 35c0f89b0a2c7c920277e7b85230f787b781564b..4da15a9c9da346c9378575cbb7c804d8c23a92ca 100644 +index 293be658b1154a09468be16583400e7389acc103..4946b206167498e92880423654580f3efd7ba559 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -311,6 +311,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -70,7 +70,7 @@ index f01ddd493d38e2e231c59841649a2e5bf3b87c49..e158fdc79c2c8f27203d6f229c1ac906 public boolean isFlapping() { return !this.isResting() && this.tickCount % 10.0F == 0.0F; diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java -index 474240c0fd68dbfe18b8fce7ae6e7634eea65956..bcf554054111f85b095341a5455856ee79f3ade6 100644 +index 069444e6de2b587f8df3b87391b1ffcf1ee1c388..24109eed60e20de9a2fde2f8c4a063b9a1be4ef9 100644 --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java @@ -471,6 +471,14 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -202,7 +202,7 @@ index 8b0a813f9dd001c6dd108ba7aac04d134a20fbc1..8bf893837586ae2a9b4ef7564d242e16 protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/animal/IronGolem.java b/net/minecraft/world/entity/animal/IronGolem.java -index 654f5855e1b69f05205e6a132d79ac94b929eeb4..d195e8658fd5a4045c95ff1e921bfeeb4dfbecf5 100644 +index 37b84f98e269bd28a67636929b200ee709804734..42780e8245b1746783084558cc2deab361b09d3b 100644 --- a/net/minecraft/world/entity/animal/IronGolem.java +++ b/net/minecraft/world/entity/animal/IronGolem.java @@ -78,6 +78,14 @@ public class IronGolem extends AbstractGolem implements NeutralMob { @@ -219,7 +219,7 @@ index 654f5855e1b69f05205e6a132d79ac94b929eeb4..d195e8658fd5a4045c95ff1e921bfeeb + @Override protected void registerGoals() { - if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables + if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur - Iron golem calm anger options diff --git a/net/minecraft/world/entity/animal/MushroomCow.java b/net/minecraft/world/entity/animal/MushroomCow.java index 1292146341022483f78a9128ef9d7a88089274a0..990723c31aa1040a4e45b9857a18d86287ef91b4 100644 --- a/net/minecraft/world/entity/animal/MushroomCow.java @@ -291,7 +291,7 @@ index 19aa39af6685a03eb584820853239a3f4fa1a515..5b07dff937c8873300eabecf1c510cf5 if (this.isLazy()) { diff --git a/net/minecraft/world/entity/animal/Parrot.java b/net/minecraft/world/entity/animal/Parrot.java -index 11a19ad96317d2e44ab998e4125596aeac0e999b..d1b0f3e0287389e8f5ada43d884af0afd6dd0a49 100644 +index 6dcb01914b7f2e0cd5d04b78f323bfd609de4ac4..cda6e1b1b113931399e33b46992d511025934eb7 100644 --- a/net/minecraft/world/entity/animal/Parrot.java +++ b/net/minecraft/world/entity/animal/Parrot.java @@ -186,6 +186,14 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder getBrain() { return (Brain)super.getBrain(); diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index c6b3894fe085c2b565651ab3ae2f1acbb6bacea4..31449094c6395857289dd56482e8b3902bac2b63 100644 +index 7e4d14d30eb3f06c0c7426e09084355ab4f3857d..b5af32a431b5ffe20b32bd82ccfae9b8343d0592 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java @@ -93,6 +93,13 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill diff --git a/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch b/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch index 206d46d39..41aa917e4 100644 --- a/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch +++ b/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Minecart settings and WASD controls diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index c03639557e498f44a53fbf223928f68e515638eb..bc0a19d7ce8a080f2e75efa8bd9ab497038a3ac1 100644 +index a5fc9dcaca63e1b30db2346f64bc49adcd263ec7..e6dab64e3a127b653e1439fc0639a378903230ea 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1233,6 +1233,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1234,6 +1234,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } else { // Purpur start - Add boat fall damage config if (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) { diff --git a/purpur-server/minecraft-patches/features/0009-Implement-elytra-settings.patch b/purpur-server/minecraft-patches/features/0009-Implement-elytra-settings.patch index 8ac7a364b..0aedbd296 100644 --- a/purpur-server/minecraft-patches/features/0009-Implement-elytra-settings.patch +++ b/purpur-server/minecraft-patches/features/0009-Implement-elytra-settings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Implement elytra settings diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 4da15a9c9da346c9378575cbb7c804d8c23a92ca..4bc1658a34c72895c11b11c54dd96c4443e2ffe1 100644 +index 4946b206167498e92880423654580f3efd7ba559..27b7e8372c6246b4040ee27bb961ca537b4b017b 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3573,7 +3573,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3584,7 +3584,18 @@ public abstract class LivingEntity extends Entity implements Attackable { if (i1 % 2 == 0) { List list = EquipmentSlot.VALUES.stream().filter(slot -> canGlideUsing(this.getItemBySlot(slot), slot)).toList(); EquipmentSlot equipmentSlot = Util.getRandom(list, this.random); @@ -53,7 +53,7 @@ index 75a9bd205f32b77c5d242cb9fac0f571ce36045a..b03f182c62c699cc222e67c1ae6eadf9 itemInHand.shrink(1); // Moved up from below } else { diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index 5d44b568718681b0a5d241037b38a787ad5aaa45..06dfd5424dcf7ab83e524803c8c11f29a6f2ea36 100644 +index 34b7ead0f14a3f8ba8a9d94996c759896004299f..75f71b90bac3a6da888366325139485e44e472e6 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java @@ -731,6 +731,14 @@ public final class ItemStack implements DataComponentHolder { @@ -72,7 +72,7 @@ index 5d44b568718681b0a5d241037b38a787ad5aaa45..06dfd5424dcf7ab83e524803c8c11f29 onBreak.accept(item); } diff --git a/net/minecraft/world/item/TridentItem.java b/net/minecraft/world/item/TridentItem.java -index 23284dbeff327d1b8dc89f3a0dc0ee549cec2daa..cf1bc55f1b5aa610bcb10316ac320344e9739086 100644 +index 1019241ccf75991fa58ea22acf791a46c5339b3a..0e431178e54fdfeac2528be2163b0b35ee7a36c6 100644 --- a/net/minecraft/world/item/TridentItem.java +++ b/net/minecraft/world/item/TridentItem.java @@ -130,6 +130,18 @@ public class TridentItem extends Item implements ProjectileItem { diff --git a/purpur-server/minecraft-patches/features/0014-Apply-display-names-from-item-forms-of-entities-to-e.patch b/purpur-server/minecraft-patches/features/0014-Apply-display-names-from-item-forms-of-entities-to-e.patch index e36e09e51..15d244724 100644 --- a/purpur-server/minecraft-patches/features/0014-Apply-display-names-from-item-forms-of-entities-to-e.patch +++ b/purpur-server/minecraft-patches/features/0014-Apply-display-names-from-item-forms-of-entities-to-e.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Apply display names from item forms of entities to entities diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java -index 927f8204d0130b410e4dbff657f57bead77b3eb3..581125b786c4d7c5fbd021e65bfd78ef4f5b7a08 100644 +index d368b1971b270c44efc849464a100832bc29a679..8c0ab32487c56e2caf42404184f86c9bcf5f8b41 100644 --- a/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -563,6 +563,7 @@ public class ArmorStand extends LivingEntity { +@@ -564,6 +564,7 @@ public class ArmorStand extends LivingEntity { private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(ServerLevel level, DamageSource damageSource) { // Paper ItemStack itemStack = new ItemStack(Items.ARMOR_STAND); diff --git a/purpur-server/minecraft-patches/features/0016-Add-mobGriefing-bypass-to-everything-affected.patch b/purpur-server/minecraft-patches/features/0016-Add-mobGriefing-bypass-to-everything-affected.patch index 4752f1882..7bdd94667 100644 --- a/purpur-server/minecraft-patches/features/0016-Add-mobGriefing-bypass-to-everything-affected.patch +++ b/purpur-server/minecraft-patches/features/0016-Add-mobGriefing-bypass-to-everything-affected.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add mobGriefing bypass to everything affected diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 4bc1658a34c72895c11b11c54dd96c4443e2ffe1..81ddf5754134f58fcfeb285fb4061e9b1e3c1f80 100644 +index 27b7e8372c6246b4040ee27bb961ca537b4b017b..dbc67eeb54e6148c8cc39cc95addc2d38f747e03 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -1797,7 +1797,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1808,7 +1808,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.level() instanceof ServerLevel serverLevel) { boolean var6 = false; if (this.dead && entitySource instanceof WitherBoss) { // Paper diff --git a/purpur-server/minecraft-patches/features/0018-Toggle-for-water-sensitive-mob-damage.patch b/purpur-server/minecraft-patches/features/0018-Toggle-for-water-sensitive-mob-damage.patch index 5d7502df8..261d2afd9 100644 --- a/purpur-server/minecraft-patches/features/0018-Toggle-for-water-sensitive-mob-damage.patch +++ b/purpur-server/minecraft-patches/features/0018-Toggle-for-water-sensitive-mob-damage.patch @@ -41,7 +41,7 @@ index e158fdc79c2c8f27203d6f229c1ac906394e5f96..2345ca8443693dafaae23a991d37e25b public boolean isFlapping() { return !this.isResting() && this.tickCount % 10.0F == 0.0F; diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java -index 62fbaed0f81b900730ab22b969ffd48d31a268ce..5c8b88e8dca604d053c59106e64bfcf32491ec4f 100644 +index 0ed9d499591a809c30d2399f64502de7505c46e7..70e90b91aaf1c5cd46d818d171194fbbba5000e6 100644 --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java @@ -177,7 +177,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -174,7 +174,7 @@ index 3d94d5c9ecab0fe7332daf4cdac879385159eaa1..22a70c6af965114e272bb56cb217f975 protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/animal/IronGolem.java b/net/minecraft/world/entity/animal/IronGolem.java -index d195e8658fd5a4045c95ff1e921bfeeb4dfbecf5..0c4edfaa16331d35c6c2383f690545cb3d2a0952 100644 +index 42780e8245b1746783084558cc2deab361b09d3b..469ebee33cc8bf8f4dcad2595c80ffad19edac18 100644 --- a/net/minecraft/world/entity/animal/IronGolem.java +++ b/net/minecraft/world/entity/animal/IronGolem.java @@ -86,6 +86,13 @@ public class IronGolem extends AbstractGolem implements NeutralMob { @@ -190,7 +190,7 @@ index d195e8658fd5a4045c95ff1e921bfeeb4dfbecf5..0c4edfaa16331d35c6c2383f690545cb + @Override protected void registerGoals() { - if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables + if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur - Iron golem calm anger options diff --git a/net/minecraft/world/entity/animal/MushroomCow.java b/net/minecraft/world/entity/animal/MushroomCow.java index a64b609bf5ce38a252bfa1bcff869f88e14389b5..5e9795f447e88a42909730d383eaa36acfaf18f5 100644 --- a/net/minecraft/world/entity/animal/MushroomCow.java @@ -246,7 +246,7 @@ index 450c7be36846bf4e95f84615fca893501415cdbc..d5d2b9656ec22536ccd9ddb0ebe48a19 protected boolean canDispenserEquipIntoSlot(EquipmentSlot slot) { return slot == EquipmentSlot.MAINHAND && this.canPickUpLoot(); diff --git a/net/minecraft/world/entity/animal/Parrot.java b/net/minecraft/world/entity/animal/Parrot.java -index f7efd5d2534a7b7d20e1951ffa6b0314434f82e2..ff8cd170064e6cfa943c228a1bc82ef7a5a45b7f 100644 +index 5aa75c82c7239734ad1e5eeb63c7f79e7e8db99d..3d11fe4a41958182764600ba0f781c4202e8f621 100644 --- a/net/minecraft/world/entity/animal/Parrot.java +++ b/net/minecraft/world/entity/animal/Parrot.java @@ -201,6 +201,13 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder getBrain() { return (Brain)super.getBrain(); diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index cef51ce86dcbc5ec01bfcbcb487325b55779be52..1d1ea911bad49d0304712512a683af13a256d0a5 100644 +index f9755f36f7863b9742fe5b840a8130891ddff7c7..5a87c3c7aca38f3fe4a003b2075f43b0ae1cddea 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java @@ -107,6 +107,13 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill diff --git a/purpur-server/minecraft-patches/features/0019-API-for-any-mob-to-burn-daylight.patch b/purpur-server/minecraft-patches/features/0019-API-for-any-mob-to-burn-daylight.patch new file mode 100644 index 000000000..42bab28d0 --- /dev/null +++ b/purpur-server/minecraft-patches/features/0019-API-for-any-mob-to-burn-daylight.patch @@ -0,0 +1,344 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ben Kerllenevich +Date: Tue, 25 May 2021 16:31:09 -0400 +Subject: [PATCH] API for any mob to burn daylight + +Co-authored by: Encode42 + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index d22350f58ad29700bdca54f4697110bf4639faf9..bc4f44fc16361903d6c1caac0114d8498a413de3 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -533,6 +533,24 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + // Purpur end - Add canSaveToDisk to Entity + ++ // Purpur start - copied from Mob - API for any mob to burn daylight ++ public boolean isSunBurnTick() { ++ if (this.level().isDay() && !this.level().isClientSide) { ++ float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); ++ BlockPos blockPos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); ++ boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; ++ if (lightLevelDependentMagicValue > 0.5F ++ && this.random.nextFloat() * 30.0F < (lightLevelDependentMagicValue - 0.4F) * 2.0F ++ && !flag ++ && this.level().canSeeSky(blockPos)) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ // Purpur end - copied from Mob - API for any mob to burn daylight ++ + public Entity(EntityType entityType, Level level) { + this.type = entityType; + this.level = level; +diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java +index dbc67eeb54e6148c8cc39cc95addc2d38f747e03..d98d93ee521d255efeffd10d269bd99691ffc4e9 100644 +--- a/net/minecraft/world/entity/LivingEntity.java ++++ b/net/minecraft/world/entity/LivingEntity.java +@@ -301,6 +301,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper + public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event + public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API ++ protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight + + @Override + public float getBukkitYaw() { +@@ -809,6 +810,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + }); + DataResult dataResult = this.brain.serializeStart(NbtOps.INSTANCE); + dataResult.resultOrPartial(LOGGER::error).ifPresent(brain -> compound.put("Brain", brain)); ++ compound.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight + } + + @Override +@@ -892,6 +894,12 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (compound.contains("Brain", 10)) { + this.brain = this.makeBrain(new Dynamic<>(NbtOps.INSTANCE, compound.get("Brain"))); + } ++ ++ // Purpur start - API for any mob to burn daylight ++ if (compound.contains("Purpur.ShouldBurnInDay")) { ++ this.shouldBurnInDay = compound.getBoolean("Purpur.ShouldBurnInDay"); ++ } ++ // Purpur end - API for any mob to burn daylight + } + + // CraftBukkit start +@@ -3563,6 +3571,32 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { + this.hurtServer(serverLevel, this.damageSources().drown(), 1.0F); + } ++ ++ // Purpur start - copied from Zombie - API for any mob to burn daylight ++ if (this.isAlive()) { ++ boolean flag = this.shouldBurnInDay() && this.isSunBurnTick(); // Paper - shouldBurnInDay API // Purpur - use shouldBurnInDay() method to handle Phantoms properly - API for any mob to burn daylight ++ if (flag) { ++ ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD); ++ if (!itemBySlot.isEmpty()) { ++ if (itemBySlot.isDamageableItem()) { ++ Item item = itemBySlot.getItem(); ++ itemBySlot.setDamageValue(itemBySlot.getDamageValue() + this.random.nextInt(2)); ++ if (itemBySlot.getDamageValue() >= itemBySlot.getMaxDamage()) { ++ this.onEquippedItemBroken(item, EquipmentSlot.HEAD); ++ this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); ++ } ++ } ++ ++ flag = false; ++ } ++ ++ if (flag) { ++ if (getRider() == null || !this.isControllable()) // Purpur - ignore mobs which are uncontrollable or without rider - API for any mob to burn daylight ++ this.igniteForSeconds(8.0F); ++ } ++ } ++ } ++ // Purpur end - copied from Zombie - API for any mob to burn daylight + } + + public boolean isSensitiveToWater() { +diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java +index d93584c6793818463e8883ffe399bf16b03263a9..70ee86993d381445855ac7e7290da384d6675987 100644 +--- a/net/minecraft/world/entity/Mob.java ++++ b/net/minecraft/world/entity/Mob.java +@@ -1655,19 +1655,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + } + + public boolean isSunBurnTick() { +- if (this.level().isDay() && !this.level().isClientSide) { +- float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); +- BlockPos blockPos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); +- boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; +- if (lightLevelDependentMagicValue > 0.5F +- && this.random.nextFloat() * 30.0F < (lightLevelDependentMagicValue - 0.4F) * 2.0F +- && !flag +- && this.level().canSeeSky(blockPos)) { +- return true; +- } +- } +- +- return false; ++ // Purpur - implemented in Entity - API for any mob to burn daylight ++ return super.isSunBurnTick(); + } + + @Override +diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java +index 6c78780166822755a89e7021733ccb7641c62ffe..fa8eeab124933c3181ec64ef22f6c4112fd7ed62 100644 +--- a/net/minecraft/world/entity/monster/AbstractSkeleton.java ++++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java +@@ -64,11 +64,12 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + AbstractSkeleton.this.setAggressive(true); + } + }; +- private boolean shouldBurnInDay = true; // Paper - shouldBurnInDay API ++ //private boolean shouldBurnInDay = true; // Paper - shouldBurnInDay API // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight + + protected AbstractSkeleton(EntityType entityType, Level level) { + super(entityType, level); + this.reassessWeaponGoal(); ++ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight + } + + @Override +@@ -110,27 +111,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + + @Override + public void aiStep() { +- boolean isSunBurnTick = this.shouldBurnInDay && this.isSunBurnTick(); // Paper - shouldBurnInDay API +- if (isSunBurnTick) { +- ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD); +- if (!itemBySlot.isEmpty()) { +- if (itemBySlot.isDamageableItem()) { +- Item item = itemBySlot.getItem(); +- itemBySlot.setDamageValue(itemBySlot.getDamageValue() + this.random.nextInt(2)); +- if (itemBySlot.getDamageValue() >= itemBySlot.getMaxDamage()) { +- this.onEquippedItemBroken(item, EquipmentSlot.HEAD); +- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); +- } +- } +- +- isSunBurnTick = false; +- } +- +- if (isSunBurnTick) { +- this.igniteForSeconds(8.0F); +- } +- } +- ++ // Purpur - implemented in LivingEntity - API for any mob to burn daylight + super.aiStep(); + } + +@@ -246,7 +227,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + super.readAdditionalSaveData(compound); + this.reassessWeaponGoal(); + // Paper start - shouldBurnInDay API +- if (compound.contains("Paper.ShouldBurnInDay")) { ++ if (false && compound.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight + this.shouldBurnInDay = compound.getBoolean("Paper.ShouldBurnInDay"); + } + // Paper end - shouldBurnInDay API +@@ -255,7 +236,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + @Override + public void addAdditionalSaveData(final net.minecraft.nbt.CompoundTag nbt) { + super.addAdditionalSaveData(nbt); +- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); ++ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight + } + // Paper end - shouldBurnInDay API + +diff --git a/net/minecraft/world/entity/monster/Husk.java b/net/minecraft/world/entity/monster/Husk.java +index 31eef2869945d9de565d627cac3fc1a5db380a2a..e618e716cb5ff3a3c5d284e985455694cc0edde0 100644 +--- a/net/minecraft/world/entity/monster/Husk.java ++++ b/net/minecraft/world/entity/monster/Husk.java +@@ -19,6 +19,7 @@ import net.minecraft.world.level.ServerLevelAccessor; + public class Husk extends Zombie { + public Husk(EntityType entityType, Level level) { + super(entityType, level); ++ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight + } + + // Purpur start - Ridables +@@ -82,7 +83,7 @@ public class Husk extends Zombie { + + @Override + public boolean isSunSensitive() { +- return false; ++ return this.shouldBurnInDay; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight + } + + @Override +diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java +index eda7ee331451bcb812d089929589027cd6b9681e..78569c2790f74fb91c3c7e7b72158e77ec568c79 100644 +--- a/net/minecraft/world/entity/monster/Phantom.java ++++ b/net/minecraft/world/entity/monster/Phantom.java +@@ -60,6 +60,7 @@ public class Phantom extends FlyingMob implements Enemy { + this.xpReward = 5; + this.moveControl = new Phantom.PhantomMoveControl(this); + this.lookControl = new Phantom.PhantomLookControl(this); ++ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight + } + + // Purpur start - Ridables +@@ -146,6 +147,16 @@ public class Phantom extends FlyingMob implements Enemy { + } + // Purpur end - Toggle for water sensitive mob damage + ++ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight ++ // Purpur start - API for any mob to burn daylight ++ public boolean shouldBurnInDay() { ++ boolean burnFromDaylight = this.shouldBurnInDay && this.level().purpurConfig.phantomBurnInDaylight; ++ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight; ++ return burnFromDaylight || burnFromLightSource; ++ } ++ public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } ++ // Purpur end - API for any mob to burn daylight ++ + @Override + public boolean isFlapping() { + return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0; +@@ -261,6 +272,7 @@ public class Phantom extends FlyingMob implements Enemy { + + @Override + public void aiStep() { ++ // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight + // Purpur start - Phantoms burn in light + boolean burnFromDaylight = this.shouldBurnInDay && this.isSunBurnTick() && this.level().purpurConfig.phantomBurnInDaylight; + boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight; +@@ -295,7 +307,7 @@ public class Phantom extends FlyingMob implements Enemy { + if (compound.hasUUID("Paper.SpawningEntity")) { + this.spawningEntity = compound.getUUID("Paper.SpawningEntity"); + } +- if (compound.contains("Paper.ShouldBurnInDay")) { ++ if (false && compound.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight + this.shouldBurnInDay = compound.getBoolean("Paper.ShouldBurnInDay"); + } + // Paper end +@@ -312,7 +324,7 @@ public class Phantom extends FlyingMob implements Enemy { + if (this.spawningEntity != null) { + compound.putUUID("Paper.SpawningEntity", this.spawningEntity); + } +- compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); ++ //compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight + // Paper end + } + +diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java +index 61767c8dc1872d7d87d0757da4d3664c4ebafa54..f769a7b3876cb8b2808102219219ac43a819d20c 100644 +--- a/net/minecraft/world/entity/monster/Zombie.java ++++ b/net/minecraft/world/entity/monster/Zombie.java +@@ -89,11 +89,12 @@ public class Zombie extends Monster { + private boolean canBreakDoors; + private int inWaterTime; + public int conversionTime; +- private boolean shouldBurnInDay = true; // Paper - Add more Zombie API ++ //private boolean shouldBurnInDay = true; // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight + + public Zombie(EntityType entityType, Level level) { + super(entityType, level); + this.breakDoorGoal = new BreakDoorGoal(this, com.google.common.base.Predicates.in(level.paperConfig().entities.behavior.doorBreakingDifficulty.getOrDefault(entityType, level.paperConfig().entities.behavior.doorBreakingDifficulty.get(EntityType.ZOMBIE)))); // Paper - Configurable door breaking difficulty ++ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight + } + + public Zombie(Level level) { +@@ -290,29 +291,7 @@ public class Zombie extends Monster { + + @Override + public void aiStep() { +- if (this.isAlive()) { +- boolean flag = this.isSunSensitive() && this.isSunBurnTick(); +- if (flag) { +- ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD); +- if (!itemBySlot.isEmpty()) { +- if (itemBySlot.isDamageableItem()) { +- Item item = itemBySlot.getItem(); +- itemBySlot.setDamageValue(itemBySlot.getDamageValue() + this.random.nextInt(2)); +- if (itemBySlot.getDamageValue() >= itemBySlot.getMaxDamage()) { +- this.onEquippedItemBroken(item, EquipmentSlot.HEAD); +- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); +- } +- } +- +- flag = false; +- } +- +- if (flag) { +- this.igniteForSeconds(8.0F); +- } +- } +- } +- ++ // Purpur - implemented in LivingEntity - API for any mob to burn daylight + super.aiStep(); + } + +@@ -371,6 +350,7 @@ public class Zombie extends Monster { + // CraftBukkit end + } + ++ public boolean shouldBurnInDay() { return this.isSunSensitive(); } // Purpur - for ABI compatibility - API for any mob to burn daylight + public boolean isSunSensitive() { + return this.shouldBurnInDay; // Paper - Add more Zombie API + } +@@ -509,7 +489,7 @@ public class Zombie extends Monster { + 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 ++ //compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight + } + + @Override +@@ -522,7 +502,7 @@ public class Zombie extends Monster { + this.startUnderWaterConversion(compound.getInt("DrownedConversionTime")); + } + // Paper start - Add more Zombie API +- if (compound.contains("Paper.ShouldBurnInDay")) { ++ if (false && compound.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight + this.shouldBurnInDay = compound.getBoolean("Paper.ShouldBurnInDay"); + } + // Paper end - Add more Zombie API diff --git a/purpur-server/paper-patches/features/0006-API-for-any-mob-to-burn-daylight.patch b/purpur-server/paper-patches/features/0006-API-for-any-mob-to-burn-daylight.patch new file mode 100644 index 000000000..66e96c8df --- /dev/null +++ b/purpur-server/paper-patches/features/0006-API-for-any-mob-to-burn-daylight.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ben Kerllenevich +Date: Tue, 25 May 2021 16:31:09 -0400 +Subject: [PATCH] API for any mob to burn daylight + +Co-authored by: Encode42 + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index fff77d5cbd2ca70ab7ced7075bf86318bfed77df..aa8976d926b486d29c6030104f259d1e53481a3b 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -87,6 +87,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); + } + ++ // Purpur start - API for any mob to burn daylight ++ @Override ++ public boolean isInDaylight() { ++ return getHandle().isSunBurnTick(); ++ } ++ // Purpur end - API for any mob to burn daylight ++ + public static CraftEntity getEntity(CraftServer server, T entity) { + Preconditions.checkArgument(entity != null, "Unknown entity"); + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +index 4f98d138a275a6c34528b7a5148ef265bc38d6b5..7ccc40555964b906be6987532de1f319e38741ce 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +@@ -1211,4 +1211,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { + return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); + } + // Paper end - Expose canUseSlot ++ ++ // Purpur start - API for any mob to burn daylight ++ @Override ++ public boolean shouldBurnInDay() { ++ return this.getHandle().shouldBurnInDay(); ++ } ++ ++ @Override ++ public void setShouldBurnInDay(final boolean shouldBurnInDay) { ++ this.getHandle().setShouldBurnInDay(shouldBurnInDay); ++ } ++ // Purpur end - API for any mob to burn daylight + }