Files
Purpur/patches/server/0165-API-for-any-mob-to-burn-daylight.patch
granny ad910f8210 Updated Upstream (Paper)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
PaperMC/Paper@812701d Do not crash when an exp orb attempts to mend an unrepairable item
PaperMC/Paper@19eefe9 Fix SoundEffects only to players diff  (#10966)
PaperMC/Paper@95aa440 Add missing effect cause and deprecate PATROL_CAPTAIN cause (#10958)
PaperMC/Paper@b2e5587 Expose LivingEntity#canUseSlot (#10930)
PaperMC/Paper@97afc9a Fix StackOverflowError for new dispenser interaction (#10949)
PaperMC/Paper@5ae4758 Fix speed for launched trident using api (#10936)
PaperMC/Paper@897ece4 Call EntityPortalEnterEvent on endgateways and make cancellable (#10892)
PaperMC/Paper@1d3fc0e Bump reflection-rewriter to 0.0.2 (#10927)
PaperMC/Paper@b99d071 Swap some nullable annotations (#10960)
PaperMC/Paper@dd31654 bump reflection-rewriter to 0.0.3 (#10969)
PaperMC/Paper@dd49fba Fix NPE when retrieving an entity with a null UUID
2024-06-23 19:37:56 -07:00

398 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/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 99562b8eb24c39a1771edf4b9084c26179c4f382..586410044c969569f8b55b0b71b08faa8a2bb578 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -536,6 +536,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Purpur end
+ // 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.passengers = ImmutableList.of();
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index ee48e98e6981225b486ea933d51fb4b9cc73fa18..9367e0f148d3aa9a60dfd8881a3c337630a53129 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -286,6 +286,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() {
@@ -816,6 +817,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
@@ -904,6 +906,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
@@ -3580,6 +3587,34 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.hurt(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 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/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 8b2dd71177b011c2a31e4959ca16057ad5288b22..6dfb13eef96ff43d368cd8163ae5883571cec604 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1780,17 +1780,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/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
index 5c1aa5859ac411098054be9f52bac0860ee667a5..1d06c612eaba8b595fa3d094577f700989d1e224 100644
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
@@ -66,6 +66,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
protected AbstractSkeleton(EntityType<? extends AbstractSkeleton> type, Level world) {
super(type, world);
this.reassessWeaponGoal();
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
@Override
@@ -96,37 +97,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();
}
@@ -241,7 +219,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
@@ -251,7 +229,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/src/main/java/net/minecraft/world/entity/monster/Husk.java b/src/main/java/net/minecraft/world/entity/monster/Husk.java
index cb96bd5769159e6c25968673ea07cd6d107cff46..cbfb5bf945b747328746d21395e66d523c268468 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Husk.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java
@@ -20,6 +20,7 @@ public class Husk extends Zombie {
public Husk(EntityType<? extends Husk> type, Level world) {
super(type, world);
+ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight
}
// Purpur start
@@ -75,7 +76,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/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index 554e01cf4fb3b15549c8c381274014c4735e08c6..f6b2e0797554baa3bc74e886e22d5bac67c424f6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -59,6 +59,7 @@ public class Phantom extends FlyingMob implements Enemy {
this.xpReward = 5;
this.moveControl = new Phantom.PhantomMoveControl(this);
this.lookControl = new Phantom.PhantomLookControl(this, this);
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
// Purpur start
@@ -247,15 +248,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public void aiStep() {
- // Purpur start
- 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
- if (getRider() == null || !this.isControllable()) // Purpur
- this.igniteForSeconds(8.0F);
- }
-
+ // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight
super.aiStep();
}
@@ -283,7 +276,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
@@ -300,7 +293,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
}
@@ -356,8 +349,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/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index e6321e1c5ed453824de4af629feff272e24def01..1910e22e9ee2d18e86c9f8e3dd06199e73599bf6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -97,11 +97,12 @@ public class Zombie extends Monster {
private int inWaterTime;
public int conversionTime;
private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field
- 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> 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) {
@@ -298,32 +299,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();
}
@@ -361,6 +337,7 @@ public class Zombie extends Monster {
}
+ 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
}
@@ -489,7 +466,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
@@ -502,7 +479,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 4be205b10229b238039e4221df043e47cba68511..d4fc45d4f419309ba11830accdc3cdafe739ab15 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -86,6 +86,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 <T extends Entity> 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 d2bb0831394c03b620b2cbd8306cb82b621f34f7..572587db064c87ac86add6d9eece5ac94374c7b9 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -1189,4 +1189,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
}