From 4c38dda7d3df0e8e9aaebd968a7393f30712bc6f Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 10 Sep 2023 02:31:20 +0800 Subject: [PATCH] category & statistics --- .../api/manager/LootManager.java | 5 + .../api/mechanic/condition/Condition.java | 25 ++-- .../api/mechanic/game/GameGroup.java | 2 +- .../api/mechanic/statistic/Statistics.java | 24 ++-- .../command/CommandManagerImpl.java | 39 +++++- .../command/sub/CompetitionCommand.java | 1 + .../command/sub/ItemCommand.java | 3 + .../command/sub/StatisticsCommand.java | 117 ++++++++++++++++++ .../compatibility/papi/CompetitionPapi.java | 11 +- .../compatibility/papi/StatisticsPapi.java | 20 ++- .../mechanic/competition/Competition.java | 2 +- .../mechanic/fishing/HookCheckTimerTask.java | 1 + .../mechanic/loot/LootManagerImpl.java | 10 ++ .../requirement/RequirementManagerImpl.java | 49 +++++++- .../customfishing/setting/Locale.java | 8 +- .../resources/contents/blocks/default.yml | 2 + .../resources/contents/categories/default.yml | 51 +++++++- .../contents/competitions/default.yml | 4 +- .../main/resources/contents/loots/default.yml | 9 ++ .../main/resources/contents/mobs/default.yml | 4 + .../main/resources/contents/rods/default.yml | 3 +- .../src/main/resources/messages/english.yml | 7 +- 22 files changed, 346 insertions(+), 51 deletions(-) diff --git a/api/src/main/java/net/momirealms/customfishing/api/manager/LootManager.java b/api/src/main/java/net/momirealms/customfishing/api/manager/LootManager.java index 13784a58..7202017a 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/manager/LootManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/manager/LootManager.java @@ -20,6 +20,7 @@ package net.momirealms.customfishing.api.manager; import net.momirealms.customfishing.api.mechanic.loot.Loot; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.List; public interface LootManager { @@ -27,4 +28,8 @@ public interface LootManager { @Nullable List getLootGroup(String key); @Nullable Loot getLoot(String key); + + Collection getAllLootKeys(); + + Collection getAllLoots(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/Condition.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/Condition.java index da8e37c1..5eedd3a3 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/Condition.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/Condition.java @@ -27,27 +27,30 @@ import java.util.Map; public class Condition { - protected @NotNull Location location; - protected final @NotNull Player player; + protected Location location; + protected final Player player; protected final @NotNull Map args; - public Condition(Player player) { + public Condition(@NotNull Player player) { this(player.getLocation(), player, new HashMap<>()); } - public Condition(Player player, Map args) { + public Condition(@NotNull Player player, @NotNull Map args) { this(player.getLocation(), player, args); } - public Condition(@NotNull Location location, @NotNull Player player, @NotNull Map args) { + public Condition(Location location, Player player, @NotNull Map args) { this.location = location; this.player = player; this.args = args; - this.args.put("{player}", player.getName()); - this.args.put("{x}", String.valueOf(location.getX())); - this.args.put("{y}", String.valueOf(location.getY())); - this.args.put("{z}", String.valueOf(location.getZ())); - this.args.put("{world}", location.getWorld().getName()); + if (player != null) + this.args.put("{player}", player.getName()); + if (location != null) { + this.args.put("{x}", String.valueOf(location.getX())); + this.args.put("{y}", String.valueOf(location.getY())); + this.args.put("{z}", String.valueOf(location.getZ())); + this.args.put("{world}", location.getWorld().getName()); + } } public void setLocation(@NotNull Location location) { @@ -58,12 +61,10 @@ public class Condition { this.args.put("{world}", location.getWorld().getName()); } - @NotNull public Location getLocation() { return location; } - @NotNull public Player getPlayer() { return player; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameGroup.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameGroup.java index 0c3a1910..2c31ff0e 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameGroup.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameGroup.java @@ -71,7 +71,7 @@ public class GameGroup implements GameConfig { } GameSettings settings = new GameSettings( ThreadLocalRandom.current().nextInt(minTime, maxTime + 1), - (int) (ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) + effect.getDifficultyModifier()) + (int) Math.min(100, Math.max(1, ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) + effect.getDifficultyModifier())) ); return Pair.of(gameInstance, settings); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/statistic/Statistics.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/statistic/Statistics.java index a2c72056..550e28e7 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/statistic/Statistics.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/statistic/Statistics.java @@ -20,6 +20,7 @@ package net.momirealms.customfishing.api.mechanic.statistic; import com.google.gson.annotations.SerializedName; import net.momirealms.customfishing.api.data.StatisticData; import net.momirealms.customfishing.api.mechanic.action.Action; +import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation; import net.momirealms.customfishing.api.mechanic.loot.Loot; @@ -38,9 +39,9 @@ public class Statistics { this.total = statisticMap.values().stream().mapToInt(Integer::intValue).sum(); } - public synchronized void addLootAmount(Loot loot, FishingPreparation fishingPreparation, int amount) { + public synchronized void addLootAmount(Loot loot, Condition condition, int amount) { if (amount == 1) { - addSingleLootAmount(loot, fishingPreparation); + addSingleLootAmount(loot, condition); return; } Integer previous = statisticMap.get(loot.getID()); @@ -48,23 +49,23 @@ public class Statistics { int after = previous + amount; statisticMap.put(loot.getID(), after); total += amount; - doSuccessTimesAction(previous, after, fishingPreparation, loot); + doSuccessTimesAction(previous, after, condition, loot); } - private void doSuccessTimesAction(Integer previous, int after, FishingPreparation fishingPreparation, Loot loot) { + private void doSuccessTimesAction(Integer previous, int after, Condition condition, Loot loot) { HashMap actionMap = loot.getSuccessTimesActionMap(); if (actionMap != null) { for (Map.Entry entry : actionMap.entrySet()) { if (entry.getKey() > previous && entry.getKey() <= after) { for (Action action : entry.getValue()) { - action.trigger(fishingPreparation); + action.trigger(condition); } } } } } - private void addSingleLootAmount(Loot loot, FishingPreparation fishingPreparation) { + private void addSingleLootAmount(Loot loot, Condition condition) { Integer previous = statisticMap.get(loot.getID()); if (previous == null) previous = 0; int after = previous + 1; @@ -73,7 +74,7 @@ public class Statistics { Action[] actions = loot.getSuccessTimesActionMap().get(after); if (actions != null) for (Action action : actions) { - action.trigger(fishingPreparation); + action.trigger(condition); } } @@ -82,12 +83,9 @@ public class Statistics { return amount == null ? 0 : amount; } - public boolean hasFished(String key) { - return statisticMap.containsKey(key); - } - public void reset() { statisticMap.clear(); + total = 0; } public Map getStatisticMap() { @@ -95,6 +93,10 @@ public class Statistics { } public void setData(String key, int value) { + if (value <= 0) { + statisticMap.remove(key); + return; + } statisticMap.put(key, value); } diff --git a/plugin/src/main/java/net/momirealms/customfishing/command/CommandManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/command/CommandManagerImpl.java index 0f305c0e..5464397e 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/command/CommandManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/command/CommandManagerImpl.java @@ -21,15 +21,16 @@ import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPIBukkitConfig; import dev.jorel.commandapi.CommandAPICommand; import dev.jorel.commandapi.CommandPermission; +import dev.jorel.commandapi.arguments.EntitySelectorArgument; import net.momirealms.customfishing.CustomFishingPluginImpl; import net.momirealms.customfishing.adventure.AdventureManagerImpl; import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.manager.CommandManager; -import net.momirealms.customfishing.command.sub.CompetitionCommand; -import net.momirealms.customfishing.command.sub.DebugCommand; -import net.momirealms.customfishing.command.sub.FishingBagCommand; -import net.momirealms.customfishing.command.sub.ItemCommand; +import net.momirealms.customfishing.command.sub.*; import net.momirealms.customfishing.setting.Locale; +import org.bukkit.entity.Player; + +import java.util.Collection; public class CommandManagerImpl implements CommandManager { @@ -47,9 +48,12 @@ public class CommandManagerImpl implements CommandManager { .withPermission(CommandPermission.OP) .withSubcommands( getReloadCommand(), + getMarketCommand(), + getAboutCommand(), CompetitionCommand.INSTANCE.getCompetitionCommand(), ItemCommand.INSTANCE.getItemCommand(), - DebugCommand.INSTANCE.getDebugCommand() + DebugCommand.INSTANCE.getDebugCommand(), + StatisticsCommand.INSTANCE.getStatisticsCommand() ) .register(); @@ -73,4 +77,29 @@ public class CommandManagerImpl implements CommandManager { AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, Locale.MSG_Reload.replace("{time}", String.valueOf(System.currentTimeMillis()-time))); }); } + + @SuppressWarnings("unchecked") + private CommandAPICommand getMarketCommand() { + return new CommandAPICommand("market").withSubcommand( + new CommandAPICommand("open") + .withArguments(new EntitySelectorArgument.ManyPlayers("player")) + .executes((sender, args) -> { + Collection players = (Collection) args.get("player"); + assert players != null; + for (Player player : players) { + plugin.getMarketManager().openMarketGUI(player); + AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, Locale.MSG_Market_GUI_Open.replace("{player}", player.getName())); + } + })); + } + + private CommandAPICommand getAboutCommand() { + return new CommandAPICommand("about").executes((sender, args) -> { + AdventureManagerImpl.getInstance().sendMessage(sender, "<#00BFFF>\uD83C\uDFA3 CustomFishing - <#87CEEB>" + CustomFishingPlugin.getInstance().getVersionManager().getPluginVersion()); + AdventureManagerImpl.getInstance().sendMessage(sender, "<#B0C4DE>A fishing plugin that provides innovative mechanics and powerful loot system"); + AdventureManagerImpl.getInstance().sendMessage(sender, "<#DA70D6>\uD83E\uDDEA Author: <#FFC0CB>XiaoMoMi"); + AdventureManagerImpl.getInstance().sendMessage(sender, "<#FF7F50>\uD83D\uDD25 Contributors: <#FFA07A>0ft3n, <#FFA07A>Peng_Lx, <#FFA07A>Masaki, <#FFA07A>g2213swo"); + AdventureManagerImpl.getInstance().sendMessage(sender, "<#FFD700>⭐ Document <#A9A9A9>| <#FAFAD2>⛏ Github <#A9A9A9>| <#48D1CC>\uD83D\uDD14 Polymart"); + }); + } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java b/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java index f71683fa..366bf365 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java +++ b/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java @@ -55,6 +55,7 @@ public class CompetitionCommand { if (Config.redisRanking) command.withOptionalArguments(new StringArgument("-allservers")); command.executes((sender, args) -> { String id = (String) args.get(0); + assert id != null; if (!allCompetitions.contains(id)) { AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, Locale.MSG_Competition_Not_Exist.replace("{id}", id)); return; diff --git a/plugin/src/main/java/net/momirealms/customfishing/command/sub/ItemCommand.java b/plugin/src/main/java/net/momirealms/customfishing/command/sub/ItemCommand.java index 8e0559de..c7bcf557 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/command/sub/ItemCommand.java +++ b/plugin/src/main/java/net/momirealms/customfishing/command/sub/ItemCommand.java @@ -76,6 +76,7 @@ public class ItemCommand { .withOptionalArguments(new IntegerArgument("amount", 1)) .executesPlayer((player, args) -> { String id = (String) args.get("id"); + assert id != null; int amount = (int) args.getOrDefault("amount", 1); ItemStack item = CustomFishingPlugin.get().getItemManager().build(player, namespace, id, new Condition(player).getArgs()); if (item != null) { @@ -87,6 +88,7 @@ public class ItemCommand { }); } + @SuppressWarnings("unchecked") private CommandAPICommand giveCommand(String namespace) { return new CommandAPICommand("give") .withArguments(new EntitySelectorArgument.ManyPlayers("player")) @@ -101,6 +103,7 @@ public class ItemCommand { int amount = (int) args.getOrDefault("amount", 1); BuildableItem buildableItem = CustomFishingPlugin.get().getItemManager().getBuildableItem(namespace, id); if (buildableItem != null) { + assert players != null; for (Player player : players) { ItemStack item = CustomFishingPlugin.get().getItemManager().build(player, namespace, id, new Condition(player).getArgs()); int actual = ItemManagerImpl.giveCertainAmountOfItem(player, item, amount); diff --git a/plugin/src/main/java/net/momirealms/customfishing/command/sub/StatisticsCommand.java b/plugin/src/main/java/net/momirealms/customfishing/command/sub/StatisticsCommand.java index 8f24f203..da076172 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/command/sub/StatisticsCommand.java +++ b/plugin/src/main/java/net/momirealms/customfishing/command/sub/StatisticsCommand.java @@ -1,4 +1,121 @@ package net.momirealms.customfishing.command.sub; +import dev.jorel.commandapi.CommandAPICommand; +import dev.jorel.commandapi.arguments.*; +import net.momirealms.customfishing.adventure.AdventureManagerImpl; +import net.momirealms.customfishing.api.CustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.condition.Condition; +import net.momirealms.customfishing.api.mechanic.loot.Loot; +import net.momirealms.customfishing.api.mechanic.statistic.Statistics; +import net.momirealms.customfishing.api.util.LogUtils; +import org.bukkit.entity.Player; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; + public class StatisticsCommand { + + public static StatisticsCommand INSTANCE = new StatisticsCommand(); + + private Collection loots = new HashSet<>(); + + public CommandAPICommand getStatisticsCommand() { + loots = CustomFishingPlugin.get().getLootManager().getAllLoots().stream().filter(it -> !it.disableStats()).map(Loot::getID).toList(); + return new CommandAPICommand("statistics") + .withSubcommands( + getSetCommand(), + getResetCommand(), + getQueryCommand(), + getAddCommand() + ); + } + + @SuppressWarnings("unchecked") + private CommandAPICommand getSetCommand() { + return new CommandAPICommand("set") + .withArguments(new EntitySelectorArgument.ManyPlayers("player")) + .withArguments(new StringArgument("id").replaceSuggestions(ArgumentSuggestions.strings(loots))) + .withArguments(new IntegerArgument("amount", 0)) + .executes((sender, args) -> { + Collection players = (Collection) args.get("player"); + String id = (String) args.get("id"); + int amount = (int) args.getOrDefault("amount", 0); + assert players != null; + Loot loot = CustomFishingPlugin.get().getLootManager().getLoot(id); + for (Player player : players) { + Statistics statistics = CustomFishingPlugin.get().getStatisticsManager().getStatistics(player.getUniqueId()); + if (statistics != null) { + if (loot != null) + statistics.setData(id, amount); + else + throw new RuntimeException("Loot " + id + " doesn't exist."); + } else { + LogUtils.warn("Player " + player.getName() + "'s statistics data has not been loaded."); + } + } + }); + } + + @SuppressWarnings("unchecked") + private CommandAPICommand getResetCommand() { + return new CommandAPICommand("reset") + .withArguments(new EntitySelectorArgument.ManyPlayers("player")) + .executes((sender, args) -> { + Collection players = (Collection) args.get("player"); + assert players != null; + for (Player player : players) { + Statistics statistics = CustomFishingPlugin.get().getStatisticsManager().getStatistics(player.getUniqueId()); + if (statistics != null) { + statistics.reset(); + } else { + LogUtils.warn("Player " + player.getName() + "'s statistics data has not been loaded."); + } + } + }); + } + + @SuppressWarnings("unchecked") + private CommandAPICommand getAddCommand() { + return new CommandAPICommand("add") + .withArguments(new EntitySelectorArgument.ManyPlayers("player")) + .withArguments(new StringArgument("id").replaceSuggestions(ArgumentSuggestions.strings(loots))) + .withArguments(new IntegerArgument("amount", 0)) + .executes((sender, args) -> { + Collection players = (Collection) args.get("player"); + String id = (String) args.get("id"); + int amount = (int) args.getOrDefault("amount", 0); + assert players != null; + Loot loot = CustomFishingPlugin.get().getLootManager().getLoot(id); + for (Player player : players) { + Statistics statistics = CustomFishingPlugin.get().getStatisticsManager().getStatistics(player.getUniqueId()); + if (statistics != null) { + if (loot != null) + statistics.addLootAmount(loot, new Condition(player), amount); + else + throw new RuntimeException("Loot " + id + " doesn't exist."); + } else { + LogUtils.warn("Player " + player.getName() + "'s statistics data has not been loaded."); + } + } + }); + } + + private CommandAPICommand getQueryCommand() { + return new CommandAPICommand("query") + .withArguments(new PlayerArgument("player")) + .executes((sender, args) -> { + Player player = (Player) args.get("player"); + assert player != null; + Statistics statistics = CustomFishingPlugin.get().getStatisticsManager().getStatistics(player.getUniqueId()); + if (statistics != null) { + var adventure = AdventureManagerImpl.getInstance(); + for (Map.Entry entry : statistics.getStatisticMap().entrySet()) { + adventure.sendMessage(sender, entry.getKey() + ": " + entry.getValue()); + } + } else { + throw new RuntimeException("Player " + player.getName() + "'s statistics data has not been loaded."); + } + }); + } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CompetitionPapi.java b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CompetitionPapi.java index fc2f8ced..d9ebd025 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CompetitionPapi.java +++ b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CompetitionPapi.java @@ -25,6 +25,8 @@ import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Optional; + public class CompetitionPapi extends PlaceholderExpansion { private final CustomFishingPlugin plugin; @@ -70,9 +72,6 @@ public class CompetitionPapi extends PlaceholderExpansion { case "nextseconds" -> { return String.valueOf(plugin.getCompetitionManager().getNextCompetitionSeconds()); } - case "nextminutes" -> { - return String.valueOf(plugin.getCompetitionManager().getNextCompetitionSeconds() / 60); - } case "nextsecond" -> { return plugin.getCompetitionManager().getNextCompetitionSeconds() % 60 + Locale.FORMAT_Second; } @@ -128,7 +127,7 @@ public class CompetitionPapi extends PlaceholderExpansion { case "score" -> { FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); if (competition == null) return ""; - if (split[1].equals("")) { + if (split.length == 1) { return String.format("%.2f", competition.getRanking().getPlayerScore(player.getName())); } else { return String.format("%.2f", competition.getRanking().getScoreAt(Integer.parseInt(split[1]))); @@ -137,8 +136,8 @@ public class CompetitionPapi extends PlaceholderExpansion { case "player" -> { FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); if (competition == null) return ""; - if (split[1].equals("")) return "Invalid format"; - return competition.getRanking().getPlayerAt(Integer.parseInt(split[1])); + if (split.length == 1) return "Invalid format"; + return Optional.ofNullable(competition.getRanking().getPlayerAt(Integer.parseInt(split[1]))).orElse(""); } } return "null"; diff --git a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/StatisticsPapi.java b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/StatisticsPapi.java index 1ccaa3e7..28221e43 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/StatisticsPapi.java +++ b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/StatisticsPapi.java @@ -72,27 +72,35 @@ public class StatisticsPapi extends PlaceholderExpansion { return String.valueOf(statistics.getTotalCatchAmount()); } - String[] split = params.split("_"); + String[] split = params.split("_", 2); switch (split[0]) { case "hascaught" -> { + if (split.length == 1) return "Invalid format"; return String.valueOf(statistics.getLootAmount(split[1]) != 0); } + case "amount" -> { + if (split.length == 1) return "Invalid format"; + return String.valueOf(statistics.getLootAmount(split[1])); + } case "category" -> { - List category = plugin.getStatisticsManager().getCategory(split[2]); - if (category == null) return "0"; - if (split[1].equals("total")) { + if (split.length == 1) return "Invalid format"; + String[] categorySplit = split[1].split("_", 2); + if (categorySplit.length == 1) return "Invalid format"; + List category = plugin.getStatisticsManager().getCategory(categorySplit[1]); + if (category == null) return "Category Not Exists"; + if (categorySplit[0].equals("total")) { int total = 0; for (String loot : category) { total += statistics.getLootAmount(loot); } return String.valueOf(total); - } else if (split[1].equals("progress")) { + } else if (categorySplit[0].equals("progress")) { int size = category.size(); int unlocked = 0; for (String loot : category) { if (statistics.getLootAmount(loot) != 0) unlocked++; } - double percent = (double) unlocked / size; + double percent = ((double) unlocked * 100) / size; String progress = String.format("%.1f", percent); return progress.equals("100.0") ? "100" : progress; } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/Competition.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/Competition.java index 9560e47e..c5703e6a 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/Competition.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/Competition.java @@ -116,7 +116,7 @@ public class Competition implements FishingCompetition { publicPlaceholders.put("{hour}", remainingTime < 3600 ? "" : (remainingTime / 3600) + Locale.FORMAT_Hour); publicPlaceholders.put("{minute}", remainingTime < 60 ? "" : (remainingTime % 3600) / 60 + Locale.FORMAT_Minute); publicPlaceholders.put("{second}", remainingTime == 0 ? "" : remainingTime % 60 + Locale.FORMAT_Second); - publicPlaceholders.put("{seconds}", remainingTime + Locale.FORMAT_Second); + publicPlaceholders.put("{seconds}", String.valueOf(remainingTime)); } @Override 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 7ec052de..366c4541 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 @@ -128,6 +128,7 @@ public class HookCheckTimerTask implements Runnable { if (fishHook.isInWater()) { this.fishingPreparation.setLocation(fishHook.getLocation()); this.fishingPreparation.insertArg("{lava}", "false"); + this.fishingPreparation.insertArg("{open-water}", String.valueOf(fishHook.isInOpenWater())); this.fishingPreparation.triggerActions(ActionTrigger.LAND); FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.WATER); Bukkit.getPluginManager().callEvent(event); 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 6331f1e6..7de75d42 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 @@ -95,6 +95,16 @@ public class LootManagerImpl implements LootManager { return lootMap.get(key); } + @Override + public Collection getAllLootKeys() { + return lootMap.keySet(); + } + + @Override + public Collection getAllLoots() { + return lootMap.values(); + } + private void loadSingleFile(File file, String namespace) { YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file); for (Map.Entry entry : yaml.getValues(false).entrySet()) { 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 b1137a72..e8819c99 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 @@ -32,7 +32,10 @@ import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.compatibility.papi.ParseUtils; import net.momirealms.customfishing.util.ClassUtils; import net.momirealms.customfishing.util.ConfigUtils; +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.MemorySection; import org.bukkit.configuration.file.YamlConfiguration; @@ -111,7 +114,7 @@ public class RequirementManagerImpl implements RequirementManager { this.registerWorldRequirement(); this.registerWeatherRequirement(); this.registerSeasonRequirement(); - this.registerInLavaRequirement(); + this.registerLavaFishingRequirement(); this.registerRodRequirement(); this.registerBaitRequirement(); this.registerCompareRequirement(); @@ -119,6 +122,8 @@ public class RequirementManagerImpl implements RequirementManager { this.registerOrRequirement(); this.registerLevelRequirement(); this.registerRandomRequirement(); + this.registerIceFishingRequirement(); + this.registerOpenWaterRequirement(); } public ConditionalLoots getConditionalLoots(ConfigurationSection section) { @@ -301,7 +306,7 @@ public class RequirementManagerImpl implements RequirementManager { }); } - private void registerInLavaRequirement() { + private void registerLavaFishingRequirement() { registerRequirement("lava-fishing", (args, actions, advanced) -> { boolean inLava = (boolean) args; return condition -> { @@ -314,6 +319,46 @@ public class RequirementManagerImpl implements RequirementManager { }); } + private void registerOpenWaterRequirement() { + registerRequirement("open-water", (args, actions, advanced) -> { + boolean inLava = (boolean) args; + return condition -> { + String current = condition.getArgs().get("{open-water}"); + if (current.equals(String.valueOf(inLava))) + return true; + if (advanced) triggerActions(actions, condition); + return false; + }; + }); + } + + private void registerIceFishingRequirement() { + registerRequirement("ice-fishing", (args, actions, advanced) -> { + boolean iceFishing = (boolean) args; + return condition -> { + Location location = condition.getLocation(); + int water = 0; + int ice = 0; + for (int i = -2; i <= 2; i++) { + for (int j = -1; j <= 2; j++) { + for (int k = -2; k <= 2; k++) { + Block block = location.clone().add(i, j, k).getBlock(); + Material material = block.getType(); + switch (material) { + case ICE -> ice++; + case WATER -> water++; + } + } + } + } + if ((ice >= 16 && water >= 25) == iceFishing) + return true; + if (advanced) triggerActions(actions, condition); + return false; + }; + }); + } + private void registerLevelRequirement() { registerRequirement("level", (args, actions, advanced) -> { int level = (int) args; diff --git a/plugin/src/main/java/net/momirealms/customfishing/setting/Locale.java b/plugin/src/main/java/net/momirealms/customfishing/setting/Locale.java index f66d9ece..4e399bf5 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/setting/Locale.java +++ b/plugin/src/main/java/net/momirealms/customfishing/setting/Locale.java @@ -51,11 +51,12 @@ public class Locale { public static String MSG_Give_Item; public static String MSG_Never_Played; public static String MSG_Unsafe_Modification; + public static String MSG_Data_Not_Loaded; + public static String MSG_Market_GUI_Open; public static String FORMAT_Day; public static String FORMAT_Hour; public static String FORMAT_Minute; public static String FORMAT_Second; - public static String MSG_Data_Not_Loaded; public static void load() { try { @@ -101,6 +102,11 @@ public class Locale { MSG_Never_Played = msgSection.getString("never-played"); MSG_Unsafe_Modification = msgSection.getString("unsafe-modification"); MSG_Data_Not_Loaded = msgSection.getString("data-not-loaded"); + MSG_Market_GUI_Open = msgSection.getString("open-market-gui"); + FORMAT_Day = msgSection.getString("format-day"); + FORMAT_Hour = msgSection.getString("format-hour"); + FORMAT_Minute = msgSection.getString("format-minute"); + FORMAT_Second = msgSection.getString("format-second"); } } } diff --git a/plugin/src/main/resources/contents/blocks/default.yml b/plugin/src/main/resources/contents/blocks/default.yml index 66afd252..ded045ad 100644 --- a/plugin/src/main/resources/contents/blocks/default.yml +++ b/plugin/src/main/resources/contents/blocks/default.yml @@ -6,6 +6,7 @@ apple_crate: show-in-fishfinder: false + disable-stat: true nick: Apple Crate block: barrel vector: @@ -48,6 +49,7 @@ apple_crate: chance: 0.8 carrot_crate: show-in-fishfinder: false + disable-stat: true nick: Carrot Crate block: barrel vector: diff --git a/plugin/src/main/resources/contents/categories/default.yml b/plugin/src/main/resources/contents/categories/default.yml index 9155e9ed..073e2686 100644 --- a/plugin/src/main/resources/contents/categories/default.yml +++ b/plugin/src/main/resources/contents/categories/default.yml @@ -54,4 +54,53 @@ golden_star_fish: - red_snapper_fish_golden_star - salmon_void_fish_golden_star - woodskip_fish_golden_star - - sturgeon_fish_golden_star \ No newline at end of file + - sturgeon_fish_golden_star + +river_fish: + - gold_fish + - gold_fish_silver_star + - gold_fish_golden_star + - perch_fish + - perch_fish_silver_star + - perch_fish_golden_star + - mullet_fish + - mullet_fish_silver_star + - mullet_fish_golden_star + - carp_fish + - carp_fish_silver_star + - carp_fish_golden_star + - cat_fish + - cat_fish_silver_star + - cat_fish_silver_star + - woodskip_fish + - woodskip_fish_silver_star + - woodskip_fish_golden_star + - sturgeon_fish + - sturgeon_fish_silver_star + - sturgeon_fish_golden_star + +ocean_fish: + - tuna_fish + - tuna_fish_silver_star + - tuna_fish_golden_star + - pike_fish + - pike_fish_silver_star + - pike_fish_golden_star + - sardine_fish + - sardine_fish_silver_star + - sardine_fish_golden_star + - octopus + - octopus_silver_star + - octopus_golden_star + - sunfish + - sunfish_silver_star + - sunfish_golden_star + - red_snapper_fish + - red_snapper_fish_silver_star + - red_snapper_fish_golden_star + - blue_jellyfish + - blue_jellyfish_silver_star + - blue_jellyfish_golden_star + - pink_jellyfish + - pink_jellyfish_silver_star + - pink_jellyfish_golden_star \ No newline at end of file diff --git a/plugin/src/main/resources/contents/competitions/default.yml b/plugin/src/main/resources/contents/competitions/default.yml index e1975fdd..787b957b 100644 --- a/plugin/src/main/resources/contents/competitions/default.yml +++ b/plugin/src/main/resources/contents/competitions/default.yml @@ -40,7 +40,7 @@ weekend_competition: color: WHITE overlay: PROGRESS text: - - '[<#87CEFA>🎣] Time Left: <#E6E6FA>{seconds} | Your Rank: <#E6E6FA>{rank} | No.1 Player: <#E6E6FA>{1_player}' + - '[<#87CEFA>🎣] Time Left: <#E6E6FA>{seconds}s | Your Rank: <#E6E6FA>{rank} | No.1 Player: <#E6E6FA>{1_player}' - '[<#87CEFA>🎣] Time Left: <#E6E6FA>{minute}{second} | Your Score: <#E6E6FA>{score} | No.1 Score: <#E6E6FA>{1_score}' - '[<#87CEFA>🎣] Time Left: <#E6E6FA>{minute}{second} | Winning condition: <#E6E6FA>{goal}' refresh-rate: 20 @@ -50,7 +50,7 @@ weekend_competition: actionbar: enable: false text: - - 'Time Left: <#E6E6FA>{seconds} | Your Rank: <#E6E6FA>{rank} | No.1 Player: <#E6E6FA>{1_player}' + - 'Time Left: <#E6E6FA>{seconds}s | Your Rank: <#E6E6FA>{rank} | No.1 Player: <#E6E6FA>{1_player}' - 'Time Left: <#E6E6FA>{minute}{second} | Your Score: <#E6E6FA>{score} | No.1 Score: <#E6E6FA>{1_score}' - 'Time Left: <#E6E6FA>{minute}{second} | Winning condition: <#E6E6FA>{goal}' refresh-rate: 5 diff --git a/plugin/src/main/resources/contents/loots/default.yml b/plugin/src/main/resources/contents/loots/default.yml index d66699af..4a95e40d 100644 --- a/plugin/src/main/resources/contents/loots/default.yml +++ b/plugin/src/main/resources/contents/loots/default.yml @@ -7,6 +7,7 @@ # Vanilla loots settings vanilla: show-in-fishfinder: false + disable-stat: true # Some rubbish stick: tag: false @@ -118,6 +119,8 @@ sharpness_book: tag: false material: enchanted_book group: enchantments + show-in-fishfinder: false + disable-stat: true random-stored-enchantments: lv5: enchant: minecraft:sharpness @@ -143,6 +146,8 @@ efficiency_book: tag: false material: enchanted_book group: enchantments + show-in-fishfinder: false + disable-stat: true random-stored-enchantments: lv5: enchant: minecraft:efficiency @@ -168,6 +173,8 @@ unbreaking_book: tag: false material: enchanted_book group: enchantments + show-in-fishfinder: false + disable-stat: true random-stored-enchantments: lv3: enchant: minecraft:unbreaking @@ -185,6 +192,8 @@ protection_book: tag: false material: enchanted_book group: enchantments + show-in-fishfinder: false + disable-stat: true random-stored-enchantments: lv4: enchant: minecraft:protection diff --git a/plugin/src/main/resources/contents/mobs/default.yml b/plugin/src/main/resources/contents/mobs/default.yml index 34fbe500..9bd0f359 100644 --- a/plugin/src/main/resources/contents/mobs/default.yml +++ b/plugin/src/main/resources/contents/mobs/default.yml @@ -6,6 +6,7 @@ skeleton: show-in-fishfinder: false + disable-stat: true mob: skeleton nick: Skeleton vector: @@ -14,6 +15,7 @@ skeleton: wither_skeleton: show-in-fishfinder: false + disable-stat: true mob: wither_skeleton nick: Wither Skeleton vector: @@ -22,6 +24,7 @@ wither_skeleton: magma_cube: show-in-fishfinder: false + disable-stat: true mob: magma_cube nick: Magma Cube vector: @@ -30,6 +33,7 @@ magma_cube: skeletalknight: show-in-fishfinder: false + disable-stat: true mob: MythicMobs:SkeletalKnight nick: Skeletal Knight vector: diff --git a/plugin/src/main/resources/contents/rods/default.yml b/plugin/src/main/resources/contents/rods/default.yml index a54e316e..5602387e 100644 --- a/plugin/src/main/resources/contents/rods/default.yml +++ b/plugin/src/main/resources/contents/rods/default.yml @@ -101,8 +101,7 @@ magical_rod: - ' - consuming experience levels upon each cast.' - '' - '<#FFD700>Effects:' - - ' - Increase the chance of getting an' - - ' enchantment book from fishing.' + - ' - Get an enchantment book from fishing.' - '' - '<#CD5C5C>Requirements:' - ' - 1x book bait' diff --git a/plugin/src/main/resources/messages/english.yml b/plugin/src/main/resources/messages/english.yml index 228f5927..56a9e8b0 100644 --- a/plugin/src/main/resources/messages/english.yml +++ b/plugin/src/main/resources/messages/english.yml @@ -24,4 +24,9 @@ messages: goal-total-score: 'Total score of the fish caught' unsafe-modification: 'You can''t edit a player''s fishing bag when the player is playing on another server that connected to the database' never-played: 'That player has never played the server. You can''t edit a non existent player''s fishing bag.' - data-not-loaded: 'Your data has not been loaded yet. Try rejoining the server. If the problem still occurs, contact the server administrator.' \ No newline at end of file + data-not-loaded: 'Your data has not been loaded yet. Try rejoining the server. If the problem still occurs, contact the server administrator.' + open-market-gui: 'Successfully opened the market gui for {player}' + format-day: 'd' + format-hour: 'h' + format-minute: 'm' + format-second: 's'