diff --git a/patches/server/0078-Add-phantom-spawning-options.patch b/patches/server/0078-Add-phantom-spawning-options.patch index 65bc5aa26..bb6156b9c 100644 --- a/patches/server/0078-Add-phantom-spawning-options.patch +++ b/patches/server/0078-Add-phantom-spawning-options.patch @@ -5,189 +5,48 @@ 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..76e47852c26c96e0ab365d56d5ab0245948204d0 100644 +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 -@@ -2,12 +2,15 @@ package net.minecraft.world.level.levelgen; - - import java.util.Iterator; - import java.util.Random; -+ -+import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent; - import net.minecraft.core.BlockPos; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.server.MCUtil; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.stats.ServerStatsCounter; -+import net.minecraft.stats.Stat; - import net.minecraft.stats.Stats; - import net.minecraft.util.Mth; - import net.minecraft.world.DifficultyInstance; -@@ -23,84 +26,100 @@ import net.minecraft.world.level.Level; - import net.minecraft.world.level.NaturalSpawner; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.material.FluidState; -+import org.bukkit.event.entity.CreatureSpawnEvent; - - public class PhantomSpawner implements CustomSpawner { - -- private int nextTick; -+ private int spawnDelay; // Purpur - - public PhantomSpawner() {} - - @Override - public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) { -+ // Purpur start - rewrite entire thing - if (!spawnMonsters) { - return 0; -- } else if (!world.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) { -+ } -+ -+ if (!world.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) { -+ return 0; -+ } -+ -+ --this.spawnDelay; -+ if (this.spawnDelay > 0) { - return 0; -- } else { -- Random random = world.random; -- -- --this.nextTick; -- if (this.nextTick > 0) { -- return 0; -- } else { +@@ -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()) { -- return 0; -- } else { -- int i = 0; -- Iterator iterator = world.players().iterator(); -- -- while (iterator.hasNext()) { -- Player entityhuman = (Player) iterator.next(); -- -- if (!entityhuman.isSpectator() && (!world.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper -- BlockPos blockposition = entityhuman.blockPosition(); -- ++ 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)) { -- DifficultyInstance difficultydamagescaler = world.getCurrentDifficultyAt(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)) { -- 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 (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)); -- 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); -- -- for (int l = 0; l < k; ++l) { -- // Paper start -- com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(world, blockposition1), ((ServerPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); -- if (!event.callEvent()) { -- if (event.shouldAbortSpawn()) { -- break; -- } -- continue; -- } -- // Paper end -- Phantom entityphantom = (Phantom) EntityType.PHANTOM.create((Level) world); -- entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper -- entityphantom.moveTo(blockposition1, 0.0F, 0.0F); -- groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null); -- world.addAllEntities(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit -- } -- -- i += k; -- } -- } -- } -- } -- } -+ } -+ this.spawnDelay += world.purpurConfig.phantomSpawnDelayMin + world.random.nextInt(world.purpurConfig.phantomSpawnDelayMax - world.purpurConfig.phantomSpawnDelayMin); -+ -+ if (!world.dimensionType().hasSkyLight() || world.getSkyDarken() < world.purpurConfig.phantomSpawnMinSkyDarkness) { -+ return 0; -+ } -+ -+ int numberSpawnsAttempted = 0; -+ for (ServerPlayer player : world.players()) { -+ if (player.isSpectator() || (player.isCreative() && world.paperConfig.phantomIgnoreCreative)) { -+ continue; -+ } -+ -+ BlockPos playerPos = player.blockPosition(); -+ if (playerPos.getY() < world.getSeaLevel() && world.purpurConfig.phantomSpawnOnlyAboveSeaLevel) { -+ continue; -+ } -+ -+ if (!world.canSeeSky(playerPos) && world.purpurConfig.phantomSpawnOnlyWithVisibleSky) { -+ continue; -+ } -+ -+ DifficultyInstance difficultyInstance = world.getCurrentDifficultyAt(playerPos); -+ if (!difficultyInstance.isHarderThan(world.random.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) { -+ continue; -+ } -+ -+ ServerStatsCounter stats = player.getStats(); -+ int timeSinceRest = Mth.clamp(stats.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE); -+ if (world.random.nextInt(timeSinceRest) < world.purpurConfig.phantomSpawnMinTimeSinceSlept) { -+ continue; -+ } -+ -+ BlockPos spawnPos = playerPos -+ .above(world.purpurConfig.phantomSpawnMinOverhead + world.random.nextInt(world.purpurConfig.phantomSpawnMaxOverhead - world.purpurConfig.phantomSpawnMinOverhead)) -+ .east(-world.purpurConfig.phantomSpawnOverheadRadius + world.random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius + 1)) -+ .south(-world.purpurConfig.phantomSpawnOverheadRadius + world.random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius + 1)); -+ -+ if (!NaturalSpawner.isValidEmptySpawnBlock(world, spawnPos, world.getTypeIfLoaded(spawnPos), world.getFluidState(spawnPos), EntityType.PHANTOM)) { -+ continue; -+ } -+ -+ int difficulty = difficultyInstance.getDifficulty().getId(); -+ int spawnAttempts = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficulty : world.purpurConfig.phantomSpawnMaxPerAttempt) + world.purpurConfig.phantomSpawnMinPerAttempt); -+ -+ SpawnGroupData groupData = null; -+ for (int count = 0; count < spawnAttempts; ++count) { -+ // Paper start -+ PhantomPreSpawnEvent event = new PhantomPreSpawnEvent(MCUtil.toLocation(world, spawnPos), player.getBukkitEntity(), CreatureSpawnEvent.SpawnReason.NATURAL); -+ if (!event.callEvent()) { -+ if (event.shouldAbortSpawn()) { -+ break; - } -+ continue; -+ } -+ // Paper end ++ 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); -- return i; -+ Phantom phantom = EntityType.PHANTOM.create(world); -+ if (phantom == null) { -+ continue; - } -+ -+ phantom.setSpawningEntity(player.getUUID()); -+ phantom.moveTo(spawnPos, 0.0F, 0.0F); -+ groupData = phantom.finalizeSpawn(world, difficultyInstance, MobSpawnType.NATURAL, groupData, null); -+ world.addEntity(phantom, CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit - } -+ -+ numberSpawnsAttempted += spawnAttempts; - } -+ -+ return numberSpawnsAttempted; -+ // Purpur end - rewrite entire thing - } - } + 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 e3bd27513287ba77efd3f2c2418b83b7646ea5e2..506e7198de3a339545bebb508d96ca95f5fc8fc1 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java