Yatopia/patches/Purpur/patches/server/0078-Add-phantom-spawning-o...

303 lines
17 KiB
Diff

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/DifficultyDamageScaler.java b/src/main/java/net/minecraft/world/DifficultyDamageScaler.java
index c2fe4329576e6dcd5df435bc580d79a2b6db1fcd..44f19d8c8f5d344b2659cf01eb4be40f5510a2c2 100644
--- a/src/main/java/net/minecraft/world/DifficultyDamageScaler.java
+++ b/src/main/java/net/minecraft/world/DifficultyDamageScaler.java
@@ -14,6 +14,7 @@ public class DifficultyDamageScaler {
this.b = this.a(enumdifficulty, i, j, f);
}
+ public EnumDifficulty getGlobalDifficulty() { return a(); } // Purpur - OBFHELPER
public EnumDifficulty a() {
return this.a;
}
@@ -22,6 +23,7 @@ public class DifficultyDamageScaler {
return this.b;
}
+ public boolean isHarderThan(float f) { return a(f); } // Purpur - OBFHELPER
public boolean a(float f) {
return this.b > f;
}
diff --git a/src/main/java/net/minecraft/world/EnumDifficulty.java b/src/main/java/net/minecraft/world/EnumDifficulty.java
index 53fac6aa71938805264b7cc4769e63a9d4a66114..a1a80aab7ef6fdb2a35082fa452d0b46c1fcdcbe 100644
--- a/src/main/java/net/minecraft/world/EnumDifficulty.java
+++ b/src/main/java/net/minecraft/world/EnumDifficulty.java
@@ -21,6 +21,7 @@ public enum EnumDifficulty {
this.g = s;
}
+ public int getId() { return a(); } // Purpur - OBFHELPER
public int a() {
return this.f;
}
diff --git a/src/main/java/net/minecraft/world/level/IBlockLightAccess.java b/src/main/java/net/minecraft/world/level/IBlockLightAccess.java
index 8b2e57c833c03940f2e0727e00decce59f263269..642bf019d32a2fdc18718337ecfe45d24022f8bd 100644
--- a/src/main/java/net/minecraft/world/level/IBlockLightAccess.java
+++ b/src/main/java/net/minecraft/world/level/IBlockLightAccess.java
@@ -15,6 +15,7 @@ public interface IBlockLightAccess extends IBlockAccess {
return this.e().b(blockposition, i);
}
+ default boolean isSkyVisible(BlockPosition blockposition) { return e(blockposition); } // Purpur - OBFHELPER
default boolean e(BlockPosition blockposition) {
return this.getBrightness(EnumSkyBlock.SKY, blockposition) >= this.K();
}
diff --git a/src/main/java/net/minecraft/world/level/SpawnerCreature.java b/src/main/java/net/minecraft/world/level/SpawnerCreature.java
index d98526785ff2fa3b72e8ffffcb89a57a2203a5c8..7859d84471436b427138593776ebd30a0429b6b4 100644
--- a/src/main/java/net/minecraft/world/level/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/world/level/SpawnerCreature.java
@@ -431,6 +431,7 @@ public final class SpawnerCreature {
return new BlockPosition(i, l, j);
}
+ public static boolean canSpawn(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, EntityTypes entitytypes) { return a(iblockaccess, blockposition, iblockdata, fluid, entitytypes); } // Purpur - OBFHELPER
public static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, EntityTypes<?> entitytypes) {
return iblockdata.r(iblockaccess, blockposition) ? false : (iblockdata.isPowerSource() ? false : (!fluid.isEmpty() ? false : (iblockdata.a((Tag) TagsBlock.PREVENT_MOB_SPAWNING_INSIDE) ? false : !entitytypes.a(iblockdata))));
}
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
index 0ede4766117e0bc28127baf1b14535370d8ea878..9c7c68a3e73734ec2dbc57983ae27a16a7618fa2 100644
--- a/src/main/java/net/minecraft/world/level/World.java
+++ b/src/main/java/net/minecraft/world/level/World.java
@@ -1759,6 +1759,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
return new DifficultyDamageScaler(this.getDifficulty(), this.getDayTime(), i, f);
}
+ public int getSkyDarkness() { return c(); } // Purpur - OBFHELPER
@Override
public int c() {
return this.d;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java b/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java
index e4f5e570636862481aac92ec9b74d6cf5723eb6e..e954adeff4fbfc1aa85ac3785c0c4c86bde24cdb 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java
@@ -1,9 +1,6 @@
package net.minecraft.world.level.levelgen;
-import java.util.Iterator;
-import java.util.Random;
import net.minecraft.core.BlockPosition;
-import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MCUtil;
import net.minecraft.server.level.EntityPlayer;
import net.minecraft.server.level.WorldServer;
@@ -15,92 +12,103 @@ import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.EnumMobSpawn;
import net.minecraft.world.entity.GroupDataEntity;
import net.minecraft.world.entity.monster.EntityPhantom;
-import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.level.GameRules;
-import net.minecraft.world.level.IBlockAccess;
import net.minecraft.world.level.MobSpawner;
import net.minecraft.world.level.SpawnerCreature;
-import net.minecraft.world.level.World;
-import net.minecraft.world.level.block.state.IBlockData;
-import net.minecraft.world.level.material.Fluid;
+import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
+import org.bukkit.event.entity.CreatureSpawnEvent;
public class MobSpawnerPhantom implements MobSpawner {
-
- private int a;
+ private int spawnDelay;
public MobSpawnerPhantom() {}
@Override
- public int a(WorldServer worldserver, boolean flag, boolean flag1) {
- if (!flag) {
+ public int a(WorldServer world, boolean allowMonsters, boolean allowAnimals) {
+ // Purpur start - rewrite entire thing
+ if (!allowMonsters) {
+ return 0;
+ }
+
+ if (!world.getGameRules().getBoolean(GameRules.DO_INSOMNIA)) {
return 0;
- } else if (!worldserver.getGameRules().getBoolean(GameRules.DO_INSOMNIA)) {
+ }
+
+ --this.spawnDelay;
+ if (this.spawnDelay > 0) {
return 0;
- } else {
- Random random = worldserver.random;
-
- --this.a;
- if (this.a > 0) {
- return 0;
- } else {
- this.a += (60 + random.nextInt(60)) * 20;
- if (worldserver.c() < 5 && worldserver.getDimensionManager().hasSkyLight()) {
- return 0;
- } else {
- int i = 0;
- Iterator iterator = worldserver.getPlayers().iterator();
-
- while (iterator.hasNext()) {
- EntityHuman entityhuman = (EntityHuman) iterator.next();
-
- if (!entityhuman.isSpectator() && (!worldserver.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper
- BlockPosition blockposition = entityhuman.getChunkCoordinates();
-
- if (!worldserver.getDimensionManager().hasSkyLight() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.e(blockposition)) {
- DifficultyDamageScaler difficultydamagescaler = worldserver.getDamageScaler(blockposition);
-
- if (difficultydamagescaler.a(random.nextFloat() * 3.0F)) {
- ServerStatisticManager serverstatisticmanager = ((EntityPlayer) entityhuman).getStatisticManager();
- int j = MathHelper.clamp(serverstatisticmanager.getStatisticValue(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
- boolean flag2 = true;
-
- if (random.nextInt(j) >= 72000) {
- BlockPosition blockposition1 = blockposition.up(20 + random.nextInt(15)).east(-10 + random.nextInt(21)).south(-10 + random.nextInt(21));
- IBlockData iblockdata = worldserver.getType(blockposition1);
- Fluid fluid = worldserver.getFluid(blockposition1);
-
- if (SpawnerCreature.a((IBlockAccess) worldserver, blockposition1, iblockdata, fluid, EntityTypes.PHANTOM)) {
- GroupDataEntity groupdataentity = null;
- int k = 1 + random.nextInt(difficultydamagescaler.a().a() + 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(worldserver, blockposition1), ((EntityPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
- if (!event.callEvent()) {
- if (event.shouldAbortSpawn()) {
- break;
- }
- continue;
- }
- // Paper end
- EntityPhantom entityphantom = (EntityPhantom) EntityTypes.PHANTOM.a((World) worldserver);
- entityphantom.setSpawningEntity(entityhuman.getUniqueID()); // Paper
- entityphantom.setPositionRotation(blockposition1, 0.0F, 0.0F);
- groupdataentity = entityphantom.prepare(worldserver, difficultydamagescaler, EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
- worldserver.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.getDimensionManager().hasSkyLight() || world.getSkyDarkness() < world.purpurConfig.phantomSpawnMinSkyDarkness) {
+ return 0;
+ }
+
+ int numberSpawnsAttempted = 0;
+ for (EntityPlayer player : world.getPlayers()) {
+ if (player.isSpectator() || (player.isCreative() && world.paperConfig.phantomIgnoreCreative)) { // Paper
+ continue;
+ }
+
+ BlockPosition playerPos = player.getChunkCoordinates();
+ if (playerPos.getY() < world.getSeaLevel() && world.purpurConfig.phantomSpawnOnlyAboveSeaLevel) {
+ continue;
+ }
+
+ if (!world.isSkyVisible(playerPos) && world.purpurConfig.phantomSpawnOnlyWithVisibleSky) {
+ continue;
+ }
+
+ DifficultyDamageScaler dmgScaler = world.getDamageScaler(playerPos);
+ if (!dmgScaler.isHarderThan(world.random.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) {
+ continue;
+ }
+
+ ServerStatisticManager stats = player.getStatisticManager();
+ int timeSinceRest = MathHelper.clamp(stats.getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
+ if (world.random.nextInt(timeSinceRest) < world.purpurConfig.phantomSpawnMinTimeSinceSlept) {
+ continue;
+ }
+
+ BlockPosition spawnPos = playerPos
+ .up(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 (!SpawnerCreature.canSpawn(world, spawnPos, world.getType(spawnPos), world.getFluid(spawnPos), EntityTypes.PHANTOM)) {
+ continue;
+ }
+
+ int difficulty = dmgScaler.getGlobalDifficulty().getId();
+ int spawnAttempts = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficulty : world.purpurConfig.phantomSpawnMaxPerAttempt) + world.purpurConfig.phantomSpawnMinPerAttempt);
+
+ GroupDataEntity 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
- return i;
+ EntityPhantom phantom = EntityTypes.PHANTOM.create(world);
+ if (phantom == null) {
+ continue;
}
+
+ phantom.setSpawningEntity(player.getUniqueID()); // Paper
+ phantom.setPositionRotation(spawnPos, 0.0F, 0.0F);
+ groupData = phantom.prepare(world, dmgScaler, EnumMobSpawn.NATURAL, groupData, null);
+ world.addEntity(phantom, CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
}
+
+ numberSpawnsAttempted += spawnAttempts;
}
+
+ return numberSpawnsAttempted;
+ // Purpur end - rewrite entire thing
}
}
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 3aec221db2cd425bc5188979bb0fc0625ca40f4a..d957ee4c10fde8596442f2f05f0347994df7bae5 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -398,10 +398,34 @@ 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() {
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 pigGiveSaddleBack = false;