diff --git a/src/main/java/net/momirealms/customcrops/ConfigReader.java b/src/main/java/net/momirealms/customcrops/ConfigReader.java index 0b03379..ce5d059 100644 --- a/src/main/java/net/momirealms/customcrops/ConfigReader.java +++ b/src/main/java/net/momirealms/customcrops/ConfigReader.java @@ -87,6 +87,7 @@ public class ConfigReader { public static boolean quality; public static boolean canAddWater; public static boolean allWorld; + public static boolean needEmptyHand; public static double quality_1; public static double quality_2; @@ -116,6 +117,7 @@ public class ConfigReader { allWorld = config.getBoolean("config.all-world-grow",false); hasParticle = config.getBoolean("config.water-particles", true); rightClickHarvest = config.getBoolean("config.right-click-harvest", true); + needEmptyHand = config.getBoolean("config.harvest-with-empty-hand", true); //数量与高度限制 enableLimit = config.getBoolean("config.limit.enable",true); @@ -378,6 +380,7 @@ public class ConfigReader { public static double sprinklerOffset; public static void loadMessage(){ + YamlConfiguration config = getConfig("messages/messages_" + Config.lang +".yml"); prefix = config.getString("messages.prefix"); reload = config.getString("messages.reload"); @@ -452,6 +455,9 @@ public class ConfigReader { if (config.contains("crops." + key + ".return")){ cropInstance.setReturnStage(config.getString("crops." + key + ".return")); } + if (config.contains("crops." + key + ".commands")){ + cropInstance.setCommands(config.getStringList("crops." + key + ".commands")); + } if (config.contains("crops." + key + ".requirements")){ List requirements = new ArrayList<>(); config.getConfigurationSection("crops." + key + ".requirements").getValues(false).forEach((requirement, value) -> { diff --git a/src/main/java/net/momirealms/customcrops/CustomCrops.java b/src/main/java/net/momirealms/customcrops/CustomCrops.java index 27286ff..3359bfc 100644 --- a/src/main/java/net/momirealms/customcrops/CustomCrops.java +++ b/src/main/java/net/momirealms/customcrops/CustomCrops.java @@ -21,13 +21,11 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.momirealms.customcrops.commands.Executor; import net.momirealms.customcrops.commands.Completer; import net.momirealms.customcrops.datamanager.*; -import net.momirealms.customcrops.helper.LibraryLoader; import net.momirealms.customcrops.listener.BreakBlock; import net.momirealms.customcrops.listener.InteractEntity; import net.momirealms.customcrops.listener.ItemSpawn; import net.momirealms.customcrops.listener.RightClick; import net.momirealms.customcrops.timer.CropTimer; -import net.momirealms.customcrops.timer.CropTimerAsync; import net.momirealms.customcrops.utils.AdventureManager; import net.momirealms.customcrops.utils.BackUp; import net.momirealms.customcrops.utils.HoloUtil; @@ -45,7 +43,6 @@ public final class CustomCrops extends JavaPlugin { public static JavaPlugin instance; public static BukkitAudiences adventure; private CropTimer cropTimer; - private CropTimerAsync cropTimerAsync; private CropManager cropManager; private SprinklerManager sprinklerManager; private SeasonManager seasonManager; @@ -54,18 +51,6 @@ public final class CustomCrops extends JavaPlugin { @Override public void onLoad(){ -// instance = this; -// LibraryLoader.load("net.kyori","adventure-api","4.11.0","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-platform-api","4.1.1","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-platform-bukkit","4.1.1","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-platform-facet","4.1.1","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-text-serializer-gson","4.11.0","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-text-serializer-plain","4.11.0","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-text-serializer-gson-legacy-impl","4.11.0","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-nbt","4.11.0","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-key","4.11.0","https://oss.sonatype.org/content/groups/public"); -// LibraryLoader.load("net.kyori","adventure-text-minimessage","4.11.0","https://oss.sonatype.org/content/groups/public"); - } @Override @@ -96,11 +81,7 @@ public final class CustomCrops extends JavaPlugin { Bukkit.getPluginManager().registerEvents(new InteractEntity(this), this); //开始计时器 - if(ConfigReader.Config.asyncCheck){ - this.cropTimerAsync = new CropTimerAsync(this); - }else { - this.cropTimer = new CropTimer(this); - } + this.cropTimer = new CropTimer(this); //载入数据 if (ConfigReader.Season.enable){ @@ -156,15 +137,10 @@ public final class CustomCrops extends JavaPlugin { if (cropTimer != null) { this.cropTimer.stopTimer(cropTimer.getTaskID()); } - if (cropTimerAsync != null){ - this.cropTimerAsync.stopTimer(cropTimerAsync.getTaskID()); - } if (adventure != null) { adventure.close(); } - - instance = null; } public CropManager getCropManager() { return this.cropManager; } diff --git a/src/main/java/net/momirealms/customcrops/integrations/GriefPrevention.java b/src/main/java/net/momirealms/customcrops/integrations/GriefPrevention.java index b226abc..ccad10e 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/GriefPrevention.java +++ b/src/main/java/net/momirealms/customcrops/integrations/GriefPrevention.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; import org.bukkit.Location; diff --git a/src/main/java/net/momirealms/customcrops/listener/BreakBlock.java b/src/main/java/net/momirealms/customcrops/listener/BreakBlock.java index 7ce3b83..57047ae 100644 --- a/src/main/java/net/momirealms/customcrops/listener/BreakBlock.java +++ b/src/main/java/net/momirealms/customcrops/listener/BreakBlock.java @@ -40,6 +40,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; +import java.util.List; import java.util.concurrent.ThreadLocalRandom; public class BreakBlock implements Listener { @@ -66,7 +67,6 @@ public class BreakBlock implements Listener { String[] cropNameList = StringUtils.split(StringUtils.split(namespacedId, ":")[1], "_"); int nextStage = Integer.parseInt(cropNameList[2]) + 1; if (CustomBlock.getInstance(StringUtils.chop(namespacedId) + nextStage) == null) { - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, ()-> { if (location.getBlock().getType() != Material.AIR) return; CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]); @@ -75,6 +75,15 @@ public class BreakBlock implements Listener { Location itemLoc = location.clone().add(0.5,0.2,0.5); World world = location.getWorld(); Fertilizer fertilizer = PotManager.Cache.get(SimpleLocation.fromLocation(location.clone().subtract(0,1,0))); + List commands = cropInstance.getCommands(); + if (commands != null){ + Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, ()-> { + for (String command : commands){ + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); + } + return null; + }); + } if (fertilizer != null){ if (fertilizer instanceof QualityCrop qualityCrop){ int[] weights = qualityCrop.getChance(); diff --git a/src/main/java/net/momirealms/customcrops/listener/RightClick.java b/src/main/java/net/momirealms/customcrops/listener/RightClick.java index cec2149..63e2dee 100644 --- a/src/main/java/net/momirealms/customcrops/listener/RightClick.java +++ b/src/main/java/net/momirealms/customcrops/listener/RightClick.java @@ -317,61 +317,74 @@ public class RightClick implements Listener { } } } + else if(ConfigReader.Config.rightClickHarvest && !ConfigReader.Config.needEmptyHand){ + rightClickHarvest(event, player); + } } else if (ConfigReader.Config.rightClickHarvest && action == Action.RIGHT_CLICK_BLOCK) { - Block block = event.getClickedBlock(); - Location location = block.getLocation(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration){ - if (!integration.canBreak(location, player)) return; - } - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.contains("_stage_")){ - if(namespacedID.equals(ConfigReader.Basic.dead)) return; - String[] cropNameList = StringUtils.split(customBlock.getId(), "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) == null) { - if (ConfigReader.Config.quality){ - CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - World world = location.getWorld(); - Location itemLoc = location.clone().add(0.5,0.2,0.5); - Fertilizer fertilizer = PotManager.Cache.get(location.clone().subtract(0,1,0)); - if (fertilizer != null){ - if (fertilizer instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - double rank_1 = weights[0]/(weightTotal); - double rank_2 = 1 - weights[1]/(weightTotal); - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < rank_1){ - world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - }else if(ran > rank_2){ - world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - }else { - world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - } - }else { - BreakBlock.normalDrop(cropInstance, random, itemLoc, world); - } - } - else { - BreakBlock.normalDrop(cropInstance, random, itemLoc, world); - } - }else { - customBlock.getLoot().forEach(loot-> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), loot)); - } - CustomBlock.remove(location); - CropInstance crop = ConfigReader.CROPS.get(cropNameList[0]); - AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey); - if(crop.getReturnStage() != null){ - CustomBlock.place(crop.getReturnStage(), location); + rightClickHarvest(event, player); + } + } + } + + private void rightClickHarvest(PlayerInteractEvent event, Player player) { + Block block = event.getClickedBlock(); + Location location = block.getLocation(); + CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); + if (customBlock == null) return; + for (Integration integration : ConfigReader.Config.integration){ + if (!integration.canBreak(location, player)) return; + } + String namespacedID = customBlock.getNamespacedID(); + if (namespacedID.contains("_stage_")){ + if(namespacedID.equals(ConfigReader.Basic.dead)) return; + String[] cropNameList = StringUtils.split(customBlock.getId(), "_"); + int nextStage = Integer.parseInt(cropNameList[2]) + 1; + if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) == null) { + if (ConfigReader.Config.quality){ + CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]); + ThreadLocalRandom current = ThreadLocalRandom.current(); + int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); + World world = location.getWorld(); + Location itemLoc = location.clone().add(0.5,0.2,0.5); + Fertilizer fertilizer = PotManager.Cache.get(location.clone().subtract(0,1,0)); + List commands = cropInstance.getCommands(); + if (commands != null){ + for (String command : commands){ + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); } } + if (fertilizer != null){ + if (fertilizer instanceof QualityCrop qualityCrop){ + int[] weights = qualityCrop.getChance(); + double weightTotal = weights[0] + weights[1] + weights[2]; + double rank_1 = weights[0]/(weightTotal); + double rank_2 = 1 - weights[1]/(weightTotal); + for (int i = 0; i < random; i++){ + double ran = Math.random(); + if (ran < rank_1){ + world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); + }else if(ran > rank_2){ + world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); + }else { + world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); + } + } + }else { + BreakBlock.normalDrop(cropInstance, random, itemLoc, world); + } + } + else { + BreakBlock.normalDrop(cropInstance, random, itemLoc, world); + } + }else { + customBlock.getLoot().forEach(loot-> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), loot)); + } + CustomBlock.remove(location); + CropInstance crop = ConfigReader.CROPS.get(cropNameList[0]); + AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey); + if(crop.getReturnStage() != null){ + CustomBlock.place(crop.getReturnStage(), location); } } } diff --git a/src/main/java/net/momirealms/customcrops/timer/CropTimer.java b/src/main/java/net/momirealms/customcrops/timer/CropTimer.java index d0e147f..308e3e3 100644 --- a/src/main/java/net/momirealms/customcrops/timer/CropTimer.java +++ b/src/main/java/net/momirealms/customcrops/timer/CropTimer.java @@ -17,6 +17,7 @@ package net.momirealms.customcrops.timer; +import net.momirealms.customcrops.ConfigReader; import net.momirealms.customcrops.CustomCrops; import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitTask; @@ -27,7 +28,12 @@ public class CropTimer { public CropTimer(CustomCrops plugin) { TimeCheck tc = new TimeCheck(plugin); - BukkitTask task = tc.runTaskTimer(CustomCrops.instance, 1,1); + BukkitTask task; + if (ConfigReader.Config.asyncCheck){ + task = tc.runTaskTimerAsynchronously(CustomCrops.instance, 1,1); + }else { + task = tc.runTaskTimer(CustomCrops.instance, 1,1); + } this.taskID = task.getTaskId(); } diff --git a/src/main/java/net/momirealms/customcrops/utils/CropInstance.java b/src/main/java/net/momirealms/customcrops/utils/CropInstance.java index 988a550..66d3188 100644 --- a/src/main/java/net/momirealms/customcrops/utils/CropInstance.java +++ b/src/main/java/net/momirealms/customcrops/utils/CropInstance.java @@ -33,6 +33,7 @@ public class CropInstance { private String quality_1; private String quality_2; private String quality_3; + private List commands; public CropInstance(int min, int max){ this.min = min; @@ -53,6 +54,7 @@ public class CropInstance { public String getQuality_3() { return quality_3; } public int getMax() { return max; } public int getMin() { return min; } + public List getCommands() { return commands; } public void setReturnStage(String stage){ this.returnStage = stage; } public void setGiant(String giant) { this.giant = giant; } @@ -62,4 +64,5 @@ public class CropInstance { public void setQuality_1(String quality_1) { this.quality_1 = quality_1; } public void setQuality_2(String quality_2) { this.quality_2 = quality_2; } public void setQuality_3(String quality_3) { this.quality_3 = quality_3; } + public void setCommands(List commands) { this.commands = commands; } } diff --git a/src/main/java/net/momirealms/customcrops/utils/Placeholders.java b/src/main/java/net/momirealms/customcrops/utils/Placeholders.java index 9f1b5f2..2867bdf 100644 --- a/src/main/java/net/momirealms/customcrops/utils/Placeholders.java +++ b/src/main/java/net/momirealms/customcrops/utils/Placeholders.java @@ -60,11 +60,23 @@ public class Placeholders extends PlaceholderExpansion{ .replace("winter", ConfigReader.Message.winter); } if (params.equalsIgnoreCase("nextseason")){ + if (!ConfigReader.Config.worlds.contains(player.getPlayer().getWorld())){ + return ConfigReader.Message.noSeason; + } return String.valueOf(ConfigReader.Season.duration - ((int) ((player.getPlayer().getWorld().getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration)); } if (params.startsWith("nextseason_")){ return String.valueOf(ConfigReader.Season.duration - ((int) ((Bukkit.getWorld(params.substring(11)).getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration)); } + if (params.equalsIgnoreCase("current")){ + if (!ConfigReader.Config.worlds.contains(player.getPlayer().getWorld())){ + return ConfigReader.Message.noSeason; + } + return String.valueOf((int) ((player.getPlayer().getWorld().getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration + 1); + } + if (params.startsWith("current_")){ + return String.valueOf(((int) (Bukkit.getWorld(params.substring(8)).getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration+ 1); + } return null; } } diff --git a/src/main/resources/basic.yml b/src/main/resources/basic.yml index cbf6d15..f6c6a27 100644 --- a/src/main/resources/basic.yml +++ b/src/main/resources/basic.yml @@ -35,12 +35,12 @@ lore: watering-can: enable: true #Lore format + #Available variables: {water_info} + #{water}current water {max_water}max storage lore: - '{water_info}' - 'Right click water to add water to the can.' - - #Available variables: {water_info} - #{water}current water {max_water}max storage + #{water_info} left: '뀂' full: '뀁뀃' empty: '뀁뀄' diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 8e17761..738ede1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,6 +13,9 @@ config: Lands: false GriefPrevention: false + AureliumSkills: false + mcMMO: false + #The time to start growing(ticks) #1000ticks is 7am in game. (0-23999) #Sprinklers will work after all crops finish growing @@ -76,4 +79,8 @@ config: #can player harvest crops with right click? #if set "false" crops can't be harvested repeatedly - right-click-harvest: true \ No newline at end of file + right-click-harvest: true + + #If "right-click-harvest" is true + #Should player be allowed to harvest with items in hand + harvest-with-empty-hand: true \ No newline at end of file diff --git a/src/main/resources/crops.yml b/src/main/resources/crops.yml index 68a3ba0..92f167e 100644 --- a/src/main/resources/crops.yml +++ b/src/main/resources/crops.yml @@ -16,6 +16,11 @@ crops: block: customcrops:gigantic_tomato chance: 0.01 + #optional + commands: + - 'say {player} harvested a tomato! lol' + + #optional season: - summer - autumn diff --git a/src/main/resources/zh-cn/config.yml b/src/main/resources/zh-cn/config.yml index f2c68fd..937a62e 100644 --- a/src/main/resources/zh-cn/config.yml +++ b/src/main/resources/zh-cn/config.yml @@ -1,6 +1,4 @@ config: - lang: chinese - #插件兼容 integration: Residence: false @@ -10,7 +8,6 @@ config: PlotSquared: false Towny: false Lands: false - GriefPrevention: false #生长时间点(tick) #1000代表上午7点,农作物陆续开始生长 @@ -78,5 +75,8 @@ config: #作为所有世界农作物生长的时间、季节判断依据 all-world-grow: false - #玩家是否能空手右键收获 - right-click-harvest: true \ No newline at end of file + #玩家是否能右键收获 + right-click-harvest: true + + #玩家是否需要空手右键收获 + harvest-with-empty-hand: true \ No newline at end of file diff --git a/src/main/resources/zh-cn/crops.yml b/src/main/resources/zh-cn/crops.yml index 89d59df..d1532ee 100644 --- a/src/main/resources/zh-cn/crops.yml +++ b/src/main/resources/zh-cn/crops.yml @@ -18,6 +18,10 @@ crops: block: customcrops:gigantic_tomato chance: 0.01 + #收获时候执行指令 + commands: + - 'say {player} harvested a tomato! lol' + #生长季节 season: - summer