diff --git a/build.gradle.kts b/build.gradle.kts index ae68752..8491126 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { allprojects { project.group = "net.momirealms" - project.version = "3.3.1.2" + project.version = "3.3.1.3" apply() apply(plugin = "java") diff --git a/plugin/src/main/java/net/momirealms/customcrops/api/object/InteractCrop.java b/plugin/src/main/java/net/momirealms/customcrops/api/object/InteractCrop.java index 27d4900..a19589f 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/api/object/InteractCrop.java +++ b/plugin/src/main/java/net/momirealms/customcrops/api/object/InteractCrop.java @@ -19,7 +19,10 @@ package net.momirealms.customcrops.api.object; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.object.action.Action; +import net.momirealms.customcrops.api.object.requirement.CurrentState; import net.momirealms.customcrops.api.object.requirement.Requirement; +import org.bukkit.Location; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; @@ -58,8 +61,14 @@ public class InteractCrop { return actions; } - @Nullable - public Requirement[] getRequirements() { - return requirements; + public boolean canInteract(Player player, Location location) { + if (requirements == null) return true; + CurrentState currentState = new CurrentState(location, player); + for (Requirement requirement : requirements) { + if (!requirement.isConditionMet(currentState)) { + return false; + } + } + return true; } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/api/object/crop/CropConfig.java b/plugin/src/main/java/net/momirealms/customcrops/api/object/crop/CropConfig.java index 1efac8a..198e53c 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/api/object/crop/CropConfig.java +++ b/plugin/src/main/java/net/momirealms/customcrops/api/object/crop/CropConfig.java @@ -22,7 +22,10 @@ import net.momirealms.customcrops.api.object.ItemMode; import net.momirealms.customcrops.api.object.action.Action; import net.momirealms.customcrops.api.object.condition.Condition; import net.momirealms.customcrops.api.object.condition.DeathCondition; +import net.momirealms.customcrops.api.object.requirement.CurrentState; import net.momirealms.customcrops.api.object.requirement.Requirement; +import org.bukkit.Location; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -127,4 +130,26 @@ public class CropConfig { public boolean isRotationEnabled() { return rotation; } + + public boolean canPlant(Player player, Location location) { + if (plantRequirements == null) return true; + CurrentState currentState = new CurrentState(location, player); + for (Requirement requirement : plantRequirements) { + if (!requirement.isConditionMet(currentState)) { + return false; + } + } + return true; + } + + public boolean canBreak(Player player, Location location) { + if (breakRequirements == null) return true; + CurrentState currentState = new CurrentState(location, player); + for (Requirement requirement : breakRequirements) { + if (!requirement.isConditionMet(currentState)) { + return false; + } + } + return true; + } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/api/object/fertilizer/FertilizerConfig.java b/plugin/src/main/java/net/momirealms/customcrops/api/object/fertilizer/FertilizerConfig.java index d1d6750..d54196f 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/api/object/fertilizer/FertilizerConfig.java +++ b/plugin/src/main/java/net/momirealms/customcrops/api/object/fertilizer/FertilizerConfig.java @@ -18,8 +18,11 @@ package net.momirealms.customcrops.api.object.fertilizer; import net.kyori.adventure.sound.Sound; +import net.momirealms.customcrops.api.object.requirement.CurrentState; import net.momirealms.customcrops.api.object.requirement.Requirement; +import org.bukkit.Location; import org.bukkit.Particle; +import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; public abstract class FertilizerConfig { @@ -105,4 +108,15 @@ public abstract class FertilizerConfig { public Requirement[] getRequirements() { return requirements; } + + public boolean canUse(Player player, Location location) { + if (requirements == null) return true; + CurrentState currentState = new CurrentState(location, player); + for (Requirement requirement : requirements) { + if (!requirement.isConditionMet(currentState)) { + return false; + } + } + return true; + } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java b/plugin/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java index f3011aa..ee55ece 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java +++ b/plugin/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java @@ -23,6 +23,7 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customcrops.api.object.fill.PositiveFillMethod; import net.momirealms.customcrops.api.object.requirement.CurrentState; import net.momirealms.customcrops.api.object.requirement.Requirement; +import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -165,7 +166,26 @@ public class WateringCanConfig { return Optional.ofNullable(appearanceMap.get(water)).orElse(0); } - public Requirement[] getRequirements() { - return requirements; + public boolean canUse(Player player, Location location) { + if (requirements == null) return true; + CurrentState currentState = new CurrentState(location, player); + for (Requirement requirement : requirements) { + if (!requirement.isConditionMet(currentState)) { + return false; + } + } + return true; + } + + public boolean isWhiteListedPot(String potID) { + if (potWhitelist != null) { + inner: { + for (String pot : potWhitelist) + if (pot.equals(potID)) + break inner; + return false; + } + } + return true; } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java b/plugin/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java index 399535d..42bdfe9 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java +++ b/plugin/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java @@ -57,13 +57,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.util.*; import java.util.concurrent.*; public class CCWorld extends Function { private final String worldName; - private final World world; + private final Reference world; private final ConcurrentHashMap chunkMap; private final ScheduledThreadPoolExecutor schedule; private long currentDay; @@ -86,7 +88,7 @@ public class CCWorld extends Function { this.chunksFolder = ConfigUtils.getFile(world, "chunks"); this.dateFile = ConfigUtils.getFile(world, "data.yml"); this.corruptedFile = ConfigUtils.getFile(world, "corrupted.yml"); - this.world = world; + this.world = new WeakReference<>(world); this.chunkMap = new ConcurrentHashMap<>(64); this.schedule = new ScheduledThreadPoolExecutor(ConfigManager.corePoolSize); this.schedule.setMaximumPoolSize(ConfigManager.maxPoolSize); @@ -127,7 +129,7 @@ public class CCWorld extends Function { } public void unload() { - if (this.timerTask != null) { + if (this.timerTask != null && !this.timerTask.isCancelled()) { this.timerTask.cancel(false); this.timerTask = null; } @@ -235,17 +237,18 @@ public class CCWorld extends Function { private void scheduleTask() { if (this.timerTask == null) { this.timerTask = plugin.getScheduler().runTaskTimerAsync(() -> { - if (world != null) { + World worldInstance = world.get(); + if (worldInstance != null) { if (ConfigManager.debugScheduler) { Log.info("Queue size: " + schedule.getQueue().size() + " Completed: " + schedule.getCompletedTaskCount()); } - long day = world.getFullTime() / 24000; - long time = world.getTime(); + long day = worldInstance.getFullTime() / 24000; + long time = worldInstance.getTime(); this.tryDayCycleTask(time, day); this.timerTask(); } else { AdventureUtils.consoleMessage("[CustomCrops] World: " + worldName + " unloaded unexpectedly. Shutdown the schedule."); - this.schedule.shutdown(); + this.disable(); } }, 1000, 1000L); } @@ -311,6 +314,9 @@ public class CCWorld extends Function { private void closePool() { this.schedule.shutdown(); + if (this.timerTask != null && !this.timerTask.isCancelled()) { + this.timerTask.cancel(false); + } } @SuppressWarnings("ResultOfMethodCallIgnored") @@ -448,7 +454,7 @@ public class CCWorld extends Function { return; } - if (world.isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) { + if (world.get().isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) { replacePot(simpleLocation, pot, potConfig); return; } @@ -533,7 +539,7 @@ public class CCWorld extends Function { SprinklerAnimation sprinklerAnimation = sprinklerConfig.getSprinklerAnimation(); - if (world.isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4) && sprinklerAnimation != null) { + if (world.get().isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4) && sprinklerAnimation != null) { for (Player player : Bukkit.getOnlinePlayers()) { SimpleLocation playerLoc = SimpleLocation.getByBukkitLocation(player.getLocation()); if (playerLoc.isNear(simpleLocation, 48)) { @@ -572,7 +578,7 @@ public class CCWorld extends Function { @Override public void run() { - if (world.isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) { + if (world.get().isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) { replacePot(simpleLocation, amount, whitelist); return; } @@ -584,7 +590,7 @@ public class CCWorld extends Function { return; } - CompletableFuture asyncGetChunk = world.getChunkAtAsync(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4); + CompletableFuture asyncGetChunk = world.get().getChunkAtAsync(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4); asyncGetChunk.whenComplete((result, throwable) -> replacePot(simpleLocation, amount, whitelist)); } } @@ -721,7 +727,7 @@ public class CCWorld extends Function { String finalNextModel = nextModel; if (finalNextModel == null || location == null) return; - if (world.isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { + if (world.get().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { switch (itemMode) { case ITEM_FRAME -> replaceItemFrameCrop(location, finalNextModel, cropConfig.isRotationEnabled()); case ITEM_DISPLAY -> replaceItemDisplayCrop(location, finalNextModel, cropConfig.isRotationEnabled()); diff --git a/plugin/src/main/java/net/momirealms/customcrops/customplugin/PlatformManager.java b/plugin/src/main/java/net/momirealms/customcrops/customplugin/PlatformManager.java index e318700..3a9910e 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/customplugin/PlatformManager.java +++ b/plugin/src/main/java/net/momirealms/customcrops/customplugin/PlatformManager.java @@ -432,13 +432,8 @@ public class PlatformManager extends Function { WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); if (wateringCanConfig != null) { - if (wateringCanConfig.getRequirements() != null) { - CurrentState currentState = new CurrentState(location, player); - for (Requirement requirement : wateringCanConfig.getRequirements()) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } + if (!wateringCanConfig.canUse(player, location)) { + return true; } String[] sprinkler_whitelist = wateringCanConfig.getSprinklerWhitelist(); @@ -579,18 +574,10 @@ public class PlatformManager extends Function { if (item_in_hand_id.equals("AIR")) { InteractCrop interactCrop = stageConfig.getInteractByHand(); if (interactCrop != null) { - Requirement[] requirements = interactCrop.getRequirements(); - if (requirements != null) { - CurrentState currentState = new CurrentState(location, player); - for (Requirement requirement : requirements) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } - } - for (Action action : interactCrop.getActions()) { + if (interactCrop.canInteract(player, location)) + return true; + for (Action action : interactCrop.getActions()) action.doOn(player, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode()); - } } return true; } @@ -623,35 +610,19 @@ public class PlatformManager extends Function { WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); if (wateringCanConfig != null) { - if (wateringCanConfig.getRequirements() != null) { - CurrentState currentState = new CurrentState(location, player); - for (Requirement requirement : wateringCanConfig.getRequirements()) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } - } + if (!wateringCanConfig.canUse(player, location)) + return true; - String[] pot_whitelist = wateringCanConfig.getPotWhitelist(); - if (pot_whitelist != null) { - inner: { - for (String pot : pot_whitelist) { - if (pot.equals(pot_id)) { - break inner; - } - } - return true; - } - } + if (!wateringCanConfig.isWhiteListedPot(pot_id)) + return true; int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand); if (current_water <= 0) return true; PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, bottomLoc); Bukkit.getPluginManager().callEvent(potWaterEvent); - if (potWaterEvent.isCancelled()) { + if (potWaterEvent.isCancelled()) return true; - } current_water--; this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), bottomLoc, player.getLocation().getYaw(), pot_id, wateringCanConfig.getParticle(), potWaterEvent.getWater()); @@ -686,30 +657,24 @@ public class PlatformManager extends Function { InteractCrop[] interactActions = stageConfig.getInteractCropWithItem(); if (interactActions != null) { - outer: for (InteractCrop interactCrop : interactActions) { if (interactCrop.isRightItem(item_in_hand_id)) { - Requirement[] requirements = interactCrop.getRequirements(); - if (requirements != null) { - CurrentState currentState = new CurrentState(location, player); - for (Requirement requirement : requirements) { - if (!requirement.isConditionMet(currentState)) { - continue outer; - } - } - } + if (interactCrop.canInteract(player, location)) + continue; if (player.getGameMode() != GameMode.CREATIVE) { - if (interactCrop.isConsumed()) { + if (interactCrop.isConsumed()) item_in_hand.setAmount(item_in_hand.getAmount() - 1); - } - if (interactCrop.getReturned() != null) { + if (interactCrop.getReturned() != null) player.getInventory().addItem(interactCrop.getReturned()); - } } Action[] inAc = interactCrop.getActions(); if (inAc != null) { for (Action action : inAc) { - action.doOn(player, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode()); + action.doOn( + player, + SimpleLocation.getByBukkitLocation(location), + cropConfig.getCropMode() + ); } } return true; @@ -721,24 +686,20 @@ public class PlatformManager extends Function { public boolean onInteractPot(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) { String pot_id = plugin.getPotManager().getPotKeyByBlockID(id); - if (pot_id == null) { + if (pot_id == null) return false; - } PotConfig potConfig = plugin.getPotManager().getPotConfig(pot_id); - if (potConfig == null) { + if (potConfig == null) return false; - } - if (!ProtectionLib.canPlace(player, location)) { + if (!ProtectionLib.canPlace(player, location)) return true; - } PotInteractEvent potInteractEvent = new PotInteractEvent(player, item_in_hand, location, pot_id); Bukkit.getPluginManager().callEvent(potInteractEvent); - if (potInteractEvent.isCancelled()) { + if (potInteractEvent.isCancelled()) return true; - } outer: { // plant @@ -756,17 +717,12 @@ public class PlatformManager extends Function { } Location crop_loc = location.clone().add(0,1,0); - Requirement[] requirements = cropConfig.getPlantRequirements(); - if (requirements != null) { - CurrentState currentState = new CurrentState(crop_loc, player); - for (Requirement requirement : requirements) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } - } + if (!cropConfig.canPlant(player, crop_loc)) + return true; + + if (plugin.getPlatformInterface().detectAnyThing(crop_loc)) + return true; - if (plugin.getPlatformInterface().detectAnyThing(crop_loc)) return true; if (ConfigManager.enableLimitation && plugin.getWorldDataManager().getChunkCropAmount(SimpleLocation.getByBukkitLocation(crop_loc)) >= plugin.getConfigManager().getCropLimit(location.getWorld().getName())) { AdventureUtils.playerMessage(player, MessageManager.prefix + MessageManager.reachChunkLimit); return true; @@ -775,9 +731,8 @@ public class PlatformManager extends Function { String crop_model = Objects.requireNonNull(cropConfig.getStageConfig(0)).getModel(); CropPlantEvent cropPlantEvent = new CropPlantEvent(player, item_in_hand, location, cropConfig.getKey(), 0, crop_model); Bukkit.getPluginManager().callEvent(cropPlantEvent); - if (cropPlantEvent.isCancelled()) { + if (cropPlantEvent.isCancelled()) return true; - } Action[] plantActions = cropConfig.getPlantActions(); if (plantActions != null) { @@ -812,9 +767,8 @@ public class PlatformManager extends Function { PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), location); Bukkit.getPluginManager().callEvent(potWaterEvent); - if (potWaterEvent.isCancelled()) { + if (potWaterEvent.isCancelled()) return true; - } event.setCancelled(true); doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,1,0)); @@ -827,26 +781,20 @@ public class PlatformManager extends Function { // use watering can WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); if (wateringCanConfig != null) { - String[] pot_whitelist = wateringCanConfig.getPotWhitelist(); - if (pot_whitelist != null) { - inner: { - for (String pot : pot_whitelist) { - if (pot.equals(pot_id)) { - break inner; - } - } - return true; - } - } + + if (!wateringCanConfig.canUse(player, location)) + return true; + + if (!wateringCanConfig.isWhiteListedPot(pot_id)) + return true; int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand); if (current_water <= 0) return true; PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, location); Bukkit.getPluginManager().callEvent(potWaterEvent); - if (potWaterEvent.isCancelled()) { + if (potWaterEvent.isCancelled()) return true; - } current_water--; this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), location, player.getLocation().getYaw(), pot_id, wateringCanConfig.getParticle(), potWaterEvent.getWater()); @@ -858,20 +806,13 @@ public class PlatformManager extends Function { FertilizerConfig fertilizerConfig = plugin.getFertilizerManager().getConfigByItemID(item_in_hand_id); if (fertilizerConfig != null) { - if (fertilizerConfig.getRequirements() != null) { - CurrentState currentState = new CurrentState(location, player); - for (Requirement requirement : fertilizerConfig.getRequirements()) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } - } + if (!fertilizerConfig.canUse(player, location)) + return true; FertilizerUseEvent fertilizerUseEvent = new FertilizerUseEvent(player, item_in_hand, fertilizerConfig.getKey(), location); Bukkit.getPluginManager().callEvent(fertilizerUseEvent); - if (fertilizerUseEvent.isCancelled()) { + if (fertilizerUseEvent.isCancelled()) return true; - } if (fertilizerConfig.isBeforePlant() && plugin.getCropManager().containsStage(plugin.getPlatformInterface().getAnyItemIDAt(location.clone().add(0,1,0)))) { AdventureUtils.playerMessage(player, MessageManager.prefix + MessageManager.beforePlant); @@ -1002,15 +943,17 @@ public class PlatformManager extends Function { // The entity might be other creatures when the pot is FARMLAND // because of vanilla farmland mechanics if (entity instanceof Player player) { - if (!canBreak(player, cropConfig, location)) { + + if (!cropConfig.canBreak(player, location)) { event.setCancelled(true); return true; } + CropBreakEvent cropBreakEvent = new CropBreakEvent(entity, cropConfig.getKey(), id, location); Bukkit.getPluginManager().callEvent(cropBreakEvent); - if (cropBreakEvent.isCancelled()) { + if (cropBreakEvent.isCancelled()) return true; - } + if (player.getGameMode() != GameMode.CREATIVE) { StageConfig stageConfig = plugin.getCropManager().getStageConfig(id); if (stageConfig != null) { @@ -1025,9 +968,9 @@ public class PlatformManager extends Function { } else { CropBreakEvent cropBreakEvent = new CropBreakEvent(entity, cropConfig.getKey(), id, location); Bukkit.getPluginManager().callEvent(cropBreakEvent); - if (cropBreakEvent.isCancelled()) { + if (cropBreakEvent.isCancelled()) return true; - } + StageConfig stageConfig = plugin.getCropManager().getStageConfig(id); if (stageConfig != null) { Action[] breakActions = stageConfig.getBreakActions(); @@ -1042,18 +985,6 @@ public class PlatformManager extends Function { return true; } - public boolean canBreak(Player player, CropConfig cropConfig, Location crop_loc) { - Requirement[] requirements = cropConfig.getBreakRequirements(); - if (requirements == null) return true; - CurrentState currentState = new CurrentState(crop_loc, player); - for (Requirement requirement : requirements) { - if (!requirement.isConditionMet(currentState)) { - return false; - } - } - return true; - } - private void waterPot(int width, int length, Location location, float yaw, String id, @Nullable Particle particle, int water){ int extend = width / 2; if (yaw < 45 && yaw > -135) { @@ -1111,7 +1042,6 @@ public class PlatformManager extends Function { return false; } - int current = plugin.getWateringCanManager().getCurrentWater(item_in_hand); if (current >= wateringCanConfig.getStorage()) return true; @@ -1119,18 +1049,11 @@ public class PlatformManager extends Function { outer: { if (id != null && location != null) { - if (!ProtectionLib.canPlace(player, location)) { - return true; - } - if (wateringCanConfig.getRequirements() != null) { - CurrentState currentState = new CurrentState(location, player); - for (Requirement requirement : wateringCanConfig.getRequirements()) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } - } + if (!ProtectionLib.canPlace(player, location)) + return true; + if (!wateringCanConfig.canUse(player, location)) + return true; for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) { if (positiveFillMethod.getId().equals(id)) { @@ -1153,26 +1076,16 @@ public class PlatformManager extends Function { int index = 0; for (String blockId : blockIds) { if (positiveFillMethod.getId().equals(blockId)) { - Block block = lineOfSight.get(index); if (!ProtectionLib.canPlace(player, block.getLocation())) return true; - if (wateringCanConfig.getRequirements() != null) { - CurrentState currentState = new CurrentState(block.getLocation(), player); - for (Requirement requirement : wateringCanConfig.getRequirements()) { - if (!requirement.isConditionMet(currentState)) { - return true; - } - } - } + if (!wateringCanConfig.canUse(player, location)) + return true; add = positiveFillMethod.getAmount(); - if (positiveFillMethod.getSound() != null) AdventureUtils.playerSound(player, positiveFillMethod.getSound()); - if (positiveFillMethod.getParticle() != null) block.getWorld().spawnParticle(positiveFillMethod.getParticle(), block.getLocation().add(0.5,1.1, 0.5),5,0.1,0.1,0.1); - break; } index++;