diff --git a/src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java b/src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java index 11d961afb..a3ee2d5b6 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java @@ -190,6 +190,26 @@ public boolean getEnforceFlight() { return configHandle.get(configNodes.enforceFlight); } + @ApiStatus.AvailableSince("5.3") + public Try setApplyEntitySpawnRate(boolean applyEntitySpawnRate) { + return configHandle.set(configNodes.applyEntitySpawnRate, applyEntitySpawnRate); + } + + @ApiStatus.AvailableSince("5.3") + public boolean getApplyEntitySpawnRate() { + return configHandle.get(configNodes.applyEntitySpawnRate); + } + + @ApiStatus.AvailableSince("5.3") + public Try setApplyEntitySpawnLimit(boolean applyEntitySpawnLimit) { + return configHandle.set(configNodes.applyEntitySpawnLimit, applyEntitySpawnLimit); + } + + @ApiStatus.AvailableSince("5.3") + public boolean getApplyEntitySpawnLimit() { + return configHandle.get(configNodes.applyEntitySpawnLimit); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java b/src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java index 8b10c33e7..670b6f039 100644 --- a/src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java +++ b/src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java @@ -137,6 +137,24 @@ private N node(N node) { .name("enforce-flight") .build()); + final ConfigNode applyEntitySpawnRate = node(ConfigNode.builder("world.apply-entity-spawn-rate", Boolean.class) + .comment("") + .comment("Sets whether Multiverse will apply the world's entity `tick-rate` config in worlds.yml.") + .comment("If disabled, the `tick-rate` config in worlds.yml will be ignored.") + .comment("Disable this if you want paper-world.yml or another plugin to handle entity spawn rate per world.") + .defaultValue(true) + .name("apply-entity-spawn-rate") + .build()); + + final ConfigNode applyEntitySpawnLimit = node(ConfigNode.builder("world.apply-entity-spawn-limit", Boolean.class) + .comment("") + .comment("Sets whether Multiverse will apply the world's entity `spawn-limit` config when a world is loaded.") + .comment("If disabled, the `spawn-limit` config in worlds.yml will be ignored.") + .comment("Disable this if you want paper-world.yml or another plugin to handle entity limits per world.") + .defaultValue(true) + .name("apply-entity-spawn-limit") + .build()); + final ConfigNode autoPurgeEntities = node(ConfigNode.builder("world.auto-purge-entities", Boolean.class) .comment("") .comment("Sets whether Multiverse will purge entities on world load based world's entity spawn config.") diff --git a/src/main/java/org/mvplugins/multiverse/core/world/WorldConfigNodes.java b/src/main/java/org/mvplugins/multiverse/core/world/WorldConfigNodes.java index 197275848..a22f0ca2f 100644 --- a/src/main/java/org/mvplugins/multiverse/core/world/WorldConfigNodes.java +++ b/src/main/java/org/mvplugins/multiverse/core/world/WorldConfigNodes.java @@ -16,6 +16,7 @@ import org.jetbrains.annotations.NotNull; import org.mvplugins.multiverse.core.MultiverseCore; +import org.mvplugins.multiverse.core.config.CoreConfig; import org.mvplugins.multiverse.core.config.node.serializer.NodeSerializer; import org.mvplugins.multiverse.core.event.world.MVWorldPropertyChangedEvent; import org.mvplugins.multiverse.core.config.node.ConfigNode; @@ -37,11 +38,13 @@ final class WorldConfigNodes { private final NodeGroup nodes = new NodeGroup(); private WorldManager worldManager; private EnforcementHandler enforcementHandler; + private CoreConfig config; private MultiverseWorld world = null; WorldConfigNodes(@NotNull MultiverseCore multiverseCore) { this.worldManager = multiverseCore.getServiceLocator().getService(WorldManager.class); this.enforcementHandler = multiverseCore.getServiceLocator().getService(EnforcementHandler.class); + this.config = multiverseCore.getServiceLocator().getService(CoreConfig.class); } MultiverseWorld getWorld() { @@ -244,7 +247,7 @@ public Object serialize(Material object, Class type) { })); final ConfigNode enititySpawnConfig = node(ConfigNode.builder("spawning", EntitySpawnConfig.class) - .defaultValue(() -> EntitySpawnConfig.fromSection(new MemoryConfiguration())) + .defaultValue(() -> EntitySpawnConfig.fromSection(config, new MemoryConfiguration())) .hidden() .serializer(new NodeSerializer<>() { @Override @@ -252,7 +255,7 @@ public EntitySpawnConfig deserialize(Object object, Class typ ConfigurationSection spawnSection = (object instanceof ConfigurationSection section) ? section : new MemoryConfiguration(); - return EntitySpawnConfig.fromSection(spawnSection); + return EntitySpawnConfig.fromSection(config, spawnSection); } @Override diff --git a/src/main/java/org/mvplugins/multiverse/core/world/entity/EntitySpawnConfig.java b/src/main/java/org/mvplugins/multiverse/core/world/entity/EntitySpawnConfig.java index 6a00a63f7..c87cce96d 100644 --- a/src/main/java/org/mvplugins/multiverse/core/world/entity/EntitySpawnConfig.java +++ b/src/main/java/org/mvplugins/multiverse/core/world/entity/EntitySpawnConfig.java @@ -1,29 +1,35 @@ package org.mvplugins.multiverse.core.world.entity; import com.dumptruckman.minecraft.util.Logging; -import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.MemoryConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.SpawnCategory; import org.jetbrains.annotations.ApiStatus; +import org.mvplugins.multiverse.core.config.CoreConfig; import org.mvplugins.multiverse.core.utils.StringFormatter; import org.mvplugins.multiverse.core.world.MultiverseWorld; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; public final class EntitySpawnConfig { + private final CoreConfig config; private final Map spawnCategoriesConfig; - EntitySpawnConfig(Map spawnCategoriesConfig) { + EntitySpawnConfig(CoreConfig config, Map spawnCategoriesConfig) { + this.config = config; this.spawnCategoriesConfig = spawnCategoriesConfig; } public SpawnCategoryConfig getSpawnCategoryConfig(SpawnCategory spawnCategory) { return spawnCategoriesConfig.computeIfAbsent(spawnCategory, - computeSpawnCategory -> new SpawnCategoryConfig(computeSpawnCategory, new MemoryConfiguration())); + computeSpawnCategory -> new SpawnCategoryConfig( + config, + computeSpawnCategory, + new MemoryConfiguration() + )); } public boolean shouldAllowSpawn(Entity entity) { @@ -52,17 +58,17 @@ public ConfigurationSection toSection() { } @ApiStatus.Internal - public static EntitySpawnConfig fromSection(ConfigurationSection section) { - Map spawnCategoriesConfig = new HashMap<>(); + public static EntitySpawnConfig fromSection(CoreConfig config, ConfigurationSection section) { + Map spawnCategoriesConfig = new LinkedHashMap<>(); section.getValues(false).forEach((key, value) -> { if (!(value instanceof ConfigurationSection sectionPart)) { Logging.warning("Invalid spawn category config for " + key + ": " + value); return; } SpawnCategory spawnCategory = SpawnCategory.valueOf(key.toUpperCase()); - spawnCategoriesConfig.put(spawnCategory, new SpawnCategoryConfig(spawnCategory, sectionPart)); + spawnCategoriesConfig.put(spawnCategory, new SpawnCategoryConfig(config, spawnCategory, sectionPart)); }); - return new EntitySpawnConfig(spawnCategoriesConfig); + return new EntitySpawnConfig(config, spawnCategoriesConfig); } @ApiStatus.Internal diff --git a/src/main/java/org/mvplugins/multiverse/core/world/entity/SpawnCategoryConfig.java b/src/main/java/org/mvplugins/multiverse/core/world/entity/SpawnCategoryConfig.java index 5f7b49c10..2eee36ad8 100644 --- a/src/main/java/org/mvplugins/multiverse/core/world/entity/SpawnCategoryConfig.java +++ b/src/main/java/org/mvplugins/multiverse/core/world/entity/SpawnCategoryConfig.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.SpawnCategory; +import org.mvplugins.multiverse.core.config.CoreConfig; import org.mvplugins.multiverse.core.config.handle.MemoryConfigurationHandle; import org.mvplugins.multiverse.core.config.handle.StringPropertyHandle; import org.mvplugins.multiverse.core.config.node.ConfigNode; @@ -21,6 +22,7 @@ public final class SpawnCategoryConfig { + private final CoreConfig config; private final SpawnCategory spawnCategory; private final MemoryConfigurationHandle handle; private final StringPropertyHandle stringPropertyHandle; @@ -28,7 +30,8 @@ public final class SpawnCategoryConfig { private MultiverseWorld world; - SpawnCategoryConfig(SpawnCategory spawnCategory, ConfigurationSection section) { + SpawnCategoryConfig(CoreConfig config, SpawnCategory spawnCategory, ConfigurationSection section) { + this.config = config; this.spawnCategory = spawnCategory; this.nodes = new Nodes(); this.handle = MemoryConfigurationHandle.builder(section, nodes.nodes) @@ -57,21 +60,37 @@ void applyConfigToWorld() { return; } loadedWorld.getBukkitWorld().peek(bukkitWorld -> { - if (!isSpawn()) { - if (getExceptions().isEmpty()) { - Logging.finer("World %s %s setTicksPerSpawns: 0", world.getName(), spawnCategory); - bukkitWorld.setTicksPerSpawns(spawnCategory, 0); - } else { - Logging.finer("World %s %s setTicksPerSpawns: -1", world.getName(), spawnCategory); - bukkitWorld.setTicksPerSpawns(spawnCategory, -1); - } + applyTickPerSpawns(bukkitWorld); + applySpawnLimit(bukkitWorld); + }); + } + + private void applyTickPerSpawns(World bukkitWorld) { + if (!config.getApplyEntitySpawnLimit()) { + Logging.finer("World %s %s skipping setTicksPerSpawns due to core config", world.getName(), spawnCategory); + return; + } + if (!isSpawn()) { + if (getExceptions().isEmpty()) { + Logging.finer("World %s %s setTicksPerSpawns: 0", world.getName(), spawnCategory); + bukkitWorld.setTicksPerSpawns(spawnCategory, 0); } else { - Logging.finer("World %s %s setTicksPerSpawns: %d", world.getName(), spawnCategory, getTickRate()); - bukkitWorld.setTicksPerSpawns(spawnCategory, getTickRate()); + Logging.finer("World %s %s setTicksPerSpawns: -1", world.getName(), spawnCategory); + bukkitWorld.setTicksPerSpawns(spawnCategory, -1); } - Logging.finer("World %s %s setSpawnLimit: %d", world.getName(), spawnCategory, getSpawnLimit()); - bukkitWorld.setSpawnLimit(spawnCategory, getSpawnLimit()); - }); + } else { + Logging.finer("World %s %s setTicksPerSpawns: %d", world.getName(), spawnCategory, getTickRate()); + bukkitWorld.setTicksPerSpawns(spawnCategory, getTickRate()); + } + } + + private void applySpawnLimit(World bukkitWorld) { + if (!config.getApplyEntitySpawnLimit()) { + Logging.finer("Skipping World %s %s setSpawnLimit due to core config", world.getName(), spawnCategory); + return; + } + Logging.finer("World %s %s setSpawnLimit: %d", world.getName(), spawnCategory, getSpawnLimit()); + bukkitWorld.setSpawnLimit(spawnCategory, getSpawnLimit()); } public StringPropertyHandle getStringPropertyHandle() { diff --git a/src/test/resources/configs/fresh_config.yml b/src/test/resources/configs/fresh_config.yml index aefac74bd..83425bd9a 100644 --- a/src/test/resources/configs/fresh_config.yml +++ b/src/test/resources/configs/fresh_config.yml @@ -4,6 +4,8 @@ world: enforce-access: false enforce-gamemode: true enforce-flight: true + apply-entity-spawn-rate: true + apply-entity-spawn-limit: true auto-purge-entities: false world-name-format: nether: '%overworld%_nether'