diff --git a/patches/server/0064-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/purpur-server/minecraft-patches/features/0011-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch similarity index 75% rename from patches/server/0064-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch rename to purpur-server/minecraft-patches/features/0011-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch index fc82f2731..5dcd3da2c 100644 --- a/patches/server/0064-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch +++ b/purpur-server/minecraft-patches/features/0011-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms diff --git a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -index 7cb3d69a69e0e3ef4b7f9f9c8b1eb67edb5d116d..931cb90a8b32eb47d5985807d74d8ef7f1d01baf 100644 +index ff1c84d37db48e1bd0283a900e199647c0e8eba1..424c1c15f9c782e81a142f132dde1674547af7ba 100644 --- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -@@ -31,6 +31,12 @@ public class EndCrystal extends Entity { +@@ -26,6 +26,12 @@ public class EndCrystal extends Entity { private static final EntityDataAccessor DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN); public int time; public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals @@ -19,13 +19,14 @@ index 7cb3d69a69e0e3ef4b7f9f9c8b1eb67edb5d116d..931cb90a8b32eb47d5985807d74d8ef7 + private int idleCooldown = 0; + // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms - public EndCrystal(EntityType type, Level world) { - super(type, world); -@@ -82,6 +88,49 @@ public class EndCrystal extends Entity { - // Paper end - Fix invulnerable end crystals + public EndCrystal(EntityType entityType, Level level) { + super(entityType, level); +@@ -74,6 +80,50 @@ public class EndCrystal extends Entity { + } } - -+ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms + // Paper end - Fix invulnerable end crystals ++ ++ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms + if (level().purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) { + return; // on cooldown + } @@ -67,23 +68,23 @@ index 7cb3d69a69e0e3ef4b7f9f9c8b1eb67edb5d116d..931cb90a8b32eb47d5985807d74d8ef7 + phantomBeamTicks = 0; + phantomDamageCooldown = 0; + idleCooldown = 60; -+ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms ++ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms } @Override diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index ee00c4c7a1e0f08cdeccab63a20c4b465fdeb549..093c2601ff561c47775f9f99cb5990e6c1b05d8c 100644 +index 21ec49ac173b9eac990b63a00f5efab4e7ccfac0..438f09ef7b116352de1c75a04b42b6096bed8d87 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -49,6 +49,7 @@ public class Phantom extends FlyingMob implements Enemy { - Vec3 moveTargetPoint; - public BlockPos anchorPoint; - Phantom.AttackPhase attackPhase; +@@ -47,6 +47,7 @@ public class Phantom extends FlyingMob implements Enemy { + Vec3 moveTargetPoint = Vec3.ZERO; + public BlockPos anchorPoint = BlockPos.ZERO; + Phantom.AttackPhase attackPhase = Phantom.AttackPhase.CIRCLE; + Vec3 crystalPosition; // Purpur - Phantoms attracted to crystals and crystals shoot phantoms - - public Phantom(EntityType type, Level world) { - super(type, world); -@@ -118,6 +119,24 @@ public class Phantom extends FlyingMob implements Enemy { + // Paper start + @Nullable + public java.util.UUID spawningEntity; +@@ -118,6 +119,25 @@ public class Phantom extends FlyingMob implements Enemy { } // Purpur end - Ridables @@ -105,10 +106,11 @@ index ee00c4c7a1e0f08cdeccab63a20c4b465fdeb549..093c2601ff561c47775f9f99cb5990e6 + return crystalPosition != null; + } + // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms ++ @Override public boolean isFlapping() { - return (this.getUniqueFlapTickOffset() + this.tickCount) % Phantom.TICKS_PER_FLAP == 0; -@@ -131,9 +150,15 @@ public class Phantom extends FlyingMob implements Enemy { + return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0; +@@ -131,9 +151,15 @@ public class Phantom extends FlyingMob implements Enemy { @Override protected void registerGoals() { this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables @@ -117,8 +119,8 @@ index ee00c4c7a1e0f08cdeccab63a20c4b465fdeb549..093c2601ff561c47775f9f99cb5990e6 - this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal()); + // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms + if (level().purpurConfig.phantomOrbitCrystalRadius > 0) { -+ this.goalSelector.addGoal(1, new FindCrystalGoal(this)); -+ this.goalSelector.addGoal(2, new OrbitCrystalGoal(this)); ++ this.goalSelector.addGoal(1, new PhantomFindCrystalGoal(this)); ++ this.goalSelector.addGoal(2, new PhantomOrbitCrystalGoal(this)); + } + this.goalSelector.addGoal(3, new Phantom.PhantomAttackStrategyGoal()); + this.goalSelector.addGoal(4, new Phantom.PhantomSweepAttackGoal()); @@ -127,17 +129,17 @@ index ee00c4c7a1e0f08cdeccab63a20c4b465fdeb549..093c2601ff561c47775f9f99cb5990e6 this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); } -@@ -334,6 +359,123 @@ public class Phantom extends FlyingMob implements Enemy { - private AttackPhase() {} +@@ -505,6 +531,124 @@ public class Phantom extends FlyingMob implements Enemy { + } } + // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms -+ class FindCrystalGoal extends Goal { ++ class PhantomFindCrystalGoal extends Goal { + private final Phantom phantom; + private net.minecraft.world.entity.boss.enderdragon.EndCrystal crystal; + private Comparator comparator; + -+ FindCrystalGoal(Phantom phantom) { ++ PhantomFindCrystalGoal(Phantom phantom) { + this.phantom = phantom; + this.comparator = Comparator.comparingDouble(phantom::distanceToSqr); + this.setFlags(EnumSet.of(Flag.LOOK)); @@ -185,14 +187,14 @@ index ee00c4c7a1e0f08cdeccab63a20c4b465fdeb549..093c2601ff561c47775f9f99cb5990e6 + } + } + -+ class OrbitCrystalGoal extends Goal { ++ class PhantomOrbitCrystalGoal extends Goal { + private final Phantom phantom; + private float offset; + private float radius; + private float verticalChange; + private float direction; + -+ OrbitCrystalGoal(Phantom phantom) { ++ PhantomOrbitCrystalGoal(Phantom phantom) { + this.phantom = phantom; + this.setFlags(EnumSet.of(Flag.MOVE)); + } @@ -248,30 +250,7 @@ index ee00c4c7a1e0f08cdeccab63a20c4b465fdeb549..093c2601ff561c47775f9f99cb5990e6 + } + } + // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms - private class PhantomMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables - ++ + class PhantomMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables private float speed = 0.1F; -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index bb8aa3d4e33e2d8ed4bf3fd668577ea901410783..429c0bd678cb726b761e32d4b22b33c630f28097 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1163,6 +1163,9 @@ public class PurpurWorldConfig { - public String phantomAttackDamage = "6 + size"; - public Map phantomMaxHealthCache = new HashMap<>(); - public Map phantomAttackDamageCache = new HashMap<>(); -+ public double phantomAttackedByCrystalRadius = 0.0D; -+ public float phantomAttackedByCrystalDamage = 1.0F; -+ public double phantomOrbitCrystalRadius = 0.0D; - private void phantomSettings() { - phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); - phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); -@@ -1184,6 +1187,9 @@ public class PurpurWorldConfig { - phantomAttackDamage = getString("mobs.phantom.attributes.attack_damage", phantomAttackDamage); - phantomMaxHealthCache.clear(); - phantomAttackDamageCache.clear(); -+ phantomAttackedByCrystalRadius = getDouble("mobs.phantom.attacked-by-crystal-range", phantomAttackedByCrystalRadius); -+ phantomAttackedByCrystalDamage = (float) getDouble("mobs.phantom.attacked-by-crystal-damage", phantomAttackedByCrystalDamage); -+ phantomOrbitCrystalRadius = getDouble("mobs.phantom.orbit-crystal-radius", phantomOrbitCrystalRadius); - } - public boolean pigRidable = false; diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java index 9df1defbd..46132b659 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -1151,6 +1151,9 @@ public class PurpurWorldConfig { public String phantomAttackDamage = "6 + size"; public Map phantomMaxHealthCache = new HashMap<>(); public Map phantomAttackDamageCache = new HashMap<>(); + public double phantomAttackedByCrystalRadius = 0.0D; + public float phantomAttackedByCrystalDamage = 1.0F; + public double phantomOrbitCrystalRadius = 0.0D; private void phantomSettings() { phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); @@ -1172,6 +1175,9 @@ public class PurpurWorldConfig { phantomAttackDamage = getString("mobs.phantom.attributes.attack_damage", phantomAttackDamage); phantomMaxHealthCache.clear(); phantomAttackDamageCache.clear(); + phantomAttackedByCrystalRadius = getDouble("mobs.phantom.attacked-by-crystal-range", phantomAttackedByCrystalRadius); + phantomAttackedByCrystalDamage = (float) getDouble("mobs.phantom.attacked-by-crystal-damage", phantomAttackedByCrystalDamage); + phantomOrbitCrystalRadius = getDouble("mobs.phantom.orbit-crystal-radius", phantomOrbitCrystalRadius); } public boolean pigRidable = false;