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 1edca56b4bf880460148d00b98225fc34bd15f17..5b0a4ef4ae5a762432dbb0def005f7505197445e 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -521,6 +521,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().isBrightOutside() && !this.level().isClientSide) { + float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); + BlockPos blockPos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); + boolean flag = this.isInWaterOrRain() || 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 13a1b5dd8b1a07a584f71b1f24da28965f5e2a5d..fb42e31e812f99bf7b74c376ed47fcaee3213238 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -273,6 +273,7 @@ public abstract class LivingEntity extends Entity implements Attackable { 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 public int shieldBlockingDelay = this.level().paperConfig().misc.shieldBlockingDelay; // Paper - Make shield blocking delay configurable + 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 // CraftBukkit end protected LivingEntity(EntityType entityType, Level level) { @@ -768,6 +769,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.getSleepingPos().ifPresent(pos -> compound.store("sleeping_pos", BlockPos.CODEC, pos)); DataResult dataResult = this.brain.serializeStart(NbtOps.INSTANCE); dataResult.resultOrPartial(LOGGER::error).ifPresent(tag -> compound.put("Brain", tag)); + compound.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight if (this.lastHurtByPlayer != null) { this.lastHurtByPlayer.store(compound, "last_hurt_by_player"); compound.putInt("last_hurt_by_player_memory_time", this.lastHurtByPlayerMemoryTime); @@ -891,6 +893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } // 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.shouldBurnInDay = compound.getBooleanOr("Purpur.ShouldBurnInDay", false); // Purpur - API for any mob to burn daylight this.lastHurtByPlayer = EntityReference.read(compound, "last_hurt_by_player"); this.lastHurtByPlayerMemoryTime = compound.getIntOr("last_hurt_by_player_memory_time", 0); this.lastHurtByMob = EntityReference.read(compound, "last_hurt_by_mob"); @@ -3614,6 +3617,32 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterOrRain()) { 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 } protected void applyInput() { diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java index b828524d62a940f89f0c0fa926ef0423019ec212..e9344f61a943d610dfabe4918c227ddba166f17f 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java @@ -1531,19 +1531,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab } public boolean isSunBurnTick() { - if (this.level().isBrightOutside() && !this.level().isClientSide) { - float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); - BlockPos blockPos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); - boolean flag = this.isInWaterOrRain() || 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 0a5de00d41c59528e9f85a7cf82363c45e24d2bc..185edd9878f5193c44b75a126e8182caade7e943 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(); } @@ -242,14 +223,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo public void readAdditionalSaveData(CompoundTag compound) { super.readAdditionalSaveData(compound); this.reassessWeaponGoal(); - this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API + //this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API // Purpur - implemented in LivingEntity - API for any mob to burn daylight } // Paper start - shouldBurnInDay API @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 9baec22561093d64157d93449e84c23b3f238b39..3f331215ef49c52fa3a53bcf744159d2221111f5 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 409e98d0981aa8be0d35bc5c93f7130a9ce16860..c2bc638b0029ac46cf388187ca74545060a54914 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java @@ -61,6 +61,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 @@ -147,6 +148,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; @@ -262,15 +273,7 @@ public class Phantom extends FlyingMob implements Enemy { @Override public void aiStep() { - // 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; - if (this.isAlive() && (burnFromDaylight || burnFromLightSource)) { // Paper - shouldBurnInDay API - // Purpur end - Phantoms burn in light - if (getRider() == null || !this.isControllable()) // Purpur - Ridables - this.igniteForSeconds(8.0F); - } - + // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight super.aiStep(); } @@ -294,7 +297,7 @@ public class Phantom extends FlyingMob implements Enemy { this.setPhantomSize(compound.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.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Purpur - implemented in LivingEntity - API for any mob to burn daylight // Paper end } @@ -305,7 +308,7 @@ public class Phantom extends FlyingMob implements Enemy { compound.putInt("size", this.getPhantomSize()); // Paper start compound.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, 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 7f9ee637f443f55ae901d1a0aebedd8f7411996d..aed6db357f5b4550407a424a5b83c590044568ee 100644 --- a/net/minecraft/world/entity/monster/Zombie.java +++ b/net/minecraft/world/entity/monster/Zombie.java @@ -93,11 +93,12 @@ public class Zombie extends Monster { private boolean canBreakDoors = false; private int inWaterTime = 0; 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) { @@ -294,29 +295,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(); } @@ -375,6 +354,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 } @@ -512,7 +492,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 @@ -527,7 +507,7 @@ public class Zombie extends Monster { } else { this.getEntityData().set(DATA_DROWNED_CONVERSION_ID, false); } - this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API + //this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight } @Override