mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
optimize collectSpawningChunks (#382)
* optimize collectSpawningChunks * add bit set * cleanup * cleanup * cleanup * cleanup
This commit is contained in:
@@ -26,7 +26,7 @@ index 79674f4bd7a12c42dec19a4175012d7a2dc88b84..0a97a491737807d59815b75635fa3d8c
|
|||||||
}
|
}
|
||||||
// Paper end - Optional per player mob spawns
|
// Paper end - Optional per player mob spawns
|
||||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
index 46e171ca454253c32e22c0c18587e9a7ba19f331..d91d6988268174ea9f2c919b57a6ba7ea00d7066 100644
|
index 46e171ca454253c32e22c0c18587e9a7ba19f331..1c7e2e5124c7d4c1b86039b0327bfd92c49df9b1 100644
|
||||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
@@ -70,11 +70,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
@@ -70,11 +70,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
@@ -47,7 +47,7 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..d91d6988268174ea9f2c919b57a6ba7e
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void tickChunks() {
|
private void tickChunks() {
|
||||||
+ // Leaf start
|
+ // Leaf start - optimize mob spawning
|
||||||
+ if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled && this.level.tickRateManager().runsNormally()) {
|
+ if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled && this.level.tickRateManager().runsNormally()) {
|
||||||
+ for (ServerPlayer player : this.level.players) {
|
+ for (ServerPlayer player : this.level.players) {
|
||||||
+ // Paper start - per player mob spawning backoff
|
+ // Paper start - per player mob spawning backoff
|
||||||
@@ -63,7 +63,7 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..d91d6988268174ea9f2c919b57a6ba7e
|
|||||||
+ // Paper end - per player mob spawning backoff
|
+ // Paper end - per player mob spawning backoff
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ // Leaf end
|
+ // Leaf end - optimize mob spawning
|
||||||
long gameTime = this.level.getGameTime();
|
long gameTime = this.level.getGameTime();
|
||||||
long l = gameTime - this.lastInhabitedUpdate;
|
long l = gameTime - this.lastInhabitedUpdate;
|
||||||
this.lastInhabitedUpdate = gameTime;
|
this.lastInhabitedUpdate = gameTime;
|
||||||
@@ -108,32 +108,81 @@ index 46e171ca454253c32e22c0c18587e9a7ba19f331..d91d6988268174ea9f2c919b57a6ba7e
|
|||||||
mobCapCalculator, // This is the key fix - was previously null
|
mobCapCalculator, // This is the key fix - was previously null
|
||||||
level.paperConfig().entities.spawning.perPlayerMobSpawns
|
level.paperConfig().entities.spawning.perPlayerMobSpawns
|
||||||
);
|
);
|
||||||
@@ -627,9 +644,23 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
@@ -610,6 +627,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
chunkRange = Math.min(chunkRange, 8);
|
||||||
|
entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
|
||||||
|
entityPlayer.playerNaturallySpawnedEvent.callEvent();
|
||||||
|
+ this.level.natureSpawnChunkMap.addPlayer(entityPlayer); // Leaf - optimize mob spawning
|
||||||
|
}
|
||||||
|
// Paper end - PlayerNaturallySpawnCreaturesEvent
|
||||||
|
boolean flag = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
|
||||||
|
@@ -621,16 +639,40 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
|
List<LevelChunk> list = this.spawningChunks;
|
||||||
|
|
||||||
|
try {
|
||||||
|
- this.chunkMap.collectSpawningChunks(list);
|
||||||
|
+ // Leaf start - optimize mob spawning
|
||||||
|
+ // this.chunkMap.collectSpawningChunks(list);
|
||||||
|
+ this.level.natureSpawnChunkMap.build();
|
||||||
|
// Paper start - chunk tick iteration optimisation
|
||||||
|
- this.shuffleRandom.setSeed(this.level.random.nextLong());
|
||||||
|
- if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
||||||
|
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) {
|
||||||
|
+ this.level.natureSpawnChunkMap.collectSpawningChunks(this.level.moonrise$getPlayerTickingChunks(), list);
|
||||||
|
+ this.shuffleRandom.setSeed(this.level.random.nextLong()); // Leaf - paw optimization - Only set seed if is really used
|
||||||
|
+ Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
||||||
|
+ }
|
||||||
// Paper end - chunk tick iteration optimisation
|
// Paper end - chunk tick iteration optimisation
|
||||||
|
|
||||||
- for (LevelChunk levelChunk : list) {
|
- for (LevelChunk levelChunk : list) {
|
||||||
- this.tickSpawningChunk(levelChunk, timeInhabited, filteredSpawningCategories, lastSpawnState); // Pufferfish
|
- this.tickSpawningChunk(levelChunk, timeInhabited, filteredSpawningCategories, lastSpawnState); // Pufferfish
|
||||||
+ // Leaf start - optimize mob spawning
|
+ if (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) {
|
||||||
+ var lastSpawnState1 = lastSpawnState;
|
+ NaturalSpawner.SpawnState currentState = lastSpawnState;
|
||||||
+ if ((!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && lastSpawnState1 != null) {
|
+ if (currentState != null) {
|
||||||
+ lastSpawnState1.applyPerPlayerMobCount(level);
|
+ currentState.applyPerPlayerMobCount(level);
|
||||||
+ if (list instanceof it.unimi.dsi.fastutil.objects.ReferenceArrayList<LevelChunk> arrayList) {
|
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) {
|
||||||
+ LevelChunk[] levelChunks = arrayList.elements();
|
+ for (LevelChunk levelChunk : list) {
|
||||||
+ int size = arrayList.size();
|
+ this.tickSpawningChunk(levelChunk, timeInhabited, filteredSpawningCategories, currentState); // Pufferfish
|
||||||
+ for (int i = 0; i < size; i++) {
|
|
||||||
+ this.tickSpawningChunk(levelChunks[i], timeInhabited, filteredSpawningCategories, lastSpawnState1); // Pufferfish
|
|
||||||
+ }
|
+ }
|
||||||
+ } else {
|
+ } else {
|
||||||
+ for (LevelChunk levelChunk : list) {
|
+ ca.spottedleaf.moonrise.common.list.ReferenceList<LevelChunk> chunks = this.level.moonrise$getPlayerTickingChunks();
|
||||||
+ this.tickSpawningChunk(levelChunk, timeInhabited, filteredSpawningCategories, lastSpawnState1); // Pufferfish
|
+ LevelChunk[] raw = chunks.getRawDataUnchecked();
|
||||||
|
+ for (int i = 0, length = chunks.size(); i < length; i++) {
|
||||||
|
+ LevelChunk levelChunk = raw[i];
|
||||||
|
+ if (level.natureSpawnChunkMap.contains(levelChunk.locX, levelChunk.locZ)) {
|
||||||
|
+ this.tickSpawningChunk(levelChunk, timeInhabited, filteredSpawningCategories, currentState); // Pufferfish
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
+ // Leaf end - optimize mob spawning
|
+ // Leaf end - optimize mob spawning
|
||||||
} finally {
|
} finally {
|
||||||
|
+ this.level.natureSpawnChunkMap.clear(); // Leaf - optimize mob spawning
|
||||||
list.clear();
|
list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -648,7 +690,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!spawnCategories.isEmpty()) {
|
||||||
|
- if (this.level.getWorldBorder().isWithinBounds(pos) && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get())) { // Paper - rewrite chunk system // Pufferfish
|
||||||
|
+ if (this.level.getWorldBorder().isWithinBounds(pos)) { // Paper - rewrite chunk system
|
||||||
|
NaturalSpawner.spawnForChunk(this.level, chunk, spawnState, spawnCategories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
index fc61a7083232148397a0b330ce2a4d70ba38543d..d13ab16368d5fed5c81211b63c7670e534f6ed01 100644
|
||||||
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
@@ -1114,6 +1114,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
|
||||||
|
private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking
|
||||||
|
|
||||||
|
+ public org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning
|
||||||
|
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
||||||
|
final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting
|
||||||
|
ChunkPos pos = chunk.getPos();
|
||||||
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
|
||||||
index 81e176d17fb072f9ee531639abfe42134ae833a9..ab6fa7ed111ef16a0b6774c21988589ee2110c66 100644
|
index 81e176d17fb072f9ee531639abfe42134ae833a9..ab6fa7ed111ef16a0b6774c21988589ee2110c66 100644
|
||||||
--- a/net/minecraft/world/level/NaturalSpawner.java
|
--- a/net/minecraft/world/level/NaturalSpawner.java
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ Subject: [PATCH] optimize random tick
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
index d91d6988268174ea9f2c919b57a6ba7ea00d7066..804ad5ae82b875d3b2cccb828eaa0ea54fe43011 100644
|
index f3489fda7f144e13e23fdb4521c942489238fe75..76c0b36025e2c12f990b9d4ec7c1d88b227c333b 100644
|
||||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||||
@@ -665,7 +665,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
@@ -676,7 +676,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||||
list.clear();
|
list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +24,13 @@ index d91d6988268174ea9f2c919b57a6ba7ea00d7066..804ad5ae82b875d3b2cccb828eaa0ea5
|
|||||||
this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
|
this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index fc61a7083232148397a0b330ce2a4d70ba38543d..d34a7cfa3b923d59ade35ce4c43cfd3f1477e057 100644
|
index d13ab16368d5fed5c81211b63c7670e534f6ed01..c49d2f7314a35763831285d7d46d34dade2f0085 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -1114,6 +1114,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -1115,6 +1115,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
|
||||||
private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking
|
private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.simpleRandom.nextInt(16); } // Gale - Airplane - optimize random calls in chunk ticking
|
||||||
|
|
||||||
|
public org.dreeam.leaf.world.NatureSpawnChunkMap natureSpawnChunkMap = new org.dreeam.leaf.world.NatureSpawnChunkMap(); // Leaf - optimize mob spawning
|
||||||
+ public org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick
|
+ public org.dreeam.leaf.world.RandomTickSystem randomTickSystem = new org.dreeam.leaf.world.RandomTickSystem(); // Leaf - optimize random tick
|
||||||
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
||||||
final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting
|
final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting
|
||||||
|
|||||||
@@ -99,28 +99,11 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194
|
|||||||
- }
|
- }
|
||||||
- // Paper end - detailed watchdog information
|
- // Paper end - detailed watchdog information
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
|
||||||
index 804ad5ae82b875d3b2cccb828eaa0ea54fe43011..328ed610f5d532784bd6c38c4833591dc19442cb 100644
|
|
||||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
|
||||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
|
||||||
@@ -640,8 +640,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
||||||
try {
|
|
||||||
this.chunkMap.collectSpawningChunks(list);
|
|
||||||
// Paper start - chunk tick iteration optimisation
|
|
||||||
- this.shuffleRandom.setSeed(this.level.random.nextLong());
|
|
||||||
- if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
|
||||||
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) {
|
|
||||||
+ this.shuffleRandom.setSeed(this.level.random.nextLong()); // Leaf - paw optimization - Only set seed if is really used
|
|
||||||
+ Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled
|
|
||||||
+ }
|
|
||||||
// Paper end - chunk tick iteration optimisation
|
|
||||||
|
|
||||||
// Leaf start - optimize mob spawning
|
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index d34a7cfa3b923d59ade35ce4c43cfd3f1477e057..e5ec54af005eb53399f9d2db49917c24023fcfdc 100644
|
index c49d2f7314a35763831285d7d46d34dade2f0085..79f2b26bc466238ec83cd049f38d257b0000028d 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -1517,13 +1517,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -1518,13 +1518,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
// Paper end - log detailed entity tick information
|
// Paper end - log detailed entity tick information
|
||||||
|
|
||||||
public void tickNonPassenger(Entity entity) {
|
public void tickNonPassenger(Entity entity) {
|
||||||
@@ -134,7 +117,7 @@ index d34a7cfa3b923d59ade35ce4c43cfd3f1477e057..e5ec54af005eb53399f9d2db49917c24
|
|||||||
entity.setOldPosAndRot();
|
entity.setOldPosAndRot();
|
||||||
entity.tickCount++;
|
entity.tickCount++;
|
||||||
entity.totalEntityAge++; // Paper - age-like counter for all entities
|
entity.totalEntityAge++; // Paper - age-like counter for all entities
|
||||||
@@ -1536,13 +1530,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -1537,13 +1531,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
for (Entity entity1 : entity.getPassengers()) {
|
for (Entity entity1 : entity.getPassengers()) {
|
||||||
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
|
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package org.dreeam.leaf.world;
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||||
|
import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NatureSpawnChunkMap {
|
||||||
|
/// breadth-first search
|
||||||
|
///
|
||||||
|
/// 0 4 12 28 48 80 112 148 196
|
||||||
|
private static final long[][] TABLE_BFS = new long[][]{
|
||||||
|
{0L},
|
||||||
|
{0L, 4294967295L, -4294967296L, 4294967296L, 1L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, 4294967294L, -8589934592L, 8589934592L, 2L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, -4294967298L, -2L, 4294967294L, -4294967297L, -8589934592L, 8589934590L, 12884901886L, 12884901887L, 8589934592L, -8589934591L, 8589934593L, -8589934590L, -4294967294L, 2L, 4294967298L, 8589934594L, 4294967293L, -12884901888L, 12884901888L, 3L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, -4294967298L, -2L, 4294967294L, -4294967297L, -8589934592L, 8589934590L, 12884901886L, 12884901887L, 8589934592L, -8589934591L, 8589934593L, -8589934590L, -4294967294L, 2L, 4294967298L, 8589934594L, -4294967299L, -3L, -8589934594L, -8589934593L, 4294967293L, 8589934589L, -12884901888L, -12884901887L, 12884901885L, 17179869182L, 17179869183L, 12884901888L, 12884901889L, -12884901886L, 12884901890L, -8589934589L, -4294967293L, 3L, 4294967299L, 8589934595L, 4294967292L, -17179869184L, 17179869184L, 4L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, -4294967298L, -2L, 4294967294L, -4294967297L, -8589934592L, 8589934590L, 12884901886L, 12884901887L, 8589934592L, -8589934591L, 8589934593L, -8589934590L, -4294967294L, 2L, 4294967298L, 8589934594L, -8589934595L, -4294967299L, -3L, -8589934594L, -8589934593L, 4294967293L, 8589934589L, -12884901888L, -12884901887L, 12884901885L, 17179869181L, 17179869182L, 17179869183L, 12884901888L, 12884901889L, -12884901886L, 12884901890L, -12884901885L, -8589934589L, -4294967293L, 3L, 4294967299L, 8589934595L, 12884901891L, -8589934596L, -4294967300L, -12884901891L, -12884901890L, -4L, 4294967292L, -12884901889L, -17179869184L, 8589934588L, 12884901884L, -17179869183L, -17179869182L, 17179869180L, 21474836477L, 21474836478L, 21474836479L, 17179869184L, 17179869185L, 17179869186L, -17179869181L, 17179869187L, -12884901884L, -8589934588L, -4294967292L, 4L, 4294967300L, 8589934596L, 12884901892L, 4294967291L, -21474836480L, 21474836480L, 5L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, -4294967298L, -2L, 4294967294L, -4294967297L, -8589934592L, 8589934590L, 12884901886L, 12884901887L, 8589934592L, -8589934591L, 8589934593L, -8589934590L, -4294967294L, 2L, 4294967298L, 8589934594L, -8589934595L, -4294967299L, -3L, -8589934594L, -8589934593L, 4294967293L, 8589934589L, -12884901888L, -12884901887L, 12884901885L, 17179869181L, 17179869182L, 17179869183L, 12884901888L, 12884901889L, -12884901886L, 12884901890L, -12884901885L, -8589934589L, -4294967293L, 3L, 4294967299L, 8589934595L, 12884901891L, -12884901892L, -8589934596L, -4294967300L, -12884901891L, -12884901890L, -4L, 4294967292L, -12884901889L, -17179869184L, 8589934588L, 12884901884L, -17179869183L, -17179869182L, 17179869180L, 21474836476L, 21474836477L, 21474836478L, 21474836479L, 17179869184L, 17179869185L, 17179869186L, -17179869181L, 17179869187L, -17179869180L, -12884901884L, -8589934588L, -4294967292L, 4L, 4294967300L, 8589934596L, 12884901892L, 17179869188L, -8589934597L, -17179869187L, -4294967301L, -5L, -17179869186L, -17179869185L, 4294967291L, 8589934587L, -21474836480L, -21474836479L, 12884901883L, 17179869179L, -21474836478L, -21474836477L, 25769803773L, 25769803774L, 25769803775L, 21474836480L, 21474836481L, 21474836482L, 21474836483L, -12884901883L, -8589934587L, -4294967291L, 5L, 4294967301L, 8589934597L, 12884901893L, 4294967290L, -25769803776L, 25769803776L, 6L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, -4294967298L, -2L, 4294967294L, -4294967297L, -8589934592L, 8589934590L, 12884901886L, 12884901887L, 8589934592L, -8589934591L, 8589934593L, -8589934590L, -4294967294L, 2L, 4294967298L, 8589934594L, -8589934595L, -4294967299L, -3L, -8589934594L, -8589934593L, 4294967293L, 8589934589L, -12884901888L, -12884901887L, 12884901885L, 17179869181L, 17179869182L, 17179869183L, 12884901888L, 12884901889L, -12884901886L, 12884901890L, -12884901885L, -8589934589L, -4294967293L, 3L, 4294967299L, 8589934595L, 12884901891L, -12884901892L, -8589934596L, -4294967300L, -12884901891L, -12884901890L, -4L, 4294967292L, -12884901889L, -17179869184L, 8589934588L, 12884901884L, -17179869183L, -17179869182L, 17179869180L, 21474836476L, 21474836477L, 21474836478L, 21474836479L, 17179869184L, 17179869185L, 17179869186L, -17179869181L, 17179869187L, -17179869180L, -12884901884L, -8589934588L, -4294967292L, 4L, 4294967300L, 8589934596L, 12884901892L, 17179869188L, -12884901893L, -8589934597L, -17179869188L, -17179869187L, -4294967301L, -5L, -17179869186L, -17179869185L, 4294967291L, 8589934587L, -21474836480L, -21474836479L, 12884901883L, 17179869179L, -21474836478L, -21474836477L, 21474836475L, 25769803772L, 25769803773L, 25769803774L, 25769803775L, 21474836480L, 21474836481L, 21474836482L, 21474836483L, -21474836476L, 21474836484L, -17179869179L, -12884901883L, -8589934587L, -4294967291L, 5L, 4294967301L, 8589934597L, 12884901893L, 17179869189L, -8589934598L, -4294967302L, -21474836483L, -21474836482L, -6L, 4294967290L, -21474836481L, -25769803776L, 8589934586L, 12884901882L, -25769803775L, -25769803774L, 17179869178L, -25769803773L, 30064771069L, 30064771070L, 30064771071L, 25769803776L, 25769803777L, 25769803778L, 25769803779L, -12884901882L, -8589934586L, -4294967290L, 6L, 4294967302L, 8589934598L, 12884901894L, 4294967289L, -30064771072L, 30064771072L, 7L},
|
||||||
|
{0L, -1L, 4294967295L, 8589934591L, -4294967296L, 4294967296L, -4294967295L, 1L, 4294967297L, -4294967298L, -2L, 4294967294L, -4294967297L, -8589934592L, 8589934590L, 12884901886L, 12884901887L, 8589934592L, -8589934591L, 8589934593L, -8589934590L, -4294967294L, 2L, 4294967298L, 8589934594L, -8589934595L, -4294967299L, -3L, -8589934594L, -8589934593L, 4294967293L, 8589934589L, -12884901888L, -12884901887L, 12884901885L, 17179869181L, 17179869182L, 17179869183L, 12884901888L, 12884901889L, -12884901886L, 12884901890L, -12884901885L, -8589934589L, -4294967293L, 3L, 4294967299L, 8589934595L, 12884901891L, -12884901892L, -8589934596L, -4294967300L, -12884901891L, -12884901890L, -4L, 4294967292L, -12884901889L, -17179869184L, 8589934588L, 12884901884L, -17179869183L, -17179869182L, 17179869180L, 21474836476L, 21474836477L, 21474836478L, 21474836479L, 17179869184L, 17179869185L, 17179869186L, -17179869181L, 17179869187L, -17179869180L, -12884901884L, -8589934588L, -4294967292L, 4L, 4294967300L, 8589934596L, 12884901892L, 17179869188L, -17179869189L, -12884901893L, -8589934597L, -17179869188L, -17179869187L, -4294967301L, -5L, -17179869186L, -17179869185L, 4294967291L, 8589934587L, -21474836480L, -21474836479L, 12884901883L, 17179869179L, -21474836478L, -21474836477L, 21474836475L, 25769803771L, 25769803772L, 25769803773L, 25769803774L, 25769803775L, 21474836480L, 21474836481L, 21474836482L, 21474836483L, -21474836476L, 21474836484L, -21474836475L, -17179869179L, -12884901883L, -8589934587L, -4294967291L, 5L, 4294967301L, 8589934597L, 12884901893L, 17179869189L, 21474836485L, -17179869190L, -12884901894L, -21474836485L, -21474836484L, -8589934598L, -4294967302L, -21474836483L, -21474836482L, -6L, 4294967290L, -21474836481L, -25769803776L, 8589934586L, 12884901882L, -25769803775L, -25769803774L, 17179869178L, 21474836474L, -25769803773L, -25769803772L, 25769803770L, 30064771067L, 30064771068L, 30064771069L, 30064771070L, 30064771071L, 25769803776L, 25769803777L, 25769803778L, 25769803779L, 25769803780L, -25769803771L, 25769803781L, -21474836474L, -17179869178L, -12884901882L, -8589934586L, -4294967290L, 6L, 4294967302L, 8589934598L, 12884901894L, 17179869190L, 21474836486L, -8589934599L, -25769803779L, -4294967303L, -7L, -25769803778L, -25769803777L, 4294967289L, 8589934585L, -30064771072L, -30064771071L, 12884901881L, 17179869177L, -30064771070L, -30064771069L, 34359738365L, 34359738366L, 34359738367L, 30064771072L, 30064771073L, 30064771074L, 30064771075L, -12884901881L, -8589934585L, -4294967289L, 7L, 4294967303L, 8589934599L, 12884901895L, 4294967288L, -34359738368L, 34359738368L, 8L}
|
||||||
|
};
|
||||||
|
private static final int MAX_RADIUS = 8;
|
||||||
|
private static final int SIZE_RADIUS = 9;
|
||||||
|
private static final int REGION_MASK = 15;
|
||||||
|
private static final int REGION_SHIFT = 4;
|
||||||
|
|
||||||
|
private final LongArrayList[] centersByRadius;
|
||||||
|
private final Long2LongOpenHashMap regionBitSets;
|
||||||
|
|
||||||
|
public NatureSpawnChunkMap() {
|
||||||
|
this.centersByRadius = new LongArrayList[SIZE_RADIUS];
|
||||||
|
for (int i = 0; i < SIZE_RADIUS; i++) {
|
||||||
|
this.centersByRadius[i] = new LongArrayList();
|
||||||
|
}
|
||||||
|
this.regionBitSets = new Long2LongOpenHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
for (LongArrayList chunkPosition : this.centersByRadius) {
|
||||||
|
chunkPosition.clear();
|
||||||
|
}
|
||||||
|
this.regionBitSets.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayer(ServerPlayer player) {
|
||||||
|
if (player.isSpectator()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlayerNaturallySpawnCreaturesEvent event = player.playerNaturallySpawnedEvent;
|
||||||
|
if (event == null || event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int range = event.getSpawnRadius();
|
||||||
|
if (range > MAX_RADIUS) {
|
||||||
|
range = MAX_RADIUS;
|
||||||
|
} else if (range < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.centersByRadius[range].add(player.chunkPosition().longKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void build() {
|
||||||
|
for (int index = 0; index < SIZE_RADIUS; index++) {
|
||||||
|
buildBy(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildBy(int index) {
|
||||||
|
LongArrayList list = this.centersByRadius[index];
|
||||||
|
int centersSize = deduplicate(list);
|
||||||
|
if (centersSize == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long[] centersRaw = list.elements();
|
||||||
|
long cachedKey = ChunkPos.asLong(ChunkPos.getX(centersRaw[0]) >> REGION_SHIFT, ChunkPos.getZ(centersRaw[0]) >> REGION_SHIFT);
|
||||||
|
long cachedVal = this.regionBitSets.get(cachedKey);
|
||||||
|
long[] offsets = TABLE_BFS[index];
|
||||||
|
for (int i = 0; i < centersSize; i++) {
|
||||||
|
long center = centersRaw[i];
|
||||||
|
int cx = ChunkPos.getX(center);
|
||||||
|
int cz = ChunkPos.getZ(center);
|
||||||
|
|
||||||
|
for (long packedOffset : offsets) {
|
||||||
|
int dx = ChunkPos.getX(packedOffset);
|
||||||
|
int dz = ChunkPos.getZ(packedOffset);
|
||||||
|
int chunkX = cx + dx;
|
||||||
|
int chunkZ = cz + dz;
|
||||||
|
|
||||||
|
int regionX = chunkX >> REGION_SHIFT;
|
||||||
|
int regionZ = chunkZ >> REGION_SHIFT;
|
||||||
|
long regionKey = ChunkPos.asLong(regionX, regionZ);
|
||||||
|
|
||||||
|
int localX = chunkX & REGION_MASK;
|
||||||
|
int localZ = chunkZ & REGION_MASK;
|
||||||
|
int bitIndex = (localZ << REGION_SHIFT) | localX;
|
||||||
|
long bitMask = 1L << bitIndex;
|
||||||
|
|
||||||
|
if (regionKey != cachedKey) {
|
||||||
|
this.regionBitSets.put(cachedKey, cachedVal);
|
||||||
|
cachedKey = regionKey;
|
||||||
|
cachedVal = this.regionBitSets.get(regionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedVal |= bitMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cachedVal != 0L) {
|
||||||
|
this.regionBitSets.put(cachedKey, cachedVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int deduplicate(LongArrayList list) {
|
||||||
|
int n = list.size();
|
||||||
|
if (n == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
list.unstableSort(null);
|
||||||
|
long[] centersRaw = list.elements();
|
||||||
|
int size = 0;
|
||||||
|
for (int i = 1; i < n; i++) {
|
||||||
|
long current = centersRaw[i];
|
||||||
|
long last = centersRaw[size];
|
||||||
|
if (current != last) {
|
||||||
|
size++;
|
||||||
|
centersRaw[size] = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void collectSpawningChunks(ReferenceList<LevelChunk> chunks, List<LevelChunk> out) {
|
||||||
|
LevelChunk[] raw = chunks.getRawDataUnchecked();
|
||||||
|
for (int i = 0, length = chunks.size(); i < length; i++) {
|
||||||
|
LevelChunk chunk = raw[i];
|
||||||
|
if (contains(chunk.locX, chunk.locZ)) {
|
||||||
|
out.add(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(int chunkX, int chunkZ) {
|
||||||
|
int regionX = chunkX >> REGION_SHIFT;
|
||||||
|
int regionZ = chunkZ >> REGION_SHIFT;
|
||||||
|
long bitset = this.regionBitSets.get(ChunkPos.asLong(regionX, regionZ));
|
||||||
|
return bitset != 0 && (bitset & (1L << (((chunkZ & REGION_MASK) << REGION_SHIFT) | (chunkX & REGION_MASK)))) != 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user