diff --git a/patches/server/0173-Shulker-spawn-from-bullet-options.patch b/patches/server/0173-Shulker-spawn-from-bullet-options.patch deleted file mode 100644 index c7acddb92..000000000 --- a/patches/server/0173-Shulker-spawn-from-bullet-options.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 25 Jun 2021 19:48:21 -0500 -Subject: [PATCH] Shulker spawn from bullet options - -(0 - 1) / 5.0 = -0.2 (can never happen because self is included in count) -(1 - 1) / 5.0 = 0.0 1.0 - 0.0 = 1.0 100% (just self) -(2 - 1) / 5.0 = 0.2 1.0 - 0.2 = 0.8 80% (1 other shulker) -(3 - 1) / 5.0 = 0.4 1.0 - 0.4 = 0.6 60% (2 other shulkers) -(4 - 1) / 5.0 = 0.6 1.0 - 0.6 = 0.4 40% (3 other shulkers) -(5 - 1) / 5.0 = 0.8 1.0 - 0.8 = 0.2 20% (4 other shulkers) -(6 - 1) / 5.0 = 1.0 1.0 - 1.0 = 0.0 0% (5 other shulkers) -(7 - 1) / 5.0 = 1.2 1.0 - 1.2 = -0.2 0% (6 other shulkers) - -diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index 2b2e68e1449606ecfe5c414834ce3e2c6912d820..1957e2be5087e7bf85be5dfba53de8385dbeadd6 100644 ---- a/net/minecraft/world/entity/monster/Shulker.java -+++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -512,12 +512,21 @@ public class Shulker extends AbstractGolem implements VariantHolder= f) { -+ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) { -+ // Purpur start -+ float chance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance; -+ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) { -+ int nearby = this.level().getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size(); -+ try { -+ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue(); -+ } catch (javax.script.ScriptException e) { -+ e.printStackTrace(); -+ chance -= (nearby - 1) / 5.0F; -+ } -+ } -+ if (this.level().random.nextFloat() <= chance) { - Shulker entityshulker = (Shulker) EntityType.SHULKER.create(this.level(), EntitySpawnReason.BREEDING); -+ // Purpur end - - if (entityshulker != null) { - entityshulker.setVariant(this.getVariant()); -@@ -631,7 +640,7 @@ public class Shulker extends AbstractGolem implements VariantHolder getVariant() { -- return Optional.ofNullable(this.getColor()); -+ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur - } - - @Nullable -diff --git a/net/minecraft/world/item/DyeColor.java b/net/minecraft/world/item/DyeColor.java -index 648e6979aa72b9d1e1ea3b40d5a876e3c690b934..d9cd4f47e9990bdd85e30f68ca3b755a953332a1 100644 ---- a/net/minecraft/world/item/DyeColor.java -+++ b/net/minecraft/world/item/DyeColor.java -@@ -123,4 +123,10 @@ public enum DyeColor implements StringRepresentable { - private static CraftingInput makeCraftColorInput(DyeColor first, DyeColor second) { - return CraftingInput.of(2, 1, List.of(new ItemStack(DyeItem.byColor(first)), new ItemStack(DyeItem.byColor(second)))); - } -+ -+ // Purpur start -+ public static DyeColor random(net.minecraft.util.RandomSource random) { -+ return values()[random.nextInt(values().length)]; -+ } -+ // Purpur end - } -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 849532c99cfad2870fd22be6e759e153e8fae10b..51609ddc3890b5a6a9106b6d2960697723651ec2 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1993,6 +1993,11 @@ public class PurpurWorldConfig { - public double shulkerMaxHealth = 30.0D; - public double shulkerScale = 1.0D; - public boolean shulkerTakeDamageFromWater = false; -+ public float shulkerSpawnFromBulletBaseChance = 1.0F; -+ public boolean shulkerSpawnFromBulletRequireOpenLid = true; -+ public double shulkerSpawnFromBulletNearbyRange = 8.0D; -+ public String shulkerSpawnFromBulletNearbyEquation = "(nearby - 1) / 5.0"; -+ public boolean shulkerSpawnFromBulletRandomColor = false; - private void shulkerSettings() { - shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); - shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); -@@ -2005,6 +2010,11 @@ public class PurpurWorldConfig { - shulkerMaxHealth = getDouble("mobs.shulker.attributes.max_health", shulkerMaxHealth); - shulkerScale = Mth.clamp(getDouble("mobs.shulker.attributes.scale", shulkerScale), 0.0625D, Shulker.MAX_SCALE); - shulkerTakeDamageFromWater = getBoolean("mobs.shulker.takes-damage-from-water", shulkerTakeDamageFromWater); -+ shulkerSpawnFromBulletBaseChance = (float) getDouble("mobs.shulker.spawn-from-bullet.base-chance", shulkerSpawnFromBulletBaseChance); -+ shulkerSpawnFromBulletRequireOpenLid = getBoolean("mobs.shulker.spawn-from-bullet.require-open-lid", shulkerSpawnFromBulletRequireOpenLid); -+ shulkerSpawnFromBulletNearbyRange = getDouble("mobs.shulker.spawn-from-bullet.nearby-range", shulkerSpawnFromBulletNearbyRange); -+ shulkerSpawnFromBulletNearbyEquation = getString("mobs.shulker.spawn-from-bullet.nearby-equation", shulkerSpawnFromBulletNearbyEquation); -+ shulkerSpawnFromBulletRandomColor = getBoolean("mobs.shulker.spawn-from-bullet.random-color", shulkerSpawnFromBulletRandomColor); - } - - public boolean silverfishRidable = false; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch new file mode 100644 index 000000000..e3ed54c06 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/world/entity/monster/Shulker.java ++++ b/net/minecraft/world/entity/monster/Shulker.java +@@ -50,6 +_,7 @@ + import net.minecraft.world.level.ServerLevelAccessor; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.entity.EntityTypeTest; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.AABB; + import net.minecraft.world.phys.Vec3; +@@ -459,11 +_,21 @@ + private void hitByShulkerBullet() { + Vec3 vec3 = this.position(); + AABB boundingBox = this.getBoundingBox(); +- if (!this.isClosed() && this.teleportSomewhere()) { +- int size = this.level().getEntities(EntityType.SHULKER, boundingBox.inflate(8.0), Entity::isAlive).size(); +- float f = (size - 1) / 5.0F; +- if (!(this.level().random.nextFloat() < f)) { ++ // Purpur start - Shulker spawn from bullet options ++ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) { ++ float chance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance; ++ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) { ++ int nearby = this.level().getEntities((EntityTypeTest) EntityType.SHULKER, boundingBox.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size(); ++ try { ++ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue(); ++ } catch (javax.script.ScriptException e) { ++ e.printStackTrace(); ++ chance -= (nearby - 1) / 5.0F; ++ } ++ } ++ if (this.level().random.nextFloat() <= chance) { + Shulker shulker = EntityType.SHULKER.create(this.level(), EntitySpawnReason.BREEDING); ++ // Purpur end - Shulker spawn from bullet options + if (shulker != null) { + shulker.setVariant(this.getVariant()); + shulker.moveTo(vec3); +@@ -573,7 +_,7 @@ + + @Override + public Optional getVariant() { +- return Optional.ofNullable(this.getColor()); ++ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur - Shulker spawn from bullet options + } + + @Nullable diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/item/DyeColor.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/item/DyeColor.java.patch new file mode 100644 index 000000000..f18d71793 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/item/DyeColor.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/item/DyeColor.java ++++ b/net/minecraft/world/item/DyeColor.java +@@ -123,4 +_,10 @@ + private static CraftingInput makeCraftColorInput(DyeColor first, DyeColor second) { + return CraftingInput.of(2, 1, List.of(new ItemStack(DyeItem.byColor(first)), new ItemStack(DyeItem.byColor(second)))); + } ++ ++ // Purpur start - Shulker spawn from bullet options ++ public static DyeColor random(net.minecraft.util.RandomSource random) { ++ return values()[random.nextInt(values().length)]; ++ } ++ // Purpur end - Shulker spawn from bullet options + } 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 c9d0e1753..3e41202ee 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -1985,6 +1985,11 @@ public class PurpurWorldConfig { public double shulkerMaxHealth = 30.0D; public double shulkerScale = 1.0D; public boolean shulkerTakeDamageFromWater = false; + public float shulkerSpawnFromBulletBaseChance = 1.0F; + public boolean shulkerSpawnFromBulletRequireOpenLid = true; + public double shulkerSpawnFromBulletNearbyRange = 8.0D; + public String shulkerSpawnFromBulletNearbyEquation = "(nearby - 1) / 5.0"; + public boolean shulkerSpawnFromBulletRandomColor = false; private void shulkerSettings() { shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); @@ -1997,6 +2002,11 @@ public class PurpurWorldConfig { shulkerMaxHealth = getDouble("mobs.shulker.attributes.max_health", shulkerMaxHealth); shulkerScale = Mth.clamp(getDouble("mobs.shulker.attributes.scale", shulkerScale), 0.0625D, Shulker.MAX_SCALE); shulkerTakeDamageFromWater = getBoolean("mobs.shulker.takes-damage-from-water", shulkerTakeDamageFromWater); + shulkerSpawnFromBulletBaseChance = (float) getDouble("mobs.shulker.spawn-from-bullet.base-chance", shulkerSpawnFromBulletBaseChance); + shulkerSpawnFromBulletRequireOpenLid = getBoolean("mobs.shulker.spawn-from-bullet.require-open-lid", shulkerSpawnFromBulletRequireOpenLid); + shulkerSpawnFromBulletNearbyRange = getDouble("mobs.shulker.spawn-from-bullet.nearby-range", shulkerSpawnFromBulletNearbyRange); + shulkerSpawnFromBulletNearbyEquation = getString("mobs.shulker.spawn-from-bullet.nearby-equation", shulkerSpawnFromBulletNearbyEquation); + shulkerSpawnFromBulletRandomColor = getBoolean("mobs.shulker.spawn-from-bullet.random-color", shulkerSpawnFromBulletRandomColor); } public boolean silverfishRidable = false;