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 }