mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
Upstream has released updates that appears to apply and compile correctly Paper Changes: 42daaadd Seperate out incremental saving 3a713bd5 Mark entities as being ticked when notifying navigation 6f709200 use getChunkImmediately for vehicles
237 lines
13 KiB
Diff
237 lines
13 KiB
Diff
From 13cceab96a020767c5cbc232a147d50faa77610e Mon Sep 17 00:00:00 2001
|
|
From: kickash32 <kickash32@gmail.com>
|
|
Date: Tue, 11 Jun 2019 22:22:16 -0400
|
|
Subject: [PATCH] implement optional per player mob spawns
|
|
|
|
---
|
|
.../destroystokyo/paper/PaperWorldConfig.java | 5 +++
|
|
.../minecraft/server/ChunkProviderServer.java | 16 +++++++--
|
|
.../net/minecraft/server/EntityTypes.java | 1 +
|
|
.../net/minecraft/server/PlayerChunkMap.java | 5 +--
|
|
.../net/minecraft/server/SpawnerCreature.java | 21 ++++++-----
|
|
.../net/minecraft/server/WorldServer.java | 36 +++++++++++++++++++
|
|
6 files changed, 69 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 318a470eea..72b77e27e8 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -509,6 +509,11 @@ public class PaperWorldConfig {
|
|
maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
|
|
}
|
|
|
|
+ public boolean perPlayerMobSpawns = false;
|
|
+ private void perPlayerMobSpawns() {
|
|
+ perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false);
|
|
+ }
|
|
+
|
|
public boolean countAllMobsForSpawning = false;
|
|
private void countAllMobsForSpawning() {
|
|
countAllMobsForSpawning = getBoolean("count-all-mobs-for-spawning", false);
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
index b1bea8f90d..d92446d79b 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
@@ -601,9 +601,21 @@ public class ChunkProviderServer extends IChunkProvider {
|
|
// Paper start - only allow spawns upto the limit per chunk and update count afterwards
|
|
int currEntityCount = object2intmap.getInt(enumcreaturetype);
|
|
int difference = k1 - currEntityCount;
|
|
+ if(this.world.paperConfig.perPlayerMobSpawns){
|
|
+ final int[] min = {Integer.MAX_VALUE};
|
|
+ final int finalLimit = limit;
|
|
+ playerChunkMap.getPlayersNear(chunk.getPos())
|
|
+ .forEach((entityplayer) -> min[0] = Math.min(
|
|
+ finalLimit - ((WorldServer)chunk.getWorld()).getMobCountNear(entityplayer, enumcreaturetype),
|
|
+ min[0]));
|
|
+ difference = (min[0] == Integer.MAX_VALUE) ? 0 : min[0];
|
|
+ }
|
|
+
|
|
if (difference > 0) {
|
|
- object2intmap.put(enumcreaturetype, currEntityCount + SpawnerCreature.spawnMobs(enumcreaturetype, world, chunk, blockposition, difference));
|
|
- // Paper end
|
|
+ List spawned = SpawnerCreature.spawnMobs(enumcreaturetype, this.world, chunk, blockposition, difference);
|
|
+ object2intmap.put(enumcreaturetype, currEntityCount + spawned.size());
|
|
+ this.world.updatePlayerMobTypeMap(spawned);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
|
|
index d92fbea4c7..f9bc2ab66e 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityTypes.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
|
|
@@ -267,6 +267,7 @@ public class EntityTypes<T extends Entity> {
|
|
return this.be;
|
|
}
|
|
|
|
+ public EnumCreatureType getEnumCreatureType(){ return this.e(); } // Paper - OBFHELPER
|
|
public EnumCreatureType e() {
|
|
return this.ba;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
index 4c774e31dc..ebf0298631 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -137,6 +137,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
|
this.setViewDistance(i);
|
|
}
|
|
|
|
+ private static double squareDist(ChunkCoordIntPair chunkcoord, Entity entity) { return a(chunkcoord, entity); } // Paper - OBFHELPER
|
|
private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) {
|
|
double d0 = (double) (chunkcoordintpair.x * 16 + 8);
|
|
double d1 = (double) (chunkcoordintpair.z * 16 + 8);
|
|
@@ -1340,8 +1341,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
|
|
|
}
|
|
|
|
- @Override
|
|
- public Stream<EntityPlayer> a(ChunkCoordIntPair chunkcoordintpair, boolean flag) {
|
|
+ public Stream<EntityPlayer> getPlayersNear(ChunkCoordIntPair coordIntPair) { return a(coordIntPair, false); } // Paper - OBFHELPER
|
|
+ @Override public Stream<EntityPlayer> a(ChunkCoordIntPair chunkcoordintpair, boolean flag) {
|
|
return this.playerMap.a(chunkcoordintpair.pair()).filter((entityplayer) -> {
|
|
int i = b(chunkcoordintpair, entityplayer, true);
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index 925efd4a15..70580355c6 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -20,16 +20,15 @@ public final class SpawnerCreature {
|
|
public static void a(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition) {
|
|
spawnMobs(enumcreaturetype, world, chunk, blockposition, Integer.MAX_VALUE);
|
|
}
|
|
-
|
|
- public static int spawnMobs(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition, int maxSpawns) {
|
|
- // Paper end
|
|
+ public static List<Entity> spawnMobs(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition, int maxSpawns) {
|
|
+ List<Entity> mobsSpawned = new java.util.ArrayList<>();
|
|
+ // Paper end
|
|
ChunkGenerator<?> chunkgenerator = world.getChunkProvider().getChunkGenerator();
|
|
int i = 0;
|
|
BlockPosition blockposition1 = getRandomPosition(world, chunk);
|
|
int j = blockposition1.getX();
|
|
int k = blockposition1.getY();
|
|
int l = blockposition1.getZ();
|
|
- int amountSpawned = 0; // Paper - keep track of mobs spawned
|
|
|
|
if (k >= 1) {
|
|
IBlockData iblockdata = world.getTypeIfLoadedAndInBounds(blockposition1); // Paper - don't load chunks for mob spawn
|
|
@@ -104,7 +103,7 @@ public final class SpawnerCreature {
|
|
);
|
|
if (!event.callEvent()) {
|
|
if (event.shouldAbortSpawn()) {
|
|
- return amountSpawned; // Paper
|
|
+ return mobsSpawned; // Paper
|
|
}
|
|
++i2;
|
|
continue;
|
|
@@ -123,7 +122,7 @@ public final class SpawnerCreature {
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
|
|
ServerInternalException.reportInternalException(exception); // Paper
|
|
- return amountSpawned; // Paper
|
|
+ return mobsSpawned; // Paper
|
|
}
|
|
|
|
entityinsentient.setPositionRotation((double) f, (double) k, (double) f1, world.random.nextFloat() * 360.0F, 0.0F);
|
|
@@ -134,15 +133,15 @@ public final class SpawnerCreature {
|
|
++i;
|
|
++i2;
|
|
// Paper start - stop when limit is reached
|
|
- ++amountSpawned;
|
|
+ mobsSpawned.add(entityinsentient);
|
|
}
|
|
- if (amountSpawned >= maxSpawns) {
|
|
- return amountSpawned;
|
|
+ if (mobsSpawned.size() >= maxSpawns) {
|
|
+ return mobsSpawned;
|
|
}
|
|
// Paper end
|
|
// CraftBukkit end
|
|
if (i >= entityinsentient.dC()) {
|
|
- return amountSpawned; // Paper
|
|
+ return mobsSpawned; // Paper
|
|
}
|
|
|
|
if (entityinsentient.c(i2)) {
|
|
@@ -168,7 +167,7 @@ public final class SpawnerCreature {
|
|
|
|
}
|
|
}
|
|
- return amountSpawned; // Paper
|
|
+ return mobsSpawned; // Paper
|
|
}
|
|
|
|
@Nullable
|
|
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
index ba4f7999f9..38768a5002 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -70,6 +70,7 @@ public class WorldServer extends World {
|
|
private boolean ticking;
|
|
@Nullable
|
|
private final MobSpawnerTrader mobSpawnerTrader;
|
|
+ private Map<UUID, Map<EnumCreatureType, Integer>> playerMobTypeMap; // Paper
|
|
|
|
// CraftBukkit start
|
|
private int tickPosition;
|
|
@@ -966,6 +967,7 @@ public class WorldServer extends World {
|
|
}
|
|
|
|
public Object2IntMap<EnumCreatureType> l() {
|
|
+ List<Entity> filteredEntities = new java.util.ArrayList<>(); // Paper
|
|
Object2IntMap<EnumCreatureType> object2intmap = new Object2IntOpenHashMap();
|
|
ObjectIterator objectiterator = this.entitiesById.values().iterator();
|
|
|
|
@@ -990,14 +992,48 @@ public class WorldServer extends World {
|
|
entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
|
|
continue;
|
|
}
|
|
+ filteredEntities.add(entity); // Paper
|
|
// Paper end
|
|
object2intmap.mergeInt(enumcreaturetype, 1, Integer::sum);
|
|
}
|
|
}
|
|
|
|
+ // Paper start
|
|
+ if(this.paperConfig.perPlayerMobSpawns) {
|
|
+ this.playerMobTypeMap = new java.util.HashMap<>(this.players.size());
|
|
+ updatePlayerMobTypeMap(filteredEntities);
|
|
+ }
|
|
+ // Paper end
|
|
return object2intmap;
|
|
}
|
|
|
|
+ // Paper start
|
|
+ public void updatePlayerMobTypeMap(List<Entity> entities) {
|
|
+ if (this.playerMobTypeMap == null) { return; }
|
|
+ for (Entity entity : entities) {
|
|
+ ((ChunkProviderServer) this.chunkProvider).playerChunkMap.getPlayersNear(entity.getChunkAtLocation().getPos()).forEach( (player) -> {
|
|
+ if (!this.playerMobTypeMap.containsKey(player.uniqueID)) { this.playerMobTypeMap.put(player.uniqueID, new java.util.EnumMap<>(EnumCreatureType.class)); }
|
|
+ Map<EnumCreatureType, Integer> tmpMap = this.playerMobTypeMap.get(player.uniqueID);
|
|
+ EnumCreatureType enumType = entity.getEntityType().getEnumCreatureType();
|
|
+ tmpMap.put(
|
|
+ enumType,
|
|
+ tmpMap.getOrDefault(enumType, 0) + 1);
|
|
+ });
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public int getMobCountNear(EntityPlayer entityPlayer, EnumCreatureType enumCreatureType) {
|
|
+ int count = 0;
|
|
+ if (this.playerMobTypeMap != null) {
|
|
+ Map<EnumCreatureType, Integer> map = this.playerMobTypeMap.get(entityPlayer.uniqueID);
|
|
+ if (map != null) {
|
|
+ count = map.getOrDefault(enumCreatureType, 0);
|
|
+ }
|
|
+ }
|
|
+ return count;
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@Override
|
|
public boolean addEntity(Entity entity) {
|
|
// CraftBukkit start
|
|
--
|
|
2.20.1
|
|
|