From 716d73033e6a6d05a0b9091f6fde40c785d38f90 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 21 Mar 2024 18:28:21 +0800 Subject: [PATCH] 2.1.1 --- .../api/manager/MarketManager.java | 31 +- .../competition/CompetitionConfig.java | 23 ++ .../api/mechanic/effect/EffectCarrier.java | 4 + build.gradle.kts | 2 +- plugin/build.gradle.kts | 2 +- .../CustomFishingPluginImpl.java | 3 +- .../libraries/dependencies/Dependency.java | 2 +- .../mechanic/action/ActionManagerImpl.java | 14 +- .../competition/CompetitionManagerImpl.java | 2 + .../mechanic/fishing/FishingManagerImpl.java | 3 +- .../mechanic/fishing/HookCheckTimerTask.java | 3 +- .../mechanic/loot/LootManagerImpl.java | 1 - .../mechanic/market/MarketGUI.java | 111 +++++-- .../mechanic/market/MarketManagerImpl.java | 290 ++++++++++++------ .../requirement/RequirementManagerImpl.java | 16 +- .../contents/competition/default.yml | 4 + plugin/src/main/resources/market.yml | 59 +++- 17 files changed, 414 insertions(+), 156 deletions(-) diff --git a/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java b/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java index 92b44f34..1388e503 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.api.manager; import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import java.util.Map; @@ -75,11 +76,18 @@ public interface MarketManager { char getItemSlot(); /** - * Gets the character representing the function slot in the MarketGUI. + * Gets the character representing the sell slot in the MarketGUI. * - * @return The function slot character. + * @return The sell slot character. */ - char getFunctionSlot(); + char getSellSlot(); + + /** + * Gets the character representing the sell-all slot in the MarketGUI. + * + * @return The sell-all slot character. + */ + char getSellAllSlot(); /** * Gets the layout of the MarketGUI as an array of strings. @@ -108,4 +116,21 @@ public interface MarketManager { * @return enable or not */ boolean isEnable(); + + /** + * Should fish in bag also be sold + * + * @return sell or not + */ + boolean sellFishingBag(); + + /** + * Get the total worth of the items in inventory + * + * @param inventory inventory + * @return total worth + */ + double getInventoryTotalWorth(Inventory inventory); + + int getInventorySellAmount(Inventory inventory); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionConfig.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionConfig.java index 9836311b..adc698a0 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionConfig.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionConfig.java @@ -18,6 +18,8 @@ package net.momirealms.customfishing.api.mechanic.competition; import net.momirealms.customfishing.api.mechanic.action.Action; +import net.momirealms.customfishing.api.mechanic.requirement.Requirement; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -33,6 +35,7 @@ public class CompetitionConfig { private Action[] startActions; private Action[] endActions; private Action[] joinActions; + private Requirement[] requirements; private CompetitionGoal goal; private HashMap rewards; @@ -52,10 +55,12 @@ public class CompetitionConfig { return minPlayers; } + @Nullable public Action[] getStartActions() { return startActions; } + @Nullable public Action[] getEndActions() { return endActions; } @@ -65,6 +70,7 @@ public class CompetitionConfig { * * @return actions */ + @Nullable public Action[] getJoinActions() { return joinActions; } @@ -74,10 +80,22 @@ public class CompetitionConfig { * * @return actions */ + @Nullable public Action[] getSkipActions() { return skipActions; } + /** + * Get the requirements for participating the competition + * + * @return requirements + */ + @Nullable + public Requirement[] getRequirements() { + return requirements; + } + + @NotNull public CompetitionGoal getGoal() { return goal; } @@ -155,6 +173,11 @@ public class CompetitionConfig { return this; } + public Builder requirements(Requirement[] requirements) { + config.requirements = requirements; + return this; + } + public Builder goal(CompetitionGoal goal) { config.goal = goal; return this; diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/EffectCarrier.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/EffectCarrier.java index 05df54f7..103edce2 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/EffectCarrier.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/EffectCarrier.java @@ -34,6 +34,10 @@ public class EffectCarrier { private Map actionMap; private boolean persist; + public static Builder builder() { + return new Builder(); + } + public static class Builder { private final EffectCarrier item; diff --git a/build.gradle.kts b/build.gradle.kts index 03ce859b..7a7623ca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { allprojects { - version = "2.1.0.3.2" + version = "2.1.1" apply() apply(plugin = "java") diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 0882a42a..015628bc 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { compileOnly("org.betonquest:betonquest:2.0.0") compileOnly("xyz.xenondevs.invui:invui:1.26") compileOnly("com.github.Xiao-MoMi:Custom-Crops:3.4-BETA-1") - compileOnly("com.github.Xiao-MoMi:BiomeAPI:0.2") + implementation("com.github.Xiao-MoMi:BiomeAPI:0.3") // local jars compileOnly(files("libs/AdvancedEnchantments-api.jar")) diff --git a/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java b/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java index d845508a..0f9daca6 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java @@ -109,8 +109,7 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin { Dependency.BSTATS_BUKKIT, Dependency.INV_UI, Dependency.INV_UI_ACCESS, - Dependency.INV_UI_NMS, - Dependency.BIOME_API + Dependency.INV_UI_NMS ) )); } diff --git a/plugin/src/main/java/net/momirealms/customfishing/libraries/dependencies/Dependency.java b/plugin/src/main/java/net/momirealms/customfishing/libraries/dependencies/Dependency.java index ca8852ca..39b5ed55 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/libraries/dependencies/Dependency.java +++ b/plugin/src/main/java/net/momirealms/customfishing/libraries/dependencies/Dependency.java @@ -325,7 +325,7 @@ public enum Dependency { BIOME_API( "com{}github{}Xiao-MoMi", "BiomeAPI", - "0.2", + "0.3", "jitpack", "biome-api", Relocation.of("biomeapi", "net{}momirealms{}biomeapi") diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java index feec5f40..a84d0b24 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java @@ -61,12 +61,12 @@ import java.util.concurrent.TimeUnit; public class ActionManagerImpl implements ActionManager { private final CustomFishingPlugin plugin; - private final HashMap actionBuilderMap; + private final HashMap actionFactoryMap; private final String EXPANSION_FOLDER = "expansions/action"; public ActionManagerImpl(CustomFishingPlugin plugin) { this.plugin = plugin; - this.actionBuilderMap = new HashMap<>(); + this.actionFactoryMap = new HashMap<>(); this.registerInbuiltActions(); } @@ -110,7 +110,7 @@ public class ActionManagerImpl implements ActionManager { public void disable() { unload(); - this.actionBuilderMap.clear(); + this.actionFactoryMap.clear(); } // Method to load global event actions from the plugin's configuration file. @@ -129,8 +129,8 @@ public class ActionManagerImpl implements ActionManager { */ @Override public boolean registerAction(String type, ActionFactory actionFactory) { - if (this.actionBuilderMap.containsKey(type)) return false; - this.actionBuilderMap.put(type, actionFactory); + if (this.actionFactoryMap.containsKey(type)) return false; + this.actionFactoryMap.put(type, actionFactory); return true; } @@ -143,7 +143,7 @@ public class ActionManagerImpl implements ActionManager { */ @Override public boolean unregisterAction(String type) { - return this.actionBuilderMap.remove(type) != null; + return this.actionFactoryMap.remove(type) != null; } /** @@ -238,7 +238,7 @@ public class ActionManagerImpl implements ActionManager { @Nullable @Override public ActionFactory getActionFactory(String type) { - return actionBuilderMap.get(type); + return actionFactoryMap.get(type); } /** diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionManagerImpl.java index 3c649cda..6493ce22 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionManagerImpl.java @@ -130,6 +130,8 @@ public class CompetitionManagerImpl implements CompetitionManager { .minPlayers(section.getInt("min-players", 0)) .duration(section.getInt("duration", 300)) .rewards(getPrizeActions(section.getConfigurationSection("rewards"))) + .requirements(plugin.getRequirementManager().getRequirements(section.getConfigurationSection("participate-requirements"), false)) + .joinActions(plugin.getActionManager().getActions(section.getConfigurationSection("participate-actions"))) .startActions(plugin.getActionManager().getActions(section.getConfigurationSection("start-actions"))) .endActions(plugin.getActionManager().getActions(section.getConfigurationSection("end-actions"))) .skipActions(plugin.getActionManager().getActions(section.getConfigurationSection("skip-actions"))); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java index 9ecf7685..1b3f2c9a 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java @@ -59,6 +59,7 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.*; +import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; @@ -718,7 +719,7 @@ public class FishingManagerImpl implements Listener, FishingManager { */ private void doSuccessActions(Loot loot, Effect effect, FishingPreparation fishingPreparation, Player player) { FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); - if (competition != null) { + if (competition != null && RequirementManager.isRequirementMet(fishingPreparation, competition.getConfig().getRequirements())) { String scoreStr = fishingPreparation.getArg("{CUSTOM_SCORE}"); if (scoreStr != null) { competition.refreshData(player, Double.parseDouble(scoreStr)); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java index 75dbfc84..1818e0b8 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java @@ -188,7 +188,8 @@ public class HookCheckTimerTask implements Runnable { private void setTempState() { Loot nextLoot = CustomFishingPlugin.get().getLootManager().getNextLoot(initialEffect, fishingPreparation); if (nextLoot == null) { - CustomFishingPlugin.get().debug("No loot available, using vanilla "); + fishHook.setWaitTime(Integer.MAX_VALUE); + CustomFishingPlugin.get().debug("No loot available at " + fishingPreparation.getLocation()); return; } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java index a402e8c2..4d8a201c 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java @@ -201,7 +201,6 @@ public class LootManagerImpl implements LootManager { public Loot getNextLoot(Effect initialEffect, Condition condition) { String key = WeightUtils.getRandom(getPossibleLootKeysWithWeight(initialEffect, condition)); if (key == null) { - LogUtils.warn("No loot available at " + condition.getLocation() + " for player: " + condition.getPlayer().getName()); return null; } Loot loot = getLoot(key); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketGUI.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketGUI.java index 148c294d..8306f0d3 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketGUI.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketGUI.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.mechanic.market; import net.momirealms.customfishing.adventure.AdventureManagerImpl; +import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.data.EarningData; import net.momirealms.customfishing.api.mechanic.market.MarketGUIHolder; import net.momirealms.customfishing.api.util.InventoryUtils; @@ -146,36 +147,86 @@ public class MarketGUI { * @return The MarketGUI instance. */ public MarketGUI refresh() { - double totalWorth = getTotalWorth(); - MarketDynamicGUIElement functionElement = (MarketDynamicGUIElement) getElement(manager.getFunctionSlot()); - if (functionElement == null) { - return this; - } double earningLimit = manager.getEarningLimit(owner); - if (totalWorth <= 0) { - functionElement.setItemStack( - manager.getFunctionIconDenyBuilder().build(owner, - Map.of("{money}", String.format("%.2f", totalWorth) - ,"{player}", owner.getName() - ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings)) - ) - ); - } else if (earningLimit != -1 && (earningLimit - earningData.earnings < totalWorth)) { - functionElement.setItemStack( - manager.getFunctionIconLimitBuilder().build(owner, - Map.of("{money}", String.format("%.2f", totalWorth) - ,"{player}", owner.getName() - ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings)) - ) - ); - } else { - functionElement.setItemStack( - manager.getFunctionIconAllowBuilder().build(owner, - Map.of("{money}", String.format("%.2f", totalWorth) - ,"{player}", owner.getName() - ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings)) - ) - ); + MarketDynamicGUIElement sellElement = (MarketDynamicGUIElement) getElement(manager.getSellSlot()); + if (sellElement != null && sellElement.getSlots().size() > 0) { + double totalWorth = getTotalWorthInMarketGUI(); + int soldAmount = getSoldAmount(); + if (totalWorth <= 0) { + sellElement.setItemStack( + manager.getSellIconDenyBuilder().build(owner, + Map.of("{money}", String.format("%.2f", totalWorth) + ,"{player}", owner.getName() + ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings) + ,"{sold-item-amount}", String.valueOf(soldAmount) + ) + ) + ); + } else if (earningLimit != -1 && (earningLimit - earningData.earnings < totalWorth)) { + sellElement.setItemStack( + manager.getSellIconLimitBuilder().build(owner, + Map.of("{money}", String.format("%.2f", totalWorth) + ,"{player}", owner.getName() + ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings) + ,"{sold-item-amount}", String.valueOf(soldAmount) + ) + ) + ); + } else { + sellElement.setItemStack( + manager.getSellIconAllowBuilder().build(owner, + Map.of("{money}", String.format("%.2f", totalWorth) + ,"{player}", owner.getName() + ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings) + ,"{sold-item-amount}", String.valueOf(soldAmount) + ) + ) + ); + } + } + + MarketDynamicGUIElement sellAllElement = (MarketDynamicGUIElement) getElement(manager.getSellAllSlot()); + if (sellAllElement != null && sellAllElement.getSlots().size() > 0) { + double totalWorth = manager.getInventoryTotalWorth(owner.getInventory()); + int sellAmount = manager.getInventorySellAmount(owner.getInventory()); + if (manager.sellFishingBag() && CustomFishingPlugin.get().getBagManager().isEnabled()) { + Inventory bag = CustomFishingPlugin.get().getBagManager().getOnlineBagInventory(owner.getUniqueId()); + if (bag != null) { + totalWorth += manager.getInventoryTotalWorth(bag); + sellAmount += manager.getInventorySellAmount(bag); + } + } + if (totalWorth <= 0) { + sellAllElement.setItemStack( + manager.getSellAllIconDenyBuilder().build(owner, + Map.of("{money}", String.format("%.2f", totalWorth) + ,"{player}", owner.getName() + ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings) + ,"{sold-item-amount}", String.valueOf(sellAmount) + ) + ) + ); + } else if (earningLimit != -1 && (earningLimit - earningData.earnings < totalWorth)) { + sellAllElement.setItemStack( + manager.getSellAllIconLimitBuilder().build(owner, + Map.of("{money}", String.format("%.2f", totalWorth) + ,"{player}", owner.getName() + ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings) + ,"{sold-item-amount}", String.valueOf(sellAmount) + ) + ) + ); + } else { + sellAllElement.setItemStack( + manager.getSellAllIconAllowBuilder().build(owner, + Map.of("{money}", String.format("%.2f", totalWorth) + ,"{player}", owner.getName() + ,"{rest}", String.format("%.2f", earningLimit - earningData.earnings) + ,"{sold-item-amount}", String.valueOf(sellAmount) + ) + ) + ); + } } for (Map.Entry entry : itemsSlotMap.entrySet()) { if (entry.getValue() instanceof MarketDynamicGUIElement dynamicGUIElement) { @@ -189,7 +240,7 @@ public class MarketGUI { * Calculate and return the total worth of items in the inventory. * @return The total worth of items. */ - public double getTotalWorth() { + public double getTotalWorthInMarketGUI() { double money = 0d; MarketGUIElement itemElement = getElement(manager.getItemSlot()); if (itemElement == null) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java index 771f5483..7cfb82f2 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java @@ -60,15 +60,23 @@ public class MarketManagerImpl implements MarketManager, Listener { private String formula; private final HashMap decorativeIcons; private char itemSlot; - private char functionSlot; - private BuildableItem functionIconAllowBuilder; - private BuildableItem functionIconDenyBuilder; - private BuildableItem functionIconLimitBuilder; - private Action[] denyActions; - private Action[] allowActions; - private Action[] limitActions; + private char sellSlot; + private char sellAllSlot; + private BuildableItem sellIconAllowBuilder; + private BuildableItem sellIconDenyBuilder; + private BuildableItem sellIconLimitBuilder; + private BuildableItem sellAllIconAllowBuilder; + private BuildableItem sellAllIconDenyBuilder; + private BuildableItem sellAllIconLimitBuilder; + private Action[] sellDenyActions; + private Action[] sellAllowActions; + private Action[] sellLimitActions; + private Action[] sellAllDenyActions; + private Action[] sellAllAllowActions; + private Action[] sellAllLimitActions; private String earningLimitExpression; private boolean allowItemWithNoPrice; + private boolean sellFishingBag; private final ConcurrentHashMap marketGUIMap; private boolean enable; private CancellableTask resetEarningsTask; @@ -123,16 +131,41 @@ public class MarketManagerImpl implements MarketManager, Listener { this.layout = config.getStringList("layout").toArray(new String[0]); this.title = config.getString("title", "market.title"); this.itemSlot = config.getString("item-slot.symbol", "I").charAt(0); - this.functionSlot = config.getString("functional-icons.symbol", "B").charAt(0); - this.functionIconAllowBuilder = plugin.getItemManager().getItemBuilder(config.getConfigurationSection("functional-icons.allow-icon"), "gui", "allow"); - this.functionIconDenyBuilder = plugin.getItemManager().getItemBuilder(config.getConfigurationSection("functional-icons.deny-icon"), "gui", "deny"); - this.functionIconLimitBuilder = plugin.getItemManager().getItemBuilder(config.getConfigurationSection("functional-icons.limit-icon"), "gui", "limit"); - this.allowActions = plugin.getActionManager().getActions(config.getConfigurationSection("functional-icons.allow-icon.action")); - this.denyActions = plugin.getActionManager().getActions(config.getConfigurationSection("functional-icons.deny-icon.action")); - this.limitActions = plugin.getActionManager().getActions(config.getConfigurationSection("functional-icons.limit-icon.action")); - this.earningLimitExpression = config.getBoolean("limitation.enable", true) ? config.getString("limitation.earnings", "10000") : "-1"; this.allowItemWithNoPrice = config.getBoolean("item-slot.allow-items-with-no-price", true); + ConfigurationSection sellAllSection = config.getConfigurationSection("sell-all-icons"); + if (sellAllSection != null) { + this.sellAllSlot = sellAllSection.getString("symbol", "S").charAt(0); + this.sellFishingBag = sellAllSection.getBoolean("fishingbag", true); + + this.sellAllIconAllowBuilder = plugin.getItemManager().getItemBuilder(sellAllSection.getConfigurationSection("allow-icon"), "gui", "sell-all"); + this.sellAllIconDenyBuilder = plugin.getItemManager().getItemBuilder(sellAllSection.getConfigurationSection("deny-icon"), "gui", "sell-all"); + this.sellAllIconLimitBuilder = plugin.getItemManager().getItemBuilder(sellAllSection.getConfigurationSection("limit-icon"), "gui", "sell-all"); + + this.sellAllAllowActions = plugin.getActionManager().getActions(sellAllSection.getConfigurationSection("allow-icon.action")); + this.sellAllDenyActions = plugin.getActionManager().getActions(sellAllSection.getConfigurationSection("deny-icon.action")); + this.sellAllLimitActions = plugin.getActionManager().getActions(sellAllSection.getConfigurationSection("limit-icon.action")); + } + + ConfigurationSection sellSection = config.getConfigurationSection("sell-icons"); + if (sellSection == null) { + // for old config compatibility + sellSection = config.getConfigurationSection("functional-icons"); + } + if (sellSection != null) { + this.sellSlot = sellSection.getString("symbol", "B").charAt(0); + + this.sellIconAllowBuilder = plugin.getItemManager().getItemBuilder(sellSection.getConfigurationSection("allow-icon"), "gui", "allow"); + this.sellIconDenyBuilder = plugin.getItemManager().getItemBuilder(sellSection.getConfigurationSection("deny-icon"), "gui", "deny"); + this.sellIconLimitBuilder = plugin.getItemManager().getItemBuilder(sellSection.getConfigurationSection("limit-icon"), "gui", "limit"); + + this.sellAllowActions = plugin.getActionManager().getActions(sellSection.getConfigurationSection("allow-icon.action")); + this.sellDenyActions = plugin.getActionManager().getActions(sellSection.getConfigurationSection("deny-icon.action")); + this.sellLimitActions = plugin.getActionManager().getActions(sellSection.getConfigurationSection("limit-icon.action")); + } + + this.earningLimitExpression = config.getBoolean("limitation.enable", true) ? config.getString("limitation.earnings", "10000") : "-1"; + // Load item prices from the configuration ConfigurationSection priceSection = config.getConfigurationSection("item-price"); if (priceSection != null) { @@ -170,7 +203,8 @@ public class MarketManagerImpl implements MarketManager, Listener { MarketGUI gui = new MarketGUI(this, player, user.getEarningData()); gui.addElement(new MarketGUIElement(getItemSlot(), new ItemStack(Material.AIR))); - gui.addElement(new MarketDynamicGUIElement(getFunctionSlot(), new ItemStack(Material.AIR))); + gui.addElement(new MarketDynamicGUIElement(getSellSlot(), new ItemStack(Material.AIR))); + gui.addElement(new MarketDynamicGUIElement(getSellAllSlot(), new ItemStack(Material.AIR))); for (Map.Entry entry : decorativeIcons.entrySet()) { gui.addElement(new MarketGUIElement(entry.getKey(), entry.getValue().build(player))); } @@ -288,8 +322,8 @@ public class MarketManagerImpl implements MarketManager, Listener { event.setCancelled(true); } - if (element.getSymbol() == functionSlot) { - double worth = gui.getTotalWorth(); + if (element.getSymbol() == sellSlot) { + double worth = gui.getTotalWorthInMarketGUI(); int amount = gui.getSoldAmount(); double earningLimit = getEarningLimit(player); Condition condition = new Condition(player, new HashMap<>(Map.of( @@ -300,8 +334,8 @@ public class MarketManagerImpl implements MarketManager, Listener { if (worth > 0) { if (earningLimit != -1 && (earningLimit - data.earnings) < worth) { // Can't earn more money - if (limitActions != null) { - for (Action action : limitActions) { + if (getSellLimitActions() != null) { + for (Action action : getSellLimitActions()) { action.trigger(condition); } } @@ -310,16 +344,65 @@ public class MarketManagerImpl implements MarketManager, Listener { gui.clearWorthyItems(); data.earnings += worth; condition.insertArg("{rest}", String.format("%.2f", (earningLimit - data.earnings))); - if (allowActions != null) { - for (Action action : allowActions) { + if (getSellAllowActions() != null) { + for (Action action : getSellAllowActions()) { action.trigger(condition); } } } } else { // Nothing to sell - if (denyActions != null) { - for (Action action : denyActions) { + if (getSellDenyActions() != null) { + for (Action action : getSellDenyActions()) { + action.trigger(condition); + } + } + } + } else if (element.getSymbol() == sellAllSlot) { + double worth = getInventoryTotalWorth(player.getInventory()); + int amount = getInventorySellAmount(player.getInventory()); + double earningLimit = getEarningLimit(player); + if (sellFishingBag() && CustomFishingPlugin.get().getBagManager().isEnabled()) { + Inventory bag = CustomFishingPlugin.get().getBagManager().getOnlineBagInventory(player.getUniqueId()); + if (bag != null) { + worth += getInventoryTotalWorth(bag); + amount += getInventorySellAmount(bag); + } + } + Condition condition = new Condition(player, new HashMap<>(Map.of( + "{money}", String.format("%.2f", worth) + ,"{rest}", String.format("%.2f", (earningLimit - data.earnings)) + ,"{sold-item-amount}", String.valueOf(amount) + ))); + if (worth > 0) { + if (earningLimit != -1 && (earningLimit - data.earnings) < worth) { + // Can't earn more money + if (getSellAllLimitActions() != null) { + for (Action action : getSellAllLimitActions()) { + action.trigger(condition); + } + } + } else { + // Clear items and update earnings + clearWorthyItems(player.getInventory()); + if (sellFishingBag() && CustomFishingPlugin.get().getBagManager().isEnabled()) { + Inventory bag = CustomFishingPlugin.get().getBagManager().getOnlineBagInventory(player.getUniqueId()); + if (bag != null) { + clearWorthyItems(bag); + } + } + data.earnings += worth; + condition.insertArg("{rest}", String.format("%.2f", (earningLimit - data.earnings))); + if (getSellAllAllowActions() != null) { + for (Action action : getSellAllAllowActions()) { + action.trigger(condition); + } + } + } + } else { + // Nothing to sell + if (getSellAllDenyActions() != null) { + for (Action action : getSellAllDenyActions()) { action.trigger(condition); } } @@ -371,11 +454,6 @@ public class MarketManagerImpl implements MarketManager, Listener { plugin.getScheduler().runTaskSyncLater(gui::refresh, player.getLocation(), 50, TimeUnit.MILLISECONDS); } - /** - * Retrieves the current date as an integer in the format MMDD (e.g., September 21 as 0921). - * - * @return An integer representing the current date. - */ @Override public int getCachedDate() { return date; @@ -387,12 +465,6 @@ public class MarketManagerImpl implements MarketManager, Listener { return (calendar.get(Calendar.MONTH) +1) * 100 + calendar.get(Calendar.DATE); } - /** - * Calculates the price of an ItemStack based on custom data or a predefined price map. - * - * @param itemStack The ItemStack for which the price is calculated. - * @return The calculated price of the ItemStack. - */ @Override public double getItemPrice(ItemStack itemStack) { if (itemStack == null || itemStack.getType() == Material.AIR) @@ -415,21 +487,11 @@ public class MarketManagerImpl implements MarketManager, Listener { return priceMap.getOrDefault(itemID, 0d) * itemStack.getAmount(); } - /** - * Retrieves the formula used for calculating prices. - * - * @return The pricing formula as a string. - */ @Override public String getFormula() { return formula; } - /** - * Calculates the price based on a formula with provided variables. - * - * @return The calculated price based on the formula and provided variables. - */ @Override public double getFishPrice(Player player, Map vars) { String temp = PlaceholderManagerImpl.getInstance().parse(player, formula, vars); @@ -440,51 +502,31 @@ public class MarketManagerImpl implements MarketManager, Listener { return new ExpressionBuilder(temp).build().evaluate(); } - /** - * Gets the character representing the item slot in the MarketGUI. - * - * @return The item slot character. - */ @Override public char getItemSlot() { return itemSlot; } - /** - * Gets the character representing the function slot in the MarketGUI. - * - * @return The function slot character. - */ @Override - public char getFunctionSlot() { - return functionSlot; + public char getSellSlot() { + return sellSlot; + } + + @Override + public char getSellAllSlot() { + return sellAllSlot; } - /** - * Gets the layout of the MarketGUI as an array of strings. - * - * @return The layout of the MarketGUI. - */ @Override public String[] getLayout() { return layout; } - /** - * Gets the title of the MarketGUI. - * - * @return The title of the MarketGUI. - */ @Override public String getTitle() { return title; } - /** - * Gets the earning limit - * - * @return The earning limit - */ @Override public double getEarningLimit(Player player) { return new ExpressionBuilder( @@ -497,40 +539,92 @@ public class MarketManagerImpl implements MarketManager, Listener { .evaluate(); } - /** - * Gets the builder for the function icon representing the limit in the MarketGUI. - * - * @return The function icon builder for the limit. - */ - public BuildableItem getFunctionIconLimitBuilder() { - return functionIconLimitBuilder; + public BuildableItem getSellIconLimitBuilder() { + return sellIconLimitBuilder; } - /** - * Gets the builder for the function icon representing allow actions in the MarketGUI. - * - * @return The function icon builder for allow actions. - */ - public BuildableItem getFunctionIconAllowBuilder() { - return functionIconAllowBuilder; + public BuildableItem getSellIconAllowBuilder() { + return sellIconAllowBuilder; } - /** - * Gets the builder for the function icon representing deny actions in the MarketGUI. - * - * @return The function icon builder for deny actions. - */ - public BuildableItem getFunctionIconDenyBuilder() { - return functionIconDenyBuilder; + public BuildableItem getSellIconDenyBuilder() { + return sellIconDenyBuilder; + } + + public BuildableItem getSellAllIconAllowBuilder() { + return sellAllIconAllowBuilder; + } + + public BuildableItem getSellAllIconDenyBuilder() { + return sellAllIconDenyBuilder; + } + + public BuildableItem getSellAllIconLimitBuilder() { + return sellAllIconLimitBuilder; + } + + public Action[] getSellDenyActions() { + return sellDenyActions; + } + + public Action[] getSellAllowActions() { + return sellAllowActions; + } + + public Action[] getSellLimitActions() { + return sellLimitActions; + } + + public Action[] getSellAllDenyActions() { + return sellAllDenyActions; + } + + public Action[] getSellAllAllowActions() { + return sellAllAllowActions; + } + + public Action[] getSellAllLimitActions() { + return sellAllLimitActions; } - /** - * Is market enabled - * - * @return enable or not - */ @Override public boolean isEnable() { return enable; } + + @Override + public boolean sellFishingBag() { + return sellFishingBag; + } + + @Override + public double getInventoryTotalWorth(Inventory inventory) { + double total = 0d; + for (ItemStack itemStack : inventory.getStorageContents()) { + double price = getItemPrice(itemStack); + total += price; + } + return total; + } + + @Override + public int getInventorySellAmount(Inventory inventory) { + int amount = 0; + for (ItemStack itemStack : inventory.getStorageContents()) { + double price = getItemPrice(itemStack); + if (price > 0 && itemStack != null) { + amount += itemStack.getAmount(); + } + } + return amount; + } + + public void clearWorthyItems(Inventory inventory) { + for (ItemStack itemStack : inventory.getStorageContents()) { + double price = getItemPrice(itemStack); + if (price > 0 && itemStack != null) { + itemStack.setAmount(0); + } + } + } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java index 29f62e7b..5fcaa747 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java @@ -59,14 +59,14 @@ public class RequirementManagerImpl implements RequirementManager { public static Requirement[] mechanicRequirements; private final CustomFishingPluginImpl plugin; - private final HashMap requirementBuilderMap; + private final HashMap requirementFactoryMap; private final LinkedHashMap conditionalLootsMap; private final LinkedHashMap conditionalGamesMap; private final String EXPANSION_FOLDER = "expansions/requirement"; public RequirementManagerImpl(CustomFishingPluginImpl plugin) { this.plugin = plugin; - this.requirementBuilderMap = new HashMap<>(); + this.requirementFactoryMap = new HashMap<>(); this.conditionalLootsMap = new LinkedHashMap<>(); this.conditionalGamesMap = new LinkedHashMap<>(); this.registerInbuiltRequirements(); @@ -82,7 +82,7 @@ public class RequirementManagerImpl implements RequirementManager { } public void disable() { - this.requirementBuilderMap.clear(); + this.requirementFactoryMap.clear(); this.conditionalLootsMap.clear(); } @@ -130,8 +130,8 @@ public class RequirementManagerImpl implements RequirementManager { */ @Override public boolean registerRequirement(String type, RequirementFactory requirementFactory) { - if (this.requirementBuilderMap.containsKey(type)) return false; - this.requirementBuilderMap.put(type, requirementFactory); + if (this.requirementFactoryMap.containsKey(type)) return false; + this.requirementFactoryMap.put(type, requirementFactory); return true; } @@ -143,7 +143,7 @@ public class RequirementManagerImpl implements RequirementManager { */ @Override public boolean unregisterRequirement(String type) { - return this.requirementBuilderMap.remove(type) != null; + return this.requirementFactoryMap.remove(type) != null; } /** @@ -282,7 +282,7 @@ public class RequirementManagerImpl implements RequirementManager { @Override public boolean hasRequirement(String type) { - return requirementBuilderMap.containsKey(type); + return requirementFactoryMap.containsKey(type); } /** @@ -350,7 +350,7 @@ public class RequirementManagerImpl implements RequirementManager { @Override @Nullable public RequirementFactory getRequirementFactory(String type) { - return requirementBuilderMap.get(type); + return requirementFactoryMap.get(type); } private void registerTimeRequirement() { diff --git a/plugin/src/main/resources/contents/competition/default.yml b/plugin/src/main/resources/contents/competition/default.yml index 787b957b..a4a65d8d 100644 --- a/plugin/src/main/resources/contents/competition/default.yml +++ b/plugin/src/main/resources/contents/competition/default.yml @@ -90,6 +90,10 @@ weekend_competition: value: - 'You have joined the competition. Good luck!' + # Requirements for participating the competition + participate-requirements: {} + + # Rewards rewards: 1: command_action: diff --git a/plugin/src/main/resources/market.yml b/plugin/src/main/resources/market.yml index ee0f3acc..bf3c5983 100644 --- a/plugin/src/main/resources/market.yml +++ b/plugin/src/main/resources/market.yml @@ -34,8 +34,63 @@ item-slot: symbol: 'I' allow-items-with-no-price: true -# Functional icon -functional-icons: +# This is an icon that allows players to sell all the fish from their inventory and fishingbag +# You can enable it by putting the symbol into layout +sell-all-icons: + symbol: 'S' + # Should the fish in fishing bag be sold + fishingbag: true + allow-icon: + material: IRON_BLOCK + display: + name: '<#00CED1>Ship the fish' + lore: + - 'You will get {money}$ by selling the fish from inventory and bag' + action: + sound_action: + type: sound + value: + key: 'minecraft:block.amethyst_block.place' + source: 'player' + volume: 1 + pitch: 1 + message_action: + type: message + value: 'You earned {money}$ by selling the fish! You can still get {rest}$ from market today' + command_action: + type: command + value: 'money give {player} {money}' + deny-icon: + material: REDSTONE_BLOCK + display: + name: 'Denied trade' + lore: + - 'Nothing to sell!' + action: + sound_action: + type: sound + value: + key: 'minecraft:entity.villager.no' + source: 'player' + volume: 1 + pitch: 1 + limit-icon: + material: REDSTONE_BLOCK + display: + name: 'Denied trade' + lore: + - 'The worth of items exceeds the money that can be earned for the rest of today!' + action: + sound_action: + type: sound + value: + key: 'minecraft:block.anvil.land' + source: 'player' + volume: 1 + pitch: 1 + +# Sell icon +sell-icons: symbol: 'B' allow-icon: material: IRON_BLOCK