diff --git a/patches/server/0218-Shulker-spawn-from-bullet-options.patch b/patches/server/0218-Shulker-spawn-from-bullet-options.patch new file mode 100644 index 000000000..8698410d4 --- /dev/null +++ b/patches/server/0218-Shulker-spawn-from-bullet-options.patch @@ -0,0 +1,90 @@ +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/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java +index d6fdaa9f9033d8b1e8aa9ef0aace387e286ebce9..03da91ee39851e8d066b8c63dce849e665c59479 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java +@@ -496,13 +496,22 @@ public class Shulker extends AbstractGolem implements Enemy { + Vec3 vec3d = this.position(); + AABB axisalignedbb = this.getBoundingBox(); + +- if (!this.isClosed() && this.teleportSomewhere()) { +- int i = this.level.getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(8.0D), Entity::isAlive).size(); +- float f = (float) (i - 1) / 5.0F; +- +- if (this.level.random.nextFloat() >= 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 { ++ scriptEngine.eval("nearby = " + nearby); ++ chance -= (float) scriptEngine.eval(this.level.purpurConfig.shulkerSpawnFromBulletNearbyEquation); ++ } catch (Exception ignore) { ++ chance -= (float) (nearby - 1) / 5.0F; ++ } ++ } ++ if (this.level.random.nextFloat() <= chance) { ++ // Purpur end + Shulker entityshulker = (Shulker) EntityType.SHULKER.create(this.level); +- DyeColor enumcolor = this.getColor(); ++ DyeColor enumcolor = this.level.purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level.random) : this.getColor(); // Purpur + + if (enumcolor != null) { + entityshulker.setColor(enumcolor); +diff --git a/src/main/java/net/minecraft/world/item/DyeColor.java b/src/main/java/net/minecraft/world/item/DyeColor.java +index f812a75985d26785639491c9a980387a3f261f2d..b11fb39b69f5225ca7da72ca1a2200c7eaf7e873 100644 +--- a/src/main/java/net/minecraft/world/item/DyeColor.java ++++ b/src/main/java/net/minecraft/world/item/DyeColor.java +@@ -109,4 +109,10 @@ public enum DyeColor implements StringRepresentable { + public String getSerializedName() { + return this.name; + } ++ ++ // Purpur start ++ public static DyeColor random(java.util.Random random) { ++ return BY_ID[random.nextInt(BY_ID.length)]; ++ } ++ // Purpur end + } +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 9c766351673b66f02db3b88ef7b1651e63779307..7d5668def342d87a645b95493a15d8b70981e4ed 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -1697,6 +1697,11 @@ public class PurpurWorldConfig { + public boolean shulkerRidable = false; + public boolean shulkerRidableInWater = false; + public double shulkerMaxHealth = 30.0D; ++ 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); +@@ -1706,6 +1711,11 @@ public class PurpurWorldConfig { + set("mobs.shulker.attributes.max_health", oldValue); + } + shulkerMaxHealth = getDouble("mobs.shulker.attributes.max_health", shulkerMaxHealth); ++ 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;