Files
Purpur/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch
granny 48dad559a7 Updated Upstream (Paper)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
PaperMC/Paper@51fe7aaa Fixed modern forwarding support (#13098)
PaperMC/Paper@5613a359 fix PlayerGameModeChangeEvent#cancelMessage
PaperMC/Paper@673abf4b use PlayerShieldDisableEvent#getCooldown
PaperMC/Paper@3a0dc7fa Fix a couple PlayerProfile mutability issues
PaperMC/Paper@e97fb404 Remove parallel generation config option
PaperMC/Paper@c3a60b8d Use ThreadLocal for Starlight and ticket level propagator cache
PaperMC/Paper@e16b369f Resize propagator queues less aggressively
PaperMC/Paper@922c85fe Add GAMEMODE_SWITCHER gamemode change cause (#13097)
PaperMC/Paper@c1013989 remove old configs
PaperMC/Paper@f57fd541 remove api scheduled for removal
2025-09-27 23:00:54 -07:00

357 lines
20 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Tue, 25 May 2021 16:31:09 -0400
Subject: [PATCH] API for any mob to burn daylight
Co-authored by: Encode42 <me@encode42.dev>
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index ef77be60df1cf44088e684c21dbcaf3032bb3ad6..92292ae5a313e85a3238427e7ab19c73e31f0ecb 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -544,6 +544,24 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
}
// 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 7c65124b4c10166d57ac3c0e8435be06bf05efef..6eb4efd8220be4a06ae3306595b64a94f23538c3 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -286,6 +286,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
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
// CraftBukkit end
protected LivingEntity(EntityType<? extends LivingEntity> entityType, Level level) {
@@ -795,6 +796,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
this.getSleepingPos().ifPresent(blockPos -> output.store("sleeping_pos", BlockPos.CODEC, blockPos));
DataResult<Dynamic<?>> dataResult = this.brain.serializeStart(NbtOps.INSTANCE).map(tag -> new Dynamic<>(NbtOps.INSTANCE, tag));
dataResult.resultOrPartial(LOGGER::error).ifPresent(dynamic -> output.store("Brain", Codec.PASSTHROUGH, (Dynamic<?>)dynamic));
+ output.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight
if (this.lastHurtByPlayer != null) {
this.lastHurtByPlayer.store(output, "last_hurt_by_player");
output.putInt("last_hurt_by_player_memory_time", this.lastHurtByPlayerMemoryTime);
@@ -921,6 +923,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
} // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong
}, this::clearSleepingPos);
input.read("Brain", Codec.PASSTHROUGH).ifPresent(dynamic -> this.brain = this.makeBrain((Dynamic<?>)dynamic));
+ this.shouldBurnInDay = input.getBooleanOr("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight
this.lastHurtByPlayer = EntityReference.read(input, "last_hurt_by_player");
this.lastHurtByPlayerMemoryTime = input.getIntOr("last_hurt_by_player_memory_time", 0);
this.lastHurtByMob = EntityReference.read(input, "last_hurt_by_mob");
@@ -3711,6 +3714,32 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
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 8f58641132231f450d0fb0c1fa61559c6cef8dcf..b9659c11204f632f42bc776453fcf5ce1eb09073 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -1589,19 +1589,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 2ef478b287e1240dd172235f7cabf31f60456a8a..b228c29e550d77f62ac53df9f32efe1a31c9f933 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<? extends AbstractSkeleton> 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();
}
@@ -245,14 +226,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
protected void readAdditionalSaveData(ValueInput input) {
super.readAdditionalSaveData(input);
this.reassessWeaponGoal();
- this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API
+ //this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
// Paper start - shouldBurnInDay API
@Override
protected void addAdditionalSaveData(final net.minecraft.world.level.storage.ValueOutput output) {
super.addAdditionalSaveData(output);
- output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ //output.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 d25baa1e1b03b38219c8851c1552f342543ba884..f8f27c7e5be15d6b7684159c193167837270d96b 100644
--- a/net/minecraft/world/entity/monster/Husk.java
+++ b/net/minecraft/world/entity/monster/Husk.java
@@ -18,6 +18,7 @@ import net.minecraft.world.level.ServerLevelAccessor;
public class Husk extends Zombie {
public Husk(EntityType<? extends Husk> entityType, Level level) {
super(entityType, level);
+ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight
}
// Purpur start - Ridables
@@ -81,7 +82,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 e0193db5ce783b4ab2b8afaeaeffde8ac8bc8a71..aa292ec60655cc9419da2a744c8cb841ddbc40e1 100644
--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -53,7 +53,7 @@ public class Phantom extends Mob implements Enemy {
// Paper start
@Nullable
public java.util.UUID spawningEntity;
- public boolean shouldBurnInDay = true;
+ //public boolean shouldBurnInDay = true; // Purpur - API for any mob to burn daylight
// Paper end
private static final net.minecraft.world.item.crafting.Ingredient TORCH = net.minecraft.world.item.crafting.Ingredient.of(net.minecraft.world.item.Items.TORCH, net.minecraft.world.item.Items.SOUL_TORCH); // Purpur - Phantoms burn in light
@@ -62,6 +62,7 @@ public class Phantom extends Mob 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
@@ -136,6 +137,16 @@ public class Phantom extends Mob 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;
@@ -246,15 +257,7 @@ public class Phantom extends Mob 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();
}
@@ -301,7 +304,7 @@ public class Phantom extends Mob implements Enemy {
this.setPhantomSize(input.getIntOr("size", 0));
// Paper start
this.spawningEntity = input.read("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null);
- this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true);
+ //this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Purpur - implemented in LivingEntity - API for any mob to burn daylight
// Paper end
}
@@ -312,7 +315,7 @@ public class Phantom extends Mob implements Enemy {
output.putInt("size", this.getPhantomSize());
// Paper start
output.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity);
- output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ //output.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 452fcb94b5d31e04bf3c96bd1b07ff9b54101595..6e3ae67dbb9a60177f26d075d42aacce580ff956 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -91,11 +91,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<? extends Zombie> 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) {
@@ -292,29 +293,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();
}
@@ -373,6 +352,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
}
@@ -510,7 +490,7 @@ public class Zombie extends Monster {
output.putBoolean("CanBreakDoors", this.canBreakDoors());
output.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
output.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
- output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
+ //output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
@Override
@@ -525,7 +505,7 @@ public class Zombie extends Monster {
} else {
this.getEntityData().set(DATA_DROWNED_CONVERSION_ID, false);
}
- this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API
+ //this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
@Override