Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-11-14 20:10:05 +01:00
661839e033
It was returning ticking chunk count instead of the intended full chunk count. We can also directly use the size of the fullChunks collection instead of iterating all chunks.
90 Zeilen
5.8 KiB
Diff
90 Zeilen
5.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: kickash32 <kickash32@gmail.com>
|
|
Date: Mon, 5 Apr 2021 01:42:35 -0400
|
|
Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob
|
|
spawns
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
index 4896c3ba81ead769972fa9efdbe563d4006e4401..5b3a886c624b36557cbfaccdc3fb05a46a4ba36a 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
@@ -246,8 +246,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
++(backingSet[i].mobCounts[index]);
|
|
}
|
|
}
|
|
+ // Paper start - per player mob count backoff
|
|
+ public void updateFailurePlayerMobTypeMap(int chunkX, int chunkZ, net.minecraft.world.entity.MobCategory mobCategory) {
|
|
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) {
|
|
+ return;
|
|
+ }
|
|
+ int idx = mobCategory.ordinal();
|
|
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<ServerPlayer> inRange =
|
|
+ this.level.moonrise$getNearbyPlayers().getPlayersByChunk(chunkX, chunkZ, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE);
|
|
+ if (inRange == null) {
|
|
+ return;
|
|
+ }
|
|
+ final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
|
|
+ for (int i = 0, len = inRange.size(); i < len; i++) {
|
|
+ ++(backingSet[i].mobBackoffCounts[idx]);
|
|
+ }
|
|
+ }
|
|
+ // Paper end - per player mob count backoff
|
|
public int getMobCountNear(final ServerPlayer player, final net.minecraft.world.entity.MobCategory mobCategory) {
|
|
- return player.mobCounts[mobCategory.ordinal()];
|
|
+ return player.mobCounts[mobCategory.ordinal()] + player.mobBackoffCounts[mobCategory.ordinal()]; // Paper - per player mob count backoff
|
|
// Paper end - Optional per player mob spawns
|
|
}
|
|
// Paper end
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
index b1ecc218034944533967375d11297705c3fc01a3..aaaadb7be8abf867624a1ca83371595bef4ab633 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
@@ -555,7 +555,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
|
|
// re-set mob counts
|
|
for (ServerPlayer player : this.level.players) {
|
|
- Arrays.fill(player.mobCounts, 0);
|
|
+ // Paper start - per player mob spawning backoff
|
|
+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
|
|
+ player.mobCounts[ii] = 0;
|
|
+
|
|
+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
|
|
+ if (newBackoff < 0) {
|
|
+ newBackoff = 0;
|
|
+ }
|
|
+ player.mobBackoffCounts[ii] = newBackoff;
|
|
+ }
|
|
+ // Paper end - per player mob spawning backoff
|
|
}
|
|
spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true);
|
|
} else {
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index 8cc02ee9b1a710e35eb65a5a095681cc7dc542bb..4e4e5b7e8c387cf13cf5bc5e39d334c3222c9103 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -307,6 +307,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
|
|
public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length;
|
|
public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper
|
|
// Paper end - Optional per player mob spawns
|
|
+ public final int[] mobBackoffCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper - per player mob count backoff
|
|
|
|
// CraftBukkit start
|
|
public CraftPlayer.TransferCookieConnection transferCookieConnection;
|
|
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
index 0beb5ab48c5405d9bc2ad8d0c430312f456d38c2..5297798c2be1ba85569c2b92ed221956bf75477a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
@@ -299,6 +299,11 @@ public final class NaturalSpawner {
|
|
|
|
// Paper start - PreCreatureSpawnEvent
|
|
PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
|
|
+ // Paper start - per player mob count backoff
|
|
+ if (doSpawning == PreSpawnStatus.ABORT || doSpawning == PreSpawnStatus.CANCELLED) {
|
|
+ world.getChunkSource().chunkMap.updateFailurePlayerMobTypeMap(blockposition_mutableblockposition.getX() >> 4, blockposition_mutableblockposition.getZ() >> 4, group);
|
|
+ }
|
|
+ // Paper end - per player mob count backoff
|
|
if (doSpawning == PreSpawnStatus.ABORT) {
|
|
return;
|
|
}
|