minecraft-src/net/minecraft/world/level/LocalMobCapCalculator.java
2025-07-04 01:41:11 +03:00

57 lines
2.2 KiB
Java

package net.minecraft.world.level;
import com.google.common.collect.Maps;
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.MobCategory;
public class LocalMobCapCalculator {
private final Long2ObjectMap<List<ServerPlayer>> playersNearChunk = new Long2ObjectOpenHashMap<>();
private final Map<ServerPlayer, LocalMobCapCalculator.MobCounts> playerMobCounts = Maps.<ServerPlayer, LocalMobCapCalculator.MobCounts>newHashMap();
private final ChunkMap chunkMap;
public LocalMobCapCalculator(ChunkMap chunkMap) {
this.chunkMap = chunkMap;
}
private List<ServerPlayer> getPlayersNear(ChunkPos pos) {
return this.playersNearChunk
.computeIfAbsent(pos.toLong(), (Long2ObjectFunction<? extends List<ServerPlayer>>)(l -> this.chunkMap.getPlayersCloseForSpawning(pos)));
}
public void addMob(ChunkPos pos, MobCategory category) {
for (ServerPlayer serverPlayer : this.getPlayersNear(pos)) {
((LocalMobCapCalculator.MobCounts)this.playerMobCounts.computeIfAbsent(serverPlayer, serverPlayerx -> new LocalMobCapCalculator.MobCounts())).add(category);
}
}
public boolean canSpawn(MobCategory category, ChunkPos pos) {
for (ServerPlayer serverPlayer : this.getPlayersNear(pos)) {
LocalMobCapCalculator.MobCounts mobCounts = (LocalMobCapCalculator.MobCounts)this.playerMobCounts.get(serverPlayer);
if (mobCounts == null || mobCounts.canSpawn(category)) {
return true;
}
}
return false;
}
static class MobCounts {
private final Object2IntMap<MobCategory> counts = new Object2IntOpenHashMap<>(MobCategory.values().length);
public void add(MobCategory category) {
this.counts.computeInt(category, (mobCategory, integer) -> integer == null ? 1 : integer + 1);
}
public boolean canSpawn(MobCategory category) {
return this.counts.getOrDefault(category, 0) < category.getMaxInstancesPerChunk();
}
}
}