diff --git a/src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java b/src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java index 3de05a1..b00c71b 100644 --- a/src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java +++ b/src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java @@ -32,4 +32,8 @@ public class SeasonUtils { public static CCSeason getSeason(World world) { return CustomCrops.plugin.getCropManager().getSeasonAPI().getSeason(world); } + + public static void unloadSeason(World world) { + CustomCrops.plugin.getCropManager().getSeasonAPI().unloadWorld(world); + } } diff --git a/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java b/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java index 45aa65d..4e0e2ca 100644 --- a/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java +++ b/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java @@ -29,7 +29,7 @@ public abstract class AbstractSubCommand implements SubCommand { } SubCommand subCommand = subCommandMap.get(args.get(0)); if (subCommand == null) { - AdventureUtil.sendMessage(sender, MessageConfig.unavailableArgs); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.unavailableArgs); } else { subCommand.onCommand(sender, args.subList(1, args.size())); } diff --git a/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java b/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java index 9c609c1..41df62b 100644 --- a/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java +++ b/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java @@ -26,14 +26,14 @@ public class PluginCommand implements TabExecutor { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { List argList = Arrays.asList(args); if (argList.size() < 1) { - AdventureUtil.sendMessage(sender, MessageConfig.nonArgs); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.nonArgs); return true; } SubCommand subCommand = subCommandMap.get(argList.get(0)); if (subCommand != null) return subCommand.onCommand(sender, argList.subList(1, argList.size())); else { - AdventureUtil.sendMessage(sender, MessageConfig.unavailableArgs); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.unavailableArgs); return true; } } diff --git a/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java b/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java index af5054a..09b7c22 100644 --- a/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java +++ b/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java @@ -3,7 +3,7 @@ package net.momirealms.customcrops.commands.subcmd; import net.momirealms.customcrops.api.utils.SeasonUtils; import net.momirealms.customcrops.commands.AbstractSubCommand; import net.momirealms.customcrops.commands.SubCommand; -import net.momirealms.customcrops.config.*; +import net.momirealms.customcrops.config.MessageConfig; import net.momirealms.customcrops.integrations.season.CCSeason; import net.momirealms.customcrops.utils.AdventureUtil; import org.bukkit.Bukkit; @@ -42,7 +42,7 @@ public class SetSeasonCommand extends AbstractSubCommand { return true; } SeasonUtils.setSeason(world, ccSeason); - AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.setSeason); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.setSeason.replace("{world}", args.get(0)).replace("{season}", args.get(1))); } return super.onCommand(sender, args); } diff --git a/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java b/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java index c92f3d5..93191c9 100644 --- a/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java +++ b/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java @@ -34,6 +34,7 @@ public class FertilizerConfig { public static void load() { FERTILIZERS = new HashMap<>(16); YamlConfiguration config = ConfigUtil.getConfig("fertilizers_" + MainConfig.customPlugin + ".yml"); + int amount = 0; for (String key : config.getKeys(false)) { switch (key) { case "speed" -> { @@ -50,6 +51,7 @@ public class FertilizerConfig { } FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), speedGrow); FERTILIZERS.put(fertilizer, speedGrow); + amount++; } } case "gigantic" -> { @@ -66,6 +68,7 @@ public class FertilizerConfig { } FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), gigantic); FERTILIZERS.put(fertilizer, gigantic); + amount++; } } case "retaining" -> { @@ -82,6 +85,7 @@ public class FertilizerConfig { } FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), retainingSoil); FERTILIZERS.put(fertilizer, retainingSoil); + amount++; } } case "quantity" -> { @@ -99,6 +103,7 @@ public class FertilizerConfig { } FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), yieldIncreasing); FERTILIZERS.put(fertilizer, yieldIncreasing); + amount++; } } case "quality" -> { @@ -123,10 +128,11 @@ public class FertilizerConfig { } FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), qualityCrop); FERTILIZERS.put(fertilizer, qualityCrop); + amount++; } } } } - AdventureUtil.consoleMessage("[CustomCrops] Loaded " + FERTILIZERS.size() / 2 + " fertilizers"); + AdventureUtil.consoleMessage("[CustomCrops] Loaded " + amount + " fertilizers"); } } diff --git a/src/main/java/net/momirealms/customcrops/config/MainConfig.java b/src/main/java/net/momirealms/customcrops/config/MainConfig.java index cef4d10..677fa7e 100644 --- a/src/main/java/net/momirealms/customcrops/config/MainConfig.java +++ b/src/main/java/net/momirealms/customcrops/config/MainConfig.java @@ -84,8 +84,9 @@ public class MainConfig { public static boolean enableAnimations; public static boolean autoGrow; public static boolean enableCompensation; - public static boolean requireLight; - public static byte lightLevel; + public static boolean syncSeason; + public static World syncWorld; + public static boolean autoBackUp; public static void load() { ConfigUtil.update("config.yml"); @@ -102,7 +103,7 @@ public class MainConfig { } } worldList = List.of(worlds); - cropMode = config.getString("crops.mode", "tripwire").equals("tripwire"); + cropMode = config.getString("mechanics.crops-mode", "tripwire").equals("tripwire"); limitation = config.getBoolean("optimization.limitation.enable", true); wireAmount = config.getInt("optimization.limitation.tripwire-amount", 64); frameAmount = config.getInt("optimization.limitation.itemframe-amount", 64); @@ -126,6 +127,11 @@ public class MainConfig { enableBoneMeal = config.getBoolean("mechanics.bone-meal", true); boneMealChance = config.getDouble("mechanics.chance", 0.5); + syncSeason = config.getBoolean("mechanics.season.sync-seasons.enable", false); + syncWorld = Bukkit.getWorld(config.getString("mechanics.season.sync-seasons.world", "world")); + + autoBackUp = config.getBoolean("optimization.auto-back-up", true); + enableParticles = !config.getBoolean("optimization.disable-water-particles", false); enableAnimations = !config.getBoolean("optimization.disable-sprinkler-animation", false); diff --git a/src/main/java/net/momirealms/customcrops/config/MessageConfig.java b/src/main/java/net/momirealms/customcrops/config/MessageConfig.java index b4f71e0..5e9d63a 100644 --- a/src/main/java/net/momirealms/customcrops/config/MessageConfig.java +++ b/src/main/java/net/momirealms/customcrops/config/MessageConfig.java @@ -30,7 +30,6 @@ public class MessageConfig { public static String seasonDisabled; public static String autoSeasonDisabled; public static String prefix; - public static String nonArgs; public static String wrongArgs; public static String unavailableArgs; public static String lackArgs; @@ -46,6 +45,7 @@ public class MessageConfig { public static String worldNotExists; public static String seasonNotExists; public static String wrongSeason; + public static String nonArgs; public static void load() { YamlConfiguration config = ConfigUtil.getConfig("messages" + File.separator + "messages_" + MainConfig.lang +".yml"); @@ -53,7 +53,9 @@ public class MessageConfig { reload = config.getString("messages.reload"); noPerm = config.getString("messages.no-perm"); lackArgs = config.getString("messages.lack-args"); + unavailableArgs = config.getString("messages.invalid-args"); wrongArgs = config.getString("messages.wrong-args"); + nonArgs = config.getString("messages.none-args"); spring = config.getString("messages.spring"); summer = config.getString("messages.summer"); autumn = config.getString("messages.autumn"); diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java index 36731ac..72a3464 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java @@ -31,6 +31,7 @@ public interface CustomInterface { void placeNoteBlock(Location location, String blockID); + @Nullable String getBlockID(Location location); @Nullable diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java index 4af570f..a9d045f 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java @@ -348,7 +348,9 @@ public abstract class HandlerP extends Function { if (customWorld == null) return false; if (fertilizer.isBefore()) { - Location above = potLoc.clone().add(0,1,0); + Location above = potLoc.clone().add(0.5,1.5,0.5); + if (MainConfig.OraxenHook) above.subtract(0, 0.46875, 0); + if (FurnitureUtil.hasFurniture(above)) { AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.beforePlant); return true; diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java index e6a27c7..b206cb6 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java @@ -17,24 +17,36 @@ package net.momirealms.customcrops.integrations.customplugin.itemsadder; +import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomFurniture; +import dev.lone.itemsadder.api.CustomStack; import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent; import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; import net.momirealms.customcrops.api.crop.Crop; -import net.momirealms.customcrops.config.BasicItemConfig; -import net.momirealms.customcrops.config.MainConfig; -import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.api.event.SeedPlantEvent; +import net.momirealms.customcrops.config.*; import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.integrations.season.CCSeason; import net.momirealms.customcrops.managers.CropManager; import net.momirealms.customcrops.managers.CustomWorld; import net.momirealms.customcrops.objects.Sprinkler; import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.requirements.PlantingCondition; +import net.momirealms.customcrops.objects.requirements.RequirementInterface; +import net.momirealms.customcrops.utils.AdventureUtil; import net.momirealms.customcrops.utils.FurnitureUtil; -import org.bukkit.Location; +import net.momirealms.customcrops.utils.LimitationUtil; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; public class ItemsAdderFrameHandler extends ItemsAdderHandler { @@ -44,39 +56,46 @@ public class ItemsAdderFrameHandler extends ItemsAdderHandler { //maybe crop or sprinkler public void onInteractFurniture(FurnitureInteractEvent event) { - if (event.isCancelled()) return; - String namespacedID = event.getNamespacedID(); + + final String namespacedID = event.getNamespacedID(); if (namespacedID == null) return; + + final Player player = event.getPlayer(); + final Entity entity = event.getBukkitEntity(); + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedID); if (sprinkler != null) { - super.onInteractSprinkler(event.getBukkitEntity().getLocation(), event.getPlayer(), event.getPlayer().getActiveItem(), sprinkler); + + if (!AntiGrief.testPlace(player, entity.getLocation())) return; + + super.onInteractSprinkler(entity.getLocation(), player, player.getInventory().getItemInMainHand(), sprinkler); return; } if (namespacedID.contains("_stage_")) { - if (!namespacedID.equals(BasicItemConfig.deadCrop)) { - - if (!hasNextStage(namespacedID) && MainConfig.canRightClickHarvest) { - CustomFurniture.remove(event.getBukkitEntity(), false); - this.onInteractRipeCrop(event.getBukkitEntity().getLocation(), namespacedID, event.getPlayer()); - } - - else { - Location potLoc = event.getBukkitEntity().getLocation().clone().subtract(0,1,0); - super.tryMisc(event.getPlayer(), event.getPlayer().getItemInUse(), potLoc); + if (!namespacedID.equals(BasicItemConfig.deadCrop) && !hasNextStage(namespacedID) && MainConfig.canRightClickHarvest) { + if (!(MainConfig.emptyHand && player.getInventory().getItemInMainHand().getType() != Material.AIR)) { + if (!AntiGrief.testBreak(player, entity.getLocation())) return; + CustomFurniture.remove(entity, false); + this.onInteractRipeCrop(entity.getLocation(), namespacedID, player); } } + + if (!AntiGrief.testPlace(player, entity.getLocation())) return; + Location potLoc = entity.getLocation().clone().subtract(0, 1, 0).getBlock().getLocation(); + super.tryMisc(player, player.getInventory().getItemInMainHand(), potLoc); } } public void onBreakFurniture(FurnitureBreakEvent event) { if (event.isCancelled()) return; - String namespacedId = event.getNamespacedID(); + + final String namespacedId = event.getNamespacedID(); if (namespacedId == null) return; - Location location = event.getBukkitEntity().getLocation(); - Player player = event.getPlayer(); + final Location location = event.getBukkitEntity().getLocation(); + final Player player = event.getPlayer(); //No need for antiGrief checks Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedId); if (sprinkler != null) { @@ -94,39 +113,137 @@ public class ItemsAdderFrameHandler extends ItemsAdderHandler { } } - //This can only be pot - public void onInteractBlock(CustomBlockInteractEvent event) { - if (event.isCancelled()) return; - String blockID = event.getNamespacedID(); - if (blockID.equals(BasicItemConfig.dryPot) || blockID.equals(BasicItemConfig.wetPot)) { - Location potLoc = event.getBlockClicked().getLocation(); - super.tryMisc(event.getPlayer(), event.getItem(), potLoc); +// Broken +// //This can only be pot +// public void onInteractBlock(CustomBlockInteractEvent event) { +// if (event.isCancelled()) return; +// String blockID = event.getNamespacedID(); +// if (blockID.equals(BasicItemConfig.dryPot) || blockID.equals(BasicItemConfig.wetPot)) { +// Location potLoc = event.getBlockClicked().getLocation(); +// super.tryMisc(event.getPlayer(), event.getItem(), potLoc); +// } +// } + + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + + final Player player = event.getPlayer(); + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - 50)) < 50) return; + coolDown.put(player, time); + + super.onPlayerInteract(event); + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + Block block = event.getClickedBlock(); + if (block == null) return; + CustomBlock cb = CustomBlock.byAlreadyPlaced(block); + if (cb == null) return; + + final String blockID = cb.getNamespacedID(); + + if (!AntiGrief.testPlace(player, block.getLocation())) return; + + //interact crop + if (blockID.equals(BasicItemConfig.wetPot) || blockID.equals(BasicItemConfig.dryPot)) { + + Location seedLoc = block.getLocation().clone().add(0,1,0); + + if (!AntiGrief.testPlace(player, seedLoc)) return; + + ItemStack itemInHand = event.getItem(); + Location potLoc = block.getLocation(); + if (super.tryMisc(player, itemInHand, potLoc)) return; + + if (event.getBlockFace() != BlockFace.UP) return; + + CustomStack customStack = CustomStack.byItemStack(itemInHand); + if (customStack == null) return; + String namespacedID = customStack.getNamespacedID(); + if (namespacedID.endsWith("_seeds")) { + String cropName = customStack.getId().substring(0, customStack.getId().length() - 6); + Crop crop = CropConfig.CROPS.get(cropName); + if (crop == null) return; + + CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); + if (customWorld == null) return; + + if (FurnitureUtil.hasFurniture(seedLoc.clone().add(0.5,0.5,0.5))) return; + if (seedLoc.getBlock().getType() != Material.AIR) return; + + PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); + + if (crop.getRequirements() != null) { + for (RequirementInterface requirement : crop.getRequirements()) { + if (!requirement.isConditionMet(plantingCondition)) { + return; + } + } + } + + if (MainConfig.limitation && LimitationUtil.reachFrameLimit(potLoc)) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount))); + return; + } + + CCSeason[] seasons = crop.getSeasons(); + if (SeasonConfig.enable && seasons != null) { + if (cropManager.isWrongSeason(seedLoc, seasons)) { + if (MainConfig.notifyInWrongSeason) AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.wrongSeason); + if (MainConfig.preventInWrongSeason) return; + } + } + + SeedPlantEvent seedPlantEvent = new SeedPlantEvent(player, seedLoc, crop); + Bukkit.getPluginManager().callEvent(seedPlantEvent); + if (seedPlantEvent.isCancelled()) { + return; + } + + if (SoundConfig.plantSeed.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.plantSeed.getSource(), + SoundConfig.plantSeed.getKey(), + 1,1 + ); + } + + if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1); + CustomFurniture customFurniture = CustomFurniture.spawn(namespacedID.substring(0, namespacedID.length() - 5) + "stage_1", seedLoc.getBlock()); + if (customFurniture != null) { + if (customFurniture.getArmorstand() instanceof ItemFrame itemFrame) { + itemFrame.setRotation(FurnitureUtil.getRandomRotation()); + } + } + customWorld.addCrop(seedLoc, cropName); + } } } @Override public void onBreakBlock(CustomBlockBreakEvent event) { - if (event.isCancelled()) return; + String namespacedId = event.getNamespacedID(); Player player = event.getPlayer(); Location location = event.getBlock().getLocation(); + if (!AntiGrief.testBreak(player, location)) { + event.setCancelled(true); + return; + } + //fix buggy chorus duplication chorusFix(event.getBlock()); if (namespacedId.equals(BasicItemConfig.dryPot) || namespacedId.equals(BasicItemConfig.wetPot)) { - if (!AntiGrief.testBreak(player, location)) { - event.setCancelled(true); - return; - } - super.onBreakPot(location); //Check if there's crop above - Location seedLocation = location.clone().add(0.5,1,0.5); + Location seedLocation = location.clone().add(0.5,1.5,0.5); ItemFrame itemFrame = FurnitureUtil.getItemFrame(seedLocation); if (itemFrame == null) return; @@ -136,7 +253,11 @@ public class ItemsAdderFrameHandler extends ItemsAdderHandler { if (seedID.contains("_stage_")) { CustomFurniture.remove(itemFrame, false); if (seedID.equals(BasicItemConfig.deadCrop)) return; - super.onBreakRipeCrop(seedLocation, seedID, player, false, true); + if (hasNextStage(namespacedId)) { + super.onBreakUnripeCrop(location); + return; + } + super.onBreakRipeCrop(location, namespacedId, player, true, true); } } } @@ -156,6 +277,11 @@ public class ItemsAdderFrameHandler extends ItemsAdderHandler { return; } customWorld.addCrop(location, crop.getKey()); - CustomFurniture.spawn(crop.getReturnStage(), location.getBlock()); + CustomFurniture customFurniture = CustomFurniture.spawn(crop.getReturnStage(), location.getBlock()); + if (customFurniture != null) { + if (customFurniture instanceof ItemFrame itemFrame) { + itemFrame.setRotation(FurnitureUtil.getRandomRotation()); + } + } } } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java index ff47458..18e2a99 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java @@ -33,6 +33,7 @@ import net.momirealms.customcrops.config.CropConfig; import net.momirealms.customcrops.config.MainConfig; import net.momirealms.customcrops.config.SoundConfig; import net.momirealms.customcrops.config.WaterCanConfig; +import net.momirealms.customcrops.integrations.AntiGrief; import net.momirealms.customcrops.integrations.customplugin.HandlerP; import net.momirealms.customcrops.integrations.customplugin.itemsadder.listeners.ItemsAdderBlockListener; import net.momirealms.customcrops.integrations.customplugin.itemsadder.listeners.ItemsAdderFurnitureListener; @@ -103,6 +104,7 @@ public abstract class ItemsAdderHandler extends HandlerP { } if (block == null) return; + if (!AntiGrief.testPlace(player, block.getLocation())) return; if (event.getBlockFace() == BlockFace.UP && placeSprinkler(namespacedID, event.getClickedBlock().getLocation(), player, item)) { return; @@ -110,22 +112,23 @@ public abstract class ItemsAdderHandler extends HandlerP { } } - public void tryMisc(Player player, ItemStack itemInHand, Location potLoc) { - if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + public boolean tryMisc(Player player, ItemStack itemInHand, Location potLoc) { + if (itemInHand == null || itemInHand.getType() == Material.AIR) return true; CustomStack customStack = CustomStack.byItemStack(itemInHand); - if (customStack == null) return; + if (customStack == null) return false; String itemID = customStack.getNamespacedID(); if (useSurveyor(potLoc, itemID, player)) { - return; + return true; } if (useFertilizer(potLoc, itemID, player, itemInHand)){ - return; + return true; } if (useWateringCan(potLoc, itemID, player, customStack)) { - return; + return true; } + return false; //for future misc } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java index 934b372..50f165b 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java @@ -17,8 +17,6 @@ package net.momirealms.customcrops.integrations.customplugin.itemsadder; -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomStack; import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; @@ -46,6 +44,7 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; @@ -61,15 +60,21 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler { public void onInteractFurniture(FurnitureInteractEvent event) { if (event.isCancelled()) return; + final Player player = event.getPlayer(); + long time = System.currentTimeMillis(); if (time - (coolDown.getOrDefault(event.getPlayer(), time - 100)) < 100) return; - coolDown.put(event.getPlayer(), time); + coolDown.put(player, time); + + Entity entity = event.getBukkitEntity(); + + if (!AntiGrief.testPlace(player, entity.getLocation())) return; String namespacedID = event.getNamespacedID(); if (namespacedID == null) return; Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedID); if (sprinkler != null) { - super.onInteractSprinkler(event.getBukkitEntity().getLocation(), event.getPlayer(), event.getPlayer().getInventory().getItemInMainHand(), sprinkler); + super.onInteractSprinkler(entity.getLocation(), event.getPlayer(), player.getInventory().getItemInMainHand(), sprinkler); } } @@ -101,36 +106,42 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler { if (block == null) return; CustomBlock cb = CustomBlock.byAlreadyPlaced(block); if (cb == null) return; + Location seedLoc = block.getLocation().clone().add(0,1,0); final String blockID = cb.getNamespacedID(); + //interact crop if (blockID.contains("_stage_")) { + //ripe crops if (!blockID.equals(BasicItemConfig.deadCrop) && !hasNextStage(blockID) && MainConfig.canRightClickHarvest) { - if (MainConfig.emptyHand && event.hasItem()) return; - Location seedLoc = block.getLocation(); - CustomBlock.remove(seedLoc); - this.onInteractRipeCrop(seedLoc, blockID, event.getPlayer()); + if (!(MainConfig.emptyHand && event.hasItem())) { + + if (!AntiGrief.testBreak(player, seedLoc)) return; + + CustomBlock.remove(seedLoc); + this.onInteractRipeCrop(seedLoc, blockID, player); + return; + } } - else { - Location potLoc = block.getLocation().clone().subtract(0,1,0); - super.tryMisc(player, event.getItem(), potLoc); - } + if (!AntiGrief.testPlace(player, seedLoc)) return; + + Location potLoc = block.getLocation().clone().subtract(0,1,0); + super.tryMisc(player, event.getItem(), potLoc); } //interact pot (must have an item) else if (blockID.equals(BasicItemConfig.wetPot) || blockID.equals(BasicItemConfig.dryPot)) { - Location seedLoc = block.getLocation().clone().add(0,1,0); if (!AntiGrief.testPlace(player, seedLoc)) return; ItemStack itemInHand = event.getItem(); Location potLoc = block.getLocation(); - super.tryMisc(player, itemInHand, potLoc); + if (super.tryMisc(player, itemInHand, potLoc)) return; if (event.getBlockFace() != BlockFace.UP) return; - if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + CustomStack customStack = CustomStack.byItemStack(itemInHand); if (customStack == null) return; String namespacedID = customStack.getNamespacedID(); @@ -142,7 +153,7 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler { CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); if (customWorld == null) return; - if (FurnitureUtil.hasFurniture(seedLoc)) return; + if (FurnitureUtil.hasFurniture(seedLoc.clone().add(0.5,0.5,0.5))) return; if (seedLoc.getBlock().getType() != Material.AIR) return; PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); @@ -161,7 +172,7 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler { } CCSeason[] seasons = crop.getSeasons(); - if (seasons != null) { + if (SeasonConfig.enable && seasons != null) { if (cropManager.isWrongSeason(seedLoc, seasons)) { if (MainConfig.notifyInWrongSeason) AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.wrongSeason); if (MainConfig.preventInWrongSeason) return; @@ -319,6 +330,7 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler { CustomBlock.byAlreadyPlaced(location.getBlock()).getLoot().forEach(itemStack -> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack)); CustomBlock.remove(location); } + if (namespacedId.equals(BasicItemConfig.deadCrop)) return; if (hasNextStage(namespacedId)) { super.onBreakUnripeCrop(location); @@ -344,16 +356,20 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler { CustomBlock customBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock()); if (customBlock == null) return; String seedID = customBlock.getNamespacedID(); + if (seedID.contains("_stage_")) { + CustomBlock.remove(seedLocation); if (seedID.equals(BasicItemConfig.deadCrop)) return; //ripe or not if (hasNextStage(seedID)) { + if (player.getGameMode() == GameMode.CREATIVE) return; customBlock.getLoot().forEach(loot -> location.getWorld().dropItemNaturally(seedLocation.getBlock().getLocation(), loot)); } else { super.onBreakRipeCrop(seedLocation, seedID, player, false, true); } + } } } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java index 113c29b..c107a1d 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java @@ -17,23 +17,44 @@ package net.momirealms.customcrops.integrations.customplugin.oraxen; +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import dev.lone.itemsadder.api.CustomFurniture; +import io.th0rgal.oraxen.OraxenPlugin; import io.th0rgal.oraxen.events.OraxenFurnitureBreakEvent; import io.th0rgal.oraxen.events.OraxenFurnitureInteractEvent; import io.th0rgal.oraxen.events.OraxenNoteBlockBreakEvent; import io.th0rgal.oraxen.events.OraxenNoteBlockInteractEvent; +import io.th0rgal.oraxen.items.OraxenItems; +import io.th0rgal.oraxen.mechanics.MechanicFactory; +import io.th0rgal.oraxen.mechanics.MechanicsManager; +import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureFactory; +import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanic; +import io.th0rgal.oraxen.utils.drops.Drop; import net.momirealms.customcrops.api.crop.Crop; -import net.momirealms.customcrops.config.BasicItemConfig; -import net.momirealms.customcrops.config.MainConfig; -import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.api.event.SeedPlantEvent; +import net.momirealms.customcrops.config.*; import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.integrations.season.CCSeason; import net.momirealms.customcrops.managers.CropManager; import net.momirealms.customcrops.managers.CustomWorld; import net.momirealms.customcrops.objects.Sprinkler; import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.requirements.PlantingCondition; +import net.momirealms.customcrops.objects.requirements.RequirementInterface; +import net.momirealms.customcrops.utils.AdventureUtil; import net.momirealms.customcrops.utils.FurnitureUtil; +import net.momirealms.customcrops.utils.LimitationUtil; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; public class OraxenFrameHandler extends OraxenHandler { @@ -60,7 +81,7 @@ public class OraxenFrameHandler extends OraxenHandler { super.onBreakPot(location); - Location seedLocation = location.clone().add(0.5,1,0.5); + Location seedLocation = location.clone().add(0.5,1.03125,0.5); ItemFrame itemFrame = FurnitureUtil.getItemFrame(seedLocation); if (itemFrame == null) return; String furnitureID = itemFrame.getPersistentDataContainer().get(OraxenHook.FURNITURE, PersistentDataType.STRING); @@ -68,6 +89,16 @@ public class OraxenFrameHandler extends OraxenHandler { if (furnitureID.contains("_stage_")) { itemFrame.remove(); if (furnitureID.equals(BasicItemConfig.deadCrop)) return; + if (hasNextStage(furnitureID)) { + FurnitureMechanic mechanic = (FurnitureMechanic) FurnitureFactory.instance.getMechanic(furnitureID); + if (mechanic == null) return; + Drop drop = mechanic.getDrop(); + if (drop != null && player.getGameMode() != GameMode.CREATIVE) { + drop.spawns(location, new ItemStack(Material.AIR)); + } + super.onBreakUnripeCrop(location); + return; + } super.onBreakRipeCrop(seedLocation, furnitureID, player, false, false); } } @@ -76,6 +107,7 @@ public class OraxenFrameHandler extends OraxenHandler { @Override public void onBreakFurniture(OraxenFurnitureBreakEvent event) { if (event.isCancelled()) return; + String id = event.getFurnitureMechanic().getItemID(); if (id == null) return; //TODO check if needs anti grief @@ -87,50 +119,123 @@ public class OraxenFrameHandler extends OraxenHandler { if (id.contains("_stage_")) { if (id.equals(BasicItemConfig.deadCrop)) return; - if (hasNextStage(id)) return; + if (hasNextStage(id)) { + super.onBreakUnripeCrop(event.getBlock().getLocation()); + return; + } super.onBreakRipeCrop(event.getBlock().getLocation(), id, event.getPlayer(), false, false); } } @Override public void onInteractNoteBlock(OraxenNoteBlockInteractEvent event) { - if (event.isCancelled()) return; + + final Player player = event.getPlayer(); + final ItemStack itemInHand = event.getItemInHand(); + final Block block = event.getBlock(); + String blockID = event.getNoteBlockMechanic().getItemID(); if (blockID.equals(BasicItemConfig.dryPot) || blockID.equals(BasicItemConfig.wetPot)) { - Location potLoc = event.getBlock().getLocation(); - super.tryMisc(event.getPlayer(), event.getItemInHand(), potLoc); + + Location seedLoc = block.getLocation().clone().add(0,1,0); + Location potLoc = block.getLocation(); + + if (!AntiGrief.testPlace(player, seedLoc)) return; + if (super.tryMisc(player, itemInHand, potLoc)) return; + if (event.getBlockFace() != BlockFace.UP) return; + + NBTItem nbtItem = new NBTItem(itemInHand); + NBTCompound bukkitCompound = nbtItem.getCompound("PublicBukkitValues"); + if (bukkitCompound == null) return; + String id = bukkitCompound.getString("oraxen:id"); + if (id == null || !id.endsWith("_seeds")) return; + + String cropName = id.substring(0, id.length() - 6); + Crop crop = CropConfig.CROPS.get(cropName); + if (crop == null) return; + + CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); + if (customWorld == null) return; + + if (FurnitureUtil.hasFurniture(seedLoc.clone().add(0.5,0.03125,0.5))) return; + if (seedLoc.getBlock().getType() != Material.AIR) return; + + PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); + if (crop.getRequirements() != null) { + for (RequirementInterface requirement : crop.getRequirements()) { + if (!requirement.isConditionMet(plantingCondition)) { + return; + } + } + } + if (MainConfig.limitation && LimitationUtil.reachFrameLimit(potLoc)) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount))); + return; + } + CCSeason[] seasons = crop.getSeasons(); + if (SeasonConfig.enable && seasons != null) { + if (cropManager.isWrongSeason(seedLoc, seasons)) { + if (MainConfig.notifyInWrongSeason) AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.wrongSeason); + if (MainConfig.preventInWrongSeason) return; + } + } + + SeedPlantEvent seedPlantEvent = new SeedPlantEvent(player, seedLoc, crop); + Bukkit.getPluginManager().callEvent(seedPlantEvent); + if (seedPlantEvent.isCancelled()) { + return; + } + + if (SoundConfig.plantSeed.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.plantSeed.getSource(), + SoundConfig.plantSeed.getKey(), + 1,1 + ); + } + + if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1); + ItemFrame itemFrame = customInterface.placeFurniture(seedLoc, id.substring(0, id.length() - 5) + "stage_1"); + if (itemFrame != null) { + itemFrame.setRotation(FurnitureUtil.getRandomRotation()); + } + customWorld.addCrop(seedLoc, cropName); } } @Override public void onInteractFurniture(OraxenFurnitureInteractEvent event) { if (event.isCancelled()) return; + String id = event.getFurnitureMechanic().getItemID(); if (id == null) return; + + final Player player = event.getPlayer(); + final ItemFrame itemFrame = event.getItemFrame(); + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id); if (sprinkler != null) { - super.onInteractSprinkler(event.getBlock().getLocation(), event.getPlayer(), event.getPlayer().getActiveItem(), sprinkler); + if (!AntiGrief.testPlace(player, itemFrame.getLocation())) return; + super.onInteractSprinkler(itemFrame.getLocation(), player, player.getInventory().getItemInMainHand(), sprinkler); return; } if (id.contains("_stage_")) { - if (!id.equals(BasicItemConfig.deadCrop)) { - - if (!hasNextStage(id) && MainConfig.canRightClickHarvest) { - event.getItemFrame().remove(); - this.onInteractRipeCrop(event.getBlock().getLocation(), id, event.getPlayer()); - } - - else { - Location potLoc = event.getBlock().getLocation().clone().subtract(0,1,0); - super.tryMisc(event.getPlayer(), event.getPlayer().getItemInUse(), potLoc); + if (!id.equals(BasicItemConfig.deadCrop) && !hasNextStage(id) && MainConfig.canRightClickHarvest) { + if (!(MainConfig.emptyHand && player.getInventory().getItemInMainHand().getType() != Material.AIR)) { + if (!AntiGrief.testBreak(player, itemFrame.getLocation())) return; + itemFrame.remove(); + this.onInteractRipeCrop(itemFrame.getLocation(), id, player); } } + if (!AntiGrief.testPlace(player, itemFrame.getLocation())) return; + Location potLoc = itemFrame.getLocation().clone().subtract(0,1,0).getBlock().getLocation(); + super.tryMisc(player, player.getInventory().getItemInMainHand(), potLoc); } } private void onInteractRipeCrop(Location location, String id, Player player) { - Crop crop = getCropFromID(id); if (crop == null) return; CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); @@ -138,12 +243,14 @@ public class OraxenFrameHandler extends OraxenHandler { Fertilizer fertilizer = customWorld.getFertilizer(location.clone().subtract(0,1,0)); cropManager.proceedHarvest(crop, player, location, fertilizer); - if (crop.getReturnStage() == null) { customWorld.removeCrop(location); return; } customWorld.addCrop(location, crop.getKey()); - cropManager.getCustomInterface().placeFurniture(location, crop.getReturnStage()); + ItemFrame itemFrame = cropManager.getCustomInterface().placeFurniture(location, crop.getReturnStage()); + if (itemFrame != null) { + itemFrame.setRotation(FurnitureUtil.getRandomRotation()); + } } -} +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java index 0a2b56f..7b0f9b6 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java @@ -17,6 +17,7 @@ package net.momirealms.customcrops.integrations.customplugin.oraxen; +import de.tr7zw.changeme.nbtapi.NBTCompound; import de.tr7zw.changeme.nbtapi.NBTItem; import io.th0rgal.oraxen.events.*; import io.th0rgal.oraxen.items.OraxenItems; @@ -24,18 +25,25 @@ import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.crop.Crop; import net.momirealms.customcrops.api.event.WaterEvent; import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.SoundConfig; import net.momirealms.customcrops.config.WaterCanConfig; import net.momirealms.customcrops.integrations.customplugin.HandlerP; import net.momirealms.customcrops.integrations.customplugin.oraxen.listeners.OraxenBlockListener; import net.momirealms.customcrops.integrations.customplugin.oraxen.listeners.OraxenFurnitureListener; import net.momirealms.customcrops.managers.CropManager; import net.momirealms.customcrops.objects.WaterCan; +import net.momirealms.customcrops.utils.AdventureUtil; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,23 +73,57 @@ public abstract class OraxenHandler extends HandlerP { HandlerList.unregisterAll(this.oraxenFurnitureListener); } - public void tryMisc(Player player, ItemStack itemInHand, Location potLoc) { - if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + public boolean tryMisc(Player player, ItemStack itemInHand, Location potLoc) { + if (itemInHand == null || itemInHand.getType() == Material.AIR) return true; String id = OraxenItems.getIdByItem(itemInHand); - if (id == null) return; + if (id == null) return false; if (useSurveyor(potLoc, id, player)) { - return; + return true; } if (useFertilizer(potLoc, id, player, itemInHand)){ - return; + return true; } if (useWateringCan(potLoc, id, player, itemInHand)) { - return; + return true; } + return false; //for future misc } + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + final Player player = event.getPlayer(); + final Action action = event.getAction(); + + if (action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) { + + Block block = event.getClickedBlock(); + + if (block != null && ((block.getType().isInteractable() && block.getType() != Material.NOTE_BLOCK) || block.getType() == Material.TRIPWIRE)) return; + + ItemStack item = event.getItem(); + if (item == null || item.getType() == Material.AIR) return; + NBTItem nbtItem = new NBTItem(item); + + NBTCompound bukkitCompound = nbtItem.getCompound("PublicBukkitValues"); + if (bukkitCompound != null) { + String id = bukkitCompound.getString("oraxen:id"); + if (id == null || id.equals("")) return; + + if (fillWaterCan(id, nbtItem, item, player)) { + return; + } + + if (block == null) return; + + if (event.getBlockFace() == BlockFace.UP && placeSprinkler(id, block.getLocation(), player, item)) { + return; + } + } + } + } + private boolean useWateringCan(Location potLoc, String id, Player player, @NotNull ItemStack can) { WaterCan waterCan = WaterCanConfig.CANS.get(id); if (waterCan == null) return false; @@ -97,6 +139,31 @@ public abstract class OraxenHandler extends HandlerP { } nbtItem.setInteger("WaterAmount", water - 1); + if (SoundConfig.waterPot.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.waterPot.getSource(), + SoundConfig.waterPot.getKey(), + 1,1 + ); + } + + if (MainConfig.enableActionBar) { + String canID = customInterface.getItemID(can); + WaterCan canConfig = WaterCanConfig.CANS.get(canID); + if (canConfig == null) return true; + + AdventureUtil.playerActionbar( + player, + (MainConfig.actionBarLeft + + MainConfig.actionBarFull.repeat(water) + + MainConfig.actionBarEmpty.repeat(canConfig.getMax() - water) + + MainConfig.actionBarRight) + .replace("{max_water}", String.valueOf(canConfig.getMax())) + .replace("{water}", String.valueOf(water)) + ); + } + can.setItemMeta(nbtItem.getItem().getItemMeta()); super.waterPot(waterCan.width(), waterCan.getLength(), potLoc, player.getLocation().getYaw()); } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java index 0e94fec..c6df658 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java @@ -46,8 +46,6 @@ import static io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureM public class OraxenHook implements CustomInterface { - static Rotation[] rotations4 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE}; - public static NamespacedKey FURNITURE = new NamespacedKey(OraxenPlugin.get(), "furniture"); @Override @@ -107,7 +105,6 @@ public class OraxenHook implements CustomInterface { frame.setPersistent(true); frame.setItemDropChance(0); frame.setItem(itemBuilder.build(), false); - frame.setRotation(rotations4[new Random().nextInt(rotations4.length-1)]); frame.setFacingDirection(BlockFace.UP, true); PersistentDataContainer pdc = frame.getPersistentDataContainer(); pdc.set(FURNITURE_KEY, PersistentDataType.STRING, id); diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java index 79b0ffa..47ad4f9 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java @@ -23,19 +23,22 @@ import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanic; import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory; import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicListener; +import io.th0rgal.oraxen.utils.drops.Drop; import net.momirealms.customcrops.api.crop.Crop; -import net.momirealms.customcrops.config.BasicItemConfig; -import net.momirealms.customcrops.config.CropConfig; -import net.momirealms.customcrops.config.MainConfig; -import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.api.event.SeedPlantEvent; +import net.momirealms.customcrops.config.*; import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.integrations.season.CCSeason; import net.momirealms.customcrops.managers.CropManager; import net.momirealms.customcrops.managers.CustomWorld; import net.momirealms.customcrops.objects.Sprinkler; import net.momirealms.customcrops.objects.fertilizer.Fertilizer; import net.momirealms.customcrops.objects.requirements.PlantingCondition; import net.momirealms.customcrops.objects.requirements.RequirementInterface; +import net.momirealms.customcrops.utils.AdventureUtil; import net.momirealms.customcrops.utils.FurnitureUtil; +import net.momirealms.customcrops.utils.LimitationUtil; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -54,6 +57,7 @@ public class OraxenWireHandler extends OraxenHandler{ @Override public void onBreakNoteBlock(OraxenNoteBlockBreakEvent event) { if (event.isCancelled()) return; + String id = event.getNoteBlockMechanic().getItemID(); if (id.equals(BasicItemConfig.dryPot) || id.equals(BasicItemConfig.wetPot)) { @@ -70,17 +74,21 @@ public class OraxenWireHandler extends OraxenHandler{ StringBlockMechanic mechanic = StringBlockMechanicListener.getStringMechanic(seedLocation.getBlock()); if (mechanic == null) return; String seedID = mechanic.getItemID(); + if (seedID.contains("_stage_")) { + seedLocation.getBlock().setType(Material.AIR); if (seedID.equals(BasicItemConfig.deadCrop)) return; //ripe or not if (hasNextStage(seedID)) { - for (ItemStack item : seedLocation.getBlock().getDrops()) - player.getWorld().dropItemNaturally(seedLocation, item); - } - else { - super.onBreakRipeCrop(seedLocation, seedID, player, false, false); + Drop drop = mechanic.getDrop(); + if (drop != null && player.getGameMode() != GameMode.CREATIVE) { + drop.spawns(location, new ItemStack(Material.AIR)); + } + super.onBreakUnripeCrop(location); + return; } + super.onBreakRipeCrop(seedLocation, seedID, player, false, false); } } } @@ -88,13 +96,20 @@ public class OraxenWireHandler extends OraxenHandler{ @Override public void onBreakStringBlock(OraxenStringBlockBreakEvent event) { if (event.isCancelled()) return; - String id = event.getStringBlockMechanic().getItemID(); + + StringBlockMechanic mechanic = event.getStringBlockMechanic(); + String id = mechanic.getItemID(); + + final Player player = event.getPlayer(); + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - 50)) < 50) return; + coolDown.put(player, time); + if (id.contains("_stage_")) { - final Player player = event.getPlayer(); final Block block = event.getBlock(); - if (!AntiGrief.testBreak(player, event.getBlock().getLocation())) { + if (!AntiGrief.testBreak(player, block.getLocation())) { event.setCancelled(true); return; } @@ -102,14 +117,17 @@ public class OraxenWireHandler extends OraxenHandler{ //Drop seeds if (player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){ event.setCancelled(true); - if (player.getGameMode() != GameMode.CREATIVE) - for (ItemStack item : block.getDrops()) - player.getWorld().dropItemNaturally(block.getLocation(), item); + Drop drop = mechanic.getDrop(); + if (player.getGameMode() != GameMode.CREATIVE && drop != null) + drop.spawns(block.getLocation(), new ItemStack(Material.AIR)); block.setType(Material.AIR); } if (id.equals(BasicItemConfig.deadCrop)) return; - if (hasNextStage(id)) return; + if (hasNextStage(id)) { + super.onBreakUnripeCrop(block.getLocation()); + return; + } super.onBreakRipeCrop(block.getLocation(), id, player, true, false); } } @@ -117,6 +135,10 @@ public class OraxenWireHandler extends OraxenHandler{ @Override public void onBreakFurniture(OraxenFurnitureBreakEvent event) { if (event.isCancelled()) return; + + //TODO Check if triggered in res + //System.out.println(1); + FurnitureMechanic mechanic = event.getFurnitureMechanic(); if (mechanic == null) return; Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(mechanic.getItemID()); @@ -128,12 +150,20 @@ public class OraxenWireHandler extends OraxenHandler{ @Override public void onInteractFurniture(OraxenFurnitureInteractEvent event) { if (event.isCancelled()) return; + + final Player player = event.getPlayer(); + + //TODO Check if air is block + final Block block = event.getBlock(); + + if (!AntiGrief.testPlace(player, block.getLocation())) return; + FurnitureMechanic mechanic = event.getFurnitureMechanic(); if (mechanic == null) return; String id = mechanic.getItemID(); Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id); if (sprinkler != null) { - super.onInteractSprinkler(event.getBlock().getLocation(), event.getPlayer(), event.getPlayer().getActiveItem(), sprinkler); + super.onInteractSprinkler(block.getLocation(), player, player.getInventory().getItemInMainHand(), sprinkler); } } @@ -146,13 +176,10 @@ public class OraxenWireHandler extends OraxenHandler{ Player player = event.getPlayer(); if (!AntiGrief.testPlace(player, potLoc)) return; - - super.tryMisc(event.getPlayer(), itemInHand, potLoc); - + if (super.tryMisc(event.getPlayer(), itemInHand, potLoc)) return; if (event.getBlockFace() != BlockFace.UP) return; - if (itemInHand == null || itemInHand.getType() == Material.AIR) return; - String id = OraxenItems.getIdByItem(itemInHand); + String id = OraxenItems.getIdByItem(itemInHand); if (id.endsWith("_seeds")) { String cropName = id.substring(0, id.length() - 6); Crop crop = CropConfig.CROPS.get(cropName); @@ -162,16 +189,48 @@ public class OraxenWireHandler extends OraxenHandler{ CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); if (customWorld == null) return; - if (FurnitureUtil.hasFurniture(seedLoc)) return; + if (FurnitureUtil.hasFurniture(seedLoc.clone().add(0.5,0.5,0.5))) return; if (seedLoc.getBlock().getType() != Material.AIR) return; PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); - for (RequirementInterface requirement : crop.getRequirements()) { - if (!requirement.isConditionMet(plantingCondition)) { - return; + if (crop.getRequirements() != null) { + for (RequirementInterface requirement : crop.getRequirements()) { + if (!requirement.isConditionMet(plantingCondition)) { + return; + } } } + + if (MainConfig.limitation && LimitationUtil.reachWireLimit(potLoc)) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount))); + return; + } + + CCSeason[] seasons = crop.getSeasons(); + if (SeasonConfig.enable && seasons != null) { + if (cropManager.isWrongSeason(seedLoc, seasons)) { + if (MainConfig.notifyInWrongSeason) AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.wrongSeason); + if (MainConfig.preventInWrongSeason) return; + } + } + + SeedPlantEvent seedPlantEvent = new SeedPlantEvent(player, seedLoc, crop); + Bukkit.getPluginManager().callEvent(seedPlantEvent); + if (seedPlantEvent.isCancelled()) { + return; + } + + if (SoundConfig.plantSeed.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.plantSeed.getSource(), + SoundConfig.plantSeed.getKey(), + 1,1 + ); + } + + if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1); StringBlockMechanicFactory.setBlockModel(seedLoc.getBlock(), id.substring(0, id.length() - 5) + "stage_1"); customWorld.addCrop(seedLoc, cropName); } @@ -181,24 +240,31 @@ public class OraxenWireHandler extends OraxenHandler{ public void onInteractStringBlock(OraxenStringBlockInteractEvent event) { if (event.isCancelled()) return; - String id = event.getStringBlockMechanic().getItemID(); - Player player = event.getPlayer(); + final String id = event.getStringBlockMechanic().getItemID(); + final Player player = event.getPlayer(); + final Block block = event.getBlock(); if (id.contains("_stage_")) { - if (!id.equals(BasicItemConfig.deadCrop)) { - //ripe crops - if (!hasNextStage(id) && MainConfig.canRightClickHarvest) { - Block seedBlock = event.getBlock(); - Location seedLoc = seedBlock.getLocation(); - seedBlock.setType(Material.AIR); - this.onInteractRipeCrop(seedLoc, id, event.getPlayer()); - } - else { - Location potLoc = event.getBlock().getLocation().clone().subtract(0,1,0); - super.tryMisc(player, event.getItemInHand(), potLoc); + Location seedLoc = block.getLocation(); + //ripe crops + if (!id.equals(BasicItemConfig.deadCrop) && !hasNextStage(id) && MainConfig.canRightClickHarvest) { + + if (!(MainConfig.emptyHand && (event.getItemInHand() != null && event.getItemInHand().getType() != Material.AIR))) { + + if (!AntiGrief.testBreak(player, seedLoc)) return; + + block.setType(Material.AIR); + this.onInteractRipeCrop(seedLoc, id, player); + return; } } + + if (!AntiGrief.testPlace(player, seedLoc)) return; + + Location potLoc = block.getLocation().clone().subtract(0,1,0); + super.tryMisc(player, event.getItemInHand(), potLoc); + } } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java index cc4e41b..0518f2e 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java @@ -40,6 +40,7 @@ public class OraxenBlockListener implements Listener { @EventHandler public void onInteractNote(OraxenNoteBlockInteractEvent event) { + handler.onInteractNoteBlock(event); } @EventHandler @@ -49,5 +50,6 @@ public class OraxenBlockListener implements Listener { @EventHandler public void onInteractString(OraxenStringBlockInteractEvent event) { + handler.onInteractStringBlock(event); } } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java index eb537ef..541a3f6 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java @@ -33,9 +33,11 @@ public class OraxenFurnitureListener implements Listener { @EventHandler public void onInteract(OraxenFurnitureInteractEvent event) { + handler.onInteractFurniture(event); } @EventHandler public void onBreak(OraxenFurnitureBreakEvent event) { + handler.onBreakFurniture(event); } } diff --git a/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java b/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java index 580e250..4d10226 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java +++ b/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.momirealms.customcrops.integrations.papi; import me.clip.placeholderapi.PlaceholderAPI; diff --git a/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java b/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java index c22ffd2..ff89c18 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java +++ b/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.momirealms.customcrops.integrations.papi; import me.clip.placeholderapi.expansion.PlaceholderExpansion; diff --git a/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java b/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java index 99c6c27..49e7229 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java +++ b/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java @@ -19,30 +19,20 @@ package net.momirealms.customcrops.integrations.season; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.Function; -import net.momirealms.customcrops.config.ConfigUtil; import net.momirealms.customcrops.config.MainConfig; import net.momirealms.customcrops.config.SeasonConfig; -import net.momirealms.customcrops.utils.AdventureUtil; -import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class InternalSeason extends Function implements SeasonInterface { private ConcurrentHashMap seasonHashMap; private BukkitTask task; - private YamlConfiguration data; public InternalSeason() { load(); @@ -52,33 +42,12 @@ public class InternalSeason extends Function implements SeasonInterface { public void load() { super.load(); this.seasonHashMap = new ConcurrentHashMap<>(); - this.data = ConfigUtil.readData(new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "season.yml")); - for (String worldName : data.getKeys(false)) { - World world = Bukkit.getWorld(worldName); - if (world != null) { - if ((MainConfig.whiteOrBlack && MainConfig.worldList.contains(world)) || (!MainConfig.whiteOrBlack && !MainConfig.worldList.contains(world))) { - seasonHashMap.put(world, CCSeason.valueOf(data.getString(worldName,"SPRING").toUpperCase())); - } - } - } - if (SeasonConfig.auto) { - startTimer(); - } + startTimer(); } @Override public void unload() { super.unload(); - for (Map.Entry season : seasonHashMap.entrySet()) { - data.set(season.getKey().getName(), season.getValue().name()); - } - try { - data.save(new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "season.yml")); - } - catch (IOException e) { - e.printStackTrace(); - AdventureUtil.consoleMessage("[CustomCrops] Error occurs when saving season data"); - } this.seasonHashMap.clear(); if (task != null) task.cancel(); } @@ -96,15 +65,15 @@ public class InternalSeason extends Function implements SeasonInterface { @Override public void unloadWorld(World world) { - CCSeason season = seasonHashMap.remove(world); - if (season == null) return; - data.set(world.getName(), season.name()); + seasonHashMap.remove(world); } @Override @NotNull public CCSeason getSeason(World world) { - CCSeason season = seasonHashMap.get(world); + CCSeason season; + if (MainConfig.syncSeason) season = seasonHashMap.get(MainConfig.syncWorld); + else season = seasonHashMap.get(world); if (season == null) { season = countSeason(world); setSeason(season, world); @@ -114,28 +83,22 @@ public class InternalSeason extends Function implements SeasonInterface { @Override public void setSeason(CCSeason season, World world) { - seasonHashMap.put(world, season); + if (season == CCSeason.UNKNOWN) { + setSeason(countSeason(world), world); + } + else { + seasonHashMap.put(world, season); + } } private void startTimer() { this.task = new BukkitRunnable() { @Override public void run() { - if (MainConfig.whiteOrBlack) { - for (World world : MainConfig.worlds) { - if (world.getTime() < 100) { - setSeason(countSeason(world), world); - } - } - } - else { - List worlds = new ArrayList<>(Bukkit.getWorlds()); - List blackWorlds = List.of(MainConfig.worlds); - worlds.removeAll(blackWorlds); - for (World world : worlds) { - if (world.getTime() < 100) { - setSeason(countSeason(world), world); - } + if (!SeasonConfig.auto) return; + for (World world : MainConfig.getWorldsArray()) { + if (world.getTime() < 100) { + setSeason(countSeason(world), world); } } } diff --git a/src/main/java/net/momirealms/customcrops/managers/CropManager.java b/src/main/java/net/momirealms/customcrops/managers/CropManager.java index 17d1ba8..b02ba89 100644 --- a/src/main/java/net/momirealms/customcrops/managers/CropManager.java +++ b/src/main/java/net/momirealms/customcrops/managers/CropManager.java @@ -17,7 +17,6 @@ package net.momirealms.customcrops.managers; -import dev.lone.itemsadder.api.CustomStack; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.Function; import net.momirealms.customcrops.api.crop.Crop; @@ -131,6 +130,9 @@ public class CropManager extends Function { customWorld.unload(true); } customWorlds.clear(); + if (this.seasonInterface != null) { + seasonInterface.unload(); + } } public void onItemSpawn(Item item) { @@ -178,7 +180,7 @@ public class CropManager extends Function { public boolean hasGlass(Location location) { for(int i = 1; i <= SeasonConfig.effectiveRange; i++){ - String blockID = customInterface.getBlockID(location); + String blockID = customInterface.getBlockID(location.clone().add(0,i,0)); if (blockID != null && blockID.equals(BasicItemConfig.greenHouseGlass)) return true; } return false; @@ -220,6 +222,9 @@ public class CropManager extends Function { } public void makePotDry(Location potLoc) { + String potID = customInterface.getBlockID(potLoc); + if (potID == null) return; + if (!potID.equals(BasicItemConfig.wetPot)) return; customInterface.removeBlock(potLoc); customInterface.placeNoteBlock(potLoc, BasicItemConfig.dryPot); } @@ -250,8 +255,6 @@ public class CropManager extends Function { if (player.getGameMode() == GameMode.CREATIVE) return; - Location itemLoc = location.clone().add(0.5,0.2,0.5); - QualityLoot qualityLoot = crop.getQualityLoot(); if (qualityLoot != null) { int amount = ThreadLocalRandom.current().nextInt(qualityLoot.getMin(), qualityLoot.getMax() + 1); @@ -266,10 +269,10 @@ public class CropManager extends Function { qualityRatio = qualityCrop.getQualityRatio(); } } - dropQualityLoots(qualityLoot, amount, itemLoc, qualityRatio); + dropQualityLoots(qualityLoot, amount, location.getBlock().getLocation(), qualityRatio); } OtherLoot[] otherLoots = crop.getOtherLoots(); - if (otherLoots != null) dropOtherLoots(otherLoots, itemLoc); + if (otherLoots != null) dropOtherLoots(otherLoots, location.getBlock().getLocation()); } public void performActions(ActionInterface[] actions, Player player) { @@ -282,9 +285,10 @@ public class CropManager extends Function { for (OtherLoot otherLoot : otherLoots) { if (Math.random() < otherLoot.getChance()) { int random = ThreadLocalRandom.current().nextInt(otherLoot.getMin(), otherLoot.getMax() + 1); - ItemStack drop = CustomStack.getInstance(otherLoot.getItemID()).getItemStack(); + ItemStack drop = customInterface.getItemStack(otherLoot.getItemID()); + if (drop == null) continue; drop.setAmount(random); - location.getWorld().dropItem(location, drop); + location.getWorld().dropItemNaturally(location, drop); } } } @@ -297,17 +301,17 @@ public class CropManager extends Function { if (random < qualityRatio.getQuality_1()) { ItemStack drop = customInterface.getItemStack(qualityLoot.getQuality_1()); if (drop == null) continue; - world.dropItem(location, drop); + world.dropItemNaturally(location, drop); } else if(random > qualityRatio.getQuality_2()){ ItemStack drop = customInterface.getItemStack(qualityLoot.getQuality_2()); if (drop == null) continue; - world.dropItem(location, drop); + world.dropItemNaturally(location, drop); } else { ItemStack drop = customInterface.getItemStack(qualityLoot.getQuality_3()); if (drop == null) continue; - world.dropItem(location, drop); + world.dropItemNaturally(location, drop); } } } diff --git a/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java b/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java index eda52ca..6c6670c 100644 --- a/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java +++ b/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java @@ -17,32 +17,31 @@ package net.momirealms.customcrops.managers; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.stream.JsonReader; +import com.google.gson.*; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.event.CustomWorldEvent; +import net.momirealms.customcrops.api.utils.SeasonUtils; import net.momirealms.customcrops.config.*; +import net.momirealms.customcrops.integrations.season.CCSeason; import net.momirealms.customcrops.objects.SimpleLocation; import net.momirealms.customcrops.objects.Sprinkler; import net.momirealms.customcrops.objects.WorldState; import net.momirealms.customcrops.objects.fertilizer.Fertilizer; import net.momirealms.customcrops.utils.AdventureUtil; import net.momirealms.customcrops.utils.MiscUtils; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.Nullable; import java.io.*; +import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -71,6 +70,7 @@ public class CustomWorld { this.playerWatered = new HashSet<>(); this.tempWatered = new HashSet<>(); Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { + loadSeason(); loadCropCache(); loadSprinklerCache(); loadFertilizerCache(); @@ -84,17 +84,21 @@ public class CustomWorld { public void unload(boolean disable) { if (disable) { + unloadSeason(); unloadCrop(); unloadSprinkler(); unloadFertilizer(); unloadPot(); + backUp(world.getName()); } else { Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { + unloadSeason(); unloadCrop(); unloadSprinkler(); unloadFertilizer(); unloadPot(); + backUp(world.getName()); for (BukkitTask task : tasksCache) { task.cancel(); } @@ -107,6 +111,56 @@ public class CustomWorld { } } + private void backUp(String worldName) { + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + try { + File file = new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), worldName + File.separator + "customcrops_data"); + File[] files = file.listFiles(); + if (files == null) return; + for (File data : files) { + FileUtils.copyFileToDirectory(data, new File(CustomCrops.plugin.getDataFolder(), "backup" + File.separator + worldName + "_" + format.format(date))); + } + } + catch (IOException e){ + e.printStackTrace(); + AdventureUtil.consoleMessage("[CustomCrops] Error! Failed to back up data for "); + } + } + + public void loadSeason() { + try { + JsonParser jsonParser = new JsonParser(); + JsonElement json= jsonParser.parse(new FileReader(new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), world.getName() + File.separator + "customcrops_data" + File.separator + "season.json"))); + if (json.isJsonObject()) { + JsonObject jsonObject = json.getAsJsonObject(); + if (jsonObject.has("season")) { + JsonPrimitive jsonPrimitive = jsonObject.getAsJsonPrimitive("season"); + String season = jsonPrimitive.getAsString(); + if (MainConfig.realisticSeasonHook) return; + SeasonUtils.setSeason(world, CCSeason.valueOf(season)); + return; + } + } + SeasonUtils.setSeason(world, CCSeason.UNKNOWN); + } + catch (FileNotFoundException e) { + //bypass + } + } + + public void unloadSeason() { + JsonObject jsonObject = new JsonObject(); + JsonPrimitive jsonPrimitive = new JsonPrimitive(SeasonUtils.getSeason(world).name()); + jsonObject.add("season", jsonPrimitive); + try (FileWriter fileWriter = new FileWriter(new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), world.getName() + File.separator + "customcrops_data" + File.separator + "season.json"))){ + fileWriter.write(jsonObject.toString().replace("\\\\", "\\")); + } catch (IOException e) { + e.printStackTrace(); + } + SeasonUtils.unloadSeason(world); + } + public void loadPot() { try { JsonParser jsonParser = new JsonParser(); diff --git a/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java b/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java index bffac7c..31b0d95 100644 --- a/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java +++ b/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java @@ -17,6 +17,7 @@ package net.momirealms.customcrops.managers; +import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.crop.Crop; import net.momirealms.customcrops.config.BasicItemConfig; import net.momirealms.customcrops.config.CropConfig; @@ -25,10 +26,11 @@ import net.momirealms.customcrops.integrations.customplugin.CustomInterface; import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenHook; import net.momirealms.customcrops.objects.GiganticCrop; import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.objects.fertilizer.RetainingSoil; +import net.momirealms.customcrops.objects.fertilizer.Gigantic; import net.momirealms.customcrops.objects.fertilizer.SpeedGrow; import net.momirealms.customcrops.utils.FurnitureUtil; import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.entity.ItemFrame; @@ -57,7 +59,10 @@ public class FrameCropImpl implements CropModeInterface { if (chunk.isEntitiesLoaded()) { - ItemFrame itemFrame = FurnitureUtil.getItemFrame(location); + Location cropLoc = location.clone().add(0.5,0.5,0.5); + if (MainConfig.OraxenHook) cropLoc.subtract(0, 0.46875, 0); + + ItemFrame itemFrame = FurnitureUtil.getItemFrame(cropLoc); if (itemFrame == null) return true; String id = customInterface.getItemID(itemFrame.getItem()); if (id == null) return true; @@ -95,13 +100,22 @@ public class FrameCropImpl implements CropModeInterface { } else { GiganticCrop giganticCrop = crop.getGiganticCrop(); - if (giganticCrop != null && Math.random() < giganticCrop.getChance()) { - customInterface.removeFurniture(itemFrame); - if (giganticCrop.isBlock()) { - customInterface.placeWire(location, giganticCrop.getBlockID()); + if (giganticCrop != null) { + double chance = giganticCrop.getChance(); + if (fertilizer instanceof Gigantic gigantic) { + chance += gigantic.getChance(); } - else { - customInterface.placeFurniture(location, giganticCrop.getBlockID()); + System.out.println(chance); + if (Math.random() < chance) { + Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> { + customInterface.removeFurniture(itemFrame); + if (giganticCrop.isBlock()) { + customInterface.placeWire(location, giganticCrop.getBlockID()); + } + else { + customInterface.placeFurniture(location, giganticCrop.getBlockID()); + } + }); } } return true; @@ -112,6 +126,6 @@ public class FrameCropImpl implements CropModeInterface { private void addStage(ItemFrame itemFrame, String stage) { itemFrame.setItem(customInterface.getItemStack(stage)); - if (!MainConfig.OraxenHook) itemFrame.getPersistentDataContainer().set(OraxenHook.FURNITURE, PersistentDataType.STRING, stage); + if (MainConfig.OraxenHook) itemFrame.getPersistentDataContainer().set(OraxenHook.FURNITURE, PersistentDataType.STRING, stage); } } diff --git a/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java b/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java index c1bc751..6bc230a 100644 --- a/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java +++ b/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java @@ -19,7 +19,6 @@ package net.momirealms.customcrops.managers.listener; import net.momirealms.customcrops.integrations.customplugin.HandlerP; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerQuitEvent; diff --git a/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java b/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java index ebcd38b..7dcabed 100644 --- a/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java +++ b/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java @@ -33,13 +33,11 @@ public class WorldListener implements Listener { @EventHandler public void onWorldUnload(WorldLoadEvent event) { - System.out.println("load"); cropManager.onWorldLoad(event.getWorld()); } @EventHandler public void onWorldUnload(WorldUnloadEvent event) { - System.out.println("unload"); cropManager.onWorldUnload(event.getWorld(), false); } } diff --git a/src/main/java/net/momirealms/customcrops/objects/CrowTask.java b/src/main/java/net/momirealms/customcrops/objects/CrowTask.java deleted file mode 100644 index ea94f16..0000000 --- a/src/main/java/net/momirealms/customcrops/objects/CrowTask.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.momirealms.customcrops.objects; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class CrowTask extends BukkitRunnable { - - private int timer; - private Player player; - private Location location; - private Vector vector_1; - private Vector vector_2; - private float yaw; - - public CrowTask(Player player, Vector vector_1, Vector vector_2, Location location, float yaw) { - this.player = player; - this.timer = 0; - this.vector_1 = vector_1; - this.vector_2 = vector_2; - this.location = location; - this.yaw = yaw; - } - - @Override - public void run() { - while (this.timer < 40) { - timer++; - location.add(vector_1).subtract(0,0.2,0); - - - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/objects/WorldState.java b/src/main/java/net/momirealms/customcrops/objects/WorldState.java index 171dc0e..a27c9b3 100644 --- a/src/main/java/net/momirealms/customcrops/objects/WorldState.java +++ b/src/main/java/net/momirealms/customcrops/objects/WorldState.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.momirealms.customcrops.objects; public enum WorldState { diff --git a/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java b/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java index 4128560..34f8b43 100644 --- a/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java +++ b/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.momirealms.customcrops.objects; import net.kyori.adventure.key.Key; diff --git a/src/main/java/net/momirealms/customcrops/utils/ArmorStandUtil.java b/src/main/java/net/momirealms/customcrops/utils/ArmorStandUtil.java index 296a18d..b7cfbfa 100644 --- a/src/main/java/net/momirealms/customcrops/utils/ArmorStandUtil.java +++ b/src/main/java/net/momirealms/customcrops/utils/ArmorStandUtil.java @@ -1,7 +1,23 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.momirealms.customcrops.utils; import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.Pair; @@ -18,7 +34,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import java.lang.reflect.InvocationTargetException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.UUID; public class ArmorStandUtil { @@ -63,8 +82,6 @@ public class ArmorStandUtil { } catch (InvocationTargetException e) { e.printStackTrace(); } - - } private WrappedDataWatcher createDataWatcher() { diff --git a/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java b/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java index 6678742..bc939ae 100644 --- a/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java +++ b/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java @@ -18,11 +18,16 @@ package net.momirealms.customcrops.utils; import org.bukkit.Location; +import org.bukkit.Rotation; import org.bukkit.entity.Entity; import org.bukkit.entity.ItemFrame; +import java.util.Random; + public class FurnitureUtil { + private static final Rotation[] rotations4 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE}; + public static ItemFrame getItemFrame(Location location) { for(Entity entity : location.getWorld().getNearbyEntities(location,0,0,0)){ if (entity instanceof ItemFrame itemFrame) { @@ -35,4 +40,8 @@ public class FurnitureUtil { public static boolean hasFurniture(Location location) { return getItemFrame(location) != null; } + + public static Rotation getRandomRotation() { + return rotations4[new Random().nextInt(rotations4.length-1)]; + } } diff --git a/src/main/java/net/momirealms/customcrops/utils/HologramUtil.java b/src/main/java/net/momirealms/customcrops/utils/HologramUtil.java index 2085998..b5ab5e8 100644 --- a/src/main/java/net/momirealms/customcrops/utils/HologramUtil.java +++ b/src/main/java/net/momirealms/customcrops/utils/HologramUtil.java @@ -18,7 +18,6 @@ package net.momirealms.customcrops.utils; import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedDataWatcher; @@ -26,6 +25,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.objects.SimpleLocation; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.EntityType; @@ -35,17 +35,17 @@ import java.util.*; public class HologramUtil { - public static HashMap cache = new HashMap<>(); + public static HashMap cache = new HashMap<>(); public static void showHolo(String text, Player player, Location location, int duration){ - Integer entityID = cache.remove(location); + Integer entityID = cache.remove(MiscUtils.getSimpleLocation(location)); if (entityID != null) { removeHolo(player, entityID); } PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); int id = new Random().nextInt(1000000000); - cache.put(location, id); + cache.put(MiscUtils.getSimpleLocation(location), id); spawnPacket.getModifier().write(0, id); spawnPacket.getModifier().write(1, UUID.randomUUID()); spawnPacket.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND); @@ -76,7 +76,7 @@ public class HologramUtil { } Bukkit.getScheduler().runTaskLater(CustomCrops.plugin, ()->{ removeHolo(player, id); - cache.remove(location); + cache.remove(MiscUtils.getSimpleLocation(location)); }, duration * 20L); } diff --git a/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java b/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java index 137138b..18aeab3 100644 --- a/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java +++ b/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java @@ -20,7 +20,6 @@ package net.momirealms.customcrops.utils; import net.momirealms.customcrops.config.MainConfig; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.entity.ItemFrame; public class LimitationUtil { diff --git a/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java b/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java index 7bcba7c..9317813 100644 --- a/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java +++ b/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.momirealms.customcrops.utils; import net.momirealms.customcrops.objects.SimpleLocation; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 8405e25..ff9160c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -46,6 +46,8 @@ optimization: disable-water-particles: false # Disable the animation when sprinkler works disable-sprinkler-animation: false + # Auto back up the data for when a world is unloaded + auto-back-up: true mechanics: @@ -97,6 +99,12 @@ mechanics: # Season would not affect ripe crops(for better performance and friendly player's experience) season: enable: true + + # If you want all the worlds share the same season + sync-seasons: + enable: false + world: world + auto-season-change: enable: true #duration of each season diff --git a/src/main/resources/crops_itemsadder.yml b/src/main/resources/crops_itemsadder.yml index edf564a..8918e16 100644 --- a/src/main/resources/crops_itemsadder.yml +++ b/src/main/resources/crops_itemsadder.yml @@ -115,7 +115,7 @@ pepper: 1: customcrops:pepper 2: customcrops:pepper_silver_star 3: customcrops:pepper_golden_star - return: customcrops:pepper_stage_4 + return: customcrops:pepper_stage_3 season: - Spring - Autumn diff --git a/src/main/resources/crops_oraxen.yml b/src/main/resources/crops_oraxen.yml index 5a824f2..955f39e 100644 --- a/src/main/resources/crops_oraxen.yml +++ b/src/main/resources/crops_oraxen.yml @@ -1,33 +1,53 @@ -crops: +# Crop Name +# Your seeds should end with "_seeds" and stage model should end with "_stage_x" +tomato: - tomato: + quality-loots: + amount: 1~4 + quality: + 1: tomato + 2: tomato_silver_star + 3: tomato_golden_star - # If you don't need quality-loots just delete them - quality-loots: - amount: 1~4 - quality: - 1: tomato - 2: tomato_silver_star - 3: tomato_golden_star + other-loots: + loot_1: + item: tomato_seeds + min_amount: 1 + max_amount: 2 + chance: 0.8 + loot_2: + item: tomato + min_amount: 1 + max_amount: 2 + chance: 0.8 - drop-other-loots: - loot_1: - item: tomato_seeds - amount: 1~2 - chance: 0.8 + gigantic-crop: + block: gigantic_tomato + # furniture: gigantic_tomato (If you want gigantic crop to be a furniture) + chance: 0.01 - gigantic-crop: - block: gigantic_tomato - #furniture: gigantic_tomato(If you want gigantic crop to be a furniture) - chance: 0.01 + harvest-actions: + messages: + - 'Hello, {player}! Click here to read the CustomCrops wiki' + - 'This plugin uses MiniMessage Format, check it here [Click Me]' + commands: + - 'say {player} harvested a tomato! lol' + xp: 10 + #skill-xp: 100 - harvest-actions: - commands: - - 'say {player} harvested a tomato! lol' - exp: 10 - #skill-xp: 100 + # When you harvest with a single right click, the crop would return to a certain stage + return: tomato_stage_1 - #optional - season: - - summer - - autumn \ No newline at end of file + season: + - Spring + + requirements: + condition_1: + # Condition System: + type: permission + # Mode: && / || + mode: '&&' + value: + - crops.plant.tomato + # The message to be shown when player doesn't fit the requirement + message: 'You don''t have permission to plant this seed!' \ No newline at end of file diff --git a/src/main/resources/fertilizers_oraxen.yml b/src/main/resources/fertilizers_oraxen.yml index dcb01b7..9d793d5 100644 --- a/src/main/resources/fertilizers_oraxen.yml +++ b/src/main/resources/fertilizers_oraxen.yml @@ -86,7 +86,7 @@ quality: #When haveresting, players have a higher chance to get more crops. quantity: quantity_1: - name: '뀆' + name: '뀏' times: 14 chance: 0.5 bonus: 1 @@ -114,7 +114,7 @@ quantity: #Crops have a higher chance to be gigantic gigantic: gigantic_1: - name: '뀆' + name: '뀒' times: 14 # If a crop's default gigantic chance is 0.01, now it's 0.03 chance: 0.02 @@ -122,14 +122,14 @@ gigantic: before-plant: true particle: SOUL gigantic_2: - name: '뀐' + name: '뀓' times: 14 chance: 0.04 item: gigantic_2 before-plant: true particle: SOUL gigantic_3: - name: '뀑' + name: '뀔' times: 14 chance: 0.08 item: gigantic_3 diff --git a/src/main/resources/messages/messages_chinese.yml b/src/main/resources/messages/messages_chinese.yml index 0b1cef2..3e66eee 100644 --- a/src/main/resources/messages/messages_chinese.yml +++ b/src/main/resources/messages/messages_chinese.yml @@ -6,6 +6,8 @@ messages: no-perm: '权限不足!' lack-args: '参数不足!' wrong-args: '参数错误!' + none-args: '非空参数!' + invalid-args: '无效参数!' spring: '春' summer: '夏' autumn: '秋'