From 0a29e9cd1c64a4561c4849d95dbcd366ea7a5831 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 Jan 2025 13:25:26 -0800 Subject: [PATCH] Special mobs naturally spawn --- .../0024-Zombie-horse-naturally-spawn.patch | 51 ----------------- ...0025-Charged-creeper-naturally-spawn.patch | 47 ---------------- ...bit-naturally-spawn-toast-and-killer.patch | 56 ------------------- ...7-Add-vindicator-johnny-spawn-chance.patch | 42 -------------- .../features/0001-Ridables.patch | 14 ++--- .../server/level/ServerLevel.java.patch | 22 ++++++++ .../world/entity/animal/Rabbit.java.patch | 26 +++++++++ .../world/entity/monster/Creeper.java.patch | 19 +++++++ .../entity/monster/Vindicator.java.patch | 14 +++++ .../purpurmc/purpur/PurpurWorldConfig.java | 10 ++++ 10 files changed, 98 insertions(+), 203 deletions(-) delete mode 100644 patches/server/0024-Zombie-horse-naturally-spawn.patch delete mode 100644 patches/server/0025-Charged-creeper-naturally-spawn.patch delete mode 100644 patches/server/0026-Rabbit-naturally-spawn-toast-and-killer.patch delete mode 100644 patches/server/0077-Add-vindicator-johnny-spawn-chance.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch diff --git a/patches/server/0024-Zombie-horse-naturally-spawn.patch b/patches/server/0024-Zombie-horse-naturally-spawn.patch deleted file mode 100644 index 1ac95e344..000000000 --- a/patches/server/0024-Zombie-horse-naturally-spawn.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 7 Jul 2019 19:52:16 -0500 -Subject: [PATCH] Zombie horse naturally spawn - - -diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 4b9434b2d03cd24f5dac7098d2f1318fd12baddb..7ab130afddb0893016fb558ed624198316ca191d 100644 ---- a/net/minecraft/server/level/ServerLevel.java -+++ b/net/minecraft/server/level/ServerLevel.java -@@ -940,10 +940,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper - Configurable spawn chances for skeleton horses - - if (flag1) { -- SkeletonHorse entityhorseskeleton = (SkeletonHorse) EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); -+ // Purpur start -+ net.minecraft.world.entity.animal.horse.AbstractHorse entityhorseskeleton; -+ if (purpurConfig.zombieHorseSpawnChance > 0D && random.nextDouble() <= purpurConfig.zombieHorseSpawnChance) { -+ entityhorseskeleton = EntityType.ZOMBIE_HORSE.create(this, EntitySpawnReason.EVENT); -+ } else { -+ entityhorseskeleton = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); -+ if (entityhorseskeleton != null) ((SkeletonHorse) entityhorseskeleton).setTrap(true); -+ } -+ // Purpur end - - if (entityhorseskeleton != null) { -- entityhorseskeleton.setTrap(true); -+ //entityhorseskeleton.setTrap(true); // Purpur - moved up - entityhorseskeleton.setAge(0); - entityhorseskeleton.setPos((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); - this.addFreshEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 3c3df7767bc97882f53f32de1b4a350f73b16f23..7c7fce74431a52de80a29c0e4ca87b45e2ce892c 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1657,6 +1657,7 @@ public class PurpurWorldConfig { - public double zombieHorseJumpStrengthMax = 1.0D; - public double zombieHorseMovementSpeedMin = 0.2D; - public double zombieHorseMovementSpeedMax = 0.2D; -+ public double zombieHorseSpawnChance = 0.0D; - private void zombieHorseSettings() { - zombieHorseRidable = getBoolean("mobs.zombie_horse.ridable", zombieHorseRidable); - zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); -@@ -1673,6 +1674,7 @@ public class PurpurWorldConfig { - zombieHorseJumpStrengthMax = getDouble("mobs.zombie_horse.attributes.jump_strength.max", zombieHorseJumpStrengthMax); - zombieHorseMovementSpeedMin = getDouble("mobs.zombie_horse.attributes.movement_speed.min", zombieHorseMovementSpeedMin); - zombieHorseMovementSpeedMax = getDouble("mobs.zombie_horse.attributes.movement_speed.max", zombieHorseMovementSpeedMax); -+ zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); - } - - public boolean zombieVillagerRidable = false; diff --git a/patches/server/0025-Charged-creeper-naturally-spawn.patch b/patches/server/0025-Charged-creeper-naturally-spawn.patch deleted file mode 100644 index b456c743f..000000000 --- a/patches/server/0025-Charged-creeper-naturally-spawn.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 29 Nov 2019 22:37:44 -0600 -Subject: [PATCH] Charged creeper naturally spawn - - -diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java -index a93b9bf974fdee49cf9fe814bfb86467971f2f53..d67136ccf5e23accb656f2532e2ced93669f2a8d 100644 ---- a/net/minecraft/world/entity/monster/Creeper.java -+++ b/net/minecraft/world/entity/monster/Creeper.java -@@ -258,6 +258,16 @@ public class Creeper extends Monster { - } - } - -+ // Purpur start - Charged creeper naturally spawn -+ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.EntitySpawnReason spawnReason, @Nullable net.minecraft.world.entity.SpawnGroupData entityData) { -+ double chance = world.getLevel().purpurConfig.creeperChargedChance; -+ if (chance > 0D && random.nextDouble() <= chance) { -+ setPowered(true); -+ } -+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData); -+ } -+ // Purpur end - Charged creeper naturally spawn -+ - @Override - protected SoundEvent getHurtSound(DamageSource source) { - return SoundEvents.CREEPER_HURT; -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 7c7fce74431a52de80a29c0e4ca87b45e2ce892c..3ec1852cc481572e87204ca800edae94e6890e05 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -408,6 +408,7 @@ public class PurpurWorldConfig { - public boolean creeperControllable = true; - public double creeperMaxHealth = 20.0D; - public double creeperScale = 1.0D; -+ public double creeperChargedChance = 0.0D; - private void creeperSettings() { - creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); - creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); -@@ -419,6 +420,7 @@ public class PurpurWorldConfig { - } - creeperMaxHealth = getDouble("mobs.creeper.attributes.max_health", creeperMaxHealth); - creeperScale = Mth.clamp(getDouble("mobs.creeper.attributes.scale", creeperScale), 0.0625D, 16.0D); -+ creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); - } - - public boolean dolphinRidable = false; diff --git a/patches/server/0026-Rabbit-naturally-spawn-toast-and-killer.patch b/patches/server/0026-Rabbit-naturally-spawn-toast-and-killer.patch deleted file mode 100644 index 6fda47fcb..000000000 --- a/patches/server/0026-Rabbit-naturally-spawn-toast-and-killer.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 31 Aug 2019 17:47:11 -0500 -Subject: [PATCH] Rabbit naturally spawn toast and killer - - -diff --git a/net/minecraft/world/entity/animal/Rabbit.java b/net/minecraft/world/entity/animal/Rabbit.java -index 7ce438ad3083ff7f431c1f292d1c38d53c14672c..6448d4f44f948f08121302784e966bf58abd9be1 100644 ---- a/net/minecraft/world/entity/animal/Rabbit.java -+++ b/net/minecraft/world/entity/animal/Rabbit.java -@@ -470,10 +470,23 @@ public class Rabbit extends Animal implements VariantHolder { - } - - this.setVariant(entityrabbit_variant); -+ -+ // Purpur start -+ if (entityrabbit_variant != Variant.EVIL && world.getLevel().purpurConfig.rabbitNaturalToast > 0D && random.nextDouble() <= world.getLevel().purpurConfig.rabbitNaturalToast) { -+ setCustomName(Component.translatable("Toast")); -+ } -+ // Purpur end -+ - return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData); - } - - private static Rabbit.Variant getRandomRabbitVariant(LevelAccessor world, BlockPos pos) { -+ // Purpur start -+ Level level = world.getMinecraftWorld(); -+ if (level.purpurConfig.rabbitNaturalKiller > 0D && world.getRandom().nextDouble() <= level.purpurConfig.rabbitNaturalKiller) { -+ return Rabbit.Variant.EVIL; -+ } -+ // Purpur end - Holder holder = world.getBiome(pos); - int i = world.getRandom().nextInt(100); - -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 3ec1852cc481572e87204ca800edae94e6890e05..0ba770af96809403dd93317dcf5120c7d87bf587 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1105,6 +1105,8 @@ public class PurpurWorldConfig { - public boolean rabbitControllable = true; - public double rabbitMaxHealth = 3.0D; - public double rabbitScale = 1.0D; -+ public double rabbitNaturalToast = 0.0D; -+ public double rabbitNaturalKiller = 0.0D; - private void rabbitSettings() { - rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); - rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); -@@ -1116,6 +1118,8 @@ public class PurpurWorldConfig { - } - rabbitMaxHealth = getDouble("mobs.rabbit.attributes.max_health", rabbitMaxHealth); - rabbitScale = Mth.clamp(getDouble("mobs.rabbit.attributes.scale", rabbitScale), 0.0625D, 16.0D); -+ rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast); -+ rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); - } - - public boolean ravagerRidable = false; diff --git a/patches/server/0077-Add-vindicator-johnny-spawn-chance.patch b/patches/server/0077-Add-vindicator-johnny-spawn-chance.patch deleted file mode 100644 index d6eeec766..000000000 --- a/patches/server/0077-Add-vindicator-johnny-spawn-chance.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 24 Jul 2020 19:38:21 -0500 -Subject: [PATCH] Add vindicator johnny spawn chance - - -diff --git a/net/minecraft/world/entity/monster/Vindicator.java b/net/minecraft/world/entity/monster/Vindicator.java -index 065bd31afe948c1ffab4da6f2a236cd931e75259..7f414f74c315db67a8e8a3d3636811abe733f62a 100644 ---- a/net/minecraft/world/entity/monster/Vindicator.java -+++ b/net/minecraft/world/entity/monster/Vindicator.java -@@ -158,6 +158,11 @@ public class Vindicator extends AbstractIllager { - RandomSource randomSource = world.getRandom(); - this.populateDefaultEquipmentSlots(randomSource, difficulty); - this.populateDefaultEquipmentEnchantments(world, randomSource, difficulty); -+ // Purpur start -+ if (level().purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level().purpurConfig.vindicatorJohnnySpawnChance) { -+ setCustomName(Component.translatable("Johnny")); -+ } -+ // Purpur end - return spawnGroupData; - } - -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 35ce3c0385f72feea1a0741ee055994f5cf0190a..a4c20f7b679150425b192a9e4411fa987aed8e1f 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1789,6 +1789,7 @@ public class PurpurWorldConfig { - public boolean vindicatorControllable = true; - public double vindicatorMaxHealth = 24.0D; - public double vindicatorScale = 1.0D; -+ public double vindicatorJohnnySpawnChance = 0D; - private void vindicatorSettings() { - vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); - vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); -@@ -1800,6 +1801,7 @@ public class PurpurWorldConfig { - } - vindicatorMaxHealth = getDouble("mobs.vindicator.attributes.max_health", vindicatorMaxHealth); - vindicatorScale = Mth.clamp(getDouble("mobs.vindicator.attributes.scale", vindicatorScale), 0.0625D, 16.0D); -+ vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance); - } - - public boolean wanderingTraderRidable = false; diff --git a/purpur-server/minecraft-patches/features/0001-Ridables.patch b/purpur-server/minecraft-patches/features/0001-Ridables.patch index 8120c96a9..ce6d3117e 100644 --- a/purpur-server/minecraft-patches/features/0001-Ridables.patch +++ b/purpur-server/minecraft-patches/features/0001-Ridables.patch @@ -30,7 +30,7 @@ index 717b2496ffb1246e6335db8eb5c8e724fbacd1cf..6812185f1d1a1fb14285267b7398f4ca /* Drop global time updates if (this.tickCount % 20 == 0) { diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index ebeeb63c3dca505a3ce8b88feaa5d2ca20ec24a2..0029717fbd4f2475b07abf4f7036cebbe68949db 100644 +index 1ed30a8fa93d248e682dae48f7cc5bae9c005b03..909eed8ed93ae9f205c3e0c63bf6b7988a1cc8be 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -215,6 +215,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1518,7 +1518,7 @@ index d94a7cfcd0f7a15ce97d3b12daa8b2c71acf997a..f7e9abf778186ad1c78dbe411980a83c protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/animal/Rabbit.java b/net/minecraft/world/entity/animal/Rabbit.java -index c5346b6e4ffe09ca1ec4b85e612c9ee52ae77329..9342662abf74b921573aba2bbacb43e6ad5683f5 100644 +index 4708c7479fdd818f6fdf672b45af1ed435d7d2ef..6e39e00fc6227edda23d4ec23a5625562a452fd2 100644 --- a/net/minecraft/world/entity/animal/Rabbit.java +++ b/net/minecraft/world/entity/animal/Rabbit.java @@ -83,6 +83,7 @@ public class Rabbit extends Animal implements VariantHolder { @@ -1613,7 +1613,7 @@ index c5346b6e4ffe09ca1ec4b85e612c9ee52ae77329..9342662abf74b921573aba2bbacb43e6 if (this.jumpDelayTicks > 0) { this.jumpDelayTicks--; } -@@ -470,7 +531,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -483,7 +544,7 @@ public class Rabbit extends Animal implements VariantHolder { } } @@ -1622,7 +1622,7 @@ index c5346b6e4ffe09ca1ec4b85e612c9ee52ae77329..9342662abf74b921573aba2bbacb43e6 private final Rabbit rabbit; private double nextJumpSpeed; -@@ -480,14 +541,14 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -493,14 +554,14 @@ public class Rabbit extends Animal implements VariantHolder { } @Override @@ -3131,7 +3131,7 @@ index 2e32567fca7a2a4cd87bc078a6eeb30e3ffabfce..4873a3d8dd9c160ecdbda594ee546c35 public boolean doHurtTarget(ServerLevel level, Entity source) { if (super.doHurtTarget(level, source)) { diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java -index e832612a7ed3f25d087c4f8f85f5d737ade5d645..9adf407bde97e607af915123a999fde2728ad7a4 100644 +index 958a69656a5fac2c04047d452deb15203f436d72..1e2acc2fb369afe8cb391e4b8ac0c2927af2127b 100644 --- a/net/minecraft/world/entity/monster/Creeper.java +++ b/net/minecraft/world/entity/monster/Creeper.java @@ -50,21 +50,98 @@ public class Creeper extends Monster { @@ -3233,7 +3233,7 @@ index e832612a7ed3f25d087c4f8f85f5d737ade5d645..9adf407bde97e607af915123a999fde2 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this)); } -@@ -288,6 +365,7 @@ public class Creeper extends Monster { +@@ -298,6 +375,7 @@ public class Creeper extends Monster { com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); if (event.callEvent()) { this.entityData.set(DATA_IS_IGNITED, event.isIgnited()); @@ -4468,7 +4468,7 @@ index 7f1cdea810db24182f8f87076c42a19b1b43e98a..26528bc9a9cffb68f82917a3e70900cf Vec3 deltaMovement = Vex.this.getDeltaMovement(); Vex.this.setYRot(-((float)Mth.atan2(deltaMovement.x, deltaMovement.z)) * (180.0F / (float)Math.PI)); diff --git a/net/minecraft/world/entity/monster/Vindicator.java b/net/minecraft/world/entity/monster/Vindicator.java -index 5f649d1e69d2be8d8e6963544e3aab6848616893..637d7a78dd92851afb8a68bfdbbf84019d21599c 100644 +index 402c22d9feaf0301ed95692b783fb0f226510833..8a6a0b7522437a3cb627a164b9164b53dee6c460 100644 --- a/net/minecraft/world/entity/monster/Vindicator.java +++ b/net/minecraft/world/entity/monster/Vindicator.java @@ -55,15 +55,34 @@ public class Vindicator extends AbstractIllager { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch new file mode 100644 index 000000000..49e8be572 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -934,9 +_,18 @@ + && this.random.nextDouble() < currentDifficultyAt.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01) // Paper - Configurable spawn chances for skeleton horses + && !this.getBlockState(blockPos.below()).is(Blocks.LIGHTNING_ROD); + if (flag) { ++ // Purpur start - Special mobs naturally spawn ++ net.minecraft.world.entity.animal.horse.AbstractHorse entityhorseskeleton; ++ if (purpurConfig.zombieHorseSpawnChance > 0D && random.nextDouble() <= purpurConfig.zombieHorseSpawnChance) { ++ entityhorseskeleton = EntityType.ZOMBIE_HORSE.create(this, EntitySpawnReason.EVENT); ++ } else { ++ entityhorseskeleton = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); ++ if (entityhorseskeleton != null) ((SkeletonHorse) entityhorseskeleton).setTrap(true); ++ } ++ // Purpur end - Special mobs naturally spawn + SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); + if (skeletonHorse != null) { +- skeletonHorse.setTrap(true); ++ //skeletonHorse.setTrap(true); // Purpur - Special mobs naturally spawn - moved up + skeletonHorse.setAge(0); + skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + this.addFreshEntity(skeletonHorse, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch new file mode 100644 index 000000000..ed0b1c6aa --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/entity/animal/Rabbit.java ++++ b/net/minecraft/world/entity/animal/Rabbit.java +@@ -376,10 +_,23 @@ + } + + this.setVariant(randomRabbitVariant); ++ ++ // Purpur start - Special mobs naturally spawn ++ if (randomRabbitVariant != Variant.EVIL && level.getLevel().purpurConfig.rabbitNaturalToast > 0D && random.nextDouble() <= level.getLevel().purpurConfig.rabbitNaturalToast) { ++ setCustomName(Component.translatable("Toast")); ++ } ++ // Purpur end - Special mobs naturally spawn ++ + return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); + } + + private static Rabbit.Variant getRandomRabbitVariant(LevelAccessor level, BlockPos pos) { ++ // Purpur start - Special mobs naturally spawn ++ Level world = level.getMinecraftWorld(); ++ if (world.purpurConfig.rabbitNaturalKiller > 0D && world.getRandom().nextDouble() <= world.purpurConfig.rabbitNaturalKiller) { ++ return Rabbit.Variant.EVIL; ++ } ++ // Purpur end - Special mobs naturally spawn + Holder biome = level.getBiome(pos); + int randomInt = level.getRandom().nextInt(100); + if (biome.is(BiomeTags.SPAWNS_WHITE_RABBITS)) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch new file mode 100644 index 000000000..1e3911d16 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/entity/monster/Creeper.java ++++ b/net/minecraft/world/entity/monster/Creeper.java +@@ -161,6 +_,16 @@ + } + } + ++ // Purpur start - Special mobs naturally spawn ++ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.EntitySpawnReason spawnReason, @Nullable net.minecraft.world.entity.SpawnGroupData entityData) { ++ double chance = world.getLevel().purpurConfig.creeperChargedChance; ++ if (chance > 0D && random.nextDouble() <= chance) { ++ setPowered(true); ++ } ++ return super.finalizeSpawn(world, difficulty, spawnReason, entityData); ++ } ++ // Purpur end - Special mobs naturally spawn ++ + @Override + protected SoundEvent getHurtSound(DamageSource damageSource) { + return SoundEvents.CREEPER_HURT; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch new file mode 100644 index 000000000..fe07bf809 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/entity/monster/Vindicator.java ++++ b/net/minecraft/world/entity/monster/Vindicator.java +@@ -132,6 +_,11 @@ + RandomSource random = level.getRandom(); + this.populateDefaultEquipmentSlots(random, difficulty); + this.populateDefaultEquipmentEnchantments(level, random, difficulty); ++ // Purpur start - Special mobs naturally spawn ++ if (level().purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level().purpurConfig.vindicatorJohnnySpawnChance) { ++ setCustomName(Component.translatable("Johnny")); ++ } ++ // Purpur end - Special mobs naturally spawn + return spawnGroupData1; + } + 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 065c9e5b9..16df261c3 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -394,6 +394,7 @@ public class PurpurWorldConfig { public boolean creeperControllable = true; public double creeperMaxHealth = 20.0D; public double creeperScale = 1.0D; + public double creeperChargedChance = 0.0D; private void creeperSettings() { creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); @@ -405,6 +406,7 @@ public class PurpurWorldConfig { } creeperMaxHealth = getDouble("mobs.creeper.attributes.max_health", creeperMaxHealth); creeperScale = Mth.clamp(getDouble("mobs.creeper.attributes.scale", creeperScale), 0.0625D, 16.0D); + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); } public boolean dolphinRidable = false; @@ -1089,6 +1091,8 @@ public class PurpurWorldConfig { public boolean rabbitControllable = true; public double rabbitMaxHealth = 3.0D; public double rabbitScale = 1.0D; + public double rabbitNaturalToast = 0.0D; + public double rabbitNaturalKiller = 0.0D; private void rabbitSettings() { rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); @@ -1100,6 +1104,8 @@ public class PurpurWorldConfig { } rabbitMaxHealth = getDouble("mobs.rabbit.attributes.max_health", rabbitMaxHealth); rabbitScale = Mth.clamp(getDouble("mobs.rabbit.attributes.scale", rabbitScale), 0.0625D, 16.0D); + rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast); + rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); } public boolean ravagerRidable = false; @@ -1478,6 +1484,7 @@ public class PurpurWorldConfig { public boolean vindicatorControllable = true; public double vindicatorMaxHealth = 24.0D; public double vindicatorScale = 1.0D; + public double vindicatorJohnnySpawnChance = 0D; private void vindicatorSettings() { vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); @@ -1489,6 +1496,7 @@ public class PurpurWorldConfig { } vindicatorMaxHealth = getDouble("mobs.vindicator.attributes.max_health", vindicatorMaxHealth); vindicatorScale = Mth.clamp(getDouble("mobs.vindicator.attributes.scale", vindicatorScale), 0.0625D, 16.0D); + vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance); } public boolean wanderingTraderRidable = false; @@ -1643,6 +1651,7 @@ public class PurpurWorldConfig { public double zombieHorseJumpStrengthMax = 1.0D; public double zombieHorseMovementSpeedMin = 0.2D; public double zombieHorseMovementSpeedMax = 0.2D; + public double zombieHorseSpawnChance = 0.0D; private void zombieHorseSettings() { zombieHorseRidable = getBoolean("mobs.zombie_horse.ridable", zombieHorseRidable); zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); @@ -1659,6 +1668,7 @@ public class PurpurWorldConfig { zombieHorseJumpStrengthMax = getDouble("mobs.zombie_horse.attributes.jump_strength.max", zombieHorseJumpStrengthMax); zombieHorseMovementSpeedMin = getDouble("mobs.zombie_horse.attributes.movement_speed.min", zombieHorseMovementSpeedMin); zombieHorseMovementSpeedMax = getDouble("mobs.zombie_horse.attributes.movement_speed.max", zombieHorseMovementSpeedMax); + zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); } public boolean zombieVillagerRidable = false;