Files
Purpur/patches/server/0091-Add-phantom-spawning-options.patch
William Blake Galbreath 67be68c780 Updated Upstream (Tuinity)
Upstream has released updates that appears to apply and compile correctly

Tuinity Changes:
3b008f5 Optimisations
200f825 Actually unload POI data
db64f14 Make sure to despawn entities if they are outside the player general
89276ac Fix villagers aggressively looking at people
8830cef Remove streams for poi searching in some zombie pathfinding
a17dc2c Attempt to fix incorrect nearest village distance tracker updating
ef8cd34 Fix NPE
3e45700Do not return complex parts for entity by class lookup
2110847 Rewrite getClosestEntity
460581d Fix getClosestEntity not working
2cb36ca Optimise non-flush packet sending
784b838 Some fixes
e2dcdd1 Correct return value for ChunkCache#getCubes
968512b Add Velocity natives for encryption and compression (#188)
102d60b Rebuild patches
57fed71 Fix decompression with Velocity natives
442890b Fix decompression with Velocity natives (#191)
0179ea8 Re-Add region manager and notify patch
cbffdcc Do not mark entities in unloaded chunks as being in blocks
f2eef4a Fixup dev branch patches and store reverted patches in revert folder
2020-11-05 18:14:13 -06:00

286 lines
16 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/server/DifficultyDamageScaler.java b/src/main/java/net/minecraft/server/DifficultyDamageScaler.java
index 75745af343..84c0ec1b50 100644
--- a/src/main/java/net/minecraft/server/DifficultyDamageScaler.java
+++ b/src/main/java/net/minecraft/server/DifficultyDamageScaler.java
@@ -13,6 +13,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;
}
@@ -21,6 +22,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/server/EnumDifficulty.java b/src/main/java/net/minecraft/server/EnumDifficulty.java
index e0e72779c0..386eae71a1 100644
--- a/src/main/java/net/minecraft/server/EnumDifficulty.java
+++ b/src/main/java/net/minecraft/server/EnumDifficulty.java
@@ -19,6 +19,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/server/IBlockLightAccess.java b/src/main/java/net/minecraft/server/IBlockLightAccess.java
index 03a89301f2..fa5eb188da 100644
--- a/src/main/java/net/minecraft/server/IBlockLightAccess.java
+++ b/src/main/java/net/minecraft/server/IBlockLightAccess.java
@@ -12,6 +12,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/server/MobSpawnerPhantom.java b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
index 4e3f01bc79..ac1ea2f0c1 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
@@ -1,85 +1,99 @@
package net.minecraft.server;
-import java.util.Iterator;
-import java.util.Random;
+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.spawningEntity = entityhuman.uniqueID; // 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.spawningEntity = player.uniqueID; // 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/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index beaea041dc..ce8834980f 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -386,6 +386,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/server/World.java b/src/main/java/net/minecraft/server/World.java
index ab8fad689a..baa8d23a92 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1564,6 +1564,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/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 32a233ceb5..01bc1a020d 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -339,10 +339,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;