From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 3 Jul 2020 00:03:52 -0500
Subject: [PATCH] Add phantom spawning options


diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
index 79504dc3448402e73b09c4232b1fd0488872cf68..300c9f136edace2babea4a574090b1849b2adf76 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -43,8 +43,8 @@ public class PhantomSpawner implements CustomSpawner {
             if (this.nextTick > 0) {
                 return 0;
             } else {
-                this.nextTick += (60 + random.nextInt(60)) * 20;
-                if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) {
+                this.nextTick += world.purpurConfig.phantomSpawnDelayMin + world.random.nextInt(world.purpurConfig.phantomSpawnDelayMax - world.purpurConfig.phantomSpawnDelayMin + 1); // Purpur
+                if (world.getSkyDarken() < world.purpurConfig.phantomSpawnMinSkyDarkness && world.dimensionType().hasSkyLight()) { // Purpur
                     return 0;
                 } else {
                     int i = 0;
@@ -56,22 +56,22 @@ public class PhantomSpawner implements CustomSpawner {
                         if (!entityhuman.isSpectator() && (!world.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper
                             BlockPos blockposition = entityhuman.blockPosition();
 
-                            if (!world.dimensionType().hasSkyLight() || blockposition.getY() >= world.getSeaLevel() && world.canSeeSky(blockposition)) {
+                            if (!world.dimensionType().hasSkyLight() || (!world.purpurConfig.phantomSpawnOnlyAboveSeaLevel || blockposition.getY() >= world.getSeaLevel()) && (!world.purpurConfig.phantomSpawnOnlyWithVisibleSky || world.canSeeSky(blockposition))) { // Purpur
                                 DifficultyInstance difficultydamagescaler = world.getCurrentDifficultyAt(blockposition);
 
-                                if (difficultydamagescaler.isHarderThan(random.nextFloat() * 3.0F)) {
+                                if (difficultydamagescaler.isHarderThan(random.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) { // Purpur
                                     ServerStatsCounter serverstatisticmanager = ((ServerPlayer) entityhuman).getStats();
                                     int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
                                     boolean flag2 = true;
 
-                                    if (random.nextInt(j) >= 72000) {
-                                        BlockPos blockposition1 = blockposition.above(20 + random.nextInt(15)).east(-10 + random.nextInt(21)).south(-10 + random.nextInt(21));
+                                    if (random.nextInt(j) >= world.purpurConfig.phantomSpawnMinTimeSinceSlept) { // Purpur
+                                        BlockPos blockposition1 = blockposition.above(world.purpurConfig.phantomSpawnMinOverhead + random.nextInt(world.purpurConfig.phantomSpawnMaxOverhead - world.purpurConfig.phantomSpawnMinOverhead + 1)).east(-world.purpurConfig.phantomSpawnOverheadRadius + random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius * 2 + 1)).south(-world.purpurConfig.phantomSpawnOverheadRadius + random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius * 2 + 1)); // Purpur
                                         BlockState iblockdata = world.getBlockState(blockposition1);
                                         FluidState fluid = world.getFluidState(blockposition1);
 
                                         if (NaturalSpawner.isValidEmptySpawnBlock((BlockGetter) world, blockposition1, iblockdata, fluid, EntityType.PHANTOM)) {
                                             SpawnGroupData groupdataentity = null;
-                                            int k = 1 + random.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
+                                            int k = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficultydamagescaler.getDifficulty().getId() : world.purpurConfig.phantomSpawnMaxPerAttempt - world.purpurConfig.phantomSpawnMinPerAttempt) + 1); // Purpur
 
                                             for (int l = 0; l < k; ++l) {
                                                 // Paper start
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 62c257b28d921d36198f925170a9ea01ec2c63be..518925c8d6269161c439c7e87b8be108296fc301 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -941,6 +941,18 @@ public class PurpurWorldConfig {
     public double phantomAttackedByCrystalRadius = 0.0D;
     public float phantomAttackedByCrystalDamage = 1.0F;
     public double phantomOrbitCrystalRadius = 0.0D;
+    public int phantomSpawnDelayMin = 1200;
+    public int phantomSpawnDelayMax = 2400;
+    public int phantomSpawnMinSkyDarkness = 5;
+    public boolean phantomSpawnOnlyAboveSeaLevel = true;
+    public boolean phantomSpawnOnlyWithVisibleSky = true;
+    public double phantomSpawnLocalDifficultyChance = 3.0D;
+    public int phantomSpawnMinTimeSinceSlept = 72000;
+    public int phantomSpawnMinOverhead = 20;
+    public int phantomSpawnMaxOverhead = 35;
+    public int phantomSpawnOverheadRadius = 10;
+    public int phantomSpawnMinPerAttempt = 1;
+    public int phantomSpawnMaxPerAttempt = -1;
     private void phantomSettings() {
         phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
         phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -957,6 +969,18 @@ public class PurpurWorldConfig {
         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);
+        phantomSpawnDelayMin = getInt("mobs.phantom.spawn.delay.min", phantomSpawnDelayMin);
+        phantomSpawnDelayMax = getInt("mobs.phantom.spawn.delay.max", phantomSpawnDelayMax);
+        phantomSpawnMinSkyDarkness = getInt("mobs.phantom.spawn.min-sky-darkness", phantomSpawnMinSkyDarkness);
+        phantomSpawnOnlyAboveSeaLevel = getBoolean("mobs.phantom.spawn.only-above-sea-level", phantomSpawnOnlyAboveSeaLevel);
+        phantomSpawnOnlyWithVisibleSky = getBoolean("mobs.phantom.spawn.only-with-visible-sky", phantomSpawnOnlyWithVisibleSky);
+        phantomSpawnLocalDifficultyChance = getDouble("mobs.phantom.spawn.local-difficulty-chance", phantomSpawnLocalDifficultyChance);
+        phantomSpawnMinTimeSinceSlept = getInt("mobs.phantom.spawn.min-time-since-slept", phantomSpawnMinTimeSinceSlept);
+        phantomSpawnMinOverhead = getInt("mobs.phantom.spawn.overhead.min", phantomSpawnMinOverhead);
+        phantomSpawnMaxOverhead = getInt("mobs.phantom.spawn.overhead.max", phantomSpawnMaxOverhead);
+        phantomSpawnOverheadRadius = getInt("mobs.phantom.spawn.overhead.radius", phantomSpawnOverheadRadius);
+        phantomSpawnMinPerAttempt = getInt("mobs.phantom.spawn.per-attempt.min", phantomSpawnMinPerAttempt);
+        phantomSpawnMaxPerAttempt = getInt("mobs.phantom.spawn.per-attempt.max", phantomSpawnMaxPerAttempt);
     }
 
     public boolean pigRidable = false;
