SPIGOT-6918: Add SpawnCategory API and configurations for Axolotls

This commit is contained in:
Doc 2022-02-07 18:47:27 +11:00 committed by md_5
parent 9dafd1092f
commit febaa1c6f5
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
9 changed files with 296 additions and 194 deletions

View File

@ -122,7 +122,7 @@
gameprofilerfiller.push("pollingChunks"); gameprofilerfiller.push("pollingChunks");
int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING);
- boolean flag1 = worlddata.getGameTime() % 400L == 0L; - boolean flag1 = worlddata.getGameTime() % 400L == 0L;
+ boolean flag1 = level.ticksPerAnimalSpawns != 0L && worlddata.getGameTime() % level.ticksPerAnimalSpawns == 0L; // CraftBukkit + boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
gameprofilerfiller.push("naturalSpawnCount"); gameprofilerfiller.push("naturalSpawnCount");
int l = this.distanceManager.getNaturalSpawnChunkCount(); int l = this.distanceManager.getNaturalSpawnChunkCount();

View File

@ -1,18 +1,20 @@
--- a/net/minecraft/world/level/SpawnerCreature.java --- a/net/minecraft/world/level/SpawnerCreature.java
+++ b/net/minecraft/world/level/SpawnerCreature.java +++ b/net/minecraft/world/level/SpawnerCreature.java
@@ -47,6 +47,11 @@ @@ -47,6 +47,13 @@
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
+// CraftBukkit start +// CraftBukkit start
+import net.minecraft.world.level.storage.WorldData; +import net.minecraft.world.level.storage.WorldData;
+import org.bukkit.craftbukkit.util.CraftSpawnCategory;
+import org.bukkit.entity.SpawnCategory;
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+// CraftBukkit end +// CraftBukkit end
+ +
public final class SpawnerCreature { public final class SpawnerCreature {
private static final Logger LOGGER = LogManager.getLogger(); private static final Logger LOGGER = LogManager.getLogger();
@@ -73,7 +78,8 @@ @@ -73,7 +80,8 @@
if (entity instanceof EntityInsentient) { if (entity instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) entity; EntityInsentient entityinsentient = (EntityInsentient) entity;
@ -22,50 +24,21 @@
continue; continue;
} }
} }
@@ -111,10 +117,54 @@ @@ -111,10 +119,25 @@
EnumCreatureType[] aenumcreaturetype = SpawnerCreature.SPAWNING_CATEGORIES; EnumCreatureType[] aenumcreaturetype = SpawnerCreature.SPAWNING_CATEGORIES;
int i = aenumcreaturetype.length; int i = aenumcreaturetype.length;
+ // CraftBukkit start - Other mob type spawn tick rate + WorldData worlddata = worldserver.getLevelData(); // CraftBukkit - Other mob type spawn tick rate
+ WorldData worlddata = worldserver.getLevelData();
+ boolean spawnAnimalThisTick = worldserver.ticksPerAnimalSpawns != 0L && worlddata.getGameTime() % worldserver.ticksPerAnimalSpawns == 0L;
+ boolean spawnMonsterThisTick = worldserver.ticksPerMonsterSpawns != 0L && worlddata.getGameTime() % worldserver.ticksPerMonsterSpawns == 0L;
+ boolean spawnWaterThisTick = worldserver.ticksPerWaterSpawns != 0L && worlddata.getGameTime() % worldserver.ticksPerWaterSpawns == 0L;
+ boolean spawnAmbientThisTick = worldserver.ticksPerAmbientSpawns != 0L && worlddata.getGameTime() % worldserver.ticksPerAmbientSpawns == 0L;
+ boolean spawnWaterAmbientThisTick = worldserver.ticksPerWaterAmbientSpawns != 0L && worlddata.getGameTime() % worldserver.ticksPerWaterAmbientSpawns == 0L;
+ boolean spawnWaterUndergroundCreatureThisTick = worldserver.ticksPerWaterUndergroundCreatureSpawns != 0L && worlddata.getGameTime() % worldserver.ticksPerWaterUndergroundCreatureSpawns == 0L;
+ // CraftBukkit end
+ +
for (int j = 0; j < i; ++j) { for (int j = 0; j < i; ++j) {
EnumCreatureType enumcreaturetype = aenumcreaturetype[j]; EnumCreatureType enumcreaturetype = aenumcreaturetype[j];
+ // CraftBukkit start - Use per-world spawn limits + // CraftBukkit start - Use per-world spawn limits
+ boolean spawnThisTick = true; + boolean spawnThisTick = true;
+ int limit = enumcreaturetype.getMaxInstancesPerChunk(); + int limit = enumcreaturetype.getMaxInstancesPerChunk();
+ switch (enumcreaturetype) { + SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(enumcreaturetype);
+ case MONSTER: + if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
+ spawnThisTick = spawnMonsterThisTick; + spawnThisTick = worldserver.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && worlddata.getGameTime() % worldserver.ticksPerSpawnCategory.getLong(spawnCategory) == 0;
+ limit = worldserver.getWorld().getMonsterSpawnLimit(); + limit = worldserver.getWorld().getSpawnLimit(spawnCategory);
+ break;
+ case CREATURE:
+ spawnThisTick = spawnAnimalThisTick;
+ limit = worldserver.getWorld().getAnimalSpawnLimit();
+ break;
+ case WATER_CREATURE:
+ spawnThisTick = spawnWaterThisTick;
+ limit = worldserver.getWorld().getWaterAnimalSpawnLimit();
+ break;
+ case UNDERGROUND_WATER_CREATURE:
+ spawnThisTick = spawnWaterUndergroundCreatureThisTick;
+ limit = worldserver.getWorld().getWaterUndergroundCreatureSpawnLimit();
+ break;
+ case AMBIENT:
+ spawnThisTick = spawnAmbientThisTick;
+ limit = worldserver.getWorld().getAmbientSpawnLimit();
+ break;
+ case WATER_AMBIENT:
+ spawnThisTick = spawnWaterAmbientThisTick;
+ limit = worldserver.getWorld().getWaterAmbientSpawnLimit();
+ break;
+ } + }
- if ((flag || !enumcreaturetype.isFriendly()) && (flag1 || enumcreaturetype.isFriendly()) && (flag2 || !enumcreaturetype.isPersistent()) && spawnercreature_d.canSpawnForCategory(enumcreaturetype, chunk.getPos())) { - if ((flag || !enumcreaturetype.isFriendly()) && (flag1 || enumcreaturetype.isFriendly()) && (flag2 || !enumcreaturetype.isPersistent()) && spawnercreature_d.canSpawnForCategory(enumcreaturetype, chunk.getPos())) {
@ -78,7 +51,7 @@
Objects.requireNonNull(spawnercreature_d); Objects.requireNonNull(spawnercreature_d);
SpawnerCreature.c spawnercreature_c = spawnercreature_d::canSpawn; SpawnerCreature.c spawnercreature_c = spawnercreature_d::canSpawn;
@@ -199,10 +249,14 @@ @@ -199,10 +222,14 @@
entityinsentient.moveTo(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F); entityinsentient.moveTo(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F);
if (isValidPositionForMob(worldserver, entityinsentient, d2)) { if (isValidPositionForMob(worldserver, entityinsentient, d2)) {
groupdataentity = entityinsentient.finalizeSpawn(worldserver, worldserver.getCurrentDifficultyAt(entityinsentient.blockPosition()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); groupdataentity = entityinsentient.finalizeSpawn(worldserver, worldserver.getCurrentDifficultyAt(entityinsentient.blockPosition()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
@ -97,7 +70,7 @@
if (j >= entityinsentient.getMaxSpawnClusterSize()) { if (j >= entityinsentient.getMaxSpawnClusterSize()) {
return; return;
} }
@@ -377,7 +431,7 @@ @@ -377,7 +404,7 @@
if (entityinsentient.checkSpawnRules(worldaccess, EnumMobSpawn.CHUNK_GENERATION) && entityinsentient.checkSpawnObstruction(worldaccess)) { if (entityinsentient.checkSpawnRules(worldaccess, EnumMobSpawn.CHUNK_GENERATION) && entityinsentient.checkSpawnObstruction(worldaccess)) {
groupdataentity = entityinsentient.finalizeSpawn(worldaccess, worldaccess.getCurrentDifficultyAt(entityinsentient.blockPosition()), EnumMobSpawn.CHUNK_GENERATION, groupdataentity, (NBTTagCompound) null); groupdataentity = entityinsentient.finalizeSpawn(worldaccess, worldaccess.getCurrentDifficultyAt(entityinsentient.blockPosition()), EnumMobSpawn.CHUNK_GENERATION, groupdataentity, (NBTTagCompound) null);
@ -106,7 +79,7 @@
flag = true; flag = true;
} }
} }
@@ -498,8 +552,10 @@ @@ -498,8 +525,10 @@
return this.unmodifiableMobCategoryCounts; return this.unmodifiableMobCategoryCounts;
} }

View File

@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/World.java --- a/net/minecraft/world/level/World.java
+++ b/net/minecraft/world/level/World.java +++ b/net/minecraft/world/level/World.java
@@ -67,6 +67,29 @@ @@ -67,6 +67,31 @@
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -22,7 +22,9 @@
+import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.craftbukkit.block.CapturedBlockState; +import org.bukkit.craftbukkit.block.CapturedBlockState;
+import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.block.data.CraftBlockData;
+import org.bukkit.craftbukkit.util.CraftSpawnCategory;
+import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey;
+import org.bukkit.entity.SpawnCategory;
+import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPhysicsEvent;
+import org.bukkit.event.world.GenericGameEvent; +import org.bukkit.event.world.GenericGameEvent;
+// CraftBukkit end +// CraftBukkit end
@ -30,7 +32,7 @@
public abstract class World implements GeneratorAccess, AutoCloseable { public abstract class World implements GeneratorAccess, AutoCloseable {
protected static final Logger LOGGER = LogManager.getLogger(); protected static final Logger LOGGER = LogManager.getLogger();
@@ -104,7 +127,46 @@ @@ -104,7 +129,43 @@
private final ResourceKey<World> dimension; private final ResourceKey<World> dimension;
private long subTickCount; private long subTickCount;
@ -47,12 +49,7 @@
+ public Map<BlockPosition, CapturedBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); + public Map<BlockPosition, CapturedBlockState> capturedBlockStates = new java.util.LinkedHashMap<>();
+ public Map<BlockPosition, TileEntity> capturedTileEntities = new HashMap<>(); + public Map<BlockPosition, TileEntity> capturedTileEntities = new HashMap<>();
+ public List<EntityItem> captureDrops; + public List<EntityItem> captureDrops;
+ public long ticksPerAnimalSpawns; + public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
+ public long ticksPerMonsterSpawns;
+ public long ticksPerWaterSpawns;
+ public long ticksPerWaterAmbientSpawns;
+ public long ticksPerWaterUndergroundCreatureSpawns;
+ public long ticksPerAmbientSpawns;
+ public boolean populating; + public boolean populating;
+ +
+ public CraftWorld getWorld() { + public CraftWorld getWorld() {
@ -68,17 +65,19 @@
+ protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, final DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) { + protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, final DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) {
+ this.generator = gen; + this.generator = gen;
+ this.world = new CraftWorld((WorldServer) this, gen, biomeProvider, env); + this.world = new CraftWorld((WorldServer) this, gen, biomeProvider, env);
+ this.ticksPerAnimalSpawns = this.getCraftServer().getTicksPerAnimalSpawns(); // CraftBukkit +
+ this.ticksPerMonsterSpawns = this.getCraftServer().getTicksPerMonsterSpawns(); // CraftBukkit + // CraftBukkit Ticks things
+ this.ticksPerWaterSpawns = this.getCraftServer().getTicksPerWaterSpawns(); // CraftBukkit + for (SpawnCategory spawnCategory : SpawnCategory.values()) {
+ this.ticksPerWaterAmbientSpawns = this.getCraftServer().getTicksPerWaterAmbientSpawns(); // CraftBukkit + if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
+ this.ticksPerWaterUndergroundCreatureSpawns = this.getCraftServer().getTicksPerWaterUndergroundCreatureSpawns(); // CraftBukkit + this.ticksPerSpawnCategory.put(spawnCategory, (long) this.getCraftServer().getTicksPerSpawns(spawnCategory));
+ this.ticksPerAmbientSpawns = this.getCraftServer().getTicksPerAmbientSpawns(); // CraftBukkit + }
+ }
+
+ // CraftBukkit end + // CraftBukkit end
this.profiler = supplier; this.profiler = supplier;
this.levelData = worlddatamutable; this.levelData = worlddatamutable;
this.dimensionType = dimensionmanager; this.dimensionType = dimensionmanager;
@@ -114,12 +176,12 @@ @@ -114,12 +175,12 @@
this.worldBorder = new WorldBorder() { this.worldBorder = new WorldBorder() {
@Override @Override
public double getCenterX() { public double getCenterX() {
@ -93,7 +92,7 @@
} }
}; };
} else { } else {
@@ -129,6 +191,42 @@ @@ -129,6 +190,42 @@
this.thread = Thread.currentThread(); this.thread = Thread.currentThread();
this.biomeManager = new BiomeManager(this, i); this.biomeManager = new BiomeManager(this, i);
this.isDebug = flag1; this.isDebug = flag1;
@ -136,7 +135,7 @@
} }
@Override @Override
@@ -186,6 +284,17 @@ @@ -186,6 +283,17 @@
@Override @Override
public boolean setBlock(BlockPosition blockposition, IBlockData iblockdata, int i, int j) { public boolean setBlock(BlockPosition blockposition, IBlockData iblockdata, int i, int j) {
@ -154,7 +153,7 @@
if (this.isOutsideBuildHeight(blockposition)) { if (this.isOutsideBuildHeight(blockposition)) {
return false; return false;
} else if (!this.isClientSide && this.isDebug()) { } else if (!this.isClientSide && this.isDebug()) {
@@ -193,9 +302,24 @@ @@ -193,9 +301,24 @@
} else { } else {
Chunk chunk = this.getChunkAt(blockposition); Chunk chunk = this.getChunkAt(blockposition);
Block block = iblockdata.getBlock(); Block block = iblockdata.getBlock();
@ -180,7 +179,7 @@
return false; return false;
} else { } else {
IBlockData iblockdata2 = this.getBlockState(blockposition); IBlockData iblockdata2 = this.getBlockState(blockposition);
@@ -206,6 +330,7 @@ @@ -206,6 +329,7 @@
this.getProfiler().pop(); this.getProfiler().pop();
} }
@ -188,7 +187,7 @@
if (iblockdata2 == iblockdata) { if (iblockdata2 == iblockdata) {
if (iblockdata1 != iblockdata2) { if (iblockdata1 != iblockdata2) {
this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); this.setBlocksDirty(blockposition, iblockdata1, iblockdata2);
@@ -232,12 +357,69 @@ @@ -232,12 +356,69 @@
this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); this.onBlockStateChange(blockposition, iblockdata1, iblockdata2);
} }
@ -258,7 +257,7 @@
public void onBlockStateChange(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} public void onBlockStateChange(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {}
@Override @Override
@@ -327,6 +509,17 @@ @@ -327,6 +508,17 @@
IBlockData iblockdata = this.getBlockState(blockposition); IBlockData iblockdata = this.getBlockState(blockposition);
try { try {
@ -276,7 +275,7 @@
iblockdata.neighborChanged(this, blockposition, block, blockposition1, false); iblockdata.neighborChanged(this, blockposition, block, blockposition1, false);
} catch (Throwable throwable) { } catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours"); CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours");
@@ -369,6 +562,14 @@ @@ -369,6 +561,14 @@
@Override @Override
public IBlockData getBlockState(BlockPosition blockposition) { public IBlockData getBlockState(BlockPosition blockposition) {
@ -291,7 +290,7 @@
if (this.isOutsideBuildHeight(blockposition)) { if (this.isOutsideBuildHeight(blockposition)) {
return Blocks.VOID_AIR.defaultBlockState(); return Blocks.VOID_AIR.defaultBlockState();
} else { } else {
@@ -494,6 +695,16 @@ @@ -494,6 +694,16 @@
@Nullable @Nullable
@Override @Override
public TileEntity getBlockEntity(BlockPosition blockposition) { public TileEntity getBlockEntity(BlockPosition blockposition) {
@ -308,7 +307,7 @@
return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, Chunk.EnumTileEntityState.IMMEDIATE)); return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, Chunk.EnumTileEntityState.IMMEDIATE));
} }
@@ -501,6 +712,12 @@ @@ -501,6 +711,12 @@
BlockPosition blockposition = tileentity.getBlockPos(); BlockPosition blockposition = tileentity.getBlockPos();
if (!this.isOutsideBuildHeight(blockposition)) { if (!this.isOutsideBuildHeight(blockposition)) {
@ -321,7 +320,7 @@
this.getChunkAt(blockposition).addAndRegisterBlockEntity(tileentity); this.getChunkAt(blockposition).addAndRegisterBlockEntity(tileentity);
} }
} }
@@ -605,7 +822,7 @@ @@ -605,7 +821,7 @@
for (int j = 0; j < i; ++j) { for (int j = 0; j < i; ++j) {
EntityComplexPart entitycomplexpart = aentitycomplexpart[j]; EntityComplexPart entitycomplexpart = aentitycomplexpart[j];
@ -330,7 +329,7 @@
if (t0 != null && predicate.test(t0)) { if (t0 != null && predicate.test(t0)) {
list.add(t0); list.add(t0);
@@ -931,6 +1148,14 @@ @@ -931,6 +1147,14 @@
public abstract LevelEntityGetter<Entity> getEntities(); public abstract LevelEntityGetter<Entity> getEntities();
protected void postGameEventInRadius(@Nullable Entity entity, GameEvent gameevent, BlockPosition blockposition, int i) { protected void postGameEventInRadius(@Nullable Entity entity, GameEvent gameevent, BlockPosition blockposition, int i) {

View File

@ -4,7 +4,6 @@ import com.google.common.base.Charsets;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
@ -13,12 +12,11 @@ import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.Lifecycle; import com.mojang.serialization.Lifecycle;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -28,7 +26,6 @@ import java.io.InputStreamReader;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64; import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -57,12 +54,8 @@ import net.minecraft.commands.arguments.ArgumentEntity;
import net.minecraft.core.BlockPosition; import net.minecraft.core.BlockPosition;
import net.minecraft.core.IRegistry; import net.minecraft.core.IRegistry;
import net.minecraft.core.RegistryMaterials; import net.minecraft.core.RegistryMaterials;
import net.minecraft.nbt.DynamicOpsNBT;
import net.minecraft.nbt.NBTBase;
import net.minecraft.resources.MinecraftKey; import net.minecraft.resources.MinecraftKey;
import net.minecraft.resources.RegistryReadOps;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerCommand; import net.minecraft.server.ServerCommand;
import net.minecraft.server.bossevents.BossBattleCustom; import net.minecraft.server.bossevents.BossBattleCustom;
import net.minecraft.server.commands.CommandReload; import net.minecraft.server.commands.CommandReload;
@ -75,7 +68,6 @@ import net.minecraft.server.level.TicketType;
import net.minecraft.server.level.WorldServer; import net.minecraft.server.level.WorldServer;
import net.minecraft.server.players.GameProfileBanEntry; import net.minecraft.server.players.GameProfileBanEntry;
import net.minecraft.server.players.IpBanEntry; import net.minecraft.server.players.IpBanEntry;
import net.minecraft.server.players.JsonListEntry;
import net.minecraft.server.players.OpListEntry; import net.minecraft.server.players.OpListEntry;
import net.minecraft.server.players.PlayerList; import net.minecraft.server.players.PlayerList;
import net.minecraft.server.players.WhiteListEntry; import net.minecraft.server.players.WhiteListEntry;
@ -199,11 +191,13 @@ import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.craftbukkit.util.CraftIconCache; import org.bukkit.craftbukkit.util.CraftIconCache;
import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.util.CraftSpawnCategory;
import org.bukkit.craftbukkit.util.DatFileFilter; import org.bukkit.craftbukkit.util.DatFileFilter;
import org.bukkit.craftbukkit.util.Versioning; import org.bukkit.craftbukkit.util.Versioning;
import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions; import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.SpawnCategory;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerChatTabCompleteEvent; import org.bukkit.event.player.PlayerChatTabCompleteEvent;
import org.bukkit.event.server.BroadcastMessageEvent; import org.bukkit.event.server.BroadcastMessageEvent;
@ -276,12 +270,7 @@ public final class CraftServer implements Server {
private final EntityMetadataStore entityMetadata = new EntityMetadataStore(); private final EntityMetadataStore entityMetadata = new EntityMetadataStore();
private final PlayerMetadataStore playerMetadata = new PlayerMetadataStore(); private final PlayerMetadataStore playerMetadata = new PlayerMetadataStore();
private final WorldMetadataStore worldMetadata = new WorldMetadataStore(); private final WorldMetadataStore worldMetadata = new WorldMetadataStore();
private int monsterSpawn = -1; private final Object2IntOpenHashMap<SpawnCategory> spawnCategoryLimit = new Object2IntOpenHashMap<>();
private int animalSpawn = -1;
private int waterAnimalSpawn = -1;
private int waterAmbientSpawn = -1;
private int waterUndergroundCreatureSpawn = -1;
private int ambientSpawn = -1;
private File container; private File container;
private WarningState warningState = WarningState.DEFAULT; private WarningState warningState = WarningState.DEFAULT;
public String minimumAPI; public String minimumAPI;
@ -366,12 +355,7 @@ public final class CraftServer implements Server {
overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*");
ignoreVanillaPermissions = commandsConfiguration.getBoolean("ignore-vanilla-permissions"); ignoreVanillaPermissions = commandsConfiguration.getBoolean("ignore-vanilla-permissions");
pluginManager.useTimings(configuration.getBoolean("settings.plugin-profiling")); pluginManager.useTimings(configuration.getBoolean("settings.plugin-profiling"));
monsterSpawn = configuration.getInt("spawn-limits.monsters"); overrideSpawnLimits();
animalSpawn = configuration.getInt("spawn-limits.animals");
waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals");
waterAmbientSpawn = configuration.getInt("spawn-limits.water-ambient");
waterUndergroundCreatureSpawn = configuration.getInt("spawn-limits.water-underground-creature");
ambientSpawn = configuration.getInt("spawn-limits.ambient");
console.autosavePeriod = configuration.getInt("ticks-per.autosave"); console.autosavePeriod = configuration.getInt("ticks-per.autosave");
warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose"));
TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks"); TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks");
@ -391,6 +375,14 @@ public final class CraftServer implements Server {
return (File) console.options.valueOf("commands-settings"); return (File) console.options.valueOf("commands-settings");
} }
private void overrideSpawnLimits() {
for (SpawnCategory spawnCategory : SpawnCategory.values()) {
if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
spawnCategoryLimit.put(spawnCategory, configuration.getInt(CraftSpawnCategory.getConfigNameSpawnLimit(spawnCategory)));
}
}
}
private void saveConfig() { private void saveConfig() {
try { try {
configuration.save(getConfigFile()); configuration.save(getConfigFile());
@ -721,33 +713,46 @@ public final class CraftServer implements Server {
} }
@Override @Override
@Deprecated
public int getTicksPerAnimalSpawns() { public int getTicksPerAnimalSpawns() {
return this.configuration.getInt("ticks-per.animal-spawns"); return getTicksPerSpawns(SpawnCategory.ANIMAL);
} }
@Override @Override
@Deprecated
public int getTicksPerMonsterSpawns() { public int getTicksPerMonsterSpawns() {
return this.configuration.getInt("ticks-per.monster-spawns"); return getTicksPerSpawns(SpawnCategory.MONSTER);
} }
@Override @Override
@Deprecated
public int getTicksPerWaterSpawns() { public int getTicksPerWaterSpawns() {
return this.configuration.getInt("ticks-per.water-spawns"); return getTicksPerSpawns(SpawnCategory.WATER_ANIMAL);
} }
@Override @Override
@Deprecated
public int getTicksPerWaterAmbientSpawns() { public int getTicksPerWaterAmbientSpawns() {
return this.configuration.getInt("ticks-per.water-ambient-spawns"); return getTicksPerSpawns(SpawnCategory.WATER_AMBIENT);
} }
@Override @Override
@Deprecated
public int getTicksPerWaterUndergroundCreatureSpawns() { public int getTicksPerWaterUndergroundCreatureSpawns() {
return this.configuration.getInt("ticks-per.water-underground-creature-spawns"); return getTicksPerSpawns(SpawnCategory.WATER_UNDERGROUND_CREATURE);
} }
@Override @Override
@Deprecated
public int getTicksPerAmbientSpawns() { public int getTicksPerAmbientSpawns() {
return this.configuration.getInt("ticks-per.ambient-spawns"); return getTicksPerSpawns(SpawnCategory.AMBIENT);
}
@Override
public int getTicksPerSpawns(SpawnCategory spawnCategory) {
Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
return this.configuration.getInt(CraftSpawnCategory.getConfigNameTicksPerSpawn(spawnCategory));
} }
@Override @Override
@ -825,12 +830,7 @@ public final class CraftServer implements Server {
console.setPvpAllowed(config.pvp); console.setPvpAllowed(config.pvp);
console.setFlightAllowed(config.allowFlight); console.setFlightAllowed(config.allowFlight);
console.setMotd(config.motd); console.setMotd(config.motd);
monsterSpawn = configuration.getInt("spawn-limits.monsters"); overrideSpawnLimits();
animalSpawn = configuration.getInt("spawn-limits.animals");
waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals");
waterAmbientSpawn = configuration.getInt("spawn-limits.water-ambient");
waterUndergroundCreatureSpawn = configuration.getInt("spawn-limits.water-underground-creature");
ambientSpawn = configuration.getInt("spawn-limits.ambient");
warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose"));
TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks"); TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks");
minimumAPI = configuration.getString("settings.minimum-api"); minimumAPI = configuration.getString("settings.minimum-api");
@ -852,40 +852,16 @@ public final class CraftServer implements Server {
for (WorldServer world : console.getAllLevels()) { for (WorldServer world : console.getAllLevels()) {
world.serverLevelData.setDifficulty(config.difficulty); world.serverLevelData.setDifficulty(config.difficulty);
world.setSpawnSettings(config.spawnMonsters, config.spawnAnimals); world.setSpawnSettings(config.spawnMonsters, config.spawnAnimals);
if (this.getTicksPerAnimalSpawns() < 0) {
world.ticksPerAnimalSpawns = 400;
} else {
world.ticksPerAnimalSpawns = this.getTicksPerAnimalSpawns();
}
if (this.getTicksPerMonsterSpawns() < 0) { for (SpawnCategory spawnCategory : SpawnCategory.values()) {
world.ticksPerMonsterSpawns = 1; if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
long ticksPerCategorySpawn = this.getTicksPerSpawns(spawnCategory);
if (ticksPerCategorySpawn < 0) {
world.ticksPerSpawnCategory.put(spawnCategory, CraftSpawnCategory.getDefaultTicksPerSpawn(spawnCategory));
} else { } else {
world.ticksPerMonsterSpawns = this.getTicksPerMonsterSpawns(); world.ticksPerSpawnCategory.put(spawnCategory, ticksPerCategorySpawn);
} }
if (this.getTicksPerWaterSpawns() < 0) {
world.ticksPerWaterSpawns = 1;
} else {
world.ticksPerWaterSpawns = this.getTicksPerWaterSpawns();
} }
if (this.getTicksPerWaterAmbientSpawns() < 0) {
world.ticksPerWaterAmbientSpawns = 1;
} else {
world.ticksPerWaterAmbientSpawns = this.getTicksPerWaterAmbientSpawns();
}
if (this.getTicksPerWaterUndergroundCreatureSpawns() < 0) {
world.ticksPerWaterUndergroundCreatureSpawns = 1;
} else {
world.ticksPerWaterUndergroundCreatureSpawns = this.getTicksPerWaterUndergroundCreatureSpawns();
}
if (this.getTicksPerAmbientSpawns() < 0) {
world.ticksPerAmbientSpawns = 1;
} else {
world.ticksPerAmbientSpawns = this.getTicksPerAmbientSpawns();
} }
} }
@ -1873,33 +1849,44 @@ public final class CraftServer implements Server {
} }
@Override @Override
@Deprecated
public int getMonsterSpawnLimit() { public int getMonsterSpawnLimit() {
return monsterSpawn; return getSpawnLimit(SpawnCategory.MONSTER);
} }
@Override @Override
@Deprecated
public int getAnimalSpawnLimit() { public int getAnimalSpawnLimit() {
return animalSpawn; return getSpawnLimit(SpawnCategory.ANIMAL);
} }
@Override @Override
@Deprecated
public int getWaterAnimalSpawnLimit() { public int getWaterAnimalSpawnLimit() {
return waterAnimalSpawn; return getSpawnLimit(SpawnCategory.WATER_ANIMAL);
} }
@Override @Override
@Deprecated
public int getWaterAmbientSpawnLimit() { public int getWaterAmbientSpawnLimit() {
return waterAmbientSpawn; return getSpawnLimit(SpawnCategory.WATER_AMBIENT);
} }
@Override @Override
@Deprecated
public int getWaterUndergroundCreatureSpawnLimit() { public int getWaterUndergroundCreatureSpawnLimit() {
return waterUndergroundCreatureSpawn; return getSpawnLimit(SpawnCategory.WATER_UNDERGROUND_CREATURE);
} }
@Override @Override
@Deprecated
public int getAmbientSpawnLimit() { public int getAmbientSpawnLimit() {
return ambientSpawn; return getSpawnLimit(SpawnCategory.AMBIENT);
}
@Override
public int getSpawnLimit(SpawnCategory spawnCategory) {
return spawnCategoryLimit.getOrDefault(spawnCategory, -1);
} }
@Override @Override

View File

@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -52,7 +53,6 @@ import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.RayTrace; import net.minecraft.world.level.RayTrace;
import net.minecraft.world.level.biome.BiomeBase; import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.IChunkAccess; import net.minecraft.world.level.chunk.IChunkAccess;
import net.minecraft.world.level.chunk.ProtoChunkExtension; import net.minecraft.world.level.chunk.ProtoChunkExtension;
@ -94,6 +94,7 @@ import org.bukkit.craftbukkit.metadata.BlockMetadataStore;
import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.CraftRayTraceResult; import org.bukkit.craftbukkit.util.CraftRayTraceResult;
import org.bukkit.craftbukkit.util.CraftSpawnCategory;
import org.bukkit.entity.AbstractArrow; import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -101,6 +102,7 @@ import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.SpawnCategory;
import org.bukkit.entity.SpectralArrow; import org.bukkit.entity.SpectralArrow;
import org.bukkit.entity.TippedArrow; import org.bukkit.entity.TippedArrow;
import org.bukkit.entity.Trident; import org.bukkit.entity.Trident;
@ -134,12 +136,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
private final BiomeProvider biomeProvider; private final BiomeProvider biomeProvider;
private final List<BlockPopulator> populators = new ArrayList<BlockPopulator>(); private final List<BlockPopulator> populators = new ArrayList<BlockPopulator>();
private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this); private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this);
private int monsterSpawn = -1; private final Object2IntOpenHashMap<SpawnCategory> spawnCategoryLimit = new Object2IntOpenHashMap<>();
private int animalSpawn = -1;
private int waterAnimalSpawn = -1;
private int waterAmbientSpawn = -1;
private int waterUndergroundCreatureSpawn = -1;
private int ambientSpawn = -1;
private static final Random rand = new Random(); private static final Random rand = new Random();
@ -1320,63 +1317,91 @@ public class CraftWorld extends CraftRegionAccessor implements World {
} }
@Override @Override
@Deprecated
public long getTicksPerAnimalSpawns() { public long getTicksPerAnimalSpawns() {
return world.ticksPerAnimalSpawns; return getTicksPerSpawns(SpawnCategory.ANIMAL);
} }
@Override @Override
@Deprecated
public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) { public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) {
world.ticksPerAnimalSpawns = ticksPerAnimalSpawns; setTicksPerSpawns(SpawnCategory.ANIMAL, ticksPerAnimalSpawns);
} }
@Override @Override
@Deprecated
public long getTicksPerMonsterSpawns() { public long getTicksPerMonsterSpawns() {
return world.ticksPerMonsterSpawns; return getTicksPerSpawns(SpawnCategory.MONSTER);
} }
@Override @Override
@Deprecated
public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) { public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) {
world.ticksPerMonsterSpawns = ticksPerMonsterSpawns; setTicksPerSpawns(SpawnCategory.MONSTER, ticksPerMonsterSpawns);
} }
@Override @Override
@Deprecated
public long getTicksPerWaterSpawns() { public long getTicksPerWaterSpawns() {
return world.ticksPerWaterSpawns; return getTicksPerSpawns(SpawnCategory.WATER_ANIMAL);
} }
@Override @Override
@Deprecated
public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) { public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) {
world.ticksPerWaterSpawns = ticksPerWaterSpawns; setTicksPerSpawns(SpawnCategory.WATER_ANIMAL, ticksPerWaterSpawns);
} }
@Override @Override
@Deprecated
public long getTicksPerWaterAmbientSpawns() { public long getTicksPerWaterAmbientSpawns() {
return world.ticksPerWaterAmbientSpawns; return getTicksPerSpawns(SpawnCategory.WATER_AMBIENT);
} }
@Override @Override
@Deprecated
public void setTicksPerWaterAmbientSpawns(int ticksPerWaterAmbientSpawns) { public void setTicksPerWaterAmbientSpawns(int ticksPerWaterAmbientSpawns) {
world.ticksPerWaterAmbientSpawns = ticksPerWaterAmbientSpawns; setTicksPerSpawns(SpawnCategory.WATER_AMBIENT, ticksPerWaterAmbientSpawns);
} }
@Override @Override
@Deprecated
public long getTicksPerWaterUndergroundCreatureSpawns() { public long getTicksPerWaterUndergroundCreatureSpawns() {
return world.ticksPerWaterUndergroundCreatureSpawns; return getTicksPerSpawns(SpawnCategory.WATER_UNDERGROUND_CREATURE);
} }
@Override @Override
@Deprecated
public void setTicksPerWaterUndergroundCreatureSpawns(int ticksPerWaterUndergroundCreatureSpawns) { public void setTicksPerWaterUndergroundCreatureSpawns(int ticksPerWaterUndergroundCreatureSpawns) {
world.ticksPerWaterUndergroundCreatureSpawns = ticksPerWaterUndergroundCreatureSpawns; setTicksPerSpawns(SpawnCategory.WATER_UNDERGROUND_CREATURE, ticksPerWaterUndergroundCreatureSpawns);
} }
@Override @Override
@Deprecated
public long getTicksPerAmbientSpawns() { public long getTicksPerAmbientSpawns() {
return world.ticksPerAmbientSpawns; return getTicksPerSpawns(SpawnCategory.AMBIENT);
} }
@Override @Override
@Deprecated
public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) { public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) {
world.ticksPerAmbientSpawns = ticksPerAmbientSpawns; setTicksPerSpawns(SpawnCategory.AMBIENT, ticksPerAmbientSpawns);
}
@Override
public void setTicksPerSpawns(SpawnCategory spawnCategory, int ticksPerCategorySpawn) {
Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
world.ticksPerSpawnCategory.put(spawnCategory, (long) ticksPerCategorySpawn);
}
@Override
public long getTicksPerSpawns(SpawnCategory spawnCategory) {
Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
return world.ticksPerSpawnCategory.getLong(spawnCategory);
} }
@Override @Override
@ -1400,87 +1425,95 @@ public class CraftWorld extends CraftRegionAccessor implements World {
} }
@Override @Override
@Deprecated
public int getMonsterSpawnLimit() { public int getMonsterSpawnLimit() {
if (monsterSpawn < 0) { return getSpawnLimit(SpawnCategory.MONSTER);
return server.getMonsterSpawnLimit();
}
return monsterSpawn;
} }
@Override @Override
@Deprecated
public void setMonsterSpawnLimit(int limit) { public void setMonsterSpawnLimit(int limit) {
monsterSpawn = limit; setSpawnLimit(SpawnCategory.MONSTER, limit);
} }
@Override @Override
@Deprecated
public int getAnimalSpawnLimit() { public int getAnimalSpawnLimit() {
if (animalSpawn < 0) { return getSpawnLimit(SpawnCategory.ANIMAL);
return server.getAnimalSpawnLimit();
}
return animalSpawn;
} }
@Override @Override
@Deprecated
public void setAnimalSpawnLimit(int limit) { public void setAnimalSpawnLimit(int limit) {
animalSpawn = limit; setSpawnLimit(SpawnCategory.ANIMAL, limit);
} }
@Override @Override
@Deprecated
public int getWaterAnimalSpawnLimit() { public int getWaterAnimalSpawnLimit() {
if (waterAnimalSpawn < 0) { return getSpawnLimit(SpawnCategory.WATER_ANIMAL);
return server.getWaterAnimalSpawnLimit();
}
return waterAnimalSpawn;
} }
@Override @Override
@Deprecated
public void setWaterAnimalSpawnLimit(int limit) { public void setWaterAnimalSpawnLimit(int limit) {
waterAnimalSpawn = limit; setSpawnLimit(SpawnCategory.WATER_ANIMAL, limit);
} }
@Override @Override
@Deprecated
public int getWaterAmbientSpawnLimit() { public int getWaterAmbientSpawnLimit() {
if (waterAmbientSpawn < 0) { return getSpawnLimit(SpawnCategory.WATER_AMBIENT);
return server.getWaterAmbientSpawnLimit();
}
return waterAmbientSpawn;
} }
@Override @Override
@Deprecated
public void setWaterAmbientSpawnLimit(int limit) { public void setWaterAmbientSpawnLimit(int limit) {
waterAmbientSpawn = limit; setSpawnLimit(SpawnCategory.WATER_AMBIENT, limit);
} }
@Override @Override
@Deprecated
public int getWaterUndergroundCreatureSpawnLimit() { public int getWaterUndergroundCreatureSpawnLimit() {
if (waterUndergroundCreatureSpawn < 0) { return getSpawnLimit(SpawnCategory.WATER_UNDERGROUND_CREATURE);
return server.getWaterUndergroundCreatureSpawnLimit();
}
return waterUndergroundCreatureSpawn;
} }
@Override @Override
@Deprecated
public void setWaterUndergroundCreatureSpawnLimit(int limit) { public void setWaterUndergroundCreatureSpawnLimit(int limit) {
waterUndergroundCreatureSpawn = limit; setSpawnLimit(SpawnCategory.WATER_UNDERGROUND_CREATURE, limit);
} }
@Override @Override
@Deprecated
public int getAmbientSpawnLimit() { public int getAmbientSpawnLimit() {
if (ambientSpawn < 0) { return getSpawnLimit(SpawnCategory.AMBIENT);
return server.getAmbientSpawnLimit();
}
return ambientSpawn;
} }
@Override @Override
@Deprecated
public void setAmbientSpawnLimit(int limit) { public void setAmbientSpawnLimit(int limit) {
ambientSpawn = limit; setSpawnLimit(SpawnCategory.AMBIENT, limit);
}
@Override
public int getSpawnLimit(SpawnCategory spawnCategory) {
Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
int limit = spawnCategoryLimit.getInt(spawnCategory);
if (limit < 0) {
limit = server.getSpawnLimit(spawnCategory);
}
return limit;
}
@Override
public void setSpawnLimit(SpawnCategory spawnCategory, int limit) {
Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
spawnCategoryLimit.put(spawnCategory, limit);
} }
@Override @Override

View File

@ -165,8 +165,10 @@ import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry;
import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.craftbukkit.util.CraftSpawnCategory;
import org.bukkit.craftbukkit.util.CraftVector; import org.bukkit.craftbukkit.util.CraftVector;
import org.bukkit.entity.Pose; import org.bukkit.entity.Pose;
import org.bukkit.entity.SpawnCategory;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.metadata.MetadataValue; import org.bukkit.metadata.MetadataValue;
@ -1021,6 +1023,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return Pose.values()[getHandle().getPose().ordinal()]; return Pose.values()[getHandle().getPose().ordinal()];
} }
@Override
public SpawnCategory getSpawnCategory() {
return CraftSpawnCategory.toBukkit(getHandle().getType().getCategory());
}
public void storeBukkitValues(NBTTagCompound c) { public void storeBukkitValues(NBTTagCompound c) {
if (!this.persistentDataContainer.isEmpty()) { if (!this.persistentDataContainer.isEmpty()) {
c.put("BukkitValues", this.persistentDataContainer.toTagCompound()); c.put("BukkitValues", this.persistentDataContainer.toTagCompound());

View File

@ -0,0 +1,74 @@
package org.bukkit.craftbukkit.util;
import net.minecraft.world.entity.EnumCreatureType;
import org.bukkit.entity.SpawnCategory;
public class CraftSpawnCategory {
public static boolean isValidForLimits(SpawnCategory spawnCategory) {
return spawnCategory != null && spawnCategory != SpawnCategory.MISC;
}
public static String getConfigNameSpawnLimit(SpawnCategory spawnCategory) {
return switch (spawnCategory) {
case MONSTER -> "spawn-limits.monsters";
case ANIMAL -> "spawn-limits.animals";
case WATER_ANIMAL -> "spawn-limits.water-animals";
case WATER_AMBIENT -> "spawn-limits.water-ambient";
case WATER_UNDERGROUND_CREATURE -> "spawn-limits.water-underground-creature";
case AMBIENT -> "spawn-limits.ambient";
case AXOLOTL -> "spawn-limits.axolotls";
default -> throw new UnsupportedOperationException("Unknown Config value " + spawnCategory + " for spawn-limits");
};
}
public static String getConfigNameTicksPerSpawn(SpawnCategory spawnCategory) {
return switch (spawnCategory) {
case MONSTER -> "ticks-per.monster-spawns";
case ANIMAL -> "ticks-per.animal-spawns";
case WATER_ANIMAL -> "ticks-per.water-spawns";
case WATER_AMBIENT -> "ticks-per.water-ambient-spawns";
case WATER_UNDERGROUND_CREATURE -> "ticks-per.water-underground-creature-spawns";
case AMBIENT -> "ticks-per.ambient-spawns";
case AXOLOTL -> "ticks-per.axolotl-spawns";
default -> throw new UnsupportedOperationException("Unknown Config value " + spawnCategory + " for ticks-per");
};
}
public static long getDefaultTicksPerSpawn(SpawnCategory spawnCategory) {
return switch (spawnCategory) {
case MONSTER, AXOLOTL, AMBIENT, WATER_UNDERGROUND_CREATURE, WATER_AMBIENT, WATER_ANIMAL -> 1;
case ANIMAL -> 400; // This value come from commit 2995a08324f
default -> throw new UnsupportedOperationException("Unknown Config value " + spawnCategory + " for ticks-per");
};
}
public static SpawnCategory toBukkit(EnumCreatureType enumCreatureType) {
return switch (enumCreatureType) {
case MONSTER -> SpawnCategory.MONSTER;
case CREATURE -> SpawnCategory.ANIMAL;
case AMBIENT -> SpawnCategory.AMBIENT;
case AXOLOTLS -> SpawnCategory.AXOLOTL;
case WATER_CREATURE -> SpawnCategory.WATER_ANIMAL;
case WATER_AMBIENT -> SpawnCategory.WATER_AMBIENT;
case UNDERGROUND_WATER_CREATURE -> SpawnCategory.WATER_UNDERGROUND_CREATURE;
case MISC -> SpawnCategory.MISC;
default -> throw new UnsupportedOperationException("Unknown EnumCreatureType " + enumCreatureType + " for SpawnCategory");
};
}
public static EnumCreatureType toNMS(SpawnCategory spawnCategory) {
return switch (spawnCategory) {
case MONSTER -> EnumCreatureType.MONSTER;
case ANIMAL -> EnumCreatureType.CREATURE;
case AMBIENT -> EnumCreatureType.AMBIENT;
case AXOLOTL -> EnumCreatureType.AXOLOTLS;
case WATER_ANIMAL -> EnumCreatureType.WATER_CREATURE;
case WATER_AMBIENT -> EnumCreatureType.WATER_AMBIENT;
case WATER_UNDERGROUND_CREATURE -> EnumCreatureType.UNDERGROUND_WATER_CREATURE;
case MISC -> EnumCreatureType.MISC;
default -> throw new UnsupportedOperationException("Unknown SpawnCategory " + spawnCategory + " for EnumCreatureType");
};
}
}

View File

@ -28,6 +28,7 @@ spawn-limits:
water-animals: 5 water-animals: 5
water-ambient: 20 water-ambient: 20
water-underground-creature: 5 water-underground-creature: 5
axolotls: 5
ambient: 15 ambient: 15
chunk-gc: chunk-gc:
period-in-ticks: 600 period-in-ticks: 600
@ -37,6 +38,7 @@ ticks-per:
water-spawns: 1 water-spawns: 1
water-ambient-spawns: 1 water-ambient-spawns: 1
water-underground-creature-spawns: 1 water-underground-creature-spawns: 1
axolotl-spawns: 1
ambient-spawns: 1 ambient-spawns: 1
autosave: 6000 autosave: 6000
aliases: now-in-commands.yml aliases: now-in-commands.yml

View File

@ -0,0 +1,27 @@
package org.bukkit.entity;
import net.minecraft.world.entity.EnumCreatureType;
import org.bukkit.craftbukkit.util.CraftSpawnCategory;
import org.junit.Test;
public class SpawnCategoryTest {
@Test
public void testMatch() {
for (EnumCreatureType enumCreatureType : EnumCreatureType.values()) {
// If it is missing a convert to Bukkit then throw a UnsupportedOperationException
SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(enumCreatureType);
if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
long defaultTicks = CraftSpawnCategory.getDefaultTicksPerSpawn(spawnCategory);
String nameConfigSpawnLimit = CraftSpawnCategory.getConfigNameSpawnLimit(spawnCategory);
String nameConfigTicksPerSpawn = CraftSpawnCategory.getConfigNameTicksPerSpawn(spawnCategory);
}
}
for (SpawnCategory spawnCategory : SpawnCategory.values()) {
// If it is missing a convert to NMS then throw a UnsupportedOperationException
EnumCreatureType enumCreatureType = CraftSpawnCategory.toNMS(spawnCategory);
}
}
}