From 308f1645607e5deb9ef633804443d537b4814648 Mon Sep 17 00:00:00 2001 From: Ryandw11 <6239385+ryandw11@users.noreply.github.com> Date: Sat, 23 Mar 2024 20:03:02 -0600 Subject: [PATCH] Improve control over what worlds a structure can spawn in. - Adds a blacklist for structures. - Adds a global whitelist and blacklist for worlds. --- .../ryandw11/structure/CustomStructures.java | 21 ++++++++++ .../commands/cstruct/TestSpawnCommand.java | 5 +-- .../ignoreblocks/IgnoreBlocks_1_20.java | 3 +- .../structure/structure/Structure.java | 6 +-- .../structure/structure/StructureBuilder.java | 1 + .../properties/StructureLocation.java | 39 +++++++++++++++++++ src/main/resources/config.yml | 5 +++ 7 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/ryandw11/structure/CustomStructures.java b/src/main/java/com/ryandw11/structure/CustomStructures.java index 820264a..dbf6c0c 100644 --- a/src/main/java/com/ryandw11/structure/CustomStructures.java +++ b/src/main/java/com/ryandw11/structure/CustomStructures.java @@ -23,6 +23,7 @@ import org.bstats.charts.AdvancedPie; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -810,4 +811,24 @@ public MythicalMobHook getMythicalMobHook() { public CitizensNpcHook getCitizensNpcHook() { return citizensNpcHook; } + + /** + * Check if a structure can spawn in a world based upon the global white and black lists. + * + *

This does not check a structure's local properties. Use {@link com.ryandw11.structure.structure.properties.StructureLocation#canSpawnInWorld(World)} + * instead. (That method also calls this method).

+ * + * @param world The world to check. + * @return If a structure can spawn in a world based upon the global white and black lists. + */ + public boolean canStructureSpawnInWorld(World world) { + List whitelist = getConfig().getStringList("GlobalWorldWhitelist"); + List blacklist = getConfig().getStringList("GlobalWorldBlacklist"); + + if (!whitelist.isEmpty() && !whitelist.contains(world.getName())) + return false; + if (blacklist.contains(world.getName())) + return false; + return true; + } } diff --git a/src/main/java/com/ryandw11/structure/commands/cstruct/TestSpawnCommand.java b/src/main/java/com/ryandw11/structure/commands/cstruct/TestSpawnCommand.java index 25aece6..e31fa42 100644 --- a/src/main/java/com/ryandw11/structure/commands/cstruct/TestSpawnCommand.java +++ b/src/main/java/com/ryandw11/structure/commands/cstruct/TestSpawnCommand.java @@ -184,9 +184,8 @@ void psuedoCalculate(Player p, Structure structure, Block bl, Chunk ch) { } void canSpawn(Player p, Structure structure, Block block, Chunk chunk) { - if (!structure.getStructureLocation().getWorlds().isEmpty()) { - if (!structure.getStructureLocation().getWorlds().contains(chunk.getWorld().getName())) - quickSendMessage(p, "&cFailed world test! Cannot spawn in current world!"); + if (!structure.getStructureLocation().canSpawnInWorld(chunk.getWorld())) { + quickSendMessage(p, "&cFailed world test! Cannot spawn in current world!"); } // Check to see if the structure is far enough away from spawn. diff --git a/src/main/java/com/ryandw11/structure/ignoreblocks/IgnoreBlocks_1_20.java b/src/main/java/com/ryandw11/structure/ignoreblocks/IgnoreBlocks_1_20.java index 25aae74..563c109 100644 --- a/src/main/java/com/ryandw11/structure/ignoreblocks/IgnoreBlocks_1_20.java +++ b/src/main/java/com/ryandw11/structure/ignoreblocks/IgnoreBlocks_1_20.java @@ -6,9 +6,8 @@ /** * Ignore blocks for 1.20 - *

- * TODO Maybe use built in list defined by data packs? Or have the option */ +// TODO: Maybe use built in list defined by data packs? Or have the option public class IgnoreBlocks_1_20 implements IgnoreBlocks { private final List ignoreBlocks = List.of( diff --git a/src/main/java/com/ryandw11/structure/structure/Structure.java b/src/main/java/com/ryandw11/structure/structure/Structure.java index 28b94ee..d61e9ed 100644 --- a/src/main/java/com/ryandw11/structure/structure/Structure.java +++ b/src/main/java/com/ryandw11/structure/structure/Structure.java @@ -263,10 +263,10 @@ public double getBaseRotation() { */ public boolean canSpawn(@Nullable Block block, @NotNull Chunk chunk) { // Check to see if the structure can spawn in the current world. - if (!getStructureLocation().getWorlds().isEmpty()) { - if (!getStructureLocation().getWorlds().contains(chunk.getWorld().getName())) - return false; + if (!getStructureLocation().canSpawnInWorld(chunk.getWorld())) { + return false; } + // If the block is null, that means it is in the void, check if it can spawn in the void. if (block == null && !getStructureProperties().canSpawnInVoid()) return false; diff --git a/src/main/java/com/ryandw11/structure/structure/StructureBuilder.java b/src/main/java/com/ryandw11/structure/structure/StructureBuilder.java index 57b703b..2169678 100644 --- a/src/main/java/com/ryandw11/structure/structure/StructureBuilder.java +++ b/src/main/java/com/ryandw11/structure/structure/StructureBuilder.java @@ -469,6 +469,7 @@ public void save(File file) throws IOException { config.set("Probability.Denominator", probabilityDenominator); config.set("StructureLocation.Worlds", structureLocation.getWorlds()); + config.set("StructureLocation.WorldBlacklist", structureLocation.getWorldBlacklist()); config.set("StructureLocation.SpawnY", structureLocation.getSpawnSettings().getValue()); config.set("StructureLocation.SpawnYHeightMap", structureLocation.getSpawnSettings().getHeightMap().toString()); config.set("StructureLocation.Biome", structureLocation.getBiomes()); diff --git a/src/main/java/com/ryandw11/structure/structure/properties/StructureLocation.java b/src/main/java/com/ryandw11/structure/structure/properties/StructureLocation.java index d9c373e..0bbfc5d 100644 --- a/src/main/java/com/ryandw11/structure/structure/properties/StructureLocation.java +++ b/src/main/java/com/ryandw11/structure/structure/properties/StructureLocation.java @@ -3,9 +3,11 @@ import com.ryandw11.structure.exceptions.StructureConfigurationException; import com.ryandw11.structure.structure.StructureBuilder; import org.bukkit.HeightMap; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -16,6 +18,7 @@ public class StructureLocation implements StructureProperty { private List worlds; + private List worldBlacklist; private StructureYSpawning spawnY; private List biomes; private double distanceFromOthers; @@ -49,6 +52,12 @@ public StructureLocation(FileConfiguration fileConfiguration) { this.worlds = cs.getStringList("Worlds"); else this.worlds = new ArrayList<>(); + + if (cs.contains("WorldBlacklist")) + this.worldBlacklist = cs.getStringList("WorldBlacklist"); + else + this.worldBlacklist = new ArrayList<>(); + this.spawnY = new StructureYSpawning(fileConfiguration); if (cs.contains("Biome")) this.biomes = cs.getStringList("Biome"); @@ -86,6 +95,7 @@ public StructureLocation(FileConfiguration fileConfiguration) { */ public StructureLocation(List worlds, StructureYSpawning spawnSettings, List biomes) { this.worlds = worlds; + this.worldBlacklist = new ArrayList<>(); this.spawnY = spawnSettings; this.biomes = biomes; this.distanceFromOthers = 100; @@ -110,6 +120,34 @@ public List getWorlds() { return worlds; } + /** + * Get the list of blacklisted worlds. + * + * @return The list of blacklisted worlds. + */ + public List getWorldBlacklist() { + return worldBlacklist; + } + + /** + * Check if a structure can spawn in the provided world. + * + * @param world The world to check. + * @return If the structure can spawn in that world. + */ + public boolean canSpawnInWorld(@NotNull World world) { + if (!worlds.isEmpty()) { + if (!worlds.contains(world.getName())) + return false; + } + + if (worldBlacklist.contains(world.getName())) { + return false; + } + + return true; + } + /** * Get the Y Spawn settings. * @@ -255,6 +293,7 @@ public void setDistanceFromSame(double distance) { @Override public void saveToFile(ConfigurationSection configurationSection) { configurationSection.set("Worlds", worlds); + configurationSection.set("WorldBlacklist", worldBlacklist); configurationSection.set("SpawnY", spawnY.getValue()); configurationSection.set("SpawnYHeightMap", spawnY.getHeightMap().toString()); configurationSection.set("Biome", biomes); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 91dff64..9a41595 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -16,5 +16,10 @@ bstats: true # Enabling this option allows developers to use the API to get the location of structures. logStructures: false +# A global list of worlds that structures are allow to spawn in. +GlobalWorldWhitelist: [] +# A global list of worlds that structures are not allowed to spawn in. +GlobalWorldBlacklist: [] + Structures: - demo \ No newline at end of file