diff --git a/API/src/main/java/com/bgsoftware/wildstacker/api/objects/StackedSpawner.java b/API/src/main/java/com/bgsoftware/wildstacker/api/objects/StackedSpawner.java index 968d6e6e..8ff77fe5 100644 --- a/API/src/main/java/com/bgsoftware/wildstacker/api/objects/StackedSpawner.java +++ b/API/src/main/java/com/bgsoftware/wildstacker/api/objects/StackedSpawner.java @@ -49,4 +49,21 @@ public interface StackedSpawner extends StackedObject, Upgradea */ ItemStack getDropItem(int amount); + /** + * Check if the spawner is natural. + * A natural spawner is a spawner that was generated by the world and not placed by a player. + * + * @return true if the spawner is natural, false otherwise. + */ + boolean isNatural(); + + /** + * Set the natural state of the spawner. + * This is used to mark a spawner as natural or not. + * + * @param natural true if the spawner is natural, false otherwise. + */ + void setNatural(boolean natural); + + } diff --git a/src/main/java/com/bgsoftware/wildstacker/Locale.java b/src/main/java/com/bgsoftware/wildstacker/Locale.java index f6fdc469..20d94ceb 100644 --- a/src/main/java/com/bgsoftware/wildstacker/Locale.java +++ b/src/main/java/com/bgsoftware/wildstacker/Locale.java @@ -51,6 +51,7 @@ public final class Locale { public static Locale ONLY_ONE_SPAWNER = new Locale("ONLY_ONE_SPAWNER"); public static Locale RELOAD_SUCCESS = new Locale("RELOAD_SUCCESS"); public static Locale SPAWNER_BREAK = new Locale("SPAWNER_BREAK"); + public static Locale SPAWNER_BREAK_NATURAL_NOT_ALLOWED = new Locale("SPAWNER_BREAK_NATURAL_NOT_ALLOWED"); public static Locale SPAWNER_BREAK_NOT_ENOUGH_MONEY = new Locale("SPAWNER_BREAK_NOT_ENOUGH_MONEY"); public static Locale SPAWNER_BREAK_WITHOUT_SILK = new Locale("SPAWNER_BREAK_WITHOUT_SILK"); public static Locale SPAWNER_PLACE = new Locale("SPAWNER_PLACE"); diff --git a/src/main/java/com/bgsoftware/wildstacker/handlers/SettingsHandler.java b/src/main/java/com/bgsoftware/wildstacker/handlers/SettingsHandler.java index 8d27f901..8b98a434 100644 --- a/src/main/java/com/bgsoftware/wildstacker/handlers/SettingsHandler.java +++ b/src/main/java/com/bgsoftware/wildstacker/handlers/SettingsHandler.java @@ -102,7 +102,7 @@ public final class SettingsHandler { public final List entitiesParticles; //Spawners settings - public final boolean spawnersStackingEnabled, perSpawnerLimit, spawnersParticlesEnabled, chunkMergeSpawners, + public final boolean spawnersStackingEnabled, allowBreakVanillaSpawners, perSpawnerLimit, spawnersParticlesEnabled, chunkMergeSpawners, silkTouchSpawners, explosionsDropSpawner, explosionsDropToInventory, dropToInventory, shiftGetWholeSpawnerStack, getStackedItem, dropSpawnerWithoutSilk, spawnersMineRequireSilk, floatingSpawnerNames, spawnersPlacementPermission, spawnersShiftPlaceStack, changeUsingEggs, eggsStackMultiply, nextSpawnerPlacement, onlyOneSpawner, inventoryTweaksEnabled, @@ -295,6 +295,7 @@ public SettingsHandler(WildStackerPlugin plugin) { entitiesFillVehicles = cfg.getBoolean("entities.entities-fill-vehicles"); spawnersStackingEnabled = cfg.getBoolean("spawners.enabled", true); + allowBreakVanillaSpawners = cfg.getBoolean("spawners.allow-break-vanilla-spawners", true); spawnersMergeRadius = FastEnumMap.fromSection(cfg.getConfigurationSection("spawners.merge-radius"), EntityType.class); perSpawnerLimit = cfg.getBoolean("spawners.per-spawner-limit", false); spawnersParticlesEnabled = cfg.getBoolean("spawners.particles", true); diff --git a/src/main/java/com/bgsoftware/wildstacker/handlers/SystemHandler.java b/src/main/java/com/bgsoftware/wildstacker/handlers/SystemHandler.java index 0a7b9707..e63ba023 100644 --- a/src/main/java/com/bgsoftware/wildstacker/handlers/SystemHandler.java +++ b/src/main/java/com/bgsoftware/wildstacker/handlers/SystemHandler.java @@ -259,6 +259,11 @@ public StackedSpawner getStackedSpawner(Location location) { //Spawner wasn't found, creating a new object stackedSpawner = new WStackedSpawner((CreatureSpawner) location.getBlock().getState()); + + if (!dataHandler.CACHED_SPAWNERS_RAW.containsKey(location)) { + stackedSpawner.setNatural(true); + } + //A new spawner was created. Let's see if we need to add him if (stackedSpawner.isCached()) dataHandler.addStackedSpawner(stackedSpawner); diff --git a/src/main/java/com/bgsoftware/wildstacker/listeners/SpawnersListener.java b/src/main/java/com/bgsoftware/wildstacker/listeners/SpawnersListener.java index 10afafb6..16e616bc 100644 --- a/src/main/java/com/bgsoftware/wildstacker/listeners/SpawnersListener.java +++ b/src/main/java/com/bgsoftware/wildstacker/listeners/SpawnersListener.java @@ -148,7 +148,7 @@ public void onBlockPlace(BlockPlaceEvent e) { try { StackedSpawner stackedSpawner = WStackedSpawner.of(e.getBlockPlaced()); - + stackedSpawner.setNatural(false); if (!stackedSpawner.isCached()) return; @@ -334,6 +334,15 @@ public void onBlockBreak(BlockBreakEvent e) { return; StackedSpawner stackedSpawner = WStackedSpawner.of(e.getBlock()); + + if (stackedSpawner.isNatural()) { + if (!plugin.getSettings().allowBreakVanillaSpawners && !e.getPlayer().hasPermission("wildstacker.break.natural.bypass")) { + e.setCancelled(true); + Locale.SPAWNER_BREAK_NATURAL_NOT_ALLOWED.send(e.getPlayer()); + } + return; + } + CreatureSpawner creatureSpawner = (CreatureSpawner) e.getBlock().getState(); e.setCancelled(true); @@ -570,6 +579,11 @@ public void onSpawnerChange(PlayerInteractEvent e) { StackedSpawner stackedSpawner = WStackedSpawner.of(e.getClickedBlock()); + if (stackedSpawner.isNatural() && !plugin.getSettings().allowBreakVanillaSpawners && !e.getPlayer().hasPermission("wildstacker.break.natural.bypass")) { + e.setCancelled(true); + return; + } + if (!plugin.getSettings().changeUsingEggs) { e.setCancelled(true); @@ -615,6 +629,11 @@ public void onSpawnerInteract(PlayerInteractEvent e) { StackedSpawner stackedSpawner = WStackedSpawner.of(e.getClickedBlock()); + if (stackedSpawner.isNatural() && !plugin.getSettings().allowBreakVanillaSpawners && !e.getPlayer().hasPermission("wildstacker.break.natural.bypass")) { + e.setCancelled(true); + return; + } + if (plugin.getSettings().manageMenuEnabled && (!plugin.getSettings().sneakingOpenMenu || e.getPlayer().isSneaking())) { SpawnersManageMenu.open(e.getPlayer(), stackedSpawner); e.setCancelled(true); diff --git a/src/main/java/com/bgsoftware/wildstacker/objects/WStackedSpawner.java b/src/main/java/com/bgsoftware/wildstacker/objects/WStackedSpawner.java index d5fea442..890b5be5 100644 --- a/src/main/java/com/bgsoftware/wildstacker/objects/WStackedSpawner.java +++ b/src/main/java/com/bgsoftware/wildstacker/objects/WStackedSpawner.java @@ -41,6 +41,7 @@ public final class WStackedSpawner extends WStackedHologramObject runStack() { Optional spawnerOptional = GeneralUtils.getClosest(blockLocation, spawnerStream .filter(stackedSpawner -> runStackCheck(stackedSpawner) == StackCheckResult.SUCCESS)); + if (spawnerOptional.isPresent()) { StackedSpawner targetSpawner = spawnerOptional.get(); @@ -280,6 +290,10 @@ public StackResult runStack(StackedObject stackedObject) { StackedSpawner targetSpawner = (StackedSpawner) stackedObject; + if (!plugin.getSettings().allowBreakVanillaSpawners && targetSpawner.isNatural()) { + return StackResult.NOT_SIMILAR; + } + if (!EventsCaller.callSpawnerStackEvent(targetSpawner, this)) return StackResult.EVENT_CANCELLED; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index da17f263..fb841db4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -481,6 +481,9 @@ spawners: # Should spawners get stacked on the server? enabled: true + # Should vanilla spawners be allowed to break? + allow-break-vanilla-spawners: true + # How many blocks from the spawner should be checked for other spawners to stack into? # EntityType list: https://bg-software.com/entities/ merge-radius: diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index f9b8e895..1ecc0f1b 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -76,6 +76,7 @@ RELOAD_SUCCESS: '&6&lWildStacker &7Successfully reloaded the configuration files # Called when a player places / breaks a spawner SPAWNER_BREAK: '&6&lWildStacker &7You broke a {0} spawner (x{1}) and were charged for ${2}.' +SPAWNER_BREAK_NATURAL_NOT_ALLOWED: '&6&lWildStacker &7You cannot break natural spawners.' SPAWNER_BREAK_NOT_ENOUGH_MONEY: '&6&lWildStacker &fYou need {0} in order to break this amount of spawners.' SPAWNER_BREAK_WITHOUT_SILK: '&6&lWildStacker &7You must have a silk touch in order to break spawners.' SPAWNER_PLACE: '&6&lWildStacker &7You placed a {0} spawner (x{1}) and were charged for ${2}.' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a4080692..893135ab 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -93,4 +93,6 @@ permissions: default: true description: Gives access to use the toggle command if enabled. wildstacker.charge.bypass: - description: Bypass charging for placing and breaking spawners \ No newline at end of file + description: Bypass charging for placing and breaking spawners + wildstacker.break.natural.bypass: + description: Bypass breaking natural spawners. \ No newline at end of file