From 95374d221e4922fdeef807a77454b61620cb4b39 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 21 Sep 2023 22:27:03 +0800 Subject: [PATCH] comments --- .../api/data/DataStorageInterface.java | 53 ++++ .../api/data/LegacyDataStorageInterface.java | 6 + .../customfishing/api/data/PlayerData.java | 4 + .../api/data/user/OfflineUser.java | 37 +++ .../api/data/user/OnlineUser.java | 6 + .../api/event/FishHookLandEvent.java | 29 +- .../api/event/FishingResultEvent.java | 38 ++- .../api/event/LavaFishingEvent.java | 23 ++ .../customfishing/api/event/RodCastEvent.java | 30 ++ .../api/event/TotemActivateEvent.java | 68 ++++- .../api/integration/EnchantmentInterface.java | 9 + .../api/integration/LevelInterface.java | 15 + .../api/integration/SeasonInterface.java | 9 +- .../api/mechanic/GlobalSettings.java | 46 +++ .../api/mechanic/TempFishingState.java | 35 ++- .../api/mechanic/competition/Ranking.java | 55 ++++ .../api/mechanic/condition/Condition.java | 59 ++++ .../condition/FishingPreparation.java | 27 ++ .../api/mechanic/effect/Effect.java | 2 +- .../api/mechanic/effect/FishingEffect.java | 170 +++++++++++ .../api/mechanic/loot/CFLoot.java | 154 +++++++++- .../customfishing/api/mechanic/loot/Loot.java | 69 +++-- .../api/mechanic/loot/WeightModifier.java | 1 + .../api/mechanic/market/MarketGUIHolder.java | 14 + .../api/mechanic/requirement/Requirement.java | 6 + .../requirement/RequirementExpansion.java | 24 ++ .../requirement/RequirementFactory.java | 19 +- .../api/mechanic/statistic/Statistics.java | 56 +++- .../api/mechanic/totem/TotemConfig.java | 197 +++++++++++++ .../api/mechanic/totem/TotemModel.java | 277 ++++++++++++++++++ .../api/mechanic/totem/TotemParticle.java | 16 + .../api/mechanic/totem/block/TotemBlock.java | 118 ++++++++ .../totem/block/property/AxisImpl.java | 71 +++++ .../totem/block/property/FaceImpl.java | 86 ++++++ .../totem/block/property/HalfImpl.java | 74 +++++ .../block/property/TotemBlockProperty.java | 50 ++++ .../totem/block/type/EndWithType.java | 56 ++++ .../mechanic/totem/block/type/EqualType.java | 56 ++++ .../totem/block/type/StartWithType.java | 55 ++++ .../totem/block/type/TypeCondition.java | 57 ++++ .../api/scheduler/CancellableTask.java | 8 + .../api/scheduler/Scheduler.java | 54 ++++ .../customfishing/api/util/FontUtils.java | 14 + .../api/util/InventoryUtils.java | 36 ++- .../customfishing/api/util/LogUtils.java | 51 +++- .../customfishing/api/util/OffsetUtils.java | 32 ++ .../customfishing/api/util/WeightUtils.java | 26 ++ .../season/CustomCropsSeasonImpl.java | 7 +- .../season/RealisticSeasonsImpl.java | 2 + .../competition/CompetitionManagerImpl.java | 17 +- .../competition/CompetitionSchedule.java | 31 ++ .../actionbar/ActionBarManager.java | 21 ++ .../actionbar/ActionBarSender.java | 29 ++ .../competition/bossbar/BossBarManager.java | 21 ++ .../competition/bossbar/BossBarSender.java | 29 ++ .../competition/ranking/LocalRankingImpl.java | 68 +++++ .../competition/ranking/RedisRankingImpl.java | 55 ++++ .../mechanic/entity/EntityManagerImpl.java | 8 + .../mechanic/fishing/BaitAnimationTask.java | 16 +- .../mechanic/fishing/FishingManagerImpl.java | 44 +++ .../mechanic/fishing/HookCheckTimerTask.java | 38 ++- .../mechanic/fishing/LavaEffectTask.java | 22 +- .../mechanic/item/ItemManagerImpl.java | 88 +++--- .../mechanic/loot/LootManagerImpl.java | 1 - .../mechanic/totem/ActivatedTotem.java | 6 +- .../mechanic/totem/TotemManagerImpl.java | 24 +- .../totem/particle/ParticleSetting.java | 3 +- .../storage/StorageManagerImpl.java | 2 +- .../customfishing/util/ConfigUtils.java | 59 ++++ 69 files changed, 2873 insertions(+), 116 deletions(-) create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java create mode 100644 api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java diff --git a/api/src/main/java/net/momirealms/customfishing/api/data/DataStorageInterface.java b/api/src/main/java/net/momirealms/customfishing/api/data/DataStorageInterface.java index 23f20510..31757898 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/data/DataStorageInterface.java +++ b/api/src/main/java/net/momirealms/customfishing/api/data/DataStorageInterface.java @@ -27,20 +27,73 @@ import java.util.concurrent.CompletableFuture; public interface DataStorageInterface { + /** + * Initialize the data resource + */ void initialize(); + + /** + * Close the data resource + */ void disable(); + /** + * Get the storage data source type + * + * @return {@link StorageType} + */ StorageType getStorageType(); + /** + * Retrieve a player's data + * + * @param uuid The UUID of the player. + * @param lock Whether to lock the player data during retrieval. + * @return A CompletableFuture containing the optional player data. + */ CompletableFuture> getPlayerData(UUID uuid, boolean lock); + /** + * Update a player's data + * + * @param uuid The UUID of the player. + * @param playerData The player data to update. + * @param unlock Whether to unlock the player data after updating. + * @return A CompletableFuture indicating the success of the update. + */ CompletableFuture updatePlayerData(UUID uuid, PlayerData playerData, boolean unlock); + /** + * Update or insert a player's data into the SQL database. + * + * @param uuid The UUID of the player. + * @param playerData The player data to update or insert. + * @param unlock Whether to unlock the player data after updating or inserting. + * @return A CompletableFuture indicating the success of the operation. + */ CompletableFuture updateOrInsertPlayerData(UUID uuid, PlayerData playerData, boolean unlock); + /** + * Update data for multiple players + * + * @param users A collection of OfflineUser objects representing players. + * @param unlock Whether to unlock the player data after updating. + */ void updateManyPlayersData(Collection users, boolean unlock); + /** + * Lock or unlock a player's data in the SQL database. + * + * @param uuid The UUID of the player. + * @param lock Whether to lock or unlock the player data. + */ void lockOrUnlockPlayerData(UUID uuid, boolean lock); + /** + * Get a set of unique user UUIDs + * + * @param legacy Whether to include legacy data in the retrieval. + * @return A set of unique user UUIDs. + */ Set getUniqueUsers(boolean legacy); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/data/LegacyDataStorageInterface.java b/api/src/main/java/net/momirealms/customfishing/api/data/LegacyDataStorageInterface.java index 0de7b499..190206bc 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/data/LegacyDataStorageInterface.java +++ b/api/src/main/java/net/momirealms/customfishing/api/data/LegacyDataStorageInterface.java @@ -23,5 +23,11 @@ import java.util.concurrent.CompletableFuture; public interface LegacyDataStorageInterface extends DataStorageInterface { + /** + * Retrieve legacy player data from the SQL database. + * + * @param uuid The UUID of the player. + * @return A CompletableFuture containing the optional legacy player data. + */ CompletableFuture> getLegacyPlayerData(UUID uuid); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/data/PlayerData.java b/api/src/main/java/net/momirealms/customfishing/api/data/PlayerData.java index 8fb06b33..29d52235 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/data/PlayerData.java +++ b/api/src/main/java/net/momirealms/customfishing/api/data/PlayerData.java @@ -34,6 +34,10 @@ public class PlayerData { public static PlayerData LOCKED = empty(); + public static Builder builder() { + return new Builder(); + } + public static PlayerData empty() { return new Builder() .setBagData(InventoryData.empty()) diff --git a/api/src/main/java/net/momirealms/customfishing/api/data/user/OfflineUser.java b/api/src/main/java/net/momirealms/customfishing/api/data/user/OfflineUser.java index dc6663a3..0ab5875a 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/data/user/OfflineUser.java +++ b/api/src/main/java/net/momirealms/customfishing/api/data/user/OfflineUser.java @@ -22,20 +22,57 @@ import net.momirealms.customfishing.api.data.PlayerData; import net.momirealms.customfishing.api.mechanic.bag.FishingBagHolder; import net.momirealms.customfishing.api.mechanic.statistic.Statistics; +import java.io.Serializable; import java.util.UUID; public interface OfflineUser { + + /** + * Get the username + * + * @return user name + */ String getName(); + /** + * Get the user's uuid + * + * @return uuid + */ UUID getUUID(); + /** + * Get the fishing bag holder + * + * @return fishing bag holder + */ FishingBagHolder getHolder(); + /** + * Get the player's earning data + * + * @return earning data + */ EarningData getEarningData(); + /** + * Get the player's statistics + * + * @return statistics + */ Statistics getStatistics(); + /** + * If the user is online on current server + * + * @return online or not + */ boolean isOnline(); + /** + * Get the data in another minimized format that can be saved + * + * @return player data + */ PlayerData getPlayerData(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/data/user/OnlineUser.java b/api/src/main/java/net/momirealms/customfishing/api/data/user/OnlineUser.java index 046d25b4..a26fe65a 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/data/user/OnlineUser.java +++ b/api/src/main/java/net/momirealms/customfishing/api/data/user/OnlineUser.java @@ -20,5 +20,11 @@ package net.momirealms.customfishing.api.data.user; import org.bukkit.entity.Player; public interface OnlineUser extends OfflineUser { + + /** + * Get the bukkit player + * + * @return player + */ Player getPlayer(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java index 489b1bc6..28bbe8d4 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java @@ -17,25 +17,52 @@ package net.momirealms.customfishing.api.event; +import org.bukkit.entity.FishHook; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.NotNull; +/** + * This class represents an event that occurs when a fishing hook lands in either lava or water. + */ public class FishHookLandEvent extends PlayerEvent { private static final HandlerList handlerList = new HandlerList(); private final Target target; + private final FishHook fishHook; - public FishHookLandEvent(@NotNull Player who, Target target) { + /** + * Constructs a new FishHookLandEvent. + * + * @param who The player who triggered the event. + * @param target The target where the fishing hook has landed (LAVA or WATER). + * @param hook The fishing hook entity. + */ + public FishHookLandEvent(@NotNull Player who, Target target, FishHook hook) { super(who); this.target = target; + this.fishHook = hook; } + /** + * Gets the target where the fishing hook has landed. + * + * @return The target, which can be either LAVA or WATER. + */ public Target getTarget() { return target; } + /** + * Gets the fish hook bukkit entity + * + * @return fish hook + */ + public FishHook getFishHook() { + return fishHook; + } + public static HandlerList getHandlerList() { return handlerList; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/FishingResultEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/FishingResultEvent.java index aa533993..19590f80 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/FishingResultEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/FishingResultEvent.java @@ -27,6 +27,9 @@ import org.jetbrains.annotations.NotNull; import java.util.Map; import java.util.Optional; +/** + * This class represents an event that occurs when a player gets a result from fishing. + */ public class FishingResultEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlerList = new HandlerList(); @@ -35,6 +38,14 @@ public class FishingResultEvent extends PlayerEvent implements Cancellable { private final Loot loot; private final Map args; + /** + * Constructs a new FishingResultEvent. + * + * @param who The player who triggered the event. + * @param result The result of the fishing action (SUCCESS or FAILURE). + * @param loot The loot received from fishing. + * @param args A map of placeholders and their corresponding values. + */ public FishingResultEvent(@NotNull Player who, Result result, Loot loot, Map args) { super(who); this.result = result; @@ -62,22 +73,47 @@ public class FishingResultEvent extends PlayerEvent implements Cancellable { isCancelled = cancel; } + /** + * Gets the value associated with a specific argument key. + * Usage example event.getArg("{x}") + * + * @param key The argument key enclosed in curly braces, e.g., "{amount}". + * @return The value associated with the argument key, or null if not found. + */ public String getArg(String key) { - return args.get("{" + key + "}"); + return args.get(key); } + /** + * Gets the result of the fishing action. + * + * @return The fishing result, which can be either SUCCESS or FAILURE. + */ public Result getResult() { return result; } + /** + * Gets the loot received from fishing. + * + * @return The loot obtained from the fishing action. + */ public Loot getLoot() { return loot; } + /** + * Gets the amount of loot received + * + * @return The amount of loot received, or 1 if the loot is block or entity + */ public int getAmount() { return Integer.parseInt(Optional.ofNullable(getArg("{amount}")).orElse("1")); } + /** + * An enumeration representing possible fishing results (SUCCESS or FAILURE). + */ public enum Result { SUCCESS, FAILURE diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/LavaFishingEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/LavaFishingEvent.java index f619b6ed..bc961c17 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/LavaFishingEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/LavaFishingEvent.java @@ -24,6 +24,9 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.NotNull; +/** + * This class represents an event that occurs when a player fishes in lava. + */ public class LavaFishingEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlerList = new HandlerList(); @@ -31,6 +34,13 @@ public class LavaFishingEvent extends PlayerEvent implements Cancellable { private boolean isCancelled; private final FishHook hook; + /** + * Constructs a new LavaFishingEvent. + * + * @param who The player who triggered the event. + * @param state The state of the fishing action (REEL_IN, CAUGHT_FISH, or BITE). + * @param hook The FishHook entity associated with the fishing action. + */ public LavaFishingEvent(@NotNull Player who, State state, FishHook hook) { super(who); this.state = state; @@ -38,10 +48,20 @@ public class LavaFishingEvent extends PlayerEvent implements Cancellable { this.hook = hook; } + /** + * Gets the state of the fishing action. + * + * @return The fishing state, which can be REEL_IN, CAUGHT_FISH, or BITE. + */ public State getState() { return state; } + /** + * Gets the FishHook entity associated with the fishing action. + * + * @return The FishHook entity used in the fishing action. + */ public FishHook getHook() { return hook; } @@ -66,6 +86,9 @@ public class LavaFishingEvent extends PlayerEvent implements Cancellable { isCancelled = cancel; } + /** + * An enumeration representing possible states of the fishing action (REEL_IN, CAUGHT_FISH, BITE). + */ public enum State { REEL_IN, CAUGHT_FISH, diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java index 1f81c4dc..7d496973 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/RodCastEvent.java @@ -25,6 +25,9 @@ import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerFishEvent; import org.jetbrains.annotations.NotNull; +/** + * This class represents an event that occurs when a player casts a fishing rod. + */ public class RodCastEvent extends PlayerEvent implements Cancellable { private final Effect effect; @@ -33,6 +36,13 @@ public class RodCastEvent extends PlayerEvent implements Cancellable { private final FishingPreparation preparation; private static final HandlerList handlerList = new HandlerList(); + /** + * Constructs a new RodCastEvent. + * + * @param event The original PlayerFishEvent that triggered the rod cast. + * @param fishingPreparation The fishing preparation associated with the rod cast. + * @param effect The effect associated with the fishing rod cast. + */ public RodCastEvent(PlayerFishEvent event, FishingPreparation fishingPreparation, Effect effect) { super(event.getPlayer()); this.effect = effect; @@ -45,6 +55,11 @@ public class RodCastEvent extends PlayerEvent implements Cancellable { return this.isCancelled; } + /** + * Cancelling this event would not cancel the bukkit PlayerFishEvent + * + * @param cancel true if you wish to cancel this event + */ @Override public void setCancelled(boolean cancel) { this.isCancelled = cancel; @@ -54,6 +69,11 @@ public class RodCastEvent extends PlayerEvent implements Cancellable { return handlerList; } + /** + * Gets the fishing preparation associated with the rod cast. + * + * @return The FishingPreparation associated with the rod cast. + */ public FishingPreparation getPreparation() { return preparation; } @@ -64,10 +84,20 @@ public class RodCastEvent extends PlayerEvent implements Cancellable { return getHandlerList(); } + /** + * Gets the effect associated with the fishing rod cast. + * + * @return The Effect associated with the rod cast. + */ public Effect getEffect() { return effect; } + /** + * Gets the original PlayerFishEvent that triggered the rod cast. + * + * @return The original PlayerFishEvent. + */ public PlayerFishEvent getBukkitPlayerFishEvent() { return event; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/TotemActivateEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/TotemActivateEvent.java index 4bd78c4d..f1d7cbf6 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/TotemActivateEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/TotemActivateEvent.java @@ -17,5 +17,71 @@ package net.momirealms.customfishing.api.event; -public class TotemActivateEvent { +import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +/** + * This class represents an event that occurs when a player activates a totem. + */ +public class TotemActivateEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlerList = new HandlerList(); + private final Location coreLocation; + private boolean isCancelled; + private final TotemConfig config; + + /** + * Constructs a new TotemActivateEvent. + * + * @param who The player who activated the totem. + * @param location The location of the totem's core. + * @param config The configuration of the totem being activated. + */ + public TotemActivateEvent(@NotNull Player who, Location location, TotemConfig config) { + super(who); + this.coreLocation = location; + this.config = config; + } + + /** + * Gets the location of the totem's core. + * + * @return The location of the totem's core. + */ + public Location getCoreLocation() { + return coreLocation; + } + + /** + * Gets the configuration of the totem being activated. + * + * @return The TotemConfig of the totem being activated. + */ + public TotemConfig getConfig() { + return config; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean cancel) { + isCancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } } diff --git a/api/src/main/java/net/momirealms/customfishing/api/integration/EnchantmentInterface.java b/api/src/main/java/net/momirealms/customfishing/api/integration/EnchantmentInterface.java index e5e145cc..04a92876 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/integration/EnchantmentInterface.java +++ b/api/src/main/java/net/momirealms/customfishing/api/integration/EnchantmentInterface.java @@ -22,5 +22,14 @@ import org.bukkit.inventory.ItemStack; import java.util.List; public interface EnchantmentInterface { + + /** + * Get a list of enchantments with level for itemStack + * format: plugin:enchantment:level + * example: minecraft:sharpness:5 + * + * @param itemStack itemStack + * @return enchantment list + */ List getEnchants(ItemStack itemStack); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/integration/LevelInterface.java b/api/src/main/java/net/momirealms/customfishing/api/integration/LevelInterface.java index d97f5509..da326178 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/integration/LevelInterface.java +++ b/api/src/main/java/net/momirealms/customfishing/api/integration/LevelInterface.java @@ -21,6 +21,21 @@ import org.bukkit.entity.Player; public interface LevelInterface { + /** + * Add exp to a certain skill or job + * + * @param player player + * @param target the skill or job, for instance "Fishing" "fisherman" + * @param amount the exp amount + */ void addXp(Player player, String target, double amount); + + /** + * Get a player's skill or job's level + * + * @param player player + * @param target the skill or job, for instance "Fishing" "fisherman" + * @return level + */ int getLevel(Player player, String target); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/integration/SeasonInterface.java b/api/src/main/java/net/momirealms/customfishing/api/integration/SeasonInterface.java index 493ce396..bae8da60 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/integration/SeasonInterface.java +++ b/api/src/main/java/net/momirealms/customfishing/api/integration/SeasonInterface.java @@ -18,8 +18,15 @@ package net.momirealms.customfishing.api.integration; import org.bukkit.World; +import org.jetbrains.annotations.NotNull; public interface SeasonInterface { - String getSeason(World world); + /** + * Get a world's season + * + * @param world world + * @return spring, summer, autumn, winter or disabled + */ + @NotNull String getSeason(World world); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/GlobalSettings.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/GlobalSettings.java index a4fa6426..2b2e35b0 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/GlobalSettings.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/GlobalSettings.java @@ -26,12 +26,21 @@ import org.bukkit.configuration.ConfigurationSection; import java.util.HashMap; import java.util.Map; +/** + * Represents global settings for actions related to fishing, loot, rods, and bait. + */ public class GlobalSettings { public static HashMap lootActions = new HashMap<>(); public static HashMap rodActions = new HashMap<>(); public static HashMap baitActions = new HashMap<>(); + public static HashMap hookActions = new HashMap<>(); + /** + * Loads global settings from a configuration section. + * + * @param section The configuration section to load settings from. + */ public static void load(ConfigurationSection section) { if (section == null) return; for (Map.Entry entry : section.getValues(false).entrySet()) { @@ -41,17 +50,27 @@ public class GlobalSettings { case "loot" -> lootActions = map; case "rod" -> rodActions = map; case "bait" -> baitActions = map; + case "hook" -> hookActions = map; } } } } + /** + * Unloads global settings, clearing all action maps. + */ public static void unload() { lootActions.clear(); rodActions.clear(); baitActions.clear(); } + /** + * Triggers loot-related actions for a specific trigger and condition. + * + * @param trigger The trigger to activate actions for. + * @param condition The condition that triggered the actions. + */ public static void triggerLootActions(ActionTrigger trigger, Condition condition) { Action[] actions = lootActions.get(trigger); if (actions != null) { @@ -61,6 +80,12 @@ public class GlobalSettings { } } + /** + * Triggers rod-related actions for a specific trigger and condition. + * + * @param trigger The trigger to activate actions for. + * @param condition The condition that triggered the actions. + */ public static void triggerRodActions(ActionTrigger trigger, Condition condition) { Action[] actions = rodActions.get(trigger); if (actions != null) { @@ -70,6 +95,12 @@ public class GlobalSettings { } } + /** + * Triggers bait-related actions for a specific trigger and condition. + * + * @param trigger The trigger to activate actions for. + * @param condition The condition that triggered the actions. + */ public static void triggerBaitActions(ActionTrigger trigger, Condition condition) { Action[] actions = baitActions.get(trigger); if (actions != null) { @@ -78,4 +109,19 @@ public class GlobalSettings { } } } + + /** + * Triggers hook-related actions for a specific trigger and condition. + * + * @param trigger The trigger to activate actions for. + * @param condition The condition that triggered the actions. + */ + public static void triggerHookActions(ActionTrigger trigger, Condition condition) { + Action[] actions = hookActions.get(trigger); + if (actions != null) { + for (Action action : actions) { + action.trigger(condition); + } + } + } } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/TempFishingState.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/TempFishingState.java index 65bd56ed..503ef51e 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/TempFishingState.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/TempFishingState.java @@ -21,27 +21,60 @@ import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation; import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.loot.Loot; +/** + * Represents a temporary state during fishing that includes an effect, preparation, and loot. + */ public class TempFishingState { private final Effect effect; private final FishingPreparation preparation; - private final Loot loot; + private Loot loot; + /** + * Creates a new instance of TempFishingState. + * + * @param effect The effect associated with this state. + * @param preparation The fishing preparation associated with this state. + * @param loot The loot associated with this state. + */ public TempFishingState(Effect effect, FishingPreparation preparation, Loot loot) { this.effect = effect; this.preparation = preparation; this.loot = loot; } + /** + * Gets the effect associated with this fishing state. + * + * @return The effect. + */ public Effect getEffect() { return effect; } + /** + * Gets the fishing preparation associated with this fishing state. + * + * @return The fishing preparation. + */ public FishingPreparation getPreparation() { return preparation; } + /** + * Gets the loot associated with this fishing state. + * + * @return The loot. + */ public Loot getLoot() { return loot; } + + /** + * Set the loot associated with this fishing state. + * + */ + public void setLoot(Loot loot) { + this.loot = loot; + } } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/Ranking.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/Ranking.java index a4cca23d..4ecaf9ae 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/Ranking.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/Ranking.java @@ -24,24 +24,79 @@ import java.util.Iterator; public interface Ranking { + /** + * Clears the list of competition players. + */ void clear(); + /** + * Retrieves a competition player by their name. + * + * @param player The name of the player to retrieve. + * @return The CompetitionPlayer object if found, or null if not found. + */ CompetitionPlayer getCompetitionPlayer(String player); + /** + * Returns an iterator for iterating over pairs of player names and scores. + * + * @return An iterator for pairs of player names and scores. + */ Iterator> getIterator(); + /** + * Returns the number of competition players. + * + * @return The number of competition players. + */ int getSize(); + /** + * Returns the rank of a player based on their name. + * + * @param player The name of the player to get the rank for. + * @return The rank of the player, or -1 if the player is not found. + */ int getPlayerRank(String player); + /** + * Returns the score of a player based on their name. + * + * @param player The name of the player to get the score for. + * @return The score of the player, or 0 if the player is not found. + */ double getPlayerScore(String player); + /** + * Refreshes the data for a player by adding a score to their existing score or creating a new player. + * + * @param player The name of the player to update or create. + * @param score The score to add to the player's existing score or set as their initial score. + */ void refreshData(String player, double score); + /** + * Sets the data for a player, updating their score or creating a new player. + * + * @param player The name of the player to update or create. + * @param score The score to set for the player. + */ void setData(String player, double score); + /** + * Returns the name of a player at a given index. + * + * @param rank The index of the player to retrieve. + * @return The name of the player at the specified index, or null if not found. + */ @Nullable String getPlayerAt(int rank); + /** + * Returns the score of a player at a given index. + * + * @param rank The index of the player to retrieve. + * @return The score of the player at the specified index, or 0 if not found. + */ double getScoreAt(int rank); } 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 4d0c799d..8d41e070 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 @@ -25,20 +25,41 @@ import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; +/** + * Represents a condition with associated data + */ public class Condition { protected Location location; protected final Player player; protected final @NotNull Map args; + /** + * Creates a new Condition object based on a player's location. + * + * @param player The player associated with this condition. + */ public Condition(@NotNull Player player) { this(player.getLocation(), player, new HashMap<>()); } + /** + * Creates a new Condition object with specified arguments. + * + * @param player The player associated with this condition. + * @param args A map of arguments associated with this condition. + */ public Condition(@NotNull Player player, @NotNull Map args) { this(player.getLocation(), player, args); } + /** + * Creates a new Condition object with a specific location, player, and arguments. + * + * @param location The location associated with this condition. + * @param player The player associated with this condition. + * @param args A map of arguments associated with this condition. + */ public Condition(Location location, Player player, @NotNull Map args) { this.location = location; this.player = player; @@ -53,6 +74,11 @@ public class Condition { } } + /** + * Sets the location associated with this condition. + * + * @param location The new location to set. + */ public void setLocation(@NotNull Location location) { this.location = location; this.args.put("{x}", String.valueOf(location.getX())); @@ -61,28 +87,61 @@ public class Condition { this.args.put("{world}", location.getWorld().getName()); } + /** + * Gets the location associated with this condition. + * + * @return The location associated with this condition. + */ public Location getLocation() { return location; } + /** + * Gets the player associated with this condition. + * + * @return The player associated with this condition. + */ public Player getPlayer() { return player; } + /** + * Gets the map of arguments associated with this condition. + * + * @return A map of arguments associated with this condition. + */ @NotNull public Map getArgs() { return args; } + /** + * Gets the value of a specific argument by its key. + * + * @param key The key of the argument to retrieve. + * @return The value of the argument or null if not found. + */ @Nullable public String getArg(String key) { return args.get(key); } + /** + * Inserts or updates an argument with the specified key and value. + * + * @param key The key of the argument to insert or update. + * @param value The value to set for the argument. + */ public void insertArg(String key, String value) { args.put(key, value); } + /** + * Deletes an argument with the specified key. + * + * @param key The key of the argument to delete. + * @return The value of the deleted argument or null if not found. + */ public String delArg(String key) { return args.remove(key); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java index 0c23dd5f..54cdcff7 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java @@ -125,20 +125,40 @@ public class FishingPreparation extends Condition { } } + /** + * Retrieves the ItemStack representing the fishing rod. + * + * @return The ItemStack representing the fishing rod. + */ @NotNull public ItemStack getRodItemStack() { return rodItemStack; } + /** + * Retrieves the ItemStack representing the bait (if available). + * + * @return The ItemStack representing the bait, or null if no bait is set. + */ @Nullable public ItemStack getBaitItemStack() { return baitItemStack; } + /** + * Checks if player meet the requirements for fishing gears + * + * @return True if can fish, false otherwise. + */ public boolean canFish() { return this.canFish; } + /** + * Merges a FishingEffect into this fishing rod, applying effect modifiers. + * + * @param effect The FishingEffect to merge into this rod. + */ public void mergeEffect(FishingEffect effect) { for (EffectCarrier effectCarrier : effects) { for (EffectModifier modifier : effectCarrier.getEffectModifiers()) { @@ -147,8 +167,15 @@ public class FishingPreparation extends Condition { } } + /** + * Triggers actions associated with a specific action trigger. + * + * @param actionTrigger The action trigger that initiates the actions. + */ public void triggerActions(ActionTrigger actionTrigger) { GlobalSettings.triggerRodActions(actionTrigger, this); + GlobalSettings.triggerBaitActions(actionTrigger, this); + GlobalSettings.triggerHookActions(actionTrigger, this); for (EffectCarrier effectCarrier : effects) { Action[] actions = effectCarrier.getActions(actionTrigger); if (actions != null) diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java index e0b240c1..6247dd41 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java @@ -42,5 +42,5 @@ public interface Effect { List> getWeightModifierIgnored(); - void merge(Effect bonus); + void merge(Effect effect); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java index 4e986e1c..1c5125b4 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java @@ -35,96 +35,200 @@ public class FishingEffect implements Effect { private final List> weightModifier = new ArrayList<>(); private final List> weightModifierIgnored = new ArrayList<>(); + /** + * Sets whether lava fishing is enabled. + * + * @param lavaFishing True if lava fishing is enabled, false otherwise. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setLavaFishing(boolean lavaFishing) { this.lavaFishing = lavaFishing; return this; } + /** + * Sets the multiple loot chance. + * + * @param multipleLootChance The multiple loot chance value to set. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setMultipleLootChance(double multipleLootChance) { this.multipleLootChance = multipleLootChance; return this; } + /** + * Sets the size multiplier. + * + * @param sizeMultiplier The size multiplier value to set. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setSizeMultiplier(double sizeMultiplier) { this.sizeMultiplier = sizeMultiplier; return this; } + /** + * Sets the score multiplier. + * + * @param scoreMultiplier The score multiplier value to set. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setScoreMultiplier(double scoreMultiplier) { this.scoreMultiplier = scoreMultiplier; return this; } + /** + * Sets the hook time modifier. + * + * @param timeModifier The hook time modifier value to set. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setHookTimeModifier(double timeModifier) { this.hookTimeModifier = timeModifier; return this; } + /** + * Sets the difficulty modifier. + * + * @param difficultyModifier The difficulty modifier value to set. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setDifficultyModifier(double difficultyModifier) { this.difficultyModifier = difficultyModifier; return this; } + /** + * Sets the game time modifier. + * + * @param gameTimeModifier The game time modifier value to set. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect setGameTimeModifier(double gameTimeModifier) { this.gameTimeModifier = gameTimeModifier; return this; } + /** + * Adds weight modifiers to the FishingEffect. + * + * @param weightModifier A list of pairs representing weight modifiers to add. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect addWeightModifier(List> weightModifier) { this.weightModifier.addAll(weightModifier); return this; } + /** + * Adds ignored weight modifiers to the FishingEffect. + * + * @param weightModifierIgnored A list of pairs representing ignored weight modifiers to add. + * @return The FishingEffect instance for method chaining. + */ public FishingEffect addWeightModifierIgnored(List> weightModifierIgnored) { this.weightModifierIgnored.addAll(weightModifierIgnored); return this; } + /** + * Checks if lava fishing is enabled. + * + * @return True if lava fishing is enabled, false otherwise. + */ @Override public boolean canLavaFishing() { return lavaFishing; } + /** + * Retrieves the multiple loot chance. + * + * @return The multiple loot chance value. + */ @Override public double getMultipleLootChance() { return multipleLootChance; } + /** + * Retrieves the size multiplier. + * + * @return The size multiplier value. + */ @Override public double getSizeMultiplier() { return sizeMultiplier; } + /** + * Retrieves the score multiplier. + * + * @return The score multiplier value. + */ @Override public double getScoreMultiplier() { return scoreMultiplier; } + /** + * Retrieves the hook time modifier. + * + * @return The hook time modifier value. + */ @Override public double getHookTimeModifier() { return hookTimeModifier; } + /** + * Retrieves the game time modifier. + * + * @return The game time modifier value. + */ @Override public double getGameTimeModifier() { return gameTimeModifier; } + /** + * Retrieves the difficulty modifier. + * + * @return The difficulty modifier value. + */ @Override public double getDifficultyModifier() { return difficultyModifier; } + /** + * Retrieves the list of weight modifiers. + * + * @return The list of weight modifiers. + */ @Override public List> getWeightModifier() { return weightModifier; } + /** + * Retrieves the list of weight modifiers ignoring conditions. + * + * @return The list of weight modifiers ignoring conditions. + */ @Override public List> getWeightModifierIgnored() { return weightModifierIgnored; } + /** + * Merges another Effect into this FishingEffect, combining their properties. + * + * @param another The Effect to merge into this FishingEffect. + */ @Override public void merge(Effect another) { if (another == null) return; @@ -139,6 +243,13 @@ public class FishingEffect implements Effect { this.weightModifier.addAll(another.getWeightModifier()); } + public static Builder builder() { + return new Builder(); + } + + /** + * Builder class for creating instances of the {@link FishingEffect} class with customizable properties. + */ public static class Builder { private final FishingEffect effect; @@ -147,51 +258,110 @@ public class FishingEffect implements Effect { this.effect = new FishingEffect(); } + /** + * Adds weight modifiers to the FishingEffect. + * + * @param modifier A list of pairs representing weight modifiers. + * @return The Builder instance for method chaining. + */ public Builder addWeightModifier(List> modifier) { effect.weightModifier.addAll(modifier); return this; } + /** + * Adds weight modifiers ignoring conditions to the FishingEffect. + * + * @param modifier A list of pairs representing ignoring conditions weight modifiers. + * @return The Builder instance for method chaining. + */ public Builder addWeightModifierIgnored(List> modifier) { effect.weightModifierIgnored.addAll(modifier); return this; } + /** + * Sets the multiple loot chance for the FishingEffect. + * + * @param multipleLootChance The multiple loot chance value to set. + * @return The Builder instance for method chaining. + */ public Builder multipleLootChance(double multipleLootChance) { effect.multipleLootChance = multipleLootChance; return this; } + /** + * Sets the difficulty modifier for the FishingEffect. + * + * @param difficultyModifier The difficulty modifier value to set. + * @return The Builder instance for method chaining. + */ public Builder difficultyModifier(double difficultyModifier) { effect.difficultyModifier = difficultyModifier; return this; } + /** + * Sets the size multiplier for the FishingEffect. + * + * @param sizeMultiplier The size multiplier value to set. + * @return The Builder instance for method chaining. + */ public Builder sizeMultiplier(double sizeMultiplier) { effect.sizeMultiplier = sizeMultiplier; return this; } + /** + * Sets the time modifier for the FishingEffect. + * + * @param timeModifier The time modifier value to set. + * @return The Builder instance for method chaining. + */ public Builder timeModifier(double timeModifier) { effect.hookTimeModifier = timeModifier; return this; } + /** + * Sets the score multiplier for the FishingEffect. + * + * @param scoreMultiplier The score multiplier value to set. + * @return The Builder instance for method chaining. + */ public Builder scoreMultiplier(double scoreMultiplier) { effect.scoreMultiplier = scoreMultiplier; return this; } + /** + * Sets the game time modifier for the FishingEffect. + * + * @param gameTimeModifier The game time modifier value to set. + * @return The Builder instance for method chaining. + */ public Builder gameTimeModifier(double gameTimeModifier) { effect.gameTimeModifier = gameTimeModifier; return this; } + /** + * Sets whether lava fishing is enabled for the FishingEffect. + * + * @param lavaFishing True if lava fishing is enabled, false otherwise. + * @return The Builder instance for method chaining. + */ public Builder lavaFishing(boolean lavaFishing) { effect.lavaFishing = lavaFishing; return this; } + /** + * Builds and returns the finalized FishingEffect instance. + * + * @return The created FishingEffect instance. + */ public FishingEffect build() { return effect; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java index b6b56b02..8279e347 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java @@ -28,7 +28,6 @@ public class CFLoot implements Loot { private final String id; private final LootType type; - private String gameConfig; private final HashMap actionMap; private final HashMap successTimesActionMap; private String nick; @@ -46,10 +45,13 @@ public class CFLoot implements Loot { this.successTimesActionMap = new HashMap<>(); } - public static CFLoot of(String id, LootType type) { - return new CFLoot(id, type); + public static Builder builder(String id, LootType type) { + return new Builder(id, type); } + /** + * Builder class for CFLoot. + */ public static class Builder { private final CFLoot loot; @@ -58,121 +60,246 @@ public class CFLoot implements Loot { this.loot = new CFLoot(id, type); } + /** + * Set the nickname for this loot. + * + * @param nick The nickname. + * @return The builder. + */ public Builder nick(String nick) { this.loot.nick = nick; return this; } + /** + * Set whether this loot should be shown in the finder. + * + * @param show True if it should be shown, false otherwise. + * @return The builder. + */ public Builder showInFinder(boolean show) { this.loot.showInFinder = show; return this; } + /** + * Set whether this loot should have an instance game. + * + * @param instant True if it should be an instance game, false otherwise. + * @return The builder. + */ public Builder instantGame(boolean instant) { this.loot.instanceGame = instant; return this; } - public Builder gameConfig(String gameConfig) { - this.loot.gameConfig = gameConfig; - return this; - } - + /** + * Set whether games are disabled for this loot. + * + * @param disable True if games are disabled, false otherwise. + * @return The builder. + */ public Builder disableGames(boolean disable) { this.loot.disableGame = disable; return this; } + /** + * Set whether statistics are disabled for this loot. + * + * @param disable True if statistics are disabled, false otherwise. + * @return The builder. + */ public Builder disableStats(boolean disable) { this.loot.disableStats = disable; return this; } + /** + * Set the score for this loot. + * + * @param score The score. + * @return The builder. + */ public Builder score(double score) { this.loot.score = score; return this; } + /** + * Set the loot group for this loot. + * + * @param groups The loot group. + * @return The builder. + */ public Builder lootGroup(String[] groups) { this.loot.lootGroup = groups; return this; } + /** + * Add actions triggered by a specific trigger. + * + * @param trigger The trigger for the actions. + * @param actions The actions to add. + * @return The builder. + */ public Builder addActions(ActionTrigger trigger, Action[] actions) { this.loot.actionMap.put(trigger, actions); return this; } + /** + * Add actions triggered by multiple triggers. + * + * @param actionMap A map of triggers to actions. + * @return The builder. + */ public Builder addActions(HashMap actionMap) { this.loot.actionMap.putAll(actionMap); return this; } + /** + * Add actions triggered by the number of successes. + * + * @param times The number of successes for triggering the actions. + * @param actions The actions to add. + * @return The builder. + */ public Builder addTimesActions(int times, Action[] actions) { this.loot.successTimesActionMap.put(times, actions); return this; } + /** + * Add actions triggered by multiple numbers of successes. + * + * @param actionMap A map of numbers of successes to actions. + * @return The builder. + */ public Builder addTimesActions(HashMap actionMap) { this.loot.successTimesActionMap.putAll(actionMap); return this; } + /** + * Build the CFLoot object. + * + * @return The built CFLoot object. + */ public CFLoot build() { return loot; } } + /** + * Check if this loot has an instance game. + * + * @return True if it's an instance game, false otherwise. + */ @Override public boolean instanceGame() { return this.instanceGame; } + /** + * Get the unique ID of this loot. + * + * @return The unique ID. + */ @Override public String getID() { return this.id; } + /** + * Get the type of this loot. + * + * @return The loot type. + */ @Override public LootType getType() { return this.type; } + /** + * Get the nickname of this loot. + * + * @return The nickname. + */ @Override public @NotNull String getNick() { return this.nick; } + /** + * Check if this loot should be shown in the finder. + * + * @return True if it should be shown, false otherwise. + */ @Override public boolean showInFinder() { return this.showInFinder; } + /** + * Get the score of this loot. + * + * @return The score. + */ @Override public double getScore() { return this.score; } + /** + * Check if games are disabled for this loot. + * + * @return True if games are disabled, false otherwise. + */ @Override public boolean disableGame() { return this.disableGame; } + /** + * Check if statistics are disabled for this loot. + * + * @return True if statistics are disabled, false otherwise. + */ @Override public boolean disableStats() { return this.disableStats; } + /** + * Get the loot group of this loot. + * + * @return The loot group. + */ @Override public String[] getLootGroup() { return lootGroup; } + /** + * Get the actions triggered by a specific action trigger. + * + * @param actionTrigger The action trigger. + * @return The actions triggered by the given trigger. + */ @Override public Action[] getActions(ActionTrigger actionTrigger) { return actionMap.get(actionTrigger); } + /** + * Trigger actions associated with a specific action trigger. + * + * @param actionTrigger The action trigger. + * @param condition The condition under which the actions are triggered. + */ @Override public void triggerActions(ActionTrigger actionTrigger, Condition condition) { Action[] actions = getActions(actionTrigger); @@ -183,11 +310,22 @@ public class CFLoot implements Loot { } } + /** + * Get the actions triggered by a specific number of successes. + * + * @param times The number of successes. + * @return The actions triggered by the specified number of successes. + */ @Override public Action[] getSuccessTimesActions(int times) { return successTimesActionMap.get(times); } + /** + * Get a map of actions triggered by different numbers of successes. + * + * @return A map of actions triggered by success times. + */ @Override public HashMap getSuccessTimesActionMap() { return successTimesActionMap; diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java index b4ede459..eb203c67 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java @@ -26,67 +26,98 @@ import java.util.HashMap; public interface Loot { + /** + * Check if this loot has an instance game. + * + * @return True if it's an instance game, false otherwise. + */ boolean instanceGame(); /** - * get the loot id - * @return id + * Get the unique ID of this loot. + * + * @return The unique ID. */ String getID(); /** - * get the loot type - * @return type + * Get the type of this loot. + * + * @return The loot type. */ LootType getType(); /** - * nick would be display.name or key name if not set (MiniMessage format) - * @return nick + * Get the nickname of this loot. + * + * @return The nickname. */ @NotNull String getNick(); /** - * if the loot can be seen from the finder - * @return show in finder or not + * Check if this loot should be shown in the finder. + * + * @return True if it should be shown, false otherwise. */ boolean showInFinder(); /** - * get the score in competition - * @return score + * Get the score of this loot. + * + * @return The score. */ double getScore(); /** - * if the game is disabled - * @return disabled or not + * Check if games are disabled for this loot. + * + * @return True if games are disabled, false otherwise. */ boolean disableGame(); /** - * if the statistics is disabled - * @return disabled or not + * Check if statistics are disabled for this loot. + * + * @return True if statistics are disabled, false otherwise. */ boolean disableStats(); + /** + * Get the loot group of this loot. + * + * @return The loot group. + */ String[] getLootGroup(); /** - * get actions triggered by certain events - * @return actions + * Get the actions triggered by a specific action trigger. + * + * @param actionTrigger The action trigger. + * @return The actions triggered by the given trigger. */ Action[] getActions(ActionTrigger actionTrigger); + /** + * Trigger actions associated with a specific action trigger. + * + * @param actionTrigger The action trigger. + * @param condition The condition under which the actions are triggered. + */ void triggerActions(ActionTrigger actionTrigger, Condition condition); /** - * get actions when succeeding in fishing for certain times - * @param times times - * @return actions + * Get the actions triggered by a specific number of successes. + * + * @param times The number of successes. + * @return The actions triggered by the specified number of successes. */ Action[] getSuccessTimesActions(int times); + /** + * Get a map of actions triggered by different numbers of successes. + * + * @return A map of actions triggered by success times. + */ HashMap getSuccessTimesActionMap(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java index 834e3a7f..7ce3a71c 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java @@ -20,5 +20,6 @@ package net.momirealms.customfishing.api.mechanic.loot; import org.bukkit.entity.Player; public interface WeightModifier { + double modify(Player player, double weight); } \ No newline at end of file diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/market/MarketGUIHolder.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/market/MarketGUIHolder.java index f4845acb..aaf8bec3 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/market/MarketGUIHolder.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/market/MarketGUIHolder.java @@ -21,14 +21,28 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.jetbrains.annotations.NotNull; +/** + * Represents a holder for the Market GUI inventory. + * This class is used to associate the Market GUI's inventory with an object. + */ public class MarketGUIHolder implements InventoryHolder { private Inventory inventory; + /** + * Sets the inventory associated with this holder. + * + * @param inventory The inventory to associate with this holder. + */ public void setInventory(Inventory inventory) { this.inventory = inventory; } + /** + * Retrieves the inventory associated with this holder. + * + * @return The associated inventory. + */ @Override public @NotNull Inventory getInventory() { return inventory; diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/Requirement.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/Requirement.java index 11ad7a85..3fac8c48 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/Requirement.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/Requirement.java @@ -21,5 +21,11 @@ import net.momirealms.customfishing.api.mechanic.condition.Condition; public interface Requirement { + /** + * Is condition met the requirement + * + * @param condition condition + * @return meet or not + */ boolean isConditionMet(Condition condition); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementExpansion.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementExpansion.java index 145abc37..11d04713 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementExpansion.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementExpansion.java @@ -17,13 +17,37 @@ package net.momirealms.customfishing.api.mechanic.requirement; +/** + * An abstract class representing a requirement expansion + * Requirement expansions are used to define custom requirements for various functionalities. + */ public abstract class RequirementExpansion { + /** + * Get the version of this requirement expansion. + * + * @return The version of the expansion. + */ public abstract String getVersion(); + /** + * Get the author of this requirement expansion. + * + * @return The author of the expansion. + */ public abstract String getAuthor(); + /** + * Get the type of requirement provided by this expansion. + * + * @return The type of requirement. + */ public abstract String getRequirementType(); + /** + * Get the factory for creating requirements defined by this expansion. + * + * @return The requirement factory. + */ public abstract RequirementFactory getRequirementFactory(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementFactory.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementFactory.java index d3ca670b..adbb1030 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementFactory.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/requirement/RequirementFactory.java @@ -21,10 +21,27 @@ import net.momirealms.customfishing.api.mechanic.action.Action; import java.util.List; +/** + * An interface for a requirement factory that builds requirements. + */ public interface RequirementFactory { - Requirement build(Object args, List notMetActions, boolean checkAction); + /** + * Build a requirement with the given arguments, not met actions, and check action flag. + * + * @param args The arguments used to build the requirement. + * @param notMetActions Actions to be triggered when the requirement is not met (can be null). + * @param advanced Flag indicating whether to check the action when building the requirement. + * @return The built requirement. + */ + Requirement build(Object args, List notMetActions, boolean advanced); + /** + * Build a requirement with the given arguments. + * + * @param args The arguments used to build the requirement. + * @return The built requirement. + */ default Requirement build(Object args) { return build(args, null, false); } 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 72c7b0df..eeb149ba 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 @@ -17,7 +17,6 @@ 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; @@ -27,17 +26,31 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +/** + * Represents a statistics system for tracking loot and catch amounts. + */ public class Statistics { - @SerializedName("statistic_map") private final ConcurrentHashMap statisticMap; private int total; + /** + * Creates a new instance of Statistics based on provided statistic data. + * + * @param statisticData The initial statistic data. + */ public Statistics(StatisticData statisticData) { this.statisticMap = new ConcurrentHashMap<>(statisticData.statisticMap); this.total = statisticMap.values().stream().mapToInt(Integer::intValue).sum(); } + /** + * Adds an amount of loot to the statistics. + * + * @param loot The loot item. + * @param condition The condition associated with the loot. + * @param amount The amount of loot to add. + */ public synchronized void addLootAmount(Loot loot, Condition condition, int amount) { if (amount == 1) { addSingleLootAmount(loot, condition); @@ -51,6 +64,14 @@ public class Statistics { doSuccessTimesAction(previous, after, condition, loot); } + /** + * Performs actions associated with the success times of acquiring loot. + * + * @param previous The previous success times. + * @param after The updated success times. + * @param condition The condition associated with the loot. + * @param loot The loot item. + */ private void doSuccessTimesAction(Integer previous, int after, Condition condition, Loot loot) { HashMap actionMap = loot.getSuccessTimesActionMap(); if (actionMap != null) { @@ -64,6 +85,12 @@ public class Statistics { } } + /** + * Adds a single loot amount to the statistics. + * + * @param loot The loot item. + * @param condition The condition associated with the loot. + */ private void addSingleLootAmount(Loot loot, Condition condition) { Integer previous = statisticMap.get(loot.getID()); if (previous == null) previous = 0; @@ -77,20 +104,40 @@ public class Statistics { } } + /** + * Gets the amount of a specific loot item in the statistics. + * + * @param key The key of the loot item. + * @return The amount of the specified loot item. + */ public int getLootAmount(String key) { Integer amount = statisticMap.get(key); return amount == null ? 0 : amount; } + /** + * Resets the statistics data. + */ public void reset() { statisticMap.clear(); total = 0; } + /** + * Gets the statistic map containing loot item keys and their respective amounts. + * + * @return The statistic map. + */ public Map getStatisticMap() { return statisticMap; } + /** + * Sets data for a specific key in the statistics. + * + * @param key The key to set data for. + * @param value The value to set. + */ public void setData(String key, int value) { if (value <= 0) { statisticMap.remove(key); @@ -99,6 +146,11 @@ public class Statistics { statisticMap.put(key, value); } + /** + * Gets the total catch amount across all loot items. + * + * @return The total catch amount. + */ public int getTotalCatchAmount() { return total; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java new file mode 100644 index 00000000..a19ef39c --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemConfig.java @@ -0,0 +1,197 @@ +/* + * 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.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.api.mechanic.requirement.Requirement; +import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock; +import org.bukkit.Location; + +/** + * This class represents the configuration for a totem. + * It defines various settings and properties for the totem. + */ +public class TotemConfig { + + private String key; + private TotemModel[] totemModels; + private TotemParticle[] particleSettings; + private Requirement[] requirements; + private double radius; + private int duration; + + /** + * Get the array of totem models that define the totem's pattern. + * + * @return An array of TotemModel objects. + */ + public TotemModel[] getTotemModels() { + return totemModels; + } + + /** + * Get the array of requirements for totem activation. + * + * @return An array of Requirement objects. + */ + public Requirement[] getRequirements() { + return requirements; + } + + /** + * Get the unique key associated with this totem configuration. + * + * @return The unique key as a string. + */ + public String getKey() { + return key; + } + + /** + * Check if the provided location matches any of the totem model patterns. + * + * @param location The location to check. + * @return True if the location matches a totem model pattern, false otherwise. + */ + public boolean isRightPattern(Location location) { + for (TotemModel totemModel : totemModels) { + if (totemModel.isPatternSatisfied(location)) { + return true; + } + } + return false; + } + + /** + * Get the array of particle settings for the totem's visual effects. + * + * @return An array of TotemParticle objects. + */ + public TotemParticle[] getParticleSettings() { + return particleSettings; + } + + /** + * Get the activation radius of the totem. + * + * @return The activation radius as a double. + */ + public double getRadius() { + return radius; + } + + /** + * Get the duration of the totem's effect when activated. + * + * @return The duration in seconds as an integer. + */ + public int getDuration() { + return duration; + } + + /** + * Get the totem core associated with the first totem model. + * This is used for some internal functionality. + * + * @return An array of TotemBlock objects representing the totem core. + */ + public TotemBlock[] getTotemCore() { + return totemModels[0].getTotemCore(); + } + + public static Builder builder(String key) { + return new Builder(key); + } + + /** + * This class represents a builder for creating instances of TotemConfig. + * It allows for the convenient construction of TotemConfig objects with various settings. + */ + public static class Builder { + + private final TotemConfig config; + + public Builder(String key) { + this.config = new TotemConfig(); + this.config.key = key; + } + + /** + * Sets the totem models for the TotemConfig being built. + * + * @param totemModels An array of TotemModel objects representing different totem models. + * @return The builder instance to allow for method chaining. + */ + public Builder setTotemModels(TotemModel[] totemModels) { + config.totemModels = totemModels; + return this; + } + + /** + * Sets the particle settings for the TotemConfig being built. + * + * @param particleSettings An array of TotemParticle objects representing particle settings. + * @return The builder instance to allow for method chaining. + */ + public Builder setParticleSettings(TotemParticle[] particleSettings) { + config.particleSettings = particleSettings; + return this; + } + + /** + * Sets the requirements for the TotemConfig being built. + * + * @param requirements An array of Requirement objects representing activation requirements. + * @return The builder instance to allow for method chaining. + */ + public Builder setRequirements(Requirement[] requirements) { + config.requirements = requirements; + return this; + } + + /** + * Sets the radius for the TotemConfig being built. + * + * @param radius The activation radius for the totem. + * @return The builder instance to allow for method chaining. + */ + public Builder setRadius(double radius) { + config.radius = radius; + return this; + } + + /** + * Sets the duration for the TotemConfig being built. + * + * @param duration The duration of the totem's effect. + * @return The builder instance to allow for method chaining. + */ + public Builder setDuration(int duration) { + config.duration = duration; + return this; + } + + /** + * Builds and returns the finalized TotemConfig object. + * + * @return The constructed TotemConfig object. + */ + public TotemConfig build() { + return config; + } + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java new file mode 100644 index 00000000..c52c6c02 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemModel.java @@ -0,0 +1,277 @@ +/* + * 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.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock; +import org.apache.commons.lang3.SerializationUtils; +import org.bukkit.Axis; +import org.bukkit.Location; + +import java.io.Serializable; +import java.util.StringJoiner; + +/** + * This class represents a totem model used to define the pattern of a totem. + */ +public class TotemModel implements Serializable { + + private int coreX; + private final int coreY; + private int coreZ; + // [Y][Z][X][alternative totem blocks] + private TotemBlock[][][][] model; + + /** + * Constructs a TotemModel with the specified parameters. + * + * @param coreX X-coordinate of the totem's core within the model. + * @param coreY Y-coordinate of the totem's core within the model. + * @param coreZ Z-coordinate of the totem's core within the model. + * @param model 3D array representing the totem model's structure. + */ + public TotemModel(int coreX, int coreY, int coreZ, TotemBlock[][][][] model) { + this.coreX = coreX; + this.coreY = coreY; + this.coreZ = coreZ; + this.model = model; + } + + /** + * Get the totem core as an array of TotemBlock objects. + * + * @return An array of TotemBlock objects representing the totem's core. + */ + public TotemBlock[] getTotemCore() { + return model[coreY][coreZ][coreX]; + } + + /** + * Get the X-coordinate of the totem's core within the model. + * + * @return The X-coordinate as an integer. + */ + public int getCoreX() { + return coreX; + } + + /** + * Get the Y-coordinate of the totem's core within the model. + * + * @return The Y-coordinate as an integer. + */ + public int getCoreY() { + return coreY; + } + + /** + * Get the Z-coordinate of the totem's core within the model. + * + * @return The Z-coordinate as an integer. + */ + public int getCoreZ() { + return coreZ; + } + + /** + * Get the 3D array representing the totem model's structure. + * + * @return The 3D array of TotemBlock objects. + */ + public TotemBlock[][][][] getModel() { + return model; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + for (int h = 0; h < model.length; h++) { + stringBuilder.append("layer: ").append(h + 1).append("\n"); + TotemBlock[][][] totemBlocks1 = model[h]; + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + StringJoiner stringJoiner = new StringJoiner("||"); + for (TotemBlock totemBlock : totemBlocks3) { + stringJoiner.add(totemBlock.toString()); + } + stringBuilder.append(stringJoiner).append("\t"); + } + stringBuilder.append("\n"); + } + } + return stringBuilder.toString(); + } + + public TotemModel deepClone() { + return SerializationUtils.clone(this); + } + + /** + * Rotate the totem model 90 degrees clockwise. + * + * @return The rotated TotemModel. + */ + public TotemModel rotate90() { + int tempX = this.coreX; + this.coreX = this.coreZ; + this.coreZ = this.model[0][0].length - 1 - tempX; + this.model = rotate90(model); + for (TotemBlock[][][] totemBlocks1 : model) { + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + for (TotemBlock totemBlock : totemBlocks3) { + totemBlock.rotate90(); + } + } + } + } + return this; + } + + /** + * Mirror the totem model horizontally. + * + * @return The mirrored TotemModel. + */ + public TotemModel mirrorHorizontally() { + mirrorHorizontally(model); + this.coreZ = model[0].length - this.coreZ - 1; + for (TotemBlock[][][] totemBlocks1 : model) { + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + for (TotemBlock totemBlock : totemBlocks3) { + totemBlock.mirror(Axis.X); + } + } + } + } + return this; + } + + /** + * Mirror the totem model vertically. + * + * @return The mirrored TotemModel. + */ + public TotemModel mirrorVertically() { + mirrorVertically(model); + this.coreX = model[0][0].length - this.coreX - 1; + + for (TotemBlock[][][] totemBlocks1 : model) { + for (TotemBlock[][] totemBlocks2 : totemBlocks1) { + for (TotemBlock[] totemBlocks3 : totemBlocks2) { + for (TotemBlock totemBlock : totemBlocks3) { + totemBlock.mirror(Axis.Z); + } + } + } + } + return this; + } + + /** + * Check if the provided location satisfies the pattern defined by the totem model. + * + * @param location The location to check. + * @return True if the location satisfies the pattern, false otherwise. + */ + public boolean isPatternSatisfied(Location location) { + Location startLoc = location.clone().subtract(0, coreY, 0); + + int height = model.length; + int width = model[0].length; + int length = model[0][0].length; + + for (int y = 0; y < height; y++) { + Location loc = startLoc.clone().add(-coreX, y, -coreZ); + for (int z = 0; z < width; z++) { + outer: + for (int x = 0; x < length; x++) { + for (TotemBlock totemBlock : model[y][z][x]) { + if (totemBlock.isRightBlock(loc.clone().add(x, 0, z).getBlock())) { + continue outer; + } + } + return false; + } + } + } + return true; + } + + /** + * Rotate a 3D totem model 90 degrees clockwise. + * + * @param matrix The 3D totem model to rotate. + * @return The rotated 3D totem model. + */ + private static TotemBlock[][][][] rotate90(TotemBlock[][][][] matrix) { + int height = matrix.length; + int rows = matrix[0].length; + int cols = matrix[0][0].length; + TotemBlock[][][][] rotated = new TotemBlock[height][cols][rows][]; + for (int h = 0; h < height; h++) { + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + rotated[h][c][rows - 1 - r] = matrix[h][r][c]; + } + } + } + return rotated; + } + + /** + * Mirror a 3D totem model horizontally. + * + * @param matrix The 3D totem model to mirror. + */ + private static void mirrorHorizontally(TotemBlock[][][][] matrix) { + int height = matrix.length; + int rows = matrix[0].length; + int cols = matrix[0][0].length; + + for (int h = 0; h < height; h++) { + for (int i = 0; i < rows / 2; i++) { + for (int j = 0; j < cols; j++) { + TotemBlock[] temp = matrix[h][i][j]; + matrix[h][i][j] = matrix[h][rows - i - 1][j]; + matrix[h][rows - i - 1][j] = temp; + } + } + } + } + + /** + * Mirror a 3D totem model vertically. + * + * @param matrix The 3D totem model to mirror. + */ + private static void mirrorVertically(TotemBlock[][][][] matrix) { + int height = matrix.length; + int rows = matrix[0].length; + int cols = matrix[0][0].length; + for (int h = 0; h < height; h++) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols / 2; j++) { + TotemBlock[] temp = matrix[h][i][j]; + matrix[h][i][j] = matrix[h][i][cols - j - 1]; + matrix[h][i][cols - j - 1] = temp; + } + } + } + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java new file mode 100644 index 00000000..f898bfd8 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/TotemParticle.java @@ -0,0 +1,16 @@ +package net.momirealms.customfishing.api.mechanic.totem; + +import net.momirealms.customfishing.api.scheduler.CancellableTask; +import org.bukkit.Location; + +public interface TotemParticle { + + /** + * Start the particle task at specified location + * + * @param location location + * @param radius totem radius + * @return cancellable task + */ + CancellableTask start(Location location, double radius); +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java new file mode 100644 index 00000000..6d69648c --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/TotemBlock.java @@ -0,0 +1,118 @@ +/* + * 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.customfishing.api.mechanic.totem.block; + +import net.momirealms.customfishing.api.mechanic.totem.block.property.TotemBlockProperty; +import net.momirealms.customfishing.api.mechanic.totem.block.type.TypeCondition; +import org.bukkit.Axis; +import org.bukkit.block.Block; + +import java.io.Serializable; +import java.util.StringJoiner; + +/** + * Represents a TotemBlock that defines conditions and properties for a specific block type in a totem structure. + */ +public class TotemBlock implements Serializable { + + private final TypeCondition typeCondition; + private final TotemBlockProperty[] properties; + + /** + * Initializes a TotemBlock with the specified TypeCondition and properties. + * + * @param typeCondition The TypeCondition that specifies the block type. + * @param properties An array of TotemBlockProperty objects representing additional block properties. + */ + public TotemBlock(TypeCondition typeCondition, TotemBlockProperty[] properties) { + this.typeCondition = typeCondition; + this.properties = properties; + } + + /** + * Gets the TypeCondition associated with this TotemBlock. + * + * @return The TypeCondition defining the block type. + */ + public TypeCondition getTypeCondition() { + return typeCondition; + } + + /** + * Gets an array of properties associated with this TotemBlock. + * + * @return An array of TotemBlockProperty objects representing block properties. + */ + public TotemBlockProperty[] getProperties() { + return properties; + } + + /** + * Checks if a given Block satisfies the TypeCondition and properties of this TotemBlock. + * + * @param block The Block to be checked against the conditions and properties. + * @return `true` if the block satisfies all conditions and properties, otherwise `false`. + */ + public boolean isRightBlock(Block block) { + if (!typeCondition.isMet(block)) { + return false; + } + for (TotemBlockProperty property : properties) { + if (!property.isPropertyMet(block)) { + return false; + } + } + return true; + } + + /** + * Rotates the properties of this TotemBlock by 90 degrees. + * This method should be called when the totem structure is rotated. + */ + public void rotate90() { + for (TotemBlockProperty property : properties) { + property.rotate90(); + } + } + + /** + * Mirrors the properties of this TotemBlock horizontally or vertically. + * This method should be called when the totem structure is mirrored. + * + * @param axis The Axis along which to mirror the properties (X or Z). + */ + public void mirror(Axis axis) { + for (TotemBlockProperty property : properties) { + property.mirror(axis); + } + } + + /** + * Returns the raw text representation of this TotemBlock, including its TypeCondition and properties. + * + * @return The raw text representation of this TotemBlock. + */ + @Override + public String toString() { + StringJoiner stringJoiner = new StringJoiner(";"); + for (TotemBlockProperty property : properties) { + stringJoiner.add(property.getRawText()); + } + return typeCondition.getRawText() + "{" + stringJoiner + "}"; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java new file mode 100644 index 00000000..7fd160e0 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/AxisImpl.java @@ -0,0 +1,71 @@ +/* + * 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.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; +import org.bukkit.block.data.Orientable; + +import java.io.Serializable; +import java.util.Locale; + +public class AxisImpl implements TotemBlockProperty, Serializable { + + private Axis axis; + + public AxisImpl(Axis axis) { + this.axis = axis; + } + + @Override + public TotemBlockProperty mirror(Axis axis) { + return this; + } + + /** + * Rotates the block axis 90 degrees. (X -> Z, Z -> X) + * @return The rotated block axis. + */ + @Override + public TotemBlockProperty rotate90() { + if (this.axis == Axis.X) { + axis = Axis.Z; + } else if (this.axis == Axis.Z) { + axis = Axis.X; + } + return this; + } + + /** + * Checks if the block has the property. + * @param block The block to check. + * @return True if the block has the property. + */ + @Override + public boolean isPropertyMet(Block block) { + if (block.getBlockData() instanceof Orientable orientable) { + return orientable.getAxis().equals(this.axis); + } + return false; + } + + @Override + public String getRawText() { + return "axis=" + axis.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java new file mode 100644 index 00000000..8519fad3 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/FaceImpl.java @@ -0,0 +1,86 @@ +/* + * 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.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Directional; + +import java.io.Serializable; +import java.util.Locale; + +public class FaceImpl implements TotemBlockProperty, Serializable { + + private BlockFace blockFace; + + public FaceImpl(BlockFace blockFace) { + this.blockFace = blockFace; + } + + /** + * Mirrors the block face if the axis is X or Z. + * @param axis The axis to mirror. + * @return The mirrored block face. + */ + @Override + public TotemBlockProperty mirror(Axis axis) { + if (axis == Axis.X) { + if (blockFace == BlockFace.SOUTH || blockFace == BlockFace.NORTH) { + return new FaceImpl(blockFace.getOppositeFace()); + } else { + return this; + } + } else if (axis == Axis.Z) { + if (blockFace == BlockFace.EAST || blockFace == BlockFace.WEST) { + return new FaceImpl(blockFace.getOppositeFace()); + } else { + return this; + } + } + return this; + } + + @Override + public TotemBlockProperty rotate90() { + switch (blockFace) { + case UP, DOWN -> { + return this; + } + case EAST -> blockFace = BlockFace.SOUTH; + case SOUTH -> blockFace = BlockFace.WEST; + case WEST -> blockFace = BlockFace.NORTH; + case NORTH -> blockFace = BlockFace.EAST; + default -> throw new IllegalArgumentException("Unsupported block facing: " + blockFace); + } + return this; + } + + @Override + public boolean isPropertyMet(Block block) { + if (block.getBlockData() instanceof Directional directional) { + return directional.getFacing().equals(this.blockFace); + } + return false; + } + + @Override + public String getRawText() { + return "face=" + blockFace.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java new file mode 100644 index 00000000..e2a2e2fb --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/HalfImpl.java @@ -0,0 +1,74 @@ +/* + * 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.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; +import org.bukkit.block.data.Bisected; + +import java.io.Serializable; +import java.util.Locale; + +public class HalfImpl implements TotemBlockProperty, Serializable { + private final Bisected.Half half; + + public HalfImpl(Bisected.Half half) { + this.half = half; + } + + /** + * half is not affected by mirroring. + * @param axis The axis to mirror. + * @return this + */ + @Override + public TotemBlockProperty mirror(Axis axis) { + return this; + } + + /** + * half is not affected by rotation. + * @return this + */ + @Override + public TotemBlockProperty rotate90() { + return this; + } + + /** + * Checks if the block's half is the same as the half of this property. + * @param block The block to check. + * @return true if the block's half is the same as the half of this property. + */ + @Override + public boolean isPropertyMet(Block block) { + if (block.getBlockData() instanceof Bisected bisected) { + return bisected.getHalf().equals(this.half); + } + return false; + } + + /** + * Returns the raw text of the half property. + * @return The raw text of the half property. + */ + @Override + public String getRawText() { + return "half=" + half.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java new file mode 100644 index 00000000..be238682 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/property/TotemBlockProperty.java @@ -0,0 +1,50 @@ +/* + * 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.customfishing.api.mechanic.totem.block.property; + +import org.bukkit.Axis; +import org.bukkit.block.Block; + +public interface TotemBlockProperty { + + /** + * Mirrors the block face if the axis is X or Z. + * @param axis The axis to mirror. + * @return The mirrored block face. + */ + TotemBlockProperty mirror(Axis axis); + + /** + * Rotates the block face 90 degrees. + * @return The rotated block face. + */ + TotemBlockProperty rotate90(); + + /** + * Checks if the block has the property. + * @param block The block to check. + * @return True if the block has the property. + */ + boolean isPropertyMet(Block block); + + /** + * Gets the raw text of the property. + * @return The raw text of the property. + */ + String getRawText(); +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java new file mode 100644 index 00000000..1d723c5f --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EndWithType.java @@ -0,0 +1,56 @@ +/* + * 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.customfishing.api.mechanic.totem.block.type; + +import org.bukkit.block.Block; + +import java.io.Serializable; + +/** + * Represents a TypeCondition that checks if a Block's type name ends with a specified string. + */ +public class EndWithType implements TypeCondition, Serializable { + + private final String end; + + public EndWithType(String end) { + this.end = end; + } + + /** + * Checks if the specified Block's type name ends with the configured ending string. + * + * @param type The Block to check. + * @return `true` if the Block's type name ends with the specified string, otherwise `false`. + */ + @Override + public boolean isMet(Block type) { + return type.getType().name().endsWith(end); + } + + /** + * Gets the raw text representation of this TypeCondition. + * The raw text includes the asterisk (*) followed by the configured ending string. + * + * @return The raw text representation of this TypeCondition. + */ + @Override + public String getRawText() { + return "*" + end; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java new file mode 100644 index 00000000..8323aac5 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/EqualType.java @@ -0,0 +1,56 @@ +/* + * 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.customfishing.api.mechanic.totem.block.type; + +import net.momirealms.customfishing.api.CustomFishingPlugin; +import org.bukkit.block.Block; + +import java.io.Serializable; + +/** + * Represents a TypeCondition that checks if a Block's type matches a specified type string. + */ +public class EqualType implements TypeCondition, Serializable { + + private final String type; + + public EqualType(String type) { + this.type = type; + } + + /** + * Checks if the specified Block's type matches the configured type string. + * + * @param type The Block to check. + * @return `true` if the Block's type matches the specified type string, otherwise `false`. + */ + @Override + public boolean isMet(Block type) { + return this.type.equals(CustomFishingPlugin.get().getBlockManager().getAnyPluginBlockID(type)); + } + + /** + * Gets the raw text representation of this TypeCondition, which is the configured type string. + * + * @return The raw text representation of this TypeCondition. + */ + @Override + public String getRawText() { + return type; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java new file mode 100644 index 00000000..7fab7ba1 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/StartWithType.java @@ -0,0 +1,55 @@ +/* + * 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.customfishing.api.mechanic.totem.block.type; + +import org.bukkit.block.Block; + +import java.io.Serializable; + +/** + * Represents a TypeCondition that checks if a Block's type starts with a specified prefix. + */ +public class StartWithType implements TypeCondition, Serializable { + + private final String start; + + public StartWithType(String start) { + this.start = start; + } + + /** + * Checks if the specified Block's type starts with the configured prefix. + * + * @param type The Block to check. + * @return `true` if the Block's type starts with the specified prefix, otherwise `false`. + */ + @Override + public boolean isMet(Block type) { + return type.getType().name().startsWith(start); + } + + /** + * Gets the raw text representation of this TypeCondition, which is the configured prefix followed by '*'. + * + * @return The raw text representation of this TypeCondition. + */ + @Override + public String getRawText() { + return start + "*"; + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java new file mode 100644 index 00000000..4f5422b2 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/totem/block/type/TypeCondition.java @@ -0,0 +1,57 @@ +/* + * 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.customfishing.api.mechanic.totem.block.type; + +import org.bukkit.block.Block; + +/** + * Represents a condition used to check the type of a Block. + */ +public interface TypeCondition { + + /** + * Checks if the specified Block meets the condition. + * + * @param block The Block to check. + * @return `true` if the condition is met, otherwise `false`. + */ + boolean isMet(Block block); + + /** + * Gets the raw text representation of this TypeCondition. + * + * @return The raw text representation of this TypeCondition. + */ + String getRawText(); + + /** + * Gets a TypeCondition based on its raw text representation. + * + * @param raw The raw text representation of the TypeCondition. + * @return A TypeCondition instance corresponding to the raw text. + */ + static TypeCondition getTypeCondition(String raw) { + if (raw.startsWith("*")) { + return new EndWithType(raw.substring(1)); + } else if (raw.endsWith("*")) { + return new StartWithType(raw.substring(0, raw.length() -1)); + } else { + return new EqualType(raw); + } + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/scheduler/CancellableTask.java b/api/src/main/java/net/momirealms/customfishing/api/scheduler/CancellableTask.java index 07202ca0..257d4a4c 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/scheduler/CancellableTask.java +++ b/api/src/main/java/net/momirealms/customfishing/api/scheduler/CancellableTask.java @@ -19,7 +19,15 @@ package net.momirealms.customfishing.api.scheduler; public interface CancellableTask { + /** + * Cancel the task + */ void cancel(); + /** + * Get if the task is cancelled or not + * + * @return cancelled or not + */ boolean isCancelled(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/scheduler/Scheduler.java b/api/src/main/java/net/momirealms/customfishing/api/scheduler/Scheduler.java index 88dbf496..515a4c51 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/scheduler/Scheduler.java +++ b/api/src/main/java/net/momirealms/customfishing/api/scheduler/Scheduler.java @@ -23,17 +23,71 @@ import java.util.concurrent.TimeUnit; public interface Scheduler { + /** + * Runs a task synchronously on the main server thread or region thread. + * + * @param runnable The task to run. + * @param location The location associated with the task. + */ void runTaskSync(Runnable runnable, Location location); + /** + * Runs a task synchronously with a specified delay and period. + * + * @param runnable The task to run. + * @param location The location associated with the task. + * @param delayTicks The delay in ticks before the first execution. + * @param periodTicks The period between subsequent executions in ticks. + * @return A CancellableTask for managing the scheduled task. + */ CancellableTask runTaskSyncTimer(Runnable runnable, Location location, long delayTicks, long periodTicks); + /** + * Runs a task asynchronously with a specified delay. + * + * @param runnable The task to run. + * @param delay The delay before the task execution. + * @param timeUnit The time unit for the delay. + * @return A CancellableTask for managing the scheduled task. + */ CancellableTask runTaskAsyncLater(Runnable runnable, long delay, TimeUnit timeUnit); + /** + * Runs a task asynchronously. + * + * @param runnable The task to run. + */ void runTaskAsync(Runnable runnable); + /** + * Runs a task synchronously with a specified delay. + * + * @param runnable The task to run. + * @param location The location associated with the task. + * @param delay The delay before the task execution. + * @param timeUnit The time unit for the delay. + * @return A CancellableTask for managing the scheduled task. + */ CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delay, TimeUnit timeUnit); + /** + * Runs a task synchronously with a specified delay in ticks. + * + * @param runnable The task to run. + * @param location The location associated with the task. + * @param delayTicks The delay in ticks before the task execution. + * @return A CancellableTask for managing the scheduled task. + */ CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delayTicks); + /** + * Runs a task asynchronously with a specified delay and period. + * + * @param runnable The task to run. + * @param delay The delay before the first execution. + * @param period The period between subsequent executions. + * @param timeUnit The time unit for the delay and period. + * @return A CancellableTask for managing the scheduled task. + */ CancellableTask runTaskAsyncTimer(Runnable runnable, long delay, long period, TimeUnit timeUnit); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/util/FontUtils.java b/api/src/main/java/net/momirealms/customfishing/api/util/FontUtils.java index 4cd8f628..cd311e70 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/util/FontUtils.java +++ b/api/src/main/java/net/momirealms/customfishing/api/util/FontUtils.java @@ -17,8 +17,22 @@ package net.momirealms.customfishing.api.util; +/** + * Utility class for working with fonts in text. + */ public class FontUtils { + private FontUtils() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + + /** + * Surrounds the given text with a specified font tag. + * + * @param text The text to be surrounded with the font tag. + * @param font The font to use in the font tag. + * @return The input text surrounded by the font tag. + */ public static String surroundWithFont(String text, String font) { return "" + text + ""; } diff --git a/api/src/main/java/net/momirealms/customfishing/api/util/InventoryUtils.java b/api/src/main/java/net/momirealms/customfishing/api/util/InventoryUtils.java index 093cb13b..906a9d0b 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/util/InventoryUtils.java +++ b/api/src/main/java/net/momirealms/customfishing/api/util/InventoryUtils.java @@ -35,8 +35,23 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +/** + * Utility class for working with Bukkit Inventories and item stacks. + */ public class InventoryUtils { + private InventoryUtils() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + + /** + * Create a custom inventory with a specified size and title component. + * + * @param inventoryHolder The holder of the inventory. + * @param size The size of the inventory. + * @param component The title component of the inventory. + * @return The created Inventory instance. + */ public static Inventory createInventory(InventoryHolder inventoryHolder, int size, Component component) { try { boolean isSpigot = CustomFishingPlugin.get().getVersionManager().isSpigot(); @@ -58,6 +73,14 @@ public class InventoryUtils { } } + /** + * Create a custom inventory with a specified type and title component. + * + * @param inventoryHolder The holder of the inventory. + * @param type The type of the inventory. + * @param component The title component of the inventory. + * @return The created Inventory instance. + */ public static Inventory createInventory(InventoryHolder inventoryHolder, InventoryType type, Component component) { try { boolean isSpigot = CustomFishingPlugin.get().getVersionManager().isSpigot(); @@ -79,6 +102,12 @@ public class InventoryUtils { } } + /** + * Serialize an array of ItemStacks to a Base64-encoded string. + * + * @param contents The ItemStack array to serialize. + * @return The Base64-encoded string representing the serialized ItemStacks. + */ public static @NotNull String stacksToBase64(ItemStack[] contents) { if (contents.length == 0) { return ""; @@ -101,9 +130,10 @@ public class InventoryUtils { } /** - * Get itemStacks from base64 - * @param base64 base64 - * @return itemStacks + * Deserialize an ItemStack array from a Base64-encoded string. + * + * @param base64 The Base64-encoded string representing the serialized ItemStacks. + * @return An array of ItemStacks deserialized from the input string. */ @Nullable public static ItemStack[] getInventoryItems(String base64) { diff --git a/api/src/main/java/net/momirealms/customfishing/api/util/LogUtils.java b/api/src/main/java/net/momirealms/customfishing/api/util/LogUtils.java index 450fa8ff..b99d4112 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/util/LogUtils.java +++ b/api/src/main/java/net/momirealms/customfishing/api/util/LogUtils.java @@ -22,30 +22,59 @@ import org.jetbrains.annotations.NotNull; import java.util.logging.Level; +/** + * Utility class for logging messages with various log levels. + */ public final class LogUtils { - public static void info(@NotNull String s) { - CustomFishingPlugin.getInstance().getLogger().info(s); + /** + * Log an informational message. + * + * @param message The message to log. + */ + public static void info(@NotNull String message) { + CustomFishingPlugin.getInstance().getLogger().info(message); } - public static void warn(@NotNull String s) { - CustomFishingPlugin.getInstance().getLogger().warning(s); + /** + * Log a warning message. + * + * @param message The message to log. + */ + public static void warn(@NotNull String message) { + CustomFishingPlugin.getInstance().getLogger().warning(message); } - public static void severe(@NotNull String s) { - CustomFishingPlugin.getInstance().getLogger().severe(s); + /** + * Log a severe error message. + * + * @param message The message to log. + */ + public static void severe(@NotNull String message) { + CustomFishingPlugin.getInstance().getLogger().severe(message); } - public static void warn(@NotNull String s, Throwable t) { - CustomFishingPlugin.getInstance().getLogger().log(Level.WARNING, s, t); + /** + * Log a warning message with a throwable exception. + * + * @param message The message to log. + * @param throwable The throwable exception to log. + */ + public static void warn(@NotNull String message, Throwable throwable) { + CustomFishingPlugin.getInstance().getLogger().log(Level.WARNING, message, throwable); } - public static void severe(@NotNull String s, Throwable t) { - CustomFishingPlugin.getInstance().getLogger().log(Level.SEVERE, s, t); + /** + * Log a severe error message with a throwable exception. + * + * @param message The message to log. + * @param throwable The throwable exception to log. + */ + public static void severe(@NotNull String message, Throwable throwable) { + CustomFishingPlugin.getInstance().getLogger().log(Level.SEVERE, message, throwable); } private LogUtils() { throw new UnsupportedOperationException("This class cannot be instantiated"); } - } diff --git a/api/src/main/java/net/momirealms/customfishing/api/util/OffsetUtils.java b/api/src/main/java/net/momirealms/customfishing/api/util/OffsetUtils.java index 8d19f614..bfb0956e 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/util/OffsetUtils.java +++ b/api/src/main/java/net/momirealms/customfishing/api/util/OffsetUtils.java @@ -19,8 +19,16 @@ package net.momirealms.customfishing.api.util; import org.bukkit.configuration.ConfigurationSection; +/** + * Utility class for generating offset characters based on a font configuration. + */ +@SuppressWarnings("DuplicatedCode") public class OffsetUtils { + private OffsetUtils() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + private static String font; private static String negative_1; private static String negative_2; @@ -39,6 +47,11 @@ public class OffsetUtils { private static String positive_64; private static String positive_128; + /** + * Load font configuration from a given section. + * + * @param section The configuration section containing font settings. + */ public static void loadConfig(ConfigurationSection section) { if (section != null) { font = section.getString("font", "customfishing:offset_chars"); @@ -61,6 +74,12 @@ public class OffsetUtils { } } + /** + * Get the shortest negative offset characters for a given number. + * + * @param n The number for which to generate offset characters. + * @return Offset characters as a string. + */ public static String getShortestNegChars(int n) { StringBuilder stringBuilder = new StringBuilder(); while (n >= 128) { @@ -97,6 +116,12 @@ public class OffsetUtils { return stringBuilder.toString(); } + /** + * Get the shortest positive offset characters for a given number. + * + * @param n The number for which to generate offset characters. + * @return Offset characters as a string. + */ public static String getShortestPosChars(int n) { StringBuilder stringBuilder = new StringBuilder(); while (n >= 128) { @@ -133,6 +158,13 @@ public class OffsetUtils { return stringBuilder.toString(); } + /** + * Get offset characters for a given number. This method selects between positive and negative + * offset characters based on the sign of the number. + * + * @param n The number for which to generate offset characters. + * @return Offset characters as a string. + */ public static String getOffsetChars(int n) { if (n > 0) { return "" + getShortestPosChars(n) + ""; diff --git a/api/src/main/java/net/momirealms/customfishing/api/util/WeightUtils.java b/api/src/main/java/net/momirealms/customfishing/api/util/WeightUtils.java index 3e14c754..4de91cab 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/util/WeightUtils.java +++ b/api/src/main/java/net/momirealms/customfishing/api/util/WeightUtils.java @@ -24,8 +24,18 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +/** + * Utility class for selecting random items based on weights. + */ public class WeightUtils { + /** + * Get a random item from a list of pairs, each associated with a weight. + * + * @param pairs A list of pairs where the left element is the item and the right element is its weight. + * @param The type of items in the list. + * @return A randomly selected item from the list, or null if no item was selected. + */ public static T getRandom(List> pairs) { List available = new ArrayList<>(); double[] weights = new double[pairs.size()]; @@ -40,6 +50,13 @@ public class WeightUtils { return getRandom(weights, available, index); } + /** + * Get a random item from a map where each entry is associated with a weight. + * + * @param map A map where each entry's key is an item, and the value is its weight. + * @param The type of items in the map. + * @return A randomly selected item from the map, or null if no item was selected. + */ public static T getRandom(Map map) { List available = new ArrayList<>(); double[] weights = new double[map.size()]; @@ -54,6 +71,15 @@ public class WeightUtils { return getRandom(weights, available, index); } + /** + * Get a random item from a list of items with associated weights. + * + * @param weights An array of weights corresponding to the available items. + * @param available A list of available items. + * @param effectiveSize The effective size of the array and list after filtering out items with non-positive weights. + * @param The type of items. + * @return A randomly selected item from the list, or null if no item was selected. + */ private static T getRandom(double[] weights, List available, int effectiveSize) { double total = Arrays.stream(weights).sum(); double[] weightRatios = new double[effectiveSize]; diff --git a/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/CustomCropsSeasonImpl.java b/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/CustomCropsSeasonImpl.java index 557b3d93..6d2b9ea2 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/CustomCropsSeasonImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/CustomCropsSeasonImpl.java @@ -18,8 +18,10 @@ package net.momirealms.customfishing.compatibility.season; import net.momirealms.customcrops.api.CustomCropsAPI; +import net.momirealms.customcrops.api.object.CCWorldSeason; import net.momirealms.customfishing.api.integration.SeasonInterface; import org.bukkit.World; +import org.jetbrains.annotations.NotNull; import java.util.Objects; @@ -31,8 +33,11 @@ public class CustomCropsSeasonImpl implements SeasonInterface { customCropsAPI = CustomCropsAPI.getInstance(); } + @NotNull @Override public String getSeason(World world) { - return Objects.requireNonNull(customCropsAPI.getSeason(world.getName())).getSeason(); + CCWorldSeason season = customCropsAPI.getSeason(world.getName()); + if (season == null) return "disabled"; + return season.getSeason(); } } \ No newline at end of file diff --git a/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/RealisticSeasonsImpl.java b/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/RealisticSeasonsImpl.java index cfe25c8b..f0999f1f 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/RealisticSeasonsImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/compatibility/season/RealisticSeasonsImpl.java @@ -20,9 +20,11 @@ package net.momirealms.customfishing.compatibility.season; import me.casperge.realisticseasons.api.SeasonsAPI; import net.momirealms.customfishing.api.integration.SeasonInterface; import org.bukkit.World; +import org.jetbrains.annotations.NotNull; public class RealisticSeasonsImpl implements SeasonInterface { + @NotNull @Override public String getSeason(World world) { return switch (SeasonsAPI.getInstance().getSeason(world)) { 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 c95f13de..8d08f340 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 @@ -27,6 +27,7 @@ import net.momirealms.customfishing.api.scheduler.CancellableTask; import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.setting.CFLocale; import net.momirealms.customfishing.storage.method.database.nosql.RedisManager; +import net.momirealms.customfishing.util.ConfigUtils; import org.bukkit.Bukkit; import org.bukkit.boss.BarColor; import org.bukkit.configuration.ConfigurationSection; @@ -155,7 +156,7 @@ public class CompetitionManagerImpl implements CompetitionManager { CompetitionConfig competitionConfig = builder.build(); List> timePairs = section.getStringList("start-time") - .stream().map(this::getTimePair).toList(); + .stream().map(ConfigUtils::splitStringIntegerArgs).toList(); List weekdays = section.getIntegerList("start-weekday"); if (weekdays.size() == 0) { weekdays.addAll(List.of(1,2,3,4,5,6,7)); @@ -171,6 +172,12 @@ public class CompetitionManagerImpl implements CompetitionManager { } } + /** + * Gets prize actions from a configuration section. + * + * @param section The configuration section containing prize actions. + * @return A HashMap where keys are action names and values are arrays of Action objects. + */ public HashMap getPrizeActions(ConfigurationSection section) { HashMap map = new HashMap<>(); if (section == null) return map; @@ -182,11 +189,9 @@ public class CompetitionManagerImpl implements CompetitionManager { return map; } - public Pair getTimePair(String time) { - String[] split = time.split(":"); - return Pair.of(Integer.parseInt(split[0]), Integer.parseInt(split[1])); - } - + /** + * Checks the timer for the next competition and starts it if necessary. + */ public void timerCheck() { LocalDateTime now = LocalDateTime.now(); CompetitionSchedule competitionSchedule = new CompetitionSchedule( diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionSchedule.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionSchedule.java index 5b6293d7..03564cf3 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionSchedule.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/CompetitionSchedule.java @@ -31,22 +31,47 @@ public class CompetitionSchedule { this.second = second; } + /** + * Gets the weekday associated with this time schedule. + * + * @return The weekday value (e.g., 1 for Monday, 2 for Tuesday, etc.). + */ public int getWeekday() { return weekday; } + /** + * Gets the hour of the day associated with this time schedule. + * + * @return The hour value (0-23). + */ public int getHour() { return hour; } + /** + * Gets the minute of the hour associated with this time schedule. + * + * @return The minute value (0-59). + */ public int getMinute() { return minute; } + /** + * Gets the second of the minute associated with this time schedule. + * + * @return The second value (0-59). + */ public int getSecond() { return second; } + /** + * Calculates the total number of seconds represented by this time schedule. + * + * @return The total number of seconds. + */ public int getTotalSeconds() { return second + minute * 60 + @@ -54,6 +79,12 @@ public class CompetitionSchedule { weekday * 24 * 60 * 60; } + /** + * Calculates the time difference (delta) in seconds between this time schedule and a given total seconds value. + * + * @param totalSeconds The total seconds value to compare against. + * @return The time difference in seconds. + */ public int getTimeDelta(int totalSeconds) { int thisSeconds = getTotalSeconds(); if (thisSeconds >= totalSeconds) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarManager.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarManager.java index 0b4f6a53..1bb6b546 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarManager.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarManager.java @@ -43,6 +43,9 @@ public class ActionBarManager implements Listener { this.competition = competition; } + /** + * Loads the ActionBar manager, registering events and showing ActionBar messages to online players. + */ public void load() { Bukkit.getPluginManager().registerEvents(this, CustomFishingPlugin.getInstance()); if (actionBarConfig.isShowToAll()) { @@ -56,6 +59,9 @@ public class ActionBarManager implements Listener { } } + /** + * Unloads the ActionBar manager, unregistering events and hiding ActionBar messages for all players. + */ public void unload() { HandlerList.unregisterAll(this); for (ActionBarSender ActionBarSender : senderMap.values()) { @@ -64,6 +70,11 @@ public class ActionBarManager implements Listener { senderMap.clear(); } + /** + * Handles the PlayerQuitEvent to hide ActionBar messages for a player when they quit the game. + * + * @param event The PlayerQuitEvent. + */ @EventHandler public void onQuit(PlayerQuitEvent event) { final Player player = event.getPlayer(); @@ -74,6 +85,11 @@ public class ActionBarManager implements Listener { } } + /** + * Handles the PlayerJoinEvent to show ActionBar messages to players when they join the game. + * + * @param event The PlayerJoinEvent. + */ @EventHandler public void onJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); @@ -90,6 +106,11 @@ public class ActionBarManager implements Listener { }, 200, TimeUnit.MILLISECONDS); } + /** + * Shows an ActionBar message to a specific player. + * + * @param player The player to show the ActionBar message to. + */ public void showActionBarTo(Player player) { ActionBarSender sender = senderMap.get(player.getUniqueId()); if (sender == null) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarSender.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarSender.java index 8dd6ae75..c859b78f 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarSender.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/actionbar/ActionBarSender.java @@ -29,6 +29,9 @@ import org.bukkit.entity.Player; import java.util.HashMap; import java.util.concurrent.TimeUnit; +/** + * Manages and updates ActionBar messages for a specific player in a competition context. + */ public class ActionBarSender { private final Player player; @@ -42,6 +45,13 @@ public class ActionBarSender { private final Competition competition; private final HashMap privatePlaceholders; + /** + * Creates a new ActionBarSender instance for a player. + * + * @param player The player to manage ActionBar messages for. + * @param config The configuration for ActionBar messages. + * @param competition The competition associated with this ActionBarSender. + */ public ActionBarSender(Player player, ActionBarConfig config, Competition competition) { this.player = player; this.config = config; @@ -59,6 +69,9 @@ public class ActionBarSender { } } + /** + * Updates private placeholders used in ActionBar messages. + */ @SuppressWarnings("DuplicatedCode") private void updatePrivatePlaceholders() { this.privatePlaceholders.put("{score}", String.format("%.2f", competition.getRanking().getPlayerScore(player.getName()))); @@ -67,6 +80,9 @@ public class ActionBarSender { this.privatePlaceholders.putAll(competition.getCachedPlaceholders()); } + /** + * Shows the ActionBar message to the player. + */ public void show() { this.isShown = true; senderTask = CustomFishingPlugin.get().getScheduler().runTaskAsyncTimer(() -> { @@ -90,16 +106,29 @@ public class ActionBarSender { }, 50, 50, TimeUnit.MILLISECONDS); } + /** + * Hides the ActionBar message from the player. + */ public void hide() { if (senderTask != null && !senderTask.isCancelled()) senderTask.cancel(); this.isShown = false; } + /** + * Checks if the ActionBar message is currently visible to the player. + * + * @return True if the ActionBar message is visible, false otherwise. + */ public boolean isVisible() { return this.isShown; } + /** + * Gets the ActionBar configuration. + * + * @return The ActionBar configuration. + */ public ActionBarConfig getConfig() { return config; } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarManager.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarManager.java index 3992a815..1dccd3d5 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarManager.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarManager.java @@ -43,6 +43,9 @@ public class BossBarManager implements Listener { this.competition = competition; } + /** + * Loads the boss bar manager, registering events and showing boss bars to online players. + */ public void load() { Bukkit.getPluginManager().registerEvents(this, CustomFishingPlugin.getInstance()); if (bossBarConfig.isShowToAll()) { @@ -56,6 +59,9 @@ public class BossBarManager implements Listener { } } + /** + * Unloads the boss bar manager, unregistering events and hiding boss bars for all players. + */ public void unload() { HandlerList.unregisterAll(this); for (BossBarSender bossBarSender : senderMap.values()) { @@ -64,6 +70,11 @@ public class BossBarManager implements Listener { senderMap.clear(); } + /** + * Handles the PlayerQuitEvent to hide the boss bar for a player when they quit the game. + * + * @param event The PlayerQuitEvent. + */ @EventHandler public void onQuit(PlayerQuitEvent event) { final Player player = event.getPlayer(); @@ -74,6 +85,11 @@ public class BossBarManager implements Listener { } } + /** + * Handles the PlayerJoinEvent to show boss bars to players when they join the game. + * + * @param event The PlayerJoinEvent. + */ @EventHandler public void onJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); @@ -90,6 +106,11 @@ public class BossBarManager implements Listener { }, 200, TimeUnit.MILLISECONDS); } + /** + * Shows a boss bar to a specific player. + * + * @param player The player to show the boss bar to. + */ public void showBossBarTo(Player player) { BossBarSender sender = senderMap.get(player.getUniqueId()); if (sender == null) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarSender.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarSender.java index ee9bd6f2..e644fb27 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarSender.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/bossbar/BossBarSender.java @@ -40,6 +40,9 @@ import java.util.HashMap; import java.util.UUID; import java.util.concurrent.TimeUnit; +/** + * Manages and updates boss bars for a specific player in a competition context. + */ public class BossBarSender { private final Player player; @@ -54,6 +57,13 @@ public class BossBarSender { private final Competition competition; private final HashMap privatePlaceholders; + /** + * Creates a new BossBarSender instance for a player. + * + * @param player The player to manage the boss bar for. + * @param config The configuration for the boss bar. + * @param competition The competition associated with this boss bar. + */ public BossBarSender(Player player, BossBarConfig config, Competition competition) { this.player = player; this.uuid = UUID.randomUUID(); @@ -72,6 +82,9 @@ public class BossBarSender { } } + /** + * Updates private placeholders used in boss bar messages. + */ @SuppressWarnings("DuplicatedCode") private void updatePrivatePlaceholders() { this.privatePlaceholders.put("{score}", String.format("%.2f", competition.getRanking().getPlayerScore(player.getName()))); @@ -80,6 +93,9 @@ public class BossBarSender { this.privatePlaceholders.putAll(competition.getCachedPlaceholders()); } + /** + * Shows the boss bar to the player. + */ public void show() { this.isShown = true; CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getCreatePacket()); @@ -103,14 +119,27 @@ public class BossBarSender { }, 50, 50, TimeUnit.MILLISECONDS); } + /** + * Checks if the boss bar is currently visible to the player. + * + * @return True if the boss bar is visible, false otherwise. + */ public boolean isVisible() { return this.isShown; } + /** + * Gets the boss bar configuration. + * + * @return The boss bar configuration. + */ public BossBarConfig getConfig() { return config; } + /** + * Hides the boss bar from the player. + */ public void hide() { CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getRemovePacket()); if (senderTask != null && !senderTask.isCancelled()) senderTask.cancel(); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/LocalRankingImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/LocalRankingImpl.java index 8b8fd5d7..f310cfdf 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/LocalRankingImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/LocalRankingImpl.java @@ -23,6 +23,9 @@ import net.momirealms.customfishing.api.mechanic.competition.Ranking; import java.util.*; +/** + * Implementation of the Ranking interface that manages the ranking of competition players locally. + */ public class LocalRankingImpl implements Ranking { private final Set competitionPlayers; @@ -31,19 +34,38 @@ public class LocalRankingImpl implements Ranking { competitionPlayers = Collections.synchronizedSet(new TreeSet<>()); } + /** + * Adds a competition player to the ranking. + * + * @param competitionPlayer The CompetitionPlayer to add. + */ public void addPlayer(CompetitionPlayer competitionPlayer) { competitionPlayers.add(competitionPlayer); } + /** + * Removes a competition player from the ranking. + * + * @param competitionPlayer The CompetitionPlayer to remove. + */ public void removePlayer(CompetitionPlayer competitionPlayer) { competitionPlayers.removeIf(e -> e.equals(competitionPlayer)); } + /** + * Clears the list of competition players. + */ @Override public void clear() { competitionPlayers.clear(); } + /** + * Retrieves a competition player by their name. + * + * @param player The name of the player to retrieve. + * @return The CompetitionPlayer object if found, or null if not found. + */ @Override public CompetitionPlayer getCompetitionPlayer(String player) { for (CompetitionPlayer competitionPlayer : competitionPlayers) { @@ -54,6 +76,11 @@ public class LocalRankingImpl implements Ranking { return null; } + /** + * Returns an iterator for iterating over pairs of player names and scores. + * + * @return An iterator for pairs of player names and scores. + */ @Override public Iterator> getIterator() { List> players = new ArrayList<>(); @@ -63,11 +90,22 @@ public class LocalRankingImpl implements Ranking { return players.iterator(); } + /** + * Returns the number of competition players. + * + * @return The number of competition players. + */ @Override public int getSize() { return competitionPlayers.size(); } + /** + * Returns the rank of a player based on their name. + * + * @param player The name of the player to get the rank for. + * @return The rank of the player, or -1 if the player is not found. + */ @Override public int getPlayerRank(String player) { int index = 1; @@ -81,6 +119,12 @@ public class LocalRankingImpl implements Ranking { return -1; } + /** + * Returns the score of a player based on their name. + * + * @param player The name of the player to get the score for. + * @return The score of the player, or 0 if the player is not found. + */ @Override public double getPlayerScore(String player) { for (CompetitionPlayer competitionPlayer : competitionPlayers) { @@ -91,6 +135,12 @@ public class LocalRankingImpl implements Ranking { return 0; } + /** + * Returns the name of a player at a given index. + * + * @param i The index of the player to retrieve. + * @return The name of the player at the specified index, or null if not found. + */ @Override public String getPlayerAt(int i) { int index = 1; @@ -103,6 +153,12 @@ public class LocalRankingImpl implements Ranking { return null; } + /** + * Returns the score of a player at a given index. + * + * @param i The index of the player to retrieve. + * @return The score of the player at the specified index, or 0 if not found. + */ @Override public double getScoreAt(int i) { int index = 1; @@ -115,6 +171,12 @@ public class LocalRankingImpl implements Ranking { return 0f; } + /** + * Refreshes the data for a player by adding a score to their existing score or creating a new player. + * + * @param player The name of the player to update or create. + * @param score The score to add to the player's existing score or set as their initial score. + */ @Override public void refreshData(String player, double score) { CompetitionPlayer competitionPlayer = getCompetitionPlayer(player); @@ -128,6 +190,12 @@ public class LocalRankingImpl implements Ranking { } } + /** + * Sets the data for a player, updating their score or creating a new player. + * + * @param player The name of the player to update or create. + * @param score The score to set for the player. + */ @Override public void setData(String player, double score) { CompetitionPlayer competitionPlayer = getCompetitionPlayer(player); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/RedisRankingImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/RedisRankingImpl.java index b9a8ac46..b71ece98 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/RedisRankingImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/competition/ranking/RedisRankingImpl.java @@ -29,6 +29,9 @@ import java.util.List; public class RedisRankingImpl implements Ranking { + /** + * Clears the ranking data by removing all players and scores. + */ @Override public void clear() { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -36,6 +39,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Retrieves a competition player by their name from the Redis ranking. + * + * @param player The name of the player to retrieve. + * @return The CompetitionPlayer object if found, or null if not found. + */ @Override public CompetitionPlayer getCompetitionPlayer(String player) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -45,6 +54,11 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Returns an iterator for iterating over pairs of player names and scores in descending order. + * + * @return An iterator for pairs of player names and scores. + */ @Override public Iterator> getIterator() { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -53,6 +67,11 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Returns the number of players in the Redis ranking. + * + * @return The number of players in the ranking. + */ @Override public int getSize() { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -61,6 +80,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Returns the rank of a player based on their name in descending order (1-based). + * + * @param player The name of the player to get the rank for. + * @return The rank of the player, or -1 if the player is not found. + */ @Override public int getPlayerRank(String player) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -71,6 +96,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Returns the score of a player based on their name from the Redis ranking. + * + * @param player The name of the player to get the score for. + * @return The score of the player, or 0 if the player is not found. + */ @Override public double getPlayerScore(String player) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -81,6 +112,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Refreshes the data for a player in the Redis ranking by adding a score to their existing score or creating a new player. + * + * @param player The name of the player to update or create. + * @param score The score to add to the player's existing score or set as their initial score. + */ @Override public void refreshData(String player, double score) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -88,6 +125,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Sets the data for a player in the Redis ranking, updating their score or creating a new player. + * + * @param player The name of the player to update or create. + * @param score The score to set for the player. + */ @Override public void setData(String player, double score) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -95,6 +138,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Returns the name of the player at a given rank in descending order. + * + * @param rank The rank of the player to retrieve (1-based). + * @return The name of the player at the specified rank, or null if not found. + */ @Override public String getPlayerAt(int rank) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { @@ -104,6 +153,12 @@ public class RedisRankingImpl implements Ranking { } } + /** + * Returns the score of the player at a given rank in descending order. + * + * @param rank The rank of the player to retrieve (1-based). + * @return The score of the player at the specified rank, or 0 if not found. + */ @Override public double getScoreAt(int rank) { try (Jedis jedis = RedisManager.getInstance().getJedis()) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/entity/EntityManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/entity/EntityManagerImpl.java index af97b0de..d1c7f108 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/entity/EntityManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/entity/EntityManagerImpl.java @@ -84,6 +84,9 @@ public class EntityManagerImpl implements EntityManager { return entityLibraryMap.remove(identification) != null; } + /** + * Load configuration files for entity properties. + */ @SuppressWarnings("DuplicatedCode") private void loadConfig() { Deque fileDeque = new ArrayDeque<>(); @@ -109,6 +112,11 @@ public class EntityManagerImpl implements EntityManager { } } + /** + * Load a single entity configuration file. + * + * @param file The YAML file to load. + */ private void loadSingleFile(File file) { YamlConfiguration config = YamlConfiguration.loadConfiguration(file); for (Map.Entry entry : config.getValues(false).entrySet()) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/BaitAnimationTask.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/BaitAnimationTask.java index ad25d762..1811506b 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/BaitAnimationTask.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/BaitAnimationTask.java @@ -28,6 +28,9 @@ import org.bukkit.inventory.ItemStack; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; +/** + * A task responsible for animating bait when it's attached to a fishing hook. + */ public class BaitAnimationTask implements Runnable { private final CancellableTask cancellableTask; @@ -35,6 +38,14 @@ public class BaitAnimationTask implements Runnable { private final Player player; private final FishHook fishHook; + /** + * Constructs a new BaitAnimationTask. + * + * @param plugin The CustomFishingPlugin instance. + * @param player The player who cast the fishing rod. + * @param fishHook The FishHook entity. + * @param baitItem The bait ItemStack. + */ public BaitAnimationTask(CustomFishingPlugin plugin, Player player, FishHook fishHook, ItemStack baitItem) { this.player = player; this.fishHook = fishHook; @@ -46,7 +57,7 @@ public class BaitAnimationTask implements Runnable { @Override public void run() { - if ( fishHook == null + if ( fishHook == null || fishHook.isOnGround() || fishHook.isInLava() || fishHook.isInWater() @@ -59,6 +70,9 @@ public class BaitAnimationTask implements Runnable { } } + /** + * Cancels the bait animation and cleans up resources. + */ private void cancelAnimation() { cancellableTask.cancel(); CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, FakeItemUtils.getDestroyPacket(entityID)); 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 53e693e2..d3a763c1 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 @@ -244,6 +244,11 @@ public class FishingManagerImpl implements Listener, FishingManager { } } + /** + * Handle the event when the fishing hook lands on the ground. + * + * @param event The PlayerFishEvent that occurred. + */ private void onInGround(PlayerFishEvent event) { final Player player = event.getPlayer(); FishHook hook = event.getHook(); @@ -262,6 +267,11 @@ public class FishingManagerImpl implements Listener, FishingManager { } } + /** + * Handle the event when a player casts a fishing rod. + * + * @param event The PlayerFishEvent that occurred. + */ public void onCastRod(PlayerFishEvent event) { var player = event.getPlayer(); var fishingPreparation = new FishingPreparation(player, plugin); @@ -312,6 +322,11 @@ public class FishingManagerImpl implements Listener, FishingManager { fishingPreparation.triggerActions(ActionTrigger.CAST); } + /** + * Handle the event when a player catches an entity. + * + * @param event The PlayerFishEvent that occurred. + */ private void onCaughtEntity(PlayerFishEvent event) { final Player player = event.getPlayer(); final UUID uuid = player.getUniqueId(); @@ -361,6 +376,11 @@ public class FishingManagerImpl implements Listener, FishingManager { } } + /** + * Handle the event when a player catches a fish. + * + * @param event The PlayerFishEvent that occurred. + */ private void onCaughtFish(PlayerFishEvent event) { final Player player = event.getPlayer(); final UUID uuid = player.getUniqueId(); @@ -405,6 +425,11 @@ public class FishingManagerImpl implements Listener, FishingManager { } } + /** + * Handle the event when a player receives a bite on their fishing hook. + * + * @param event The PlayerFishEvent that occurred. + */ private void onBite(PlayerFishEvent event) { final Player player = event.getPlayer(); final UUID uuid = player.getUniqueId(); @@ -432,6 +457,11 @@ public class FishingManagerImpl implements Listener, FishingManager { } } + /** + * Handle the event when a player reels in their fishing line. + * + * @param event The PlayerFishEvent that occurred. + */ private void onReelIn(PlayerFishEvent event) { final Player player = event.getPlayer(); final UUID uuid = player.getUniqueId(); @@ -559,6 +589,12 @@ public class FishingManagerImpl implements Listener, FishingManager { ItemUtils.decreaseHookDurability(fishingPreparation.getRodItemStack(), 1, true); } + /** + * Handle the success of a fishing attempt, including spawning loot, calling events, and executing success actions. + * + * @param state The temporary fishing state containing information about the loot and effect. + * @param hook The FishHook entity associated with the fishing attempt. + */ public void success(TempFishingState state, FishHook hook) { var loot = state.getLoot(); var effect = state.getEffect(); @@ -617,6 +653,14 @@ public class FishingManagerImpl implements Listener, FishingManager { doSuccessActions(loot, effect, fishingPreparation, player); } + /** + * Execute success-related actions after a successful fishing attempt, including updating competition data, triggering events and actions, and updating player statistics. + * + * @param loot The loot that was successfully caught. + * @param effect The effect applied during fishing. + * @param fishingPreparation The fishing preparation containing preparation data. + * @param player The player who successfully caught the loot. + */ private void doSuccessActions(Loot loot, Effect effect, FishingPreparation fishingPreparation, Player player) { FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition(); if (competition != null) { 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 3a8747f8..e020d75c 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 @@ -46,6 +46,9 @@ import java.util.Objects; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; +/** + * A task responsible for checking the state of a fishing hook and handling lava fishing mechanics. + */ public class HookCheckTimerTask implements Runnable { private final FishingManagerImpl manager; @@ -62,6 +65,14 @@ public class HookCheckTimerTask implements Runnable { private Entity hookedEntity; private Loot loot; + /** + * Constructs a new HookCheckTimerTask. + * + * @param manager The FishingManagerImpl instance. + * @param fishHook The FishHook entity being checked. + * @param fishingPreparation The FishingPreparation instance. + * @param initialEffect The initial fishing effect. + */ public HookCheckTimerTask( FishingManagerImpl manager, FishHook fishHook, @@ -99,7 +110,7 @@ public class HookCheckTimerTask implements Runnable { this.fishingPreparation.setLocation(fishHook.getLocation()); this.fishingPreparation.insertArg("{lava}", "true"); this.fishingPreparation.triggerActions(ActionTrigger.LAND); - FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.LAVA); + FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.LAVA, fishHook); Bukkit.getPluginManager().callEvent(event); firstTime = false; this.setTempState(); @@ -130,7 +141,7 @@ public class HookCheckTimerTask implements Runnable { 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); + FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.WATER, fishHook); Bukkit.getPluginManager().callEvent(event); // if the hook is in water // then cancel the task @@ -140,6 +151,9 @@ public class HookCheckTimerTask implements Runnable { } } + /** + * Destroys the task and associated entities. + */ public void destroy() { this.cancelSubTask(); this.removeTempEntity(); @@ -147,6 +161,9 @@ public class HookCheckTimerTask implements Runnable { this.manager.removeHookCheckTask(fishingPreparation.getPlayer()); } + /** + * Cancels the lava fishing subtask if it's active. + */ public void cancelSubTask() { if (lavaFishingTask != null && !lavaFishingTask.isCancelled()) { lavaFishingTask.cancel(); @@ -154,6 +171,9 @@ public class HookCheckTimerTask implements Runnable { } } + /** + * Sets temporary state and prepares for the next loot. + */ private void setTempState() { Loot nextLoot = CustomFishingPlugin.get().getLootManager().getNextLoot(initialEffect, fishingPreparation); if (nextLoot == null) @@ -171,11 +191,17 @@ public class HookCheckTimerTask implements Runnable { ))); } + /** + * Removes the temporary hooked entity. + */ public void removeTempEntity() { if (hookedEntity != null && !hookedEntity.isDead()) hookedEntity.remove(); } + /** + * Starts the lava fishing mechanic. + */ private void startLavaFishingMechanic() { // get random time int random = ThreadLocalRandom.current().nextInt(CFConfig.lavaMinTime, CFConfig.lavaMaxTime); @@ -191,6 +217,9 @@ public class HookCheckTimerTask implements Runnable { ); } + /** + * Handles the hook state of the fish hook. + */ public void getHooked() { LavaFishingEvent lavaFishingEvent = new LavaFishingEvent(fishingPreparation.getPlayer(), LavaFishingEvent.State.BITE, fishHook); Bukkit.getPluginManager().callEvent(lavaFishingEvent); @@ -240,6 +269,11 @@ public class HookCheckTimerTask implements Runnable { fishHook.setHookedEntity(hookedEntity); } + /** + * Checks if the fish hook is currently hooked. + * + * @return True if the fish hook is hooked, false otherwise. + */ public boolean isFishHooked() { return fishHooked; } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/LavaEffectTask.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/LavaEffectTask.java index ec4b4592..22a06065 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/LavaEffectTask.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/LavaEffectTask.java @@ -24,6 +24,9 @@ import org.bukkit.Particle; import java.util.concurrent.TimeUnit; +/** + * A task responsible for creating a lava effect animation between two points. + */ public class LavaEffectTask implements Runnable { private final Location startLoc; @@ -33,9 +36,16 @@ public class LavaEffectTask implements Runnable { private final CancellableTask lavaTask; private final HookCheckTimerTask hookCheckTimerTask; - public LavaEffectTask(HookCheckTimerTask hookCheckTimerTask, Location loc, int delay) { + /** + * Constructs a new LavaEffectTask. + * + * @param hookCheckTimerTask The HookCheckTimerTask instance. + * @param location The starting location for the lava effect. + * @param delay The delay before starting the task. + */ + public LavaEffectTask(HookCheckTimerTask hookCheckTimerTask, Location location, int delay) { this.hookCheckTimerTask = hookCheckTimerTask; - this.startLoc = loc.clone().add(0,0.3,0); + this.startLoc = location.clone().add(0,0.3,0); this.endLoc = this.startLoc.clone().add((Math.random() * 16 - 8), startLoc.getY(), (Math.random() * 16 - 8)); this.controlLoc = new Location( startLoc.getWorld(), @@ -60,11 +70,19 @@ public class LavaEffectTask implements Runnable { } } + /** + * Cancels the lava effect task. + */ public void cancel() { if (lavaTask != null && !lavaTask.isCancelled()) lavaTask.cancel(); } + /** + * Checks if the lava effect task is cancelled. + * + * @return True if the task is cancelled, false otherwise. + */ public boolean isCancelled() { return lavaTask.isCancelled(); } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java index 6a24ad92..20f77774 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java @@ -39,6 +39,7 @@ import net.momirealms.customfishing.compatibility.item.CustomFishingItemImpl; import net.momirealms.customfishing.compatibility.item.VanillaItemImpl; import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl; import net.momirealms.customfishing.setting.CFConfig; +import net.momirealms.customfishing.util.ConfigUtils; import net.momirealms.customfishing.util.ItemUtils; import net.momirealms.customfishing.util.NBTUtils; import org.bukkit.Bukkit; @@ -116,6 +117,10 @@ public class ItemManagerImpl implements ItemManager, Listener { this.itemLibraryMap.clear(); } + /** + * Loads items from the plugin folder. + * This method scans various item types (item, bait, rod, util, hook) in the plugin's content folder and loads their configurations. + */ @SuppressWarnings("DuplicatedCode") public void loadItemsFromPluginFolder() { Deque fileDeque = new ArrayDeque<>(); @@ -141,6 +146,12 @@ public class ItemManagerImpl implements ItemManager, Listener { } } + /** + * Loads a single item configuration file. + * + * @param file The YAML configuration file to load. + * @param namespace The namespace of the item type (item, bait, rod, util, hook). + */ private void loadSingleFile(File file, String namespace) { YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file); for (Map.Entry entry : yaml.getValues(false).entrySet()) { @@ -304,16 +315,16 @@ public class ItemManagerImpl implements ItemManager, Listener { itemCFBuilder .amount(section.getInt("amount", 1)) .stackable(section.getBoolean("stackable", true)) - .size(getSizePair(section.getString("size"))) + .size(ConfigUtils.getSizePair(section.getString("size"))) .price((float) section.getDouble("price.base"), (float) section.getDouble("price.bonus")) .customModelData(section.getInt("custom-model-data")) .nbt(section.getConfigurationSection("nbt")) .maxDurability(section.getInt("max-durability")) .itemFlag(section.getStringList("item-flags").stream().map(flag -> ItemFlag.valueOf(flag.toUpperCase())).toList()) - .enchantment(getEnchantmentPair(section.getConfigurationSection("enchantments")), false) - .enchantment(getEnchantmentPair(section.getConfigurationSection("stored-enchantments")), true) - .randomEnchantments(getEnchantmentTuple(section.getConfigurationSection("random-enchantments")), false) - .randomEnchantments(getEnchantmentTuple(section.getConfigurationSection("random-stored-enchantments")), true) + .enchantment(ConfigUtils.getEnchantmentPair(section.getConfigurationSection("enchantments")), false) + .enchantment(ConfigUtils.getEnchantmentPair(section.getConfigurationSection("stored-enchantments")), true) + .randomEnchantments(ConfigUtils.getEnchantmentTuple(section.getConfigurationSection("random-enchantments")), false) + .randomEnchantments(ConfigUtils.getEnchantmentTuple(section.getConfigurationSection("random-stored-enchantments")), true) .tag(section.getBoolean("tag", true), type, id) .randomDamage(section.getBoolean("random-durability", false)) .unbreakable(section.getBoolean("unbreakable", false)) @@ -445,42 +456,6 @@ public class ItemManagerImpl implements ItemManager, Listener { ItemUtils.setDurability(itemStack, amount, updateLore); } - @NotNull - private List> getEnchantmentPair(ConfigurationSection section) { - List> list = new ArrayList<>(); - if (section == null) return list; - for (Map.Entry entry : section.getValues(false).entrySet()) { - if (entry.getValue() instanceof Integer integer) { - list.add(Pair.of(entry.getKey(), Short.valueOf(String.valueOf(integer)))); - } - } - return list; - } - - @NotNull - private List> getEnchantmentTuple(ConfigurationSection section) { - List> list = new ArrayList<>(); - if (section == null) return list; - for (Map.Entry entry : section.getValues(false).entrySet()) { - if (entry.getValue() instanceof ConfigurationSection inner) { - Tuple tuple = Tuple.of( - inner.getDouble("chance"), - inner.getString("enchant"), - Short.valueOf(String.valueOf(inner.getInt("level"))) - ); - list.add(tuple); - } - } - return list; - } - - @Nullable - private Pair getSizePair(String size) { - if (size == null) return null; - String[] split = size.split("~", 2); - return Pair.of(Float.parseFloat(split[0]), Float.parseFloat(split[1])); - } - public static class CFBuilder implements ItemBuilder { private final String library; @@ -763,6 +738,11 @@ public class ItemManagerImpl implements ItemManager, Listener { } } + /** + * Handles item pickup by players. + * + * @param event The PlayerAttemptPickupItemEvent. + */ @EventHandler public void onPickUp(PlayerAttemptPickupItemEvent event) { if (event.isCancelled()) return; @@ -777,6 +757,11 @@ public class ItemManagerImpl implements ItemManager, Listener { } } + /** + * Handles item movement in inventories. + * + * @param event The InventoryPickupItemEvent. + */ @EventHandler public void onMove(InventoryPickupItemEvent event) { if (event.isCancelled()) return; @@ -787,7 +772,11 @@ public class ItemManagerImpl implements ItemManager, Listener { itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); } - + /** + * Handles item consumption by players. + * + * @param event The PlayerItemConsumeEvent. + */ @EventHandler public void onConsumeItem(PlayerItemConsumeEvent event) { if (event.isCancelled()) return; @@ -801,6 +790,11 @@ public class ItemManagerImpl implements ItemManager, Listener { } } + /** + * Handles the repair of custom items in an anvil. + * + * @param event The PrepareAnvilEvent. + */ @EventHandler public void onRepairItem(PrepareAnvilEvent event) { ItemStack result = event.getInventory().getResult(); @@ -816,6 +810,11 @@ public class ItemManagerImpl implements ItemManager, Listener { event.setResult(nbtItem.getItem()); } + /** + * Handles the mending of custom items. + * + * @param event The PlayerItemMendEvent. + */ @EventHandler public void onMending(PlayerItemMendEvent event) { if (event.isCancelled()) return; @@ -827,6 +826,11 @@ public class ItemManagerImpl implements ItemManager, Listener { ItemUtils.increaseDurability(itemStack, event.getRepairAmount(), true); } + /** + * Handles interactions with custom utility items. + * + * @param event The PlayerInteractEvent. + */ @EventHandler public void onInteractWithUtils(PlayerInteractEvent event) { if (event.useItemInHand() == Event.Result.DENY) 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 a4fb9e29..38550b0d 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 @@ -254,7 +254,6 @@ public class LootManagerImpl implements LootManager { .disableGames(section.getBoolean("disable-game", false)) .instantGame(section.getBoolean("instant-game", false)) .showInFinder(section.getBoolean("show-in-fishfinder", true)) - .gameConfig(section.getString("game")) .score(section.getDouble("score")) .lootGroup(ConfigUtils.stringListArgs(section.get("group")).toArray(new String[0])) .nick(section.getString("nick", section.getString("display.name", key))) diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/ActivatedTotem.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/ActivatedTotem.java index 1e9f3e04..1fe18109 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/ActivatedTotem.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/ActivatedTotem.java @@ -22,8 +22,10 @@ import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier; -import net.momirealms.customfishing.api.scheduler.CancellableTask; +import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; +import net.momirealms.customfishing.api.mechanic.totem.TotemParticle; import net.momirealms.customfishing.mechanic.totem.particle.ParticleSetting; +import net.momirealms.customfishing.api.scheduler.CancellableTask; import org.bukkit.Location; import java.util.ArrayList; @@ -44,7 +46,7 @@ public class ActivatedTotem { this.coreLocation = coreLocation.clone().add(0.5,0,0.5); this.totemConfig = config; this.effectCarrier = CustomFishingPlugin.get().getEffectManager().getEffectCarrier("totem", config.getKey()); - for (ParticleSetting particleSetting : config.getParticleSettings()) { + for (TotemParticle particleSetting : config.getParticleSettings()) { this.subTasks.add(particleSetting.start(coreLocation, config.getRadius())); } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/TotemManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/TotemManagerImpl.java index 349c838f..0b5b97ea 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/TotemManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/TotemManagerImpl.java @@ -20,18 +20,21 @@ package net.momirealms.customfishing.mechanic.totem; import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.common.SimpleLocation; +import net.momirealms.customfishing.api.event.TotemActivateEvent; import net.momirealms.customfishing.api.manager.TotemManager; import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier; +import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; +import net.momirealms.customfishing.api.mechanic.totem.TotemModel; import net.momirealms.customfishing.api.scheduler.CancellableTask; -import net.momirealms.customfishing.mechanic.totem.block.TotemBlock; -import net.momirealms.customfishing.mechanic.totem.block.property.AxisImpl; -import net.momirealms.customfishing.mechanic.totem.block.property.FaceImpl; -import net.momirealms.customfishing.mechanic.totem.block.property.HalfImpl; -import net.momirealms.customfishing.mechanic.totem.block.property.TotemBlockProperty; -import net.momirealms.customfishing.mechanic.totem.block.type.TypeCondition; +import net.momirealms.customfishing.api.mechanic.totem.block.TotemBlock; +import net.momirealms.customfishing.api.mechanic.totem.block.property.AxisImpl; +import net.momirealms.customfishing.api.mechanic.totem.block.property.FaceImpl; +import net.momirealms.customfishing.api.mechanic.totem.block.property.HalfImpl; +import net.momirealms.customfishing.api.mechanic.totem.block.property.TotemBlockProperty; +import net.momirealms.customfishing.api.mechanic.totem.block.type.TypeCondition; import net.momirealms.customfishing.mechanic.totem.particle.DustParticleSetting; import net.momirealms.customfishing.mechanic.totem.particle.ParticleSetting; import net.momirealms.customfishing.util.LocationUtils; @@ -165,6 +168,13 @@ public class TotemManagerImpl implements TotemManager, Listener { Condition condition = new Condition(block.getLocation(), event.getPlayer(), new HashMap<>()); if (!carrier.isConditionMet(condition)) return; + + TotemActivateEvent totemActivateEvent = new TotemActivateEvent(event.getPlayer(), block.getLocation(), config); + Bukkit.getPluginManager().callEvent(totemActivateEvent); + if (totemActivateEvent.isCancelled()) { + return; + } + Action[] actions = carrier.getActionMap().get(ActionTrigger.ACTIVATE); if (actions != null) for (Action action : actions) { @@ -331,7 +341,7 @@ public class TotemManagerImpl implements TotemManager, Listener { TotemModel originalModel = parseModel(section); List modelList = new ArrayList<>(); for (int i = 0; i < 4; i++) { - originalModel = originalModel.clone().rotate90(); + originalModel = originalModel.deepClone().rotate90(); modelList.add(originalModel); if (i % 2 == 0) { modelList.add(originalModel.mirrorVertically()); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/particle/ParticleSetting.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/particle/ParticleSetting.java index d7585b00..0ec64ac1 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/particle/ParticleSetting.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/totem/particle/ParticleSetting.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.mechanic.totem.particle; import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.common.Pair; +import net.momirealms.customfishing.api.mechanic.totem.TotemParticle; import net.momirealms.customfishing.api.scheduler.CancellableTask; import net.objecthunter.exp4j.Expression; import net.objecthunter.exp4j.ExpressionBuilder; @@ -29,7 +30,7 @@ import org.bukkit.World; import java.util.List; import java.util.concurrent.TimeUnit; -public class ParticleSetting { +public class ParticleSetting implements TotemParticle { protected final Expression expressionHorizontal; protected final Expression expressionVertical; diff --git a/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java index 11d92dc3..f0c65076 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java @@ -75,7 +75,7 @@ public class StorageManagerImpl implements StorageManager, Listener { private RedisManager redisManager; private String uniqueID; private CancellableTask timerSaveTask; - private Gson gson; + private final Gson gson; public StorageManagerImpl(CustomFishingPluginImpl plugin) { this.plugin = plugin; diff --git a/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java b/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java index a0bd9934..34587316 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java +++ b/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java @@ -18,18 +18,23 @@ package net.momirealms.customfishing.util; import net.momirealms.customfishing.api.common.Pair; +import net.momirealms.customfishing.api.common.Tuple; import net.momirealms.customfishing.api.mechanic.loot.WeightModifier; import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl; import net.objecthunter.exp4j.Expression; import net.objecthunter.exp4j.ExpressionBuilder; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; /** * Utility class for configuration-related operations. @@ -97,6 +102,19 @@ public class ConfigUtils { return 0; } + /** + * Parses a string representing a size range and returns a pair of floats. + * + * @param size The size string in the format "min~max". + * @return A pair of floats representing the minimum and maximum size. + */ + @Nullable + public static Pair getSizePair(String size) { + if (size == null) return null; + String[] split = size.split("~", 2); + return Pair.of(Float.parseFloat(split[0]), Float.parseFloat(split[1])); + } + /** * Converts a list of strings in the format "key:value" into a list of Pairs with keys and WeightModifiers. * @@ -113,6 +131,47 @@ public class ConfigUtils { return result; } + /** + * Retrieves a list of enchantment pairs from a configuration section. + * + * @param section The configuration section to extract enchantment data from. + * @return A list of enchantment pairs. + */ + @NotNull + public static List> getEnchantmentPair(ConfigurationSection section) { + List> list = new ArrayList<>(); + if (section == null) return list; + for (Map.Entry entry : section.getValues(false).entrySet()) { + if (entry.getValue() instanceof Integer integer) { + list.add(Pair.of(entry.getKey(), Short.valueOf(String.valueOf(integer)))); + } + } + return list; + } + + /** + * Retrieves a list of enchantment tuples from a configuration section. + * + * @param section The configuration section to extract enchantment data from. + * @return A list of enchantment tuples. + */ + @NotNull + public static List> getEnchantmentTuple(ConfigurationSection section) { + List> list = new ArrayList<>(); + if (section == null) return list; + for (Map.Entry entry : section.getValues(false).entrySet()) { + if (entry.getValue() instanceof ConfigurationSection inner) { + Tuple tuple = Tuple.of( + inner.getDouble("chance"), + inner.getString("enchant"), + Short.valueOf(String.valueOf(inner.getInt("level"))) + ); + list.add(tuple); + } + } + return list; + } + /** * Reads data from a YAML configuration file and creates it if it doesn't exist. *