9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-23 00:49:24 +00:00

checkpoint - 1

This commit is contained in:
XiaoMoMi
2024-05-18 03:16:02 +08:00
parent f19d0e05c5
commit 5166989a48
397 changed files with 6706 additions and 6383 deletions

View File

@@ -9,7 +9,7 @@
<img src="https://img.shields.io/badge/docs-gitbook-brightgreen" alt="Gitbook"/> <img src="https://img.shields.io/badge/docs-gitbook-brightgreen" alt="Gitbook"/>
</a> </a>
CustomFishing is a Paper plugin that provides minigames and a powerful condition & action library for fishing. CustomFishing is a Paper plugin that provides minigames and a powerful playerContext & action library for fishing.
With the new concept of weight system, CustomFishing brings unlimited customization possibilities and best performance. With the new concept of weight system, CustomFishing brings unlimited customization possibilities and best performance.
## How to build ## How to build

View File

@@ -1,11 +1,44 @@
dependencies { plugins {
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") id("io.github.goooler.shadow") version "8.1.7"
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
compileOnly("de.tr7zw:item-nbt-api:2.12.4")
} }
repositories {
maven("https://repo.codemc.io/repository/maven-public/")
maven("https://jitpack.io/")
}
dependencies {
implementation(project(":common"))
implementation("dev.dejvokep:boosted-yaml:${rootProject.properties["boosted_yaml_version"]}")
implementation("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}") {
exclude(module = "adventure-bom")
exclude(module = "checker-qual")
exclude(module = "annotations")
}
implementation("com.saicone.rtag:rtag:1.5.3")
implementation("com.saicone.rtag:rtag-item:1.5.3")
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.release.set(17)
dependsOn(tasks.clean)
}
tasks { tasks {
shadowJar { shadowJar {
relocate ("de.tr7zw.changeme", "net.momirealms.customfishing.libraries") relocate("net.kyori", "net.momirealms.customfishing.libraries")
relocate("dev.dejvokep", "net.momirealms.customfishing.libraries")
} }
} }

View File

@@ -17,17 +17,36 @@
package net.momirealms.customfishing.api; package net.momirealms.customfishing.api;
import net.momirealms.customfishing.api.integration.IntegrationManager;
import net.momirealms.customfishing.api.manager.*; import net.momirealms.customfishing.api.manager.*;
import net.momirealms.customfishing.api.scheduler.Scheduler; import net.momirealms.customfishing.api.mechanic.action.ActionManager;
import net.momirealms.customfishing.api.mechanic.bag.BagManager;
import net.momirealms.customfishing.api.mechanic.block.BlockManager;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionManager;
import net.momirealms.customfishing.api.mechanic.effect.EffectManager;
import net.momirealms.customfishing.api.mechanic.entity.EntityManager;
import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
import net.momirealms.customfishing.api.mechanic.game.GameManager;
import net.momirealms.customfishing.api.mechanic.hook.HookManager;
import net.momirealms.customfishing.api.mechanic.item.ItemManager;
import net.momirealms.customfishing.api.mechanic.loot.LootManager;
import net.momirealms.customfishing.api.mechanic.market.MarketManager;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsManager;
import net.momirealms.customfishing.api.mechanic.totem.TotemManager;
import net.momirealms.customfishing.common.command.CustomFishingCommandManager;
import net.momirealms.customfishing.common.plugin.CustomFishingPlugin;
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerAdapter;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
public abstract class CustomFishingPlugin extends JavaPlugin { public abstract class BukkitCustomFishingPlugin extends JavaPlugin implements CustomFishingPlugin {
protected boolean initialized; protected boolean initialized;
protected Scheduler scheduler; protected SchedulerAdapter<Location> scheduler;
protected CommandManager commandManager; protected CustomFishingCommandManager<CommandSender> commandManager;
protected VersionManager versionManager; protected VersionManager versionManager;
protected ItemManager itemManager; protected ItemManager itemManager;
protected RequirementManager requirementManager; protected RequirementManager requirementManager;
@@ -37,7 +56,6 @@ public abstract class CustomFishingPlugin extends JavaPlugin {
protected EffectManager effectManager; protected EffectManager effectManager;
protected EntityManager entityManager; protected EntityManager entityManager;
protected BlockManager blockManager; protected BlockManager blockManager;
protected AdventureManager adventure;
protected BagManager bagManager; protected BagManager bagManager;
protected GameManager gameManager; protected GameManager gameManager;
protected MarketManager marketManager; protected MarketManager marketManager;
@@ -49,29 +67,20 @@ public abstract class CustomFishingPlugin extends JavaPlugin {
protected TotemManager totemManager; protected TotemManager totemManager;
protected HookManager hookManager; protected HookManager hookManager;
private static CustomFishingPlugin instance; private static BukkitCustomFishingPlugin instance;
public CustomFishingPlugin() { public BukkitCustomFishingPlugin() {
instance = this; instance = this;
} }
public static CustomFishingPlugin get() { public static BukkitCustomFishingPlugin get() {
return getInstance(); return getInstance();
} }
@NotNull public static BukkitCustomFishingPlugin getInstance() {
public static CustomFishingPlugin getInstance() {
return instance; return instance;
} }
public Scheduler getScheduler() {
return scheduler;
}
public CommandManager getCommandManager() {
return commandManager;
}
public VersionManager getVersionManager() { public VersionManager getVersionManager() {
return versionManager; return versionManager;
} }

View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.common;
public record Key(String namespace, String value) {
public static Key of(String namespace, String value) {
return new Key(namespace, value);
}
@Override
public int hashCode() {
int result = this.namespace.hashCode();
result = (31 * result) + this.value.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Key key)) return false;
return this.namespace.equals(key.namespace()) && this.value.equals(key.value());
}
@Override
public String toString() {
return namespace + ":" + value;
}
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.data;
import java.util.Optional;
import java.util.UUID;
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<Optional<PlayerData>> getLegacyPlayerData(UUID uuid);
}

View File

@@ -17,7 +17,7 @@
package net.momirealms.customfishing.api.event; package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -25,9 +25,9 @@ import org.jetbrains.annotations.NotNull;
public class CustomFishingReloadEvent extends Event { public class CustomFishingReloadEvent extends Event {
private static final HandlerList handlerList = new HandlerList(); private static final HandlerList handlerList = new HandlerList();
private final CustomFishingPlugin plugin; private final BukkitCustomFishingPlugin plugin;
public CustomFishingReloadEvent(CustomFishingPlugin plugin) { public CustomFishingReloadEvent(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
@@ -41,7 +41,7 @@ public class CustomFishingReloadEvent extends Event {
return getHandlerList(); return getHandlerList();
} }
public CustomFishingPlugin getPluginInstance() { public BukkitCustomFishingPlugin getPluginInstance() {
return plugin; return plugin;
} }
} }

View File

@@ -33,7 +33,7 @@ public class FishHookLandEvent extends PlayerEvent {
private final Target target; private final Target target;
private final FishHook fishHook; private final FishHook fishHook;
private final Effect effect; private final Effect effect;
private boolean isFirst; private final boolean isFirst;
/** /**
* Constructs a new FishHookLandEvent. * Constructs a new FishHookLandEvent.

View File

@@ -17,7 +17,6 @@
package net.momirealms.customfishing.api.event; package net.momirealms.customfishing.api.event;
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;

View File

@@ -17,19 +17,19 @@
package net.momirealms.customfishing.api.integration; package net.momirealms.customfishing.api.integration;
import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.common.util.Pair;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.List; import java.util.List;
public interface EnchantmentInterface { public interface EnchantmentProvider extends ExternalProvider {
/** /**
* Get a list of enchantments with level for itemStack * Get a list of enchantments with level for itemStack
* format: plugin:enchantment:level
* example: minecraft:sharpness:5
* *
* @param itemStack itemStack * @param itemStack itemStack
* @return enchantment list * @return enchantment list
*/ */
List<String> getEnchants(ItemStack itemStack); List<Pair<Key, Short>> getEnchants(ItemStack itemStack);
} }

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.integration;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public interface EntityProvider extends ExternalProvider {
/**
* Spawns an entity at the specified location with the given properties.
*
* @param location The location where the entity will be spawned.
* @param id The identifier of the entity to be spawned.
* @param propertyMap A map containing additional properties for the entity.
* @return The spawned entity.
*/
@NotNull
Entity spawn(@NotNull Location location, @NotNull String id, @NotNull Map<String, Object> propertyMap);
default Entity spawn(@NotNull Location location, @NotNull String id) {
return spawn(location, id, new HashMap<>());
}
}

View File

@@ -0,0 +1,11 @@
package net.momirealms.customfishing.api.integration;
public interface ExternalProvider {
/**
* Gets the identification of the external provider.
*
* @return The identification string of the external provider.
*/
String identifier();
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.integration;
import org.jetbrains.annotations.Nullable;
/**
* Interface for managing integration providers in the custom fishing API.
* This allows for the registration and retrieval of various types of providers
* such as Leveler, Enchantment, and Season providers.
*/
public interface IntegrationManager {
/**
* Registers a LevelerProvider.
*
* @param level the LevelerProvider to register
* @return true if registration is successful, false otherwise
*/
boolean registerLevelerProvider(LevelerProvider level);
/**
* Unregisters a LevelerProvider by its ID.
*
* @param id the ID of the LevelerProvider to unregister
* @return true if unregistration is successful, false otherwise
*/
boolean unregisterLevelerProvider(String id);
/**
* Registers an EnchantmentProvider.
*
* @param enchantment the EnchantmentProvider to register
* @return true if registration is successful, false otherwise
*/
boolean registerEnchantmentProvider(EnchantmentProvider enchantment);
/**
* Unregisters an EnchantmentProvider by its ID.
*
* @param id the ID of the EnchantmentProvider to unregister
* @return true if unregistration is successful, false otherwise
*/
boolean unregisterEnchantmentProvider(String id);
/**
* Registers a SeasonProvider.
*
* @param season the SeasonProvider to register
* @return true if registration is successful, false otherwise
*/
boolean registerSeasonProvider(SeasonProvider season);
/**
* Unregisters a SeasonProvider by its ID.
*
* @param id the ID of the SeasonProvider to unregister
* @return true if unregistration is successful, false otherwise
*/
boolean unregisterSeasonProvider(String id);
boolean registerEntityProvider(EntityProvider entity);
boolean unregisterEntityProvider(String identifier);
/**
* Retrieves a registered LevelerProvider by its ID.
*
* @param id the ID of the LevelerProvider to retrieve
* @return the LevelerProvider if found, or null if not found
*/
@Nullable
LevelerProvider getLevelerProvider(String id);
/**
* Retrieves a registered EnchantmentProvider by its ID.
*
* @param id the ID of the EnchantmentProvider to retrieve
* @return the EnchantmentProvider if found, or null if not found
*/
@Nullable
EnchantmentProvider getEnchantmentProvider(String id);
/**
* Retrieves a registered SeasonProvider by its ID.
*
* @param id the ID of the SeasonProvider to retrieve
* @return the SeasonProvider if found, or null if not found
*/
@Nullable
SeasonProvider getSeasonProvider(String id);
}

View File

@@ -15,13 +15,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.mechanic.misc; package net.momirealms.customfishing.api.integration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map; public interface ItemProvider extends ExternalProvider {
public interface Value { @NotNull
ItemStack buildItem(Player player, String id);
double get(Player player, Map<String, String> values); @Nullable
String itemID(ItemStack itemStack);
} }

View File

@@ -19,7 +19,7 @@ package net.momirealms.customfishing.api.integration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public interface LevelInterface { public interface LevelerProvider extends ExternalProvider {
/** /**
* Add exp to a certain skill or job * Add exp to a certain skill or job

View File

@@ -17,10 +17,11 @@
package net.momirealms.customfishing.api.integration; package net.momirealms.customfishing.api.integration;
import net.momirealms.customfishing.api.mechanic.misc.season.Season;
import org.bukkit.World; import org.bukkit.World;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public interface SeasonInterface { public interface SeasonProvider extends ExternalProvider {
/** /**
* Get a world's season * Get a world's season
@@ -28,5 +29,6 @@ public interface SeasonInterface {
* @param world world * @param world world
* @return spring, summer, autumn, winter or disabled * @return spring, summer, autumn, winter or disabled
*/ */
@NotNull String getSeason(World world); @NotNull
Season getSeason(World world);
} }

View File

@@ -1,139 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public interface AdventureManager {
/**
* Get component from text
* @param text text
* @return component
*/
Component getComponentFromMiniMessage(String text);
/**
* Send a message to a command sender
* @param sender sender
* @param msg message
*/
void sendMessage(CommandSender sender, String msg);
/**
* Send a message with prefix
*
* @param sender command sender
* @param s message
*/
void sendMessageWithPrefix(CommandSender sender, String s);
/**
* Send a message to console
* @param msg message
*/
void sendConsoleMessage(String msg);
/**
* Send a message to a player
* @param player player
* @param msg message
*/
void sendPlayerMessage(Player player, String msg);
/**
* Send a title to a player
* @param player player
* @param title title
* @param subtitle subtitle
* @param in in (ms)
* @param duration duration (ms)
* @param out out (ms)
*/
void sendTitle(Player player, String title, String subtitle, int in, int duration, int out);
/**
* Send a title to a player
* @param player player
* @param title title
* @param subtitle subtitle
* @param in in (ms)
* @param duration duration (ms)
* @param out out (ms)
*/
void sendTitle(Player player, Component title, Component subtitle, int in, int duration, int out);
/**
* Send actionbar
* @param player player
* @param msg msg
*/
void sendActionbar(Player player, String msg);
/**
* Play a sound to a player
* @param player player
* @param source sound source
* @param key sound key
* @param volume volume
* @param pitch pitch
*/
void sendSound(Player player, Sound.Source source, Key key, float volume, float pitch);
void sendSound(Player player, Sound sound);
/**
* Replace legacy color codes to MiniMessage format
* @param legacy legacy text
* @return MiniMessage format text
*/
String legacyToMiniMessage(String legacy);
/**
* if a char is legacy color code
* @param c char
* @return is legacy color
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
boolean isColorCode(char c);
/**
* Get legacy format text
* @param component component
* @return legacy format text
*/
String componentToLegacy(Component component);
/**
* Get json
* @param component component
* @return json
*/
String componentToJson(Component component);
/**
* Get paper component
* @param component shaded component
* @return paper component
*/
Object shadedComponentToOriginalComponent(Component component);
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
import net.momirealms.customfishing.api.integration.EnchantmentInterface;
import net.momirealms.customfishing.api.integration.LevelInterface;
import net.momirealms.customfishing.api.integration.SeasonInterface;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface IntegrationManager {
/**
* Registers a level plugin with the specified name.
*
* @param plugin The name of the level plugin.
* @param level The implementation of the LevelInterface.
* @return true if the registration was successful, false if the plugin name is already registered.
*/
boolean registerLevelPlugin(String plugin, LevelInterface level);
/**
* Unregisters a level plugin with the specified name.
*
* @param plugin The name of the level plugin to unregister.
* @return true if the unregistration was successful, false if the plugin name is not found.
*/
boolean unregisterLevelPlugin(String plugin);
/**
* Registers an enchantment provided by a plugin.
*
* @param plugin The name of the plugin providing the enchantment.
* @param enchantment The enchantment to register.
* @return true if the registration was successful, false if the enchantment name is already in use.
*/
boolean registerEnchantment(String plugin, EnchantmentInterface enchantment);
/**
* Unregisters an enchantment provided by a plugin.
*
* @param plugin The name of the plugin providing the enchantment.
* @return true if the enchantment was successfully unregistered, false if the enchantment was not found.
*/
boolean unregisterEnchantment(String plugin);
/**
* Get the LevelInterface provided by a plugin.
*
* @param plugin The name of the plugin providing the LevelInterface.
* @return The LevelInterface provided by the specified plugin, or null if the plugin is not registered.
*/
@Nullable LevelInterface getLevelPlugin(String plugin);
/**
* Get an enchantment plugin by its plugin name.
*
* @param plugin The name of the enchantment plugin.
* @return The enchantment plugin interface, or null if not found.
*/
@Nullable EnchantmentInterface getEnchantmentPlugin(String plugin);
/**
* Get a list of enchantment keys with level applied to the given ItemStack.
*
* @param itemStack The ItemStack to check for enchantments.
* @return A list of enchantment names applied to the ItemStack.
*/
List<String> getEnchantments(ItemStack itemStack);
/**
* Get the current season interface, if available.
*
* @return The current season interface, or null if not available.
*/
@Nullable SeasonInterface getSeasonInterface();
/**
* Set the current season interface.
*
* @param season The season interface to set.
*/
void setSeasonInterface(SeasonInterface season);
}

View File

@@ -1,207 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.manager;
import net.momirealms.customfishing.api.common.Key;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.item.BuildableItem;
import net.momirealms.customfishing.api.mechanic.item.ItemBuilder;
import net.momirealms.customfishing.api.mechanic.item.ItemLibrary;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Set;
public interface ItemManager {
/**
* Build an ItemStack with a specified namespace and value for a player.
*
* @param player The player for whom the ItemStack is being built.
* @param namespace The namespace of the item.
* @param value The value of the item.
* @return The constructed ItemStack.
*/
@Nullable
ItemStack build(Player player, String namespace, String value);
/**
* Build an ItemStack with a specified namespace and value, replacing placeholders,
* for a player.
*
* @param player The player for whom the ItemStack is being built.
* @param namespace The namespace of the item.
* @param value The value of the item.
* @param placeholders The placeholders to replace in the item's attributes.
* @return The constructed ItemStack, or null if the item doesn't exist.
*/
@Nullable
ItemStack build(Player player, String namespace, String value, Map<String, String> placeholders);
/**
* Build an ItemStack using an ItemBuilder for a player.
*
* @param player The player for whom the ItemStack is being built.
* @param builder The ItemBuilder used to construct the ItemStack.
* @return The constructed ItemStack.
*/
@NotNull ItemStack build(Player player, ItemBuilder builder);
/**
* Build an ItemStack using the provided ItemBuilder, player, and placeholders.
*
* @param player The player for whom the item is being built.
* @param builder The ItemBuilder that defines the item's properties.
* @param placeholders A map of placeholders and their corresponding values to be applied to the item.
* @return The constructed ItemStack.
*/
@NotNull ItemStack build(Player player, ItemBuilder builder, Map<String, String> placeholders);
/**
* Build an ItemStack for a player based on the provided item ID.
*
* @param player The player for whom the ItemStack is being built.
* @param id The item ID, which include an identification (e.g., "Oraxen:id").
* @return The constructed ItemStack or null if the ID is not valid.
*/
@Nullable ItemStack buildAnyPluginItemByID(Player player, String id);
/**
* Get the item ID associated with the given ItemStack, if available.
*
* @param itemStack The ItemStack to retrieve the item ID from.
* @return The item ID without type or null if not found or if the ItemStack is null or empty.
*/
@Nullable String getCustomFishingItemID(ItemStack itemStack);
/**
* Get the item ID associated with the given ItemStack by checking all available item libraries.
* The detection order is determined by the configuration.
*
* @param itemStack The ItemStack to retrieve the item ID from.
* @return The item ID or "AIR" if not found or if the ItemStack is null or empty.
*/
@NotNull String getAnyPluginItemID(ItemStack itemStack);
/**
* Create a ItemBuilder instance for an item configuration section
* <p>
* xxx_item: <- section
* material: xxx
* custom-model-data: xxx
*
* @param section The configuration section containing item settings.
* @param type The type of the item (e.g., "rod", "bait").
* @param id The unique identifier for the item.
* @return A CFBuilder instance representing the configured item, or null if the section is null.
*/
@Nullable ItemBuilder getItemBuilder(ConfigurationSection section, String type, String id);
/**
* Get a set of all item keys in the CustomFishing plugin.
*
* @return A set of item keys.
*/
Set<Key> getAllItemsKey();
/**
* Retrieve a BuildableItem by its namespace and value.
*
* @param namespace The namespace of the BuildableItem.
* @param value The value of the BuildableItem.
* @return The BuildableItem with the specified namespace and value, or null if not found.
*/
@Nullable
BuildableItem getBuildableItem(String namespace, String value);
/**
* Get an itemStack's appearance (material + custom model data)
*
* @param player player
* @param material id
* @return appearance
*/
ItemStack getItemStackAppearance(Player player, String material);
/**
* Register an item library.
*
* @param itemLibrary The item library to register.
* @return True if the item library was successfully registered, false if it already exists.
*/
boolean registerItemLibrary(ItemLibrary itemLibrary);
/**
* Unregister an item library.
*
* @param identification The item library to unregister.
* @return True if the item library was successfully unregistered, false if it doesn't exist.
*/
boolean unRegisterItemLibrary(String identification);
/**
* Drops an item based on the provided loot, applying velocity from a hook location to a player location.
*
* @param player The player for whom the item is intended.
* @param hookLocation The location where the item will initially drop.
* @param playerLocation The target location towards which the item's velocity is applied.
* @param itemStack The loot to drop
* @param condition A map of placeholders for item customization.
*/
void dropItem(Player player, Location hookLocation, Location playerLocation, ItemStack itemStack, Condition condition);
/**
* Checks if the provided ItemStack is a custom fishing item
*
* @param itemStack The ItemStack to check.
* @return True if the ItemStack is a custom fishing item; otherwise, false.
*/
boolean isCustomFishingItem(ItemStack itemStack);
/**
* Decreases the durability of an ItemStack by a specified amount and optionally updates its lore.
*
* @param itemStack The ItemStack to modify.
* @param amount The amount by which to decrease the durability.
* @param updateLore Whether to update the lore of the ItemStack.
*/
void decreaseDurability(Player player, ItemStack itemStack, int amount, boolean updateLore);
/**
* Increases the durability of an ItemStack by a specified amount and optionally updates its lore.
*
* @param itemStack The ItemStack to modify.
* @param amount The amount by which to increase the durability.
* @param updateLore Whether to update the lore of the ItemStack.
*/
void increaseDurability(ItemStack itemStack, int amount, boolean updateLore);
/**
* Sets the durability of an ItemStack to a specific amount and optionally updates its lore.
*
* @param itemStack The ItemStack to modify.
* @param amount The new durability value.
* @param updateLore Whether to update the lore of the ItemStack.
*/
void setDurability(ItemStack itemStack, int amount, boolean updateLore);
}

View File

@@ -23,14 +23,16 @@ public interface VersionManager {
boolean isVersionNewerThan1_19(); boolean isVersionNewerThan1_19();
boolean isVersionNewerThan1_19_R3(); boolean isVersionNewerThan1_19_4();
boolean isVersionNewerThan1_19_R2(); boolean isVersionNewerThan1_19_3();
CompletableFuture<Boolean> checkUpdate(); CompletableFuture<Boolean> checkUpdate();
boolean isVersionNewerThan1_20(); boolean isVersionNewerThan1_20();
boolean isNewerThan1_20_5();
boolean isSpigot(); boolean isSpigot();
public boolean hasRegionScheduler(); public boolean hasRegionScheduler();

View File

@@ -17,10 +17,9 @@
package net.momirealms.customfishing.api.mechanic; package net.momirealms.customfishing.api.mechanic;
import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier; import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@@ -47,7 +46,7 @@ public class GlobalSettings {
if (section == null) return; if (section == null) return;
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) { for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
if (entry.getValue() instanceof ConfigurationSection inner) { if (entry.getValue() instanceof ConfigurationSection inner) {
HashMap<ActionTrigger, Action[]> map = CustomFishingPlugin.get().getActionManager().getActionMap(inner); HashMap<ActionTrigger, Action[]> map = BukkitCustomFishingPlugin.get().getActionManager().getActionMap(inner);
switch (entry.getKey()) { switch (entry.getKey()) {
case "loot" -> lootActions = map; case "loot" -> lootActions = map;
case "rod" -> rodActions = map; case "rod" -> rodActions = map;
@@ -79,13 +78,13 @@ public class GlobalSettings {
* Triggers loot-related actions for a specific trigger and condition. * Triggers loot-related actions for a specific trigger and condition.
* *
* @param trigger The trigger to activate actions for. * @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions. * @param playerContext The condition that triggered the actions.
*/ */
public static void triggerLootActions(ActionTrigger trigger, Condition condition) { public static void triggerLootActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = lootActions.get(trigger); Action[] actions = lootActions.get(trigger);
if (actions != null) { if (actions != null) {
for (Action action : actions) { for (Action action : actions) {
action.trigger(condition); action.trigger(playerContext);
} }
} }
} }
@@ -94,13 +93,13 @@ public class GlobalSettings {
* Triggers rod-related actions for a specific trigger and condition. * Triggers rod-related actions for a specific trigger and condition.
* *
* @param trigger The trigger to activate actions for. * @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions. * @param playerContext The condition that triggered the actions.
*/ */
public static void triggerRodActions(ActionTrigger trigger, Condition condition) { public static void triggerRodActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = rodActions.get(trigger); Action[] actions = rodActions.get(trigger);
if (actions != null) { if (actions != null) {
for (Action action : actions) { for (Action action : actions) {
action.trigger(condition); action.trigger(playerContext);
} }
} }
} }
@@ -109,13 +108,13 @@ public class GlobalSettings {
* Triggers bait-related actions for a specific trigger and condition. * Triggers bait-related actions for a specific trigger and condition.
* *
* @param trigger The trigger to activate actions for. * @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions. * @param playerContext The condition that triggered the actions.
*/ */
public static void triggerBaitActions(ActionTrigger trigger, Condition condition) { public static void triggerBaitActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = baitActions.get(trigger); Action[] actions = baitActions.get(trigger);
if (actions != null) { if (actions != null) {
for (Action action : actions) { for (Action action : actions) {
action.trigger(condition); action.trigger(playerContext);
} }
} }
} }
@@ -124,13 +123,13 @@ public class GlobalSettings {
* Triggers hook-related actions for a specific trigger and condition. * Triggers hook-related actions for a specific trigger and condition.
* *
* @param trigger The trigger to activate actions for. * @param trigger The trigger to activate actions for.
* @param condition The condition that triggered the actions. * @param playerContext The condition that triggered the actions.
*/ */
public static void triggerHookActions(ActionTrigger trigger, Condition condition) { public static void triggerHookActions(ActionTrigger trigger, PlayerContext playerContext) {
Action[] actions = hookActions.get(trigger); Action[] actions = hookActions.get(trigger);
if (actions != null) { if (actions != null) {
for (Action action : actions) { for (Action action : actions) {
action.trigger(condition); action.trigger(playerContext);
} }
} }
} }

View File

@@ -17,7 +17,6 @@
package net.momirealms.customfishing.api.mechanic; package net.momirealms.customfishing.api.mechanic;
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;

View File

@@ -17,10 +17,14 @@
package net.momirealms.customfishing.api.mechanic.action; package net.momirealms.customfishing.api.mechanic.action;
import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.context.Context;
public interface Action { public interface Action<T> {
void trigger(Condition condition);
/**
* Triggers the action based on the provided condition.
*
* @param context the context
*/
void trigger(Context<T> context);
} }

View File

@@ -17,13 +17,39 @@
package net.momirealms.customfishing.api.mechanic.action; package net.momirealms.customfishing.api.mechanic.action;
public abstract class ActionExpansion { /**
* Abstract class representing an expansion of an action in the custom fishing API.
* This class should be extended to provide specific implementations of actions.
*
* @param <T> the type parameter for the action factory
*/
public abstract class ActionExpansion<T> {
/**
* Retrieves the version of this action expansion.
*
* @return a String representing the version of the action expansion
*/
public abstract String getVersion(); public abstract String getVersion();
/**
* Retrieves the author of this action expansion.
*
* @return a String representing the author of the action expansion
*/
public abstract String getAuthor(); public abstract String getAuthor();
/**
* Retrieves the type of this action.
*
* @return a String representing the type of action
*/
public abstract String getActionType(); public abstract String getActionType();
public abstract ActionFactory getActionFactory(); /**
* Retrieves the action factory associated with this action expansion.
*
* @return an ActionFactory of type T that creates instances of the action
*/
public abstract ActionFactory<T> getActionFactory();
} }

View File

@@ -17,7 +17,18 @@
package net.momirealms.customfishing.api.mechanic.action; package net.momirealms.customfishing.api.mechanic.action;
public interface ActionFactory { /**
* Interface representing a factory for creating actions.
*
* @param <T> the type of object that the action will operate on
*/
public interface ActionFactory<T> {
Action build(Object args, double chance); /**
* Constructs an action based on the provided arguments.
*
* @param args the args containing the arguments needed to build the action
* @return the constructed action
*/
Action<T> process(Object args);
} }

View File

@@ -15,17 +15,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.action;
import net.momirealms.customfishing.api.mechanic.action.Action; import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.action.ActionFactory; import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import org.jetbrains.annotations.NotNull;
import net.momirealms.customfishing.api.mechanic.condition.Condition; import org.jetbrains.annotations.Nullable;
import org.bukkit.configuration.ConfigurationSection;
import java.util.HashMap; import java.util.HashMap;
public interface ActionManager { public interface ActionManager<T> {
/** /**
* Registers an ActionFactory for a specific action type. * Registers an ActionFactory for a specific action type.
@@ -35,7 +34,7 @@ public interface ActionManager {
* @param actionFactory The ActionFactory responsible for creating actions of the specified type. * @param actionFactory The ActionFactory responsible for creating actions of the specified type.
* @return True if the registration was successful (the action type was not already registered), false otherwise. * @return True if the registration was successful (the action type was not already registered), false otherwise.
*/ */
boolean registerAction(String type, ActionFactory actionFactory); boolean registerAction(String type, ActionFactory<T> actionFactory);
/** /**
* Unregisters an ActionFactory for a specific action type. * Unregisters an ActionFactory for a specific action type.
@@ -59,7 +58,7 @@ public interface ActionManager {
* @param section The ConfigurationSection containing the action configuration. * @param section The ConfigurationSection containing the action configuration.
* @return An Action object created based on the configuration, or an EmptyAction instance if the action type is invalid. * @return An Action object created based on the configuration, or an EmptyAction instance if the action type is invalid.
*/ */
Action getAction(ConfigurationSection section); Action<T> getAction(Section section);
/** /**
* Retrieves a mapping of ActionTriggers to arrays of Actions from a ConfigurationSection. * Retrieves a mapping of ActionTriggers to arrays of Actions from a ConfigurationSection.
@@ -74,7 +73,7 @@ public interface ActionManager {
* @param section The ConfigurationSection containing action mappings. * @param section The ConfigurationSection containing action mappings.
* @return A HashMap where keys are ActionTriggers and values are arrays of Action objects. * @return A HashMap where keys are ActionTriggers and values are arrays of Action objects.
*/ */
HashMap<ActionTrigger, Action[]> getActionMap(ConfigurationSection section); HashMap<ActionTrigger, Action<T>[]> getActionMap(Section section);
/** /**
* Retrieves an array of Action objects from a ConfigurationSection. * Retrieves an array of Action objects from a ConfigurationSection.
@@ -89,7 +88,8 @@ public interface ActionManager {
* @param section The ConfigurationSection containing action configurations. * @param section The ConfigurationSection containing action configurations.
* @return An array of Action objects created based on the configurations in the section. * @return An array of Action objects created based on the configurations in the section.
*/ */
Action[] getActions(ConfigurationSection section); @NotNull
Action<T>[] getActions(@NotNull Section section);
/** /**
* Retrieves an ActionFactory associated with a specific action type. * Retrieves an ActionFactory associated with a specific action type.
@@ -97,7 +97,8 @@ public interface ActionManager {
* @param type The action type for which to retrieve the ActionFactory. * @param type The action type for which to retrieve the ActionFactory.
* @return The ActionFactory associated with the specified action type, or null if not found. * @return The ActionFactory associated with the specified action type, or null if not found.
*/ */
ActionFactory getActionFactory(String type); @Nullable
ActionFactory<T> getActionFactory(@NotNull String type);
/** /**
* Retrieves a mapping of success times to corresponding arrays of actions from a ConfigurationSection. * Retrieves a mapping of success times to corresponding arrays of actions from a ConfigurationSection.
@@ -111,18 +112,19 @@ public interface ActionManager {
* @param section The ConfigurationSection containing success times actions. * @param section The ConfigurationSection containing success times actions.
* @return A HashMap where success times associated with actions. * @return A HashMap where success times associated with actions.
*/ */
HashMap<Integer, Action[]> getTimesActionMap(ConfigurationSection section); @NotNull
HashMap<Integer, Action<T>[]> getTimesActionMap(@NotNull Section section);
/** /**
* Triggers a list of actions with the given condition. * Triggers a list of actions with the given condition.
* If the list of actions is not null, each action in the list is triggered. * If the list of actions is not null, each action in the list is triggered.
* *
* @param actions The list of actions to trigger. * @param actions The list of actions to trigger.
* @param condition The condition associated with the actions. * @param context The context associated with the actions.
*/ */
static void triggerActions(Condition condition, Action... actions) { static <T> void trigger(@NotNull Context<T> context, @Nullable Action<T>... actions) {
if (actions != null) if (actions != null)
for (Action action : actions) for (Action<T> action : actions)
action.trigger(condition); action.trigger(context);
} }
} }

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.bag;
import net.momirealms.customfishing.api.data.user.OfflineUser; import net.momirealms.customfishing.api.data.user.OfflineUser;
import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.Action;
@@ -30,7 +30,7 @@ import java.util.UUID;
public interface BagManager { public interface BagManager {
/** /**
* Is bag enabled * Is bag mechanics enabled
* *
* @return enabled or not * @return enabled or not
*/ */

View File

@@ -21,5 +21,6 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public interface BlockDataModifier { public interface BlockDataModifier {
void apply(Player player, BlockData blockData); void apply(Player player, BlockData blockData);
} }

View File

@@ -15,11 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.block;
import net.momirealms.customfishing.api.mechanic.block.BlockDataModifierBuilder;
import net.momirealms.customfishing.api.mechanic.block.BlockLibrary;
import net.momirealms.customfishing.api.mechanic.block.BlockStateModifierBuilder;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;

View File

@@ -21,5 +21,6 @@ import org.bukkit.block.BlockState;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public interface BlockStateModifier { public interface BlockStateModifier {
void apply(Player player, BlockState blockState); void apply(Player player, BlockState blockState);
} }

View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.competition;
public class ActionBarConfig extends AbstractCompetitionInfo {
public static class Builder {
private final ActionBarConfig config;
public Builder() {
this.config = new ActionBarConfig();
}
public Builder showToAll(boolean showToAll) {
this.config.showToAll = showToAll;
return this;
}
public Builder refreshRate(int rate) {
this.config.refreshRate = rate;
return this;
}
public Builder switchInterval(int interval) {
this.config.switchInterval = interval;
return this;
}
public Builder text(String[] texts) {
this.config.texts = texts;
return this;
}
public ActionBarConfig build() {
return this.config;
}
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.competition;
import org.bukkit.boss.BarColor;
public class BossBarConfig extends AbstractCompetitionInfo {
private BarColor color;
private Overlay overlay;
public BarColor getColor() {
return color;
}
public Overlay getOverlay() {
return overlay;
}
public static class Builder {
private final BossBarConfig config;
public Builder() {
this.config = new BossBarConfig();
}
public Builder showToAll(boolean showToAll) {
this.config.showToAll = showToAll;
return this;
}
public Builder refreshRate(int rate) {
this.config.refreshRate = rate;
return this;
}
public Builder switchInterval(int interval) {
this.config.switchInterval = interval;
return this;
}
public Builder text(String[] texts) {
this.config.texts = texts;
return this;
}
public Builder color(BarColor color) {
this.config.color = color;
return this;
}
public Builder overlay(Overlay overlay) {
this.config.overlay = overlay;
return this;
}
public BossBarConfig build() {
return this.config;
}
}
public enum Overlay {
NOTCHED_6,
NOTCHED_10,
NOTCHED_12,
NOTCHED_20,
PROGRESS
}
}

View File

@@ -18,6 +18,8 @@
package net.momirealms.customfishing.api.mechanic.competition; package net.momirealms.customfishing.api.mechanic.competition;
import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.competition.info.ActionBarConfigImpl;
import net.momirealms.customfishing.api.mechanic.competition.info.BossBarConfigImpl;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -29,8 +31,8 @@ public class CompetitionConfig {
private final String key; private final String key;
private int duration; private int duration;
private int minPlayers; private int minPlayers;
private BossBarConfig bossBarConfig; private BossBarConfigImpl bossBarConfigImpl;
private ActionBarConfig actionBarConfig; private ActionBarConfigImpl actionBarConfigImpl;
private Action[] skipActions; private Action[] skipActions;
private Action[] startActions; private Action[] startActions;
private Action[] endActions; private Action[] endActions;
@@ -110,13 +112,13 @@ public class CompetitionConfig {
} }
@Nullable @Nullable
public BossBarConfig getBossBarConfig() { public BossBarConfigImpl getBossBarConfig() {
return bossBarConfig; return bossBarConfigImpl;
} }
@Nullable @Nullable
public ActionBarConfig getActionBarConfig() { public ActionBarConfigImpl getActionBarConfig() {
return actionBarConfig; return actionBarConfigImpl;
} }
public static Builder builder(String key) { public static Builder builder(String key) {
@@ -162,14 +164,14 @@ public class CompetitionConfig {
} }
@SuppressWarnings("UnusedReturnValue") @SuppressWarnings("UnusedReturnValue")
public Builder actionbar(ActionBarConfig actionBarConfig) { public Builder actionbar(ActionBarConfigImpl actionBarConfigImpl) {
config.actionBarConfig = actionBarConfig; config.actionBarConfigImpl = actionBarConfigImpl;
return this; return this;
} }
@SuppressWarnings("UnusedReturnValue") @SuppressWarnings("UnusedReturnValue")
public Builder bossbar(BossBarConfig bossBarConfig) { public Builder bossbar(BossBarConfigImpl bossBarConfigImpl) {
config.bossBarConfig = bossBarConfig; config.bossBarConfigImpl = bossBarConfigImpl;
return this; return this;
} }

View File

@@ -17,17 +17,64 @@
package net.momirealms.customfishing.api.mechanic.competition; package net.momirealms.customfishing.api.mechanic.competition;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.util.Index;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public enum CompetitionGoal { public final class CompetitionGoal {
CATCH_AMOUNT, public static final CompetitionGoal CATCH_AMOUNT = new CompetitionGoal(Key.key("customfishing", "catch_amount"));
TOTAL_SCORE, public static final CompetitionGoal TOTAL_SCORE = new CompetitionGoal(Key.key("customfishing", "total_score"));
MAX_SIZE, public static final CompetitionGoal MAX_SIZE = new CompetitionGoal(Key.key("customfishing", "max_size"));
TOTAL_SIZE, public static final CompetitionGoal TOTAL_SIZE = new CompetitionGoal(Key.key("customfishing", "total_size"));
RANDOM; public static final CompetitionGoal RANDOM = new CompetitionGoal(Key.key("customfishing", "random"));
private static final CompetitionGoal[] values = new CompetitionGoal[] {
CATCH_AMOUNT, TOTAL_SCORE, MAX_SIZE, TOTAL_SIZE, RANDOM
};
private static final Index<Key, CompetitionGoal> index = Index.create(CompetitionGoal::key, values());
/**
* Gets an array containing all defined competition goals.
*
* @return An array of all competition goals.
*/
public static CompetitionGoal[] values() {
return values;
}
/**
* Gets the index of competition goals by their keys.
*
* @return An index mapping keys to competition goals.
*/
public static Index<Key, CompetitionGoal> index() {
return index;
}
/**
* Gets a randomly selected competition goal.
*
* @return A randomly selected competition goal.
*/
public static CompetitionGoal getRandom() { public static CompetitionGoal getRandom() {
return CompetitionGoal.values()[ThreadLocalRandom.current().nextInt(CompetitionGoal.values().length - 1)]; return CompetitionGoal.values()[ThreadLocalRandom.current().nextInt(CompetitionGoal.values().length - 1)];
} }
private final Key key;
private CompetitionGoal(Key key) {
this.key = key;
}
/**
* Gets the key representing this competition goal.
*
* @return The key of the competition goal.
*/
public Key key() {
return key;
}
} }

View File

@@ -15,11 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.competition;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionConfig;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionGoal;
import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;

View File

@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
public class CompetitionPlayer implements Comparable<CompetitionPlayer>{ public class CompetitionPlayer implements Comparable<CompetitionPlayer>{
public static CompetitionPlayer empty = new CompetitionPlayer("", 0); private static CompetitionPlayer empty = new CompetitionPlayer("", 0);
private long time; private long time;
private final String player; private final String player;
private double score; private double score;
@@ -32,12 +32,13 @@ public class CompetitionPlayer implements Comparable<CompetitionPlayer>{
this.time = System.currentTimeMillis(); this.time = System.currentTimeMillis();
} }
public void addScore(double score){ public void addScore(double score) {
this.score += score; this.score += score;
if (score <= 0) return;
this.time = System.currentTimeMillis(); this.time = System.currentTimeMillis();
} }
public void setScore(double score){ public void setScore(double score) {
this.score = score; this.score = score;
this.time = System.currentTimeMillis(); this.time = System.currentTimeMillis();
} }

View File

@@ -29,7 +29,7 @@ public interface FishingCompetition {
/** /**
* Start the fishing competition * Start the fishing competition
*/ */
void start(); void start(boolean triggerEvent);
/** /**
* Stop the fishing competition * Stop the fishing competition

View File

@@ -17,7 +17,7 @@
package net.momirealms.customfishing.api.mechanic.competition; package net.momirealms.customfishing.api.mechanic.competition;
import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.common.util.Pair;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Iterator; import java.util.Iterator;

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.mechanic.competition; package net.momirealms.customfishing.api.mechanic.competition.info;
/** /**
* Abstract base class for competition information. * Abstract base class for competition information.
@@ -28,12 +28,19 @@ public abstract class AbstractCompetitionInfo {
protected boolean showToAll; protected boolean showToAll;
protected String[] texts; protected String[] texts;
protected AbstractCompetitionInfo(int refreshRate, int switchInterval, boolean showToAll, String[] texts) {
this.refreshRate = refreshRate;
this.switchInterval = switchInterval;
this.showToAll = showToAll;
this.texts = texts;
}
/** /**
* Get the refresh rate for updating competition information. * Get the refresh rate for updating competition information.
* *
* @return The refresh rate in ticks. * @return The refresh rate in ticks.
*/ */
public int getRefreshRate() { public int refreshRate() {
return refreshRate; return refreshRate;
} }
@@ -42,7 +49,7 @@ public abstract class AbstractCompetitionInfo {
* *
* @return The switch interval in ticks. * @return The switch interval in ticks.
*/ */
public int getSwitchInterval() { public int switchInterval() {
return switchInterval; return switchInterval;
} }
@@ -51,7 +58,7 @@ public abstract class AbstractCompetitionInfo {
* *
* @return True if information is shown to all players, otherwise only to participants. * @return True if information is shown to all players, otherwise only to participants.
*/ */
public boolean isShowToAll() { public boolean showToAll() {
return showToAll; return showToAll;
} }
@@ -60,7 +67,7 @@ public abstract class AbstractCompetitionInfo {
* *
* @return An array of competition information texts. * @return An array of competition information texts.
*/ */
public String[] getTexts() { public String[] texts() {
return texts; return texts;
} }
} }

View File

@@ -0,0 +1,91 @@
package net.momirealms.customfishing.api.mechanic.competition.info;
public interface ActionBarConfig {
int DEFAULT_REFRESH_RATE = 20;
int DEFAULT_SWITCH_INTERVAL = 200;
boolean DEFAULT_VISIBILITY = true;
String[] DEFAULT_TEXTS = new String[]{""};
/**
* Get the refresh rate for updating the competition information on the action bar.
*
* @return The refresh rate in ticks.
*/
int refreshRate();
/**
* Get the switch interval for displaying different competition texts.
*
* @return The switch interval in ticks.
*/
int switchInterval();
/**
* Check if competition information should be shown to all players.
*
* @return True if information is shown to all players, otherwise only to participants.
*/
boolean showToAll();
/**
* Get an array of competition information texts.
*
* @return An array of competition information texts.
*/
String[] texts();
/**
* Creates a new builder instance for constructing {@code ActionBarConfig} objects.
*
* @return A new {@code Builder} instance.
*/
static Builder builder() {
return new ActionBarConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@code ActionBarConfig} objects.
*/
interface Builder {
/**
* Sets whether the competition information should be shown to all players.
*
* @param showToAll True to show information to all players, false to show only to participants.
* @return The current {@code Builder} instance.
*/
Builder showToAll(boolean showToAll);
/**
* Sets the refresh rate for updating the competition information.
*
* @param rate The refresh rate in ticks.
* @return The current {@code Builder} instance.
*/
Builder refreshRate(int rate);
/**
* Sets the interval for switching between different competition texts.
*
* @param interval The switch interval in ticks.
* @return The current {@code Builder} instance.
*/
Builder switchInterval(int interval);
/**
* Sets the texts to be displayed on the action bar during the competition.
*
* @param texts An array of competition information texts.
* @return The current {@code Builder} instance.
*/
Builder text(String[] texts);
/**
* Builds the {@code ActionBarConfig} object with the configured settings.
*
* @return The constructed {@code ActionBarConfig} object.
*/
ActionBarConfig build();
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.competition.info;
public class ActionBarConfigImpl extends AbstractCompetitionInfo implements ActionBarConfig {
public ActionBarConfigImpl(int refreshRate, int switchInterval, boolean showToAll, String[] texts) {
super(refreshRate, switchInterval, showToAll, texts);
}
public static class BuilderImpl implements Builder {
private int refreshRate = DEFAULT_REFRESH_RATE;
private int switchInterval = DEFAULT_SWITCH_INTERVAL;
private boolean showToAll = DEFAULT_VISIBILITY;
private String[] texts = DEFAULT_TEXTS;
@Override
public BuilderImpl showToAll(boolean showToAll) {
this.showToAll = showToAll;
return this;
}
@Override
public BuilderImpl refreshRate(int rate) {
this.refreshRate = rate;
return this;
}
@Override
public BuilderImpl switchInterval(int interval) {
this.switchInterval = interval;
return this;
}
@Override
public BuilderImpl text(String[] texts) {
this.texts = texts;
return this;
}
@Override
public ActionBarConfigImpl build() {
return new ActionBarConfigImpl(refreshRate, switchInterval, showToAll, texts);
}
}
}

View File

@@ -0,0 +1,125 @@
package net.momirealms.customfishing.api.mechanic.competition.info;
import net.kyori.adventure.bossbar.BossBar;
public interface BossBarConfig {
int DEFAULT_REFRESH_RATE = 20;
int DEFAULT_SWITCH_INTERVAL = 200;
boolean DEFAULT_VISIBILITY = true;
String[] DEFAULT_TEXTS = new String[]{""};
BossBar.Color DEFAULT_COLOR = BossBar.Color.BLUE;
BossBar.Overlay DEFAULT_OVERLAY = BossBar.Overlay.PROGRESS;
/**
* Get the refresh rate for updating competition information.
*
* @return The refresh rate in ticks.
*/
int refreshRate();
/**
* Get the switch interval for displaying different competition texts.
*
* @return The switch interval in ticks.
*/
int switchInterval();
/**
* Check if competition information should be shown to all players.
*
* @return True if information is shown to all players, otherwise only to participants.
*/
boolean showToAll();
/**
* Get an array of competition information texts.
*
* @return An array of competition information texts.
*/
String[] texts();
/**
* Gets the color of the boss bar.
*
* @return The color of the boss bar.
*/
BossBar.Color color();
/**
* Gets the overlay style of the boss bar.
*
* @return The overlay style of the boss bar.
*/
BossBar.Overlay overlay();
/**
* Creates a new builder instance for constructing {@code BossBarConfig} objects.
*
* @return A new {@code Builder} instance.
*/
static Builder builder() {
return new BossBarConfigImpl.BuilderImpl();
}
/**
* Builder interface for constructing {@code BossBarConfig} objects.
*/
interface Builder {
/**
* Sets whether the competition information should be shown to all players.
*
* @param showToAll True to show information to all players, false to show only to participants.
* @return The current {@code Builder} instance.
*/
Builder showToAll(boolean showToAll);
/**
* Sets the refresh rate for updating the competition information.
*
* @param rate The refresh rate in ticks.
* @return The current {@code Builder} instance.
*/
Builder refreshRate(int rate);
/**
* Sets the interval for switching between different competition texts.
*
* @param interval The switch interval in ticks.
* @return The current {@code Builder} instance.
*/
Builder switchInterval(int interval);
/**
* Sets the texts to be displayed on the boss bar during the competition.
*
* @param texts An array of competition information texts.
* @return The current {@code Builder} instance.
*/
Builder text(String[] texts);
/**
* Sets the color of the boss bar.
*
* @param color The color of the boss bar.
* @return The current {@code Builder} instance.
*/
Builder color(BossBar.Color color);
/**
* Sets the overlay style of the boss bar.
*
* @param overlay The overlay style of the boss bar.
* @return The current {@code Builder} instance.
*/
Builder overlay(BossBar.Overlay overlay);
/**
* Builds the {@code BossBarConfig} object with the configured settings.
*
* @return The constructed {@code BossBarConfig} object.
*/
BossBarConfig build();
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.competition.info;
import net.kyori.adventure.bossbar.BossBar;
public class BossBarConfigImpl extends AbstractCompetitionInfo implements BossBarConfig {
private final BossBar.Color color;
private final BossBar.Overlay overlay;
public BossBarConfigImpl(int refreshRate, int switchInterval, boolean showToAll, String[] texts, BossBar.Color color, BossBar.Overlay overlay) {
super(refreshRate, switchInterval, showToAll, texts);
this.color = color;
this.overlay = overlay;
}
@Override
public BossBar.Color color() {
return color;
}
@Override
public BossBar.Overlay overlay() {
return overlay;
}
public static class BuilderImpl implements Builder {
private int refreshRate = DEFAULT_REFRESH_RATE;
private int switchInterval = DEFAULT_SWITCH_INTERVAL;
private boolean showToAll = DEFAULT_VISIBILITY;
private String[] texts = DEFAULT_TEXTS;
private BossBar.Overlay overlay = DEFAULT_OVERLAY;
public BossBar.Color color = DEFAULT_COLOR;
@Override
public BuilderImpl showToAll(boolean showToAll) {
this.showToAll = showToAll;
return this;
}
@Override
public BuilderImpl refreshRate(int rate) {
this.refreshRate = rate;
return this;
}
@Override
public BuilderImpl switchInterval(int interval) {
this.switchInterval = interval;
return this;
}
@Override
public BuilderImpl text(String[] texts) {
this.texts = texts;
return this;
}
@Override
public BuilderImpl color(BossBar.Color color) {
this.color = color;
return this;
}
@Override
public BuilderImpl overlay(BossBar.Overlay overlay) {
this.overlay = overlay;
return this;
}
@Override
public BossBarConfigImpl build() {
return new BossBarConfigImpl(refreshRate, switchInterval, showToAll, texts, color, overlay);
}
}
}

View File

@@ -1,148 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.condition;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
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<String, String> 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<String, String> 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<String, String> args) {
this.location = location;
this.player = player;
this.args = args;
if (player != null)
this.args.put("{player}", player.getName());
if (location != null) {
this.args.put("{x}", String.valueOf(location.getX()));
this.args.put("{y}", String.valueOf(location.getY()));
this.args.put("{z}", String.valueOf(location.getZ()));
this.args.put("{world}", location.getWorld().getName());
}
}
/**
* 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()));
this.args.put("{y}", String.valueOf(location.getY()));
this.args.put("{z}", String.valueOf(location.getZ()));
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<String, String> 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);
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.condition;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class FishingPreparation extends Condition {
public FishingPreparation(Player player) {
super(player);
}
/**
* Retrieves the ItemStack representing the fishing rod.
*
* @return The ItemStack representing the fishing rod.
*/
@NotNull
public abstract ItemStack getRodItemStack();
/**
* Retrieves the ItemStack representing the bait (if available).
*
* @return The ItemStack representing the bait, or null if no bait is set.
*/
@Nullable
public abstract ItemStack getBaitItemStack();
/**
* Checks if player meet the requirements for fishing gears
*
* @return True if can fish, false otherwise.
*/
public abstract boolean canFish();
/**
* Merges a FishingEffect into this fishing rod, applying effect modifiers.
*
* @param effect The FishingEffect to merge into this rod.
*/
public abstract void mergeEffect(FishingEffect effect);
/**
* Triggers actions associated with a specific action trigger.
*
* @param actionTrigger The action trigger that initiates the actions.
*/
public abstract void triggerActions(ActionTrigger actionTrigger);
}

View File

@@ -0,0 +1,163 @@
package net.momirealms.customfishing.api.mechanic.config;
import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings;
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.misc.function.FormatFunction;
import net.momirealms.customfishing.api.mechanic.misc.function.ItemPropertyFunction;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
import net.momirealms.customfishing.common.config.ConfigManager;
import net.momirealms.customfishing.common.config.node.Node;
import net.momirealms.customfishing.common.helper.AdventureHelper;
import net.momirealms.customfishing.common.item.Item;
import net.momirealms.customfishing.common.plugin.CustomFishingPlugin;
import net.momirealms.customfishing.common.util.ListUtils;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class BukkitConfigManager implements ConfigManager {
private final CustomFishingPlugin plugin;
private final HashMap<String, Node<FormatFunction>> formatFunctions = new HashMap<>();
public BukkitConfigManager(CustomFishingPlugin plugin) {
this.plugin = plugin;
this.registerBuiltInItemProperties();
}
private void registerBuiltInItemProperties() {
this.registerItemFunction(arg -> {
MathValue<Player> mathValue = MathValue.auto(arg);
return (item, context) -> item.customModelData((int) mathValue.evaluate(context));
}, 4000, "custom-model-data");
this.registerItemFunction(arg -> {
TextValue<Player> textValue = TextValue.auto((String) arg);
return (item, context) -> {
item.displayName(AdventureHelper.miniMessageToJson(textValue.render(context)));
};
}, 3000, "display", "name");
this.registerItemFunction(arg -> {
List<String> list = ListUtils.toList(arg);
List<TextValue<Player>> lore = new ArrayList<>();
for (String text : list) {
lore.add(TextValue.auto(text));
}
return (item, context) -> {
item.lore(lore.stream()
.map(it -> AdventureHelper.miniMessageToJson(it.render(context)))
.toList());
};
}, 2000, "display", "lore");
this.registerItemFunction(arg -> {
boolean enable = (boolean) arg;
return (item, context) -> {
if (!enable) return;
item.setTag(context.arg(ContextKeys.ID), "CustomFishing", "id");
item.setTag(context.arg(ContextKeys.TYPE), "CustomFishing", "type");
};
}, 1000, "tag");
}
private void registerItemFunction(Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> function, int priority, String... nodes) {
registerNodeFunction(nodes, new ItemPropertyFunction(priority, function));
}
public void registerNodeFunction(String[] nodes, FormatFunction formatFunction) {
Map<String, Node<FormatFunction>> functionMap = formatFunctions;
for (int i = 0; i < nodes.length; i++) {
if (functionMap.containsKey(nodes[i])) {
Node<FormatFunction> functionNode = functionMap.get(nodes[i]);
if (functionNode.nodeValue() != null) {
throw new IllegalArgumentException("Format function '" + nodes[i] + "' already exists");
}
functionMap = functionNode.getChildTree();
} else {
if (i != nodes.length - 1) {
Node<FormatFunction> newNode = new Node<>();
functionMap.put(nodes[i], newNode);
functionMap = newNode.getChildTree();
} else {
functionMap.put(nodes[i], new Node<>(formatFunction));
}
}
}
}
protected Path resolveConfig(String filePath) {
if (filePath == null || filePath.equals("")) {
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
}
filePath = filePath.replace('\\', '/');
Path configFile = plugin.getConfigDirectory().resolve(filePath);
// if the config doesn't exist, create it based on the template in the resources dir
if (!Files.exists(configFile)) {
try {
Files.createDirectories(configFile.getParent());
} catch (IOException e) {
// ignore
}
try (InputStream is = plugin.getResourceStream(filePath)) {
if (is == null) {
throw new IllegalArgumentException("The embedded resource '" + filePath + "' cannot be found");
}
Files.copy(is, configFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return configFile;
}
@Override
public YamlDocument loadConfig(String filePath) {
return loadConfig(filePath, '.');
}
@Override
public YamlDocument loadConfig(String filePath, char routeSeparator) {
try {
return YamlDocument.create(
resolveConfig(filePath).toFile(),
plugin.getResourceStream(filePath),
GeneralSettings.builder().setRouteSeparator(routeSeparator).build(),
LoaderSettings
.builder()
.setAutoUpdate(true)
.build(),
DumperSettings.DEFAULT,
UpdaterSettings
.builder()
.setVersioning(new BasicVersioning("config-version"))
.build()
);
} catch (IOException e) {
plugin.getPluginLogger().severe("Failed to load config " + filePath, e);
return null;
}
}
}

View File

@@ -0,0 +1,62 @@
package net.momirealms.customfishing.api.mechanic.config;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem;
import net.momirealms.customfishing.api.mechanic.misc.function.FormatFunction;
import net.momirealms.customfishing.api.mechanic.misc.function.ItemPropertyFunction;
import net.momirealms.customfishing.api.mechanic.misc.function.PriorityFunction;
import net.momirealms.customfishing.common.config.node.Node;
import net.momirealms.customfishing.common.item.Item;
import net.momirealms.customfishing.common.util.Key;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
public class ItemConfig {
private final String id;
private final String material;
private final List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers = new ArrayList<>();
public ItemConfig(String id, Section section, Map<String, Node<FormatFunction>> functionMap) {
this.id = id;
this.material = section.getString("material");
analyze(section, functionMap);
}
private void analyze(Section section, Map<String, Node<FormatFunction>> functionMap) {
Map<String, Object> dataMap = section.getStringRouteMappedValues(false);
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
String key = entry.getKey();
Node<FormatFunction> node = functionMap.get(key);
if (node == null) continue;
FormatFunction function = node.nodeValue();
if (function != null) {
if (function instanceof ItemPropertyFunction propertyFunction) {
BiConsumer<Item<ItemStack>, Context<Player>> result = propertyFunction.accept(entry.getValue());
tagConsumers.add(new PriorityFunction<>(, result));
}
continue;
}
if (entry.getValue() instanceof Section innerSection) {
analyze(innerSection, node.getChildTree());
}
}
}
public Key key() {
return Key.of("item", id);
}
public CustomFishingItem getItem() {
return CustomFishingItem.builder()
.material(material)
.tagConsumers(tagConsumers)
.build();
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.context;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* The Context interface represents a generic context for custom fishing mechanics.
* It allows for storing and retrieving arguments, as well as getting the holder
* of the context. This can be used to maintain state or pass parameters within
* the custom fishing mechanics.
*
* @param <T> the type of the holder object for this context
*/
public interface Context<T> {
/**
* Retrieves the map of arguments associated with this context.
*
* @return a map where the keys are argument names and the values are argument values.
*/
Map<ContextKeys<?>, Object> args();
<C> Context<T> arg(ContextKeys<C> key, C value);
<C> C arg(ContextKeys<C> key);
/**
* Gets the holder of this context.
*
* @return the holder object of type T.
*/
T getHolder();
/**
* Creates a player-specific context.
*
* @param player the player to be used as the holder of the context.
* @return a new Context instance with the specified player as the holder.
*/
static Context<Player> player(@NotNull Player player) {
return new PlayerContextImpl(player);
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.context;
import org.bukkit.Location;
import java.util.Objects;
public class ContextKeys<T> {
public static final ContextKeys<Location> LOCATION = of("location", Location.class);
public static final ContextKeys<Integer> X = of("x", Integer.class);
public static final ContextKeys<Integer> Y = of("y", Integer.class);
public static final ContextKeys<Integer> Z = of("z", Integer.class);
public static final ContextKeys<String> WORLD = of("world", String.class);
public static final ContextKeys<String> ID = of("id", String.class);
public static final ContextKeys<String> TYPE = of("type", String.class);
private final String key;
private final Class<T> type;
private ContextKeys(String key, Class<T> type) {
this.key = key;
this.type = type;
}
public String key() {
return key;
}
public Class<T> type() {
return type;
}
public static <T> ContextKeys<T> of(String key, Class<T> type) {
return new ContextKeys<T>(key, type);
}
@Override
public final boolean equals(final Object other) {
if (this == other) {
return true;
} else if (other != null && this.getClass() == other.getClass()) {
ContextKeys<?> that = (ContextKeys) other;
return Objects.equals(this.key, that.key);
} else {
return false;
}
}
@Override
public final int hashCode() {
return Objects.hashCode(this.key);
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.context;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* The PlayerContextImpl class implements the Context interface specifically
* for the Player type. It allows for storing and retrieving arguments related
* to a player in the custom fishing mechanics.
*/
public final class PlayerContextImpl implements Context<Player> {
private final Player player;
private final HashMap<ContextKeys<?>, Object> args = new HashMap<>();
/**
* Constructs a new PlayerContextImpl with the specified player.
*
* @param player the player to be associated with this context.
*/
public PlayerContextImpl(@NotNull Player player) {
this.player = player;
final Location location = player.getLocation();
arg(ContextKeys.LOCATION, location)
.arg(ContextKeys.X, location.getBlockX())
.arg(ContextKeys.Y, location.getBlockY())
.arg(ContextKeys.Z, location.getBlockZ())
.arg(ContextKeys.WORLD, location.getWorld().getName());
}
/**
* Retrieves the map of arguments associated with this context.
*
* @return a map where the keys are argument names and the values are argument values.
*/
@Override
public Map<ContextKeys<?>, Object> args() {
return args;
}
/**
* Adds an argument to the context and returns the context itself
* to allow for method chaining.
*
* @param key the name of the argument to add.
* @param value the value of the argument to add.
* @return the PlayerContextImpl instance to allow for method chaining.
*/
@Override
public <C> PlayerContextImpl arg(ContextKeys<C> key, C value) {
args.put(key, value);
return this;
}
/**
* Retrieves the value of a specific argument from the context.
*
* @param key the name of the argument to retrieve.
* @return the value of the argument, or null if no argument with the given key exists.
*/
@Override
@SuppressWarnings("unchecked")
public <C> C arg(ContextKeys<C> key) {
return (C) args.get(key);
}
/**
* Gets the player associated with this context.
*
* @return the player object associated with this context.
*/
@Override
public Player getHolder() {
return player;
}
}

View File

@@ -1,20 +1,20 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.mechanic.misc.Value; import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Map; import java.util.Map;
public class BaseEffect { public class BaseEffect {
private final Value waitTime; private final MathValue<Player> waitTime;
private final Value waitTimeMultiplier; private final MathValue<Player> waitTimeMultiplier;
private final Value difficulty; private final MathValue<Player> difficulty;
private final Value difficultyMultiplier; private final MathValue<Player> difficultyMultiplier;
private final Value gameTime; private final MathValue<Player> gameTime;
private final Value gameTimeMultiplier; private final MathValue<Player> gameTimeMultiplier;
public BaseEffect(Value waitTime, Value waitTimeMultiplier, Value difficulty, Value difficultyMultiplier, Value gameTime, Value gameTimeMultiplier) { public BaseEffect(MathValue<Player> waitTime, MathValue<Player> waitTimeMultiplier, MathValue<Player> difficulty, MathValue difficultyMultiplier, MathValue gameTime, MathValue gameTimeMultiplier) {
this.waitTime = waitTime; this.waitTime = waitTime;
this.waitTimeMultiplier = waitTimeMultiplier; this.waitTimeMultiplier = waitTimeMultiplier;
this.difficulty = difficulty; this.difficulty = difficulty;

View File

@@ -17,40 +17,45 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.common.util.Pair;
import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
import java.util.function.BiFunction;
public interface Effect { public interface Effect {
boolean canLavaFishing(); boolean allowLavaFishing();
double getMultipleLootChance(); double multipleLootChance();
double getSize(); double sizeAdder();
double getSizeMultiplier(); double sizeMultiplier();
double getScore(); double scoreAdder();
double getScoreMultiplier(); double scoreMultiplier();
double getWaitTime(); double waitTimeAdder();
double getWaitTimeMultiplier(); double getWaitTimeMultiplier();
double getGameTime(); double gameTimeAdder();
double getGameTimeMultiplier(); double gameTimeMultiplier();
double getDifficulty(); double difficultyAdder();
double getDifficultyMultiplier(); double difficultyMultiplier();
List<Pair<String, WeightModifier>> getWeightModifier(); List<Pair<String, BiFunction<Player, Double, Double>>> weightModifier();
List<Pair<String, WeightModifier>> getWeightModifierIgnored(); List<Pair<String, BiFunction<Player, Double, Double>>> weightModifierIgnored();
void merge(Effect effect); void merge(Effect effect);
interface Builder {
}
} }

View File

@@ -17,10 +17,9 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Key; import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -102,10 +101,10 @@ public class EffectCarrier {
} }
@SuppressWarnings("BooleanMethodIsAlwaysInverted") @SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isConditionMet(Condition condition) { public boolean isConditionMet(PlayerContext playerContext) {
if (requirements == null) return true; if (requirements == null) return true;
for (Requirement requirement : requirements) { for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(condition)) { if (!requirement.check(playerContext)) {
return false; return false;
} }
} }

View File

@@ -0,0 +1,4 @@
package net.momirealms.customfishing.api.mechanic.effect;
public class EffectImpl {
}

View File

@@ -15,13 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Key; import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.api.mechanic.effect.BaseEffect;
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;

View File

@@ -17,9 +17,10 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.context.Context;
import org.bukkit.entity.Player;
public interface EffectModifier { public interface EffectModifier {
void modify(FishingEffect effect, Condition condition); void modify(FishingEffect effect, Context<Player> playerContext);
} }

View File

@@ -18,7 +18,6 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.misc.WeightModifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -214,7 +213,7 @@ public class FishingEffect implements Effect {
* @return True if lava fishing is enabled, false otherwise. * @return True if lava fishing is enabled, false otherwise.
*/ */
@Override @Override
public boolean canLavaFishing() { public boolean allowLavaFishing() {
return lavaFishing; return lavaFishing;
} }
@@ -224,7 +223,7 @@ public class FishingEffect implements Effect {
* @return The multiple loot chance value. * @return The multiple loot chance value.
*/ */
@Override @Override
public double getMultipleLootChance() { public double multipleLootChance() {
return multipleLootChance; return multipleLootChance;
} }
@@ -234,7 +233,7 @@ public class FishingEffect implements Effect {
* @return The size multiplier value. * @return The size multiplier value.
*/ */
@Override @Override
public double getSizeMultiplier() { public double sizeMultiplier() {
return sizeMultiplier; return sizeMultiplier;
} }
@@ -244,7 +243,7 @@ public class FishingEffect implements Effect {
* @return The size value. * @return The size value.
*/ */
@Override @Override
public double getSize() { public double sizeAdder() {
return size; return size;
} }
@@ -254,7 +253,7 @@ public class FishingEffect implements Effect {
* @return The score multiplier value. * @return The score multiplier value.
*/ */
@Override @Override
public double getScoreMultiplier() { public double scoreMultiplier() {
return scoreMultiplier; return scoreMultiplier;
} }
@@ -274,7 +273,7 @@ public class FishingEffect implements Effect {
* @return The wait time . * @return The wait time .
*/ */
@Override @Override
public double getWaitTime() { public double waitTimeAdder() {
return waitTime; return waitTime;
} }
@@ -284,7 +283,7 @@ public class FishingEffect implements Effect {
* @return The game time value. * @return The game time value.
*/ */
@Override @Override
public double getGameTime() { public double gameTimeAdder() {
return gameTime; return gameTime;
} }
@@ -294,7 +293,7 @@ public class FishingEffect implements Effect {
* @return The game time value multiplier. * @return The game time value multiplier.
*/ */
@Override @Override
public double getGameTimeMultiplier() { public double gameTimeMultiplier() {
return gameTimeMultiplier; return gameTimeMultiplier;
} }
@@ -304,7 +303,7 @@ public class FishingEffect implements Effect {
* @return The score value. * @return The score value.
*/ */
@Override @Override
public double getScore() { public double scoreAdder() {
return score; return score;
} }
@@ -314,7 +313,7 @@ public class FishingEffect implements Effect {
* @return The difficulty value. * @return The difficulty value.
*/ */
@Override @Override
public double getDifficulty() { public double difficultyAdder() {
return difficulty; return difficulty;
} }
@@ -324,7 +323,7 @@ public class FishingEffect implements Effect {
* @return The difficulty multiplier value. * @return The difficulty multiplier value.
*/ */
@Override @Override
public double getDifficultyMultiplier() { public double difficultyMultiplier() {
return difficultyMultiplier; return difficultyMultiplier;
} }
@@ -334,7 +333,7 @@ public class FishingEffect implements Effect {
* @return The list of weight modifiers. * @return The list of weight modifiers.
*/ */
@Override @Override
public List<Pair<String, WeightModifier>> getWeightModifier() { public List<Pair<String, WeightModifier>> weightModifier() {
return weightModifier; return weightModifier;
} }
@@ -344,7 +343,7 @@ public class FishingEffect implements Effect {
* @return The list of weight modifiers ignoring conditions. * @return The list of weight modifiers ignoring conditions.
*/ */
@Override @Override
public List<Pair<String, WeightModifier>> getWeightModifierIgnored() { public List<Pair<String, WeightModifier>> weightModifierIgnored() {
return weightModifierIgnored; return weightModifierIgnored;
} }
@@ -356,18 +355,18 @@ public class FishingEffect implements Effect {
@Override @Override
public void merge(Effect another) { public void merge(Effect another) {
if (another == null) return; if (another == null) return;
if (another.canLavaFishing()) this.lavaFishing = true; if (another.allowLavaFishing()) this.lavaFishing = true;
this.scoreMultiplier += (another.getScoreMultiplier() -1); this.scoreMultiplier += (another.scoreMultiplier() -1);
this.score += another.getScore(); this.score += another.scoreAdder();
this.sizeMultiplier += (another.getSizeMultiplier() -1); this.sizeMultiplier += (another.sizeMultiplier() -1);
this.size += another.getSize(); this.size += another.sizeAdder();
this.difficultyMultiplier += (another.getDifficultyMultiplier() -1); this.difficultyMultiplier += (another.difficultyMultiplier() -1);
this.difficulty += another.getDifficulty(); this.difficulty += another.difficultyAdder();
this.gameTimeMultiplier += (another.getGameTimeMultiplier() - 1); this.gameTimeMultiplier += (another.gameTimeMultiplier() - 1);
this.gameTime += another.getGameTime(); this.gameTime += another.gameTimeAdder();
this.waitTimeMultiplier += (another.getWaitTimeMultiplier() -1); this.waitTimeMultiplier += (another.getWaitTimeMultiplier() -1);
this.multipleLootChance += another.getMultipleLootChance(); this.multipleLootChance += another.multipleLootChance();
this.weightModifierIgnored.addAll(another.getWeightModifierIgnored()); this.weightModifierIgnored.addAll(another.weightModifierIgnored());
this.weightModifier.addAll(another.getWeightModifier()); this.weightModifier.addAll(another.weightModifier());
} }
} }

View File

@@ -17,76 +17,104 @@
package net.momirealms.customfishing.api.mechanic.entity; package net.momirealms.customfishing.api.mechanic.entity;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class EntityConfig implements EntitySettings { /**
* The EntityConfig interface defines the configuration for an entity used in custom fishing mechanics.
* It includes methods to retrieve various properties of the entity such as vectors and an ID, as well
* as a nested Builder interface for constructing instances of EntityConfig.
*/
public interface EntityConfig {
private String entity; double DEFAULT_HORIZONTAL_VECTOR = 1;
private double horizontalVector; double DEFAULT_VERTICAL_VECTOR = 1;
private double verticalVector; String DEFAULT_ENTITY_ID = "";
private Map<String, Object> propertyMap; Map<String, Object> DEFAULT_PROPERTY_MAP = Map.of();
private boolean persist;
@Override /**
public boolean isPersist() { * Retrieves the horizontal vector value for the entity.
return persist; *
* @return the horizontal vector value as a double
*/
double getHorizontalVector();
/**
* Retrieves the vertical vector value for the entity.
*
* @return the vertical vector value as a double
*/
double getVerticalVector();
/**
* Retrieves the unique identifier for the entity.
*
* @return the entity ID as a non-null String
*/
@NotNull
String getEntityID();
/**
* Retrieves a map of properties associated with the entity.
*
* @return a non-null map where keys are property names and values are property values
*/
@NotNull
Map<String, Object> getPropertyMap();
/**
* Creates a new Builder instance for constructing an EntityConfig.
*
* @return a new Builder instance
*/
static Builder builder() {
return new EntityConfigImpl.BuilderImpl();
} }
@Override /**
public double getHorizontalVector() { * Builder interface for constructing instances of EntityConfig.
return horizontalVector; */
} interface Builder {
@Override /**
public double getVerticalVector() { * Sets the entity ID for the EntityConfig being built.
return verticalVector; *
} * @param value the entity ID as a String
* @return the current Builder instance
*/
Builder entityID(String value);
@Override /**
public String getEntityID() { * Sets the vertical vector value for the EntityConfig being built.
return entity; *
} * @param value the vertical vector value as a double
* @return the current Builder instance
*/
Builder verticalVector(double value);
@Override /**
public Map<String, Object> getPropertyMap() { * Sets the horizontal vector value for the EntityConfig being built.
return propertyMap; *
} * @param value the horizontal vector value as a double
* @return the current Builder instance
*/
Builder horizontalVector(double value);
public static class Builder { /**
* Sets the property map for the EntityConfig being built.
*
* @param value a map of properties where keys are property names and values are property values
* @return the current Builder instance
*/
Builder propertyMap(Map<String, Object> value);
private final EntityConfig config; /**
* Builds and returns the EntityConfig instance based on the current state of the Builder.
public Builder() { *
this.config = new EntityConfig(); * @return a new EntityConfig instance
} */
EntityConfig build();
public Builder entityID(String value) {
this.config.entity = value;
return this;
}
public Builder persist(boolean value) {
this.config.persist = value;
return this;
}
public Builder verticalVector(double value) {
this.config.verticalVector = value;
return this;
}
public Builder horizontalVector(double value) {
this.config.horizontalVector = value;
return this;
}
public Builder propertyMap(Map<String, Object> value) {
this.config.propertyMap = value;
return this;
}
public EntityConfig build() {
return config;
}
} }
} }

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.entity;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class EntityConfigImpl implements EntityConfig {
private final String id;
private final double horizontalVector;
private final double verticalVector;
private final Map<String, Object> propertyMap;
public EntityConfigImpl(String id, double horizontalVector, double verticalVector, Map<String, Object> propertyMap) {
this.id = id;
this.horizontalVector = horizontalVector;
this.verticalVector = verticalVector;
this.propertyMap = propertyMap;
}
@Override
public double getHorizontalVector() {
return horizontalVector;
}
@Override
public double getVerticalVector() {
return verticalVector;
}
@NotNull
@Override
public String getEntityID() {
return id;
}
@NotNull
@Override
public Map<String, Object> getPropertyMap() {
return propertyMap;
}
public static class BuilderImpl implements Builder {
private String entity = DEFAULT_ENTITY_ID;
private double horizontalVector = DEFAULT_HORIZONTAL_VECTOR;
private double verticalVector = DEFAULT_VERTICAL_VECTOR;
private Map<String, Object> propertyMap = DEFAULT_PROPERTY_MAP;
@Override
public BuilderImpl entityID(String value) {
this.entity = value;
return this;
}
@Override
public BuilderImpl verticalVector(double value) {
this.verticalVector = value;
return this;
}
@Override
public BuilderImpl horizontalVector(double value) {
this.horizontalVector = value;
return this;
}
@Override
public BuilderImpl propertyMap(Map<String, Object> value) {
this.propertyMap = value;
return this;
}
@Override
public EntityConfigImpl build() {
return new EntityConfigImpl(entity, horizontalVector, verticalVector, propertyMap);
}
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.entity;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import java.util.Map;
public interface EntityLibrary {
String identification();
Entity spawn(Location location, String id, Map<String, Object> propertyMap);
}

View File

@@ -15,30 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.entity;
import net.momirealms.customfishing.api.mechanic.entity.EntityLibrary;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.Location; import org.bukkit.Location;
public interface EntityManager { public interface EntityManager {
/**
* Registers an entity library for use in the plugin.
*
* @param entityLibrary The entity library to register.
* @return {@code true} if the entity library was successfully registered, {@code false} if it already exists.
*/
boolean registerEntityLibrary(EntityLibrary entityLibrary);
/**
* Unregisters an entity library by its identification key.
*
* @param identification The identification key of the entity library to unregister.
* @return {@code true} if the entity library was successfully unregistered, {@code false} if it does not exist.
*/
boolean unregisterEntityLibrary(String identification);
/** /**
* Summons an entity based on the given loot configuration to a specified location. * Summons an entity based on the given loot configuration to a specified location.
* *

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.entity;
import java.util.Map;
public interface EntitySettings {
boolean isPersist();
double getHorizontalVector();
double getVerticalVector();
String getEntityID();
Map<String, Object> getPropertyMap();
}

View File

@@ -15,10 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.fishing;
import net.momirealms.customfishing.api.mechanic.TempFishingState; import net.momirealms.customfishing.api.mechanic.TempFishingState;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.game.GameInstance; import net.momirealms.customfishing.api.mechanic.game.GameInstance;
import net.momirealms.customfishing.api.mechanic.game.GameSettings; import net.momirealms.customfishing.api.mechanic.game.GameSettings;
@@ -81,10 +80,10 @@ public interface FishingManager {
* Starts a fishing game for the specified player with the given condition and effect. * Starts a fishing game for the specified player with the given condition and effect.
* *
* @param player The player starting the fishing game. * @param player The player starting the fishing game.
* @param condition The condition used to determine the game. * @param playerContext The condition used to determine the game.
* @param effect The effect applied to the game. * @param effect The effect applied to the game.
*/ */
boolean startFishingGame(Player player, Condition condition, Effect effect); boolean startFishingGame(Player player, PlayerContext playerContext, Effect effect);
/** /**
* Starts a fishing game for the specified player with the given settings and game instance. * Starts a fishing game for the specified player with the given settings and game instance.

View File

@@ -17,8 +17,8 @@
package net.momirealms.customfishing.api.mechanic.game; package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.manager.FishingManager; import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.scheduler.CancellableTask; import net.momirealms.customfishing.api.scheduler.CancellableTask;
import org.bukkit.Material; import org.bukkit.Material;
@@ -41,13 +41,13 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
this.player = player; this.player = player;
this.fishHook = hook; this.fishHook = hook;
this.settings = settings; this.settings = settings;
this.manager = CustomFishingPlugin.get().getFishingManager(); this.manager = BukkitCustomFishingPlugin.get().getFishingManager();
this.deadline = (long) (System.currentTimeMillis() + settings.getTime() * 1000L); this.deadline = (long) (System.currentTimeMillis() + settings.getTime() * 1000L);
this.arrangeTask(); this.arrangeTask();
} }
public void arrangeTask() { public void arrangeTask() {
this.task = CustomFishingPlugin.get().getScheduler().runTaskSyncTimer(this, fishHook.getLocation(), 1, 1); this.task = BukkitCustomFishingPlugin.get().getScheduler().runTaskSyncTimer(this, fishHook.getLocation(), 1, 1);
} }
@Override @Override

View File

@@ -79,8 +79,8 @@ public class BasicGameConfig {
@Nullable @Nullable
public GameSettings getGameSetting(Effect effect) { public GameSettings getGameSetting(Effect effect) {
return new GameSettings( return new GameSettings(
ThreadLocalRandom.current().nextInt(minTime, maxTime + 1) * effect.getGameTimeMultiplier() + effect.getGameTime(), ThreadLocalRandom.current().nextInt(minTime, maxTime + 1) * effect.gameTimeMultiplier() + effect.gameTimeAdder(),
(int) Math.min(100, Math.max(1, ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) * effect.getDifficultyMultiplier() + effect.getDifficulty())) (int) Math.min(100, Math.max(1, ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) * effect.difficultyMultiplier() + effect.difficultyAdder()))
); );
} }
} }

View File

@@ -15,13 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.game.BasicGameConfig;
import net.momirealms.customfishing.api.mechanic.game.GameFactory;
import net.momirealms.customfishing.api.mechanic.game.GameInstance;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.HashMap; import java.util.HashMap;
@@ -65,8 +61,8 @@ public interface GameManager {
/** /**
* Retrieves a map of game names and their associated weights based on the specified conditions. * Retrieves a map of game names and their associated weights based on the specified conditions.
* *
* @param condition The condition to evaluate game weights. * @param playerContext The condition to evaluate game weights.
* @return A {@code HashMap} containing game names as keys and their associated weights as values. * @return A {@code HashMap} containing game names as keys and their associated weights as values.
*/ */
HashMap<String, Double> getGameWithWeight(Condition condition); HashMap<String, Double> getGameWithWeight(PlayerContext playerContext);
} }

View File

@@ -15,9 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.hook;
import net.momirealms.customfishing.api.mechanic.hook.HookSetting;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
public interface BuildableItem {
default ItemStack build() {
return build(null, new HashMap<>());
}
default ItemStack build(Player player) {
return build(player, new HashMap<>());
}
ItemStack build(Player player, Map<String, String> placeholders);
/**
* Whether the item would be removed from cache when reloading
*/
boolean persist();
}

View File

@@ -0,0 +1,69 @@
package net.momirealms.customfishing.api.mechanic.item;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.function.PriorityFunction;
import net.momirealms.customfishing.common.item.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.TreeSet;
import java.util.function.BiConsumer;
public interface CustomFishingItem {
String DEFAULT_MATERIAL = "PAPER";
/**
* Returns the material type of the custom fishing item.
*
* @return the material type as a String.
*/
String material();
/**
* Returns a list of tag consumers which are functions that take an item and context as parameters
* and perform some operation on them.
*
* @return a set of BiConsumer instances.
*/
List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers();
/**
* Creates a new Builder instance to construct a CustomFishingItem.
*
* @return a new Builder instance.
*/
static Builder builder() {
return new CustomFishingItemImpl.BuilderImpl();
}
/**
* Builder interface for constructing instances of CustomFishingItem.
*/
interface Builder {
/**
* Sets the material type for the CustomFishingItem being built.
*
* @param material the material type as a String.
* @return the Builder instance for method chaining.
*/
Builder material(String material);
/**
* Sets the list of tag consumers for the CustomFishingItem being built.
*
* @param tagConsumers a list of BiConsumer instances.
* @return the Builder instance for method chaining.
*/
Builder tagConsumers(List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers);
/**
* Builds and returns a new CustomFishingItem instance.
*
* @return a new CustomFishingItem instance.
*/
CustomFishingItem build();
}
}

View File

@@ -0,0 +1,57 @@
package net.momirealms.customfishing.api.mechanic.item;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.function.PriorityFunction;
import net.momirealms.customfishing.common.item.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.TreeSet;
import java.util.function.BiConsumer;
public class CustomFishingItemImpl implements CustomFishingItem {
private final String material;
private final List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers;
public CustomFishingItemImpl(String material, List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers) {
this.material = material;
this.tagConsumers = tagConsumers;
}
@Override
public String material() {
return material;
}
@Override
public List<BiConsumer<Item<ItemStack>, Context<Player>>> tagConsumers() {
return tagConsumers;
}
public static class BuilderImpl implements Builder {
private String material = DEFAULT_MATERIAL;
private final TreeSet<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers = new TreeSet<>();
@Override
public Builder material(String material) {
this.material = material;
return this;
}
@Override
public Builder tagConsumers(List<PriorityFunction<BiConsumer<Item<ItemStack>, Context<Player>>>> tagConsumers) {
this.tagConsumers.addAll(tagConsumers);
return this;
}
@Override
public CustomFishingItem build() {
return new CustomFishingItemImpl(material, tagConsumers.stream().map(PriorityFunction::get).toList());
}
}
}

View File

@@ -1,99 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.item;
import de.tr7zw.changeme.nbtapi.NBTItem;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.common.Tuple;
import net.momirealms.customfishing.api.mechanic.misc.Value;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface ItemBuilder extends BuildableItem {
ItemBuilder customModelData(int value);
ItemBuilder name(String name);
ItemBuilder amount(int amount);
ItemBuilder amount(int min_amount, int max_amount);
ItemBuilder tag(boolean tag, String type, String id);
ItemBuilder unbreakable(boolean unbreakable);
ItemBuilder placeable(boolean placeable);
ItemBuilder lore(List<String> lore);
ItemBuilder nbt(Map<String, Object> nbt);
ItemBuilder itemFlag(List<ItemFlag> itemFlags);
ItemBuilder nbt(ConfigurationSection section);
ItemBuilder enchantment(List<Pair<String, Short>> enchantments, boolean store);
ItemBuilder randomEnchantments(List<Tuple<Double, String, Short>> enchantments, boolean store);
ItemBuilder enchantmentPool(List<Pair<Integer, Value>> amountPairs, List<Pair<Pair<String, Short>, Value>> enchantments, boolean store);
ItemBuilder maxDurability(int max);
ItemBuilder price(float base, float bonus);
ItemBuilder size(Pair<Float, Float> size);
ItemBuilder stackable(boolean stackable);
ItemBuilder preventGrabbing(boolean prevent);
ItemBuilder head(String base64);
ItemBuilder randomDamage(boolean damage);
@NotNull
String getId();
@NotNull
String getLibrary();
int getAmount();
Collection<ItemPropertyEditor> getEditors();
ItemBuilder removeEditor(String type);
ItemBuilder registerCustomEditor(String type, ItemPropertyEditor editor);
interface ItemPropertyEditor {
void edit(Player player, NBTItem nbtItem, Map<String, String> placeholders);
default void edit(Player player, NBTItem nbtItem) {
edit(player, nbtItem, null);
}
}
}

View File

@@ -17,14 +17,14 @@
package net.momirealms.customfishing.api.mechanic.item; package net.momirealms.customfishing.api.mechanic.item;
import net.kyori.adventure.key.Key;
import net.momirealms.customfishing.api.mechanic.context.Context;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
public interface ItemLibrary { public interface ItemManager {
String identification(); @Nullable
ItemStack build(Context<Player> context, Key key);
ItemStack buildItem(Player player, String id);
String getItemID(ItemStack itemStack);
} }

View File

@@ -1,328 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.loot;
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.BaseEffect;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public class CFLoot implements Loot {
private final String id;
private final LootType type;
private final HashMap<ActionTrigger, Action[]> actionMap;
private final HashMap<Integer, Action[]> successTimesActionMap;
private String nick;
private boolean showInFinder;
private boolean disableGame;
private boolean disableGlobalAction;
private boolean disableStats;
private boolean instanceGame;
private double score;
private String[] lootGroup;
private StatisticsKey statisticsKey;
private BaseEffect effect;
public CFLoot(String id, LootType type) {
this.id = id;
this.type = type;
this.actionMap = new HashMap<>();
this.successTimesActionMap = new HashMap<>();
}
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;
public Builder(String id, LootType type) {
this.loot = new CFLoot(id, type);
}
/**
* Set the file path for this loot.
*
* @param path file path
* @return The builder.
*/
public Builder filePath(String path) {
return this;
}
/**
* 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;
}
/**
* 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 whether global actions are disabled for this loot.
*
* @param disable True if statistics are disabled, false otherwise.
* @return The builder.
*/
public Builder disableGlobalActions(boolean disable) {
this.loot.disableGlobalAction = 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;
}
/**
* Set the statistics key for this loot
*
* @param statisticsKey statistics key
* @return The builder.
*/
public Builder statsKey(StatisticsKey statisticsKey) {
this.loot.statisticsKey = statisticsKey;
return this;
}
/**
* Set the effects for the loot
*
* @param effect effect
* @return The builder.
*/
public Builder baseEffect(BaseEffect effect) {
this.loot.effect = effect;
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<ActionTrigger, Action[]> 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<Integer, Action[]> actionMap) {
this.loot.successTimesActionMap.putAll(actionMap);
return this;
}
/**
* Build the CFLoot object.
*
* @return The built CFLoot object.
*/
public CFLoot build() {
return loot;
}
}
@Override
public boolean instanceGame() {
return this.instanceGame;
}
@Override
public String getID() {
return this.id;
}
@Override
public LootType getType() {
return this.type;
}
@Override
public @NotNull String getNick() {
return this.nick;
}
@Override
public StatisticsKey getStatisticKey() {
return this.statisticsKey;
}
@Override
public boolean showInFinder() {
return this.showInFinder;
}
@Override
public double getScore() {
return this.score;
}
@Override
public boolean disableGame() {
return this.disableGame;
}
@Override
public boolean disableStats() {
return this.disableStats;
}
@Override
public boolean disableGlobalAction() {
return this.disableGlobalAction;
}
@Override
public String[] getLootGroup() {
return lootGroup;
}
@Override
public Action[] getActions(ActionTrigger actionTrigger) {
return actionMap.get(actionTrigger);
}
@Override
public void triggerActions(ActionTrigger actionTrigger, Condition condition) {
Action[] actions = getActions(actionTrigger);
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
}
}
}
@Override
public BaseEffect getBaseEffect() {
return effect;
}
@Override
public Action[] getSuccessTimesActions(int times) {
return successTimesActionMap.get(times);
}
@Override
public HashMap<Integer, Action[]> getSuccessTimesActionMap() {
return successTimesActionMap;
}
}

View File

@@ -19,9 +19,9 @@ package net.momirealms.customfishing.api.mechanic.loot;
import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.BaseEffect; import net.momirealms.customfishing.api.mechanic.effect.BaseEffect;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey; import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKeys;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -63,7 +63,7 @@ public interface Loot {
@NotNull @NotNull
String getNick(); String getNick();
StatisticsKey getStatisticKey(); StatisticsKeys getStatisticKey();
/** /**
* Check if this loot should be shown in the finder. * Check if this loot should be shown in the finder.
@@ -113,9 +113,9 @@ public interface Loot {
* Trigger actions associated with a specific action trigger. * Trigger actions associated with a specific action trigger.
* *
* @param actionTrigger The action trigger. * @param actionTrigger The action trigger.
* @param condition The condition under which the actions are triggered. * @param playerContext The condition under which the actions are triggered.
*/ */
void triggerActions(ActionTrigger actionTrigger, Condition condition); void triggerActions(ActionTrigger actionTrigger, PlayerContext playerContext);
/** /**
* Get effects that bond to this loot * Get effects that bond to this loot
@@ -130,12 +130,12 @@ public interface Loot {
* @param times The number of successes. * @param times The number of successes.
* @return The actions triggered by the specified number of successes. * @return The actions triggered by the specified number of successes.
*/ */
Action[] getSuccessTimesActions(int times); Action<Player>[] getRecordActions(int times);
/** /**
* Get a map of actions triggered by different numbers of successes. * Get a map of actions triggered by different numbers of successes.
* *
* @return A map of actions triggered by success times. * @return A map of actions triggered by success times.
*/ */
HashMap<Integer, Action[]> getSuccessTimesActionMap(); HashMap<Integer, Action<Player>[]> getRecordActionMap();
} }

View File

@@ -15,11 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.loot;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -63,34 +61,34 @@ public interface LootManager {
/** /**
* Retrieves loot configurations with weights based on a given condition. * Retrieves loot configurations with weights based on a given condition.
* *
* @param condition The condition used to filter loot configurations. * @param playerContext The condition used to filter loot configurations.
* @return A mapping of loot configuration keys to their associated weights. * @return A mapping of loot configuration keys to their associated weights.
*/ */
HashMap<String, Double> getLootWithWeight(Condition condition); HashMap<String, Double> getLootWithWeight(PlayerContext playerContext);
/** /**
* Get a collection of possible loot keys based on a given condition. * Get a collection of possible loot keys based on a given condition.
* *
* @param condition The condition to determine possible loot. * @param playerContext The condition to determine possible loot.
* @return A collection of loot keys. * @return A collection of loot keys.
*/ */
Collection<String> getPossibleLootKeys(Condition condition); Collection<String> getPossibleLootKeys(PlayerContext playerContext);
/** /**
* Get a map of possible loot keys with their corresponding weights, considering fishing effect and condition. * Get a map of possible loot keys with their corresponding weights, considering fishing effect and condition.
* *
* @param initialEffect The effect to apply weight modifiers. * @param initialEffect The effect to apply weight modifiers.
* @param condition The condition to determine possible loot. * @param playerContext The condition to determine possible loot.
* @return A map of loot keys and their weights. * @return A map of loot keys and their weights.
*/ */
@NotNull Map<String, Double> getPossibleLootKeysWithWeight(Effect initialEffect, Condition condition); @NotNull Map<String, Double> getPossibleLootKeysWithWeight(Effect initialEffect, PlayerContext playerContext);
/** /**
* Get the next loot item based on fishing effect and condition. * Get the next loot item based on fishing effect and condition.
* *
* @param effect The effect to apply weight modifiers. * @param effect The effect to apply weight modifiers.
* @param condition The condition to determine possible loot. * @param playerContext The condition to determine possible loot.
* @return The next loot item, or null if it doesn't exist. * @return The next loot item, or null if it doesn't exist.
*/ */
@Nullable Loot getNextLoot(Effect effect, Condition condition); @Nullable Loot getNextLoot(Effect effect, PlayerContext playerContext);
} }

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.market;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
@@ -44,7 +44,7 @@ public interface MarketManager {
* *
* @return An integer representing the current date. * @return An integer representing the current date.
*/ */
int getDate(); int getRealTimeDate();
/** /**
* Calculates the price of an ItemStack based on custom data or a predefined price map. * Calculates the price of an ItemStack based on custom data or a predefined price map.

View File

@@ -1,25 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.misc;
import org.bukkit.entity.Player;
public interface WeightModifier {
double modify(Player player, double weight);
}

View File

@@ -0,0 +1,4 @@
package net.momirealms.customfishing.api.mechanic.misc.function;
public interface FormatFunction {
}

View File

@@ -0,0 +1,27 @@
package net.momirealms.customfishing.api.mechanic.misc.function;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.common.item.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class ItemPropertyFunction implements FormatFunction {
private Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> function;
private int priority;
public ItemPropertyFunction(int priority, Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> function) {
this.function = function;
}
public BiConsumer<Item<ItemStack>, Context<Player>> accept(Object object) {
return function.apply(object);
}
public int getPriority() {
return priority;
}
}

View File

@@ -0,0 +1,23 @@
package net.momirealms.customfishing.api.mechanic.misc.function;
import org.jetbrains.annotations.NotNull;
public class PriorityFunction<T> implements Comparable<PriorityFunction<T>> {
private final int priority;
private final T function;
public PriorityFunction(int priority, T function) {
this.priority = priority;
this.function = function;
}
public T get() {
return function;
}
@Override
public int compareTo(@NotNull PriorityFunction<T> o) {
return Integer.compare(this.priority, o.priority);
}
}

View File

@@ -0,0 +1,9 @@
package net.momirealms.customfishing.api.mechanic.misc.season;
public enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER,
DISABLE
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class ExpressionMathValueImpl<T> implements MathValue<T> {
private String raw;
public ExpressionMathValueImpl(String raw) {
this.raw = raw;
}
@Override
public double evaluate(Context<T> context) {
return 0;
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
/**
* The MathValue interface represents a mathematical value that can be evaluated
* within a specific context. This interface allows for the evaluation of mathematical
* expressions or plain numerical values in the context of custom fishing mechanics.
*
* @param <T> the type of the holder object for the context
*/
public interface MathValue<T> {
/**
* Evaluates the mathematical value within the given context.
*
* @param context the context in which the value is evaluated
* @return the evaluated value as a double
*/
double evaluate(Context<T> context);
/**
* Creates a MathValue based on a mathematical expression.
*
* @param expression the mathematical expression to evaluate
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given expression
*/
static <T> MathValue<T> expression(String expression) {
return new ExpressionMathValueImpl<>(expression);
}
/**
* Creates a MathValue based on a plain numerical value.
*
* @param value the numerical value to represent
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given plain value
*/
static <T> MathValue<T> plain(double value) {
return new PlainMathValueImpl<>(value);
}
/**
* Automatically creates a MathValue based on the given object.
* If the object is a String, it is treated as a mathematical expression.
* If the object is a numerical type (Double, Integer, Long, Float), it is treated as a plain value.
*
* @param o the object to evaluate and create a MathValue from
* @param <T> the type of the holder object for the context
* @return a MathValue instance representing the given object, either as an expression or a plain value
* @throws IllegalArgumentException if the object type is not supported
*/
static <T> MathValue<T> auto(Object o) {
if (o instanceof String s) {
return expression(s);
} else if (o instanceof Number n) {
return plain(n.doubleValue());
}
throw new IllegalArgumentException("Unsupported type: " + o.getClass());
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class PlaceholderTextValueImpl<T> implements TextValue<T> {
private final String raw;
public PlaceholderTextValueImpl(String raw) {
this.raw = raw;
}
@Override
public String render(Context<T> context) {
return raw;
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class PlainMathValueImpl<T> implements MathValue<T> {
private final double value;
public PlainMathValueImpl(double value) {
this.value = value;
}
@Override
public double evaluate(Context<T> context) {
return value;
}
}

View File

@@ -0,0 +1,17 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
public class PlainTextValueImpl<T> implements TextValue<T> {
private final String raw;
public PlainTextValueImpl(String raw) {
this.raw = raw;
}
@Override
public String render(Context<T> context) {
return raw;
}
}

View File

@@ -0,0 +1,65 @@
package net.momirealms.customfishing.api.mechanic.misc.value;
import net.momirealms.customfishing.api.mechanic.context.Context;
import java.util.regex.Pattern;
/**
* The TextValue interface represents a text value that can be rendered
* within a specific context. This interface allows for the rendering of
* placeholder-based or plain text values in the context of custom fishing mechanics.
*
* @param <T> the type of the holder object for the context
*/
public interface TextValue<T> {
Pattern pattern = Pattern.compile("\\{[^{}]+}");
/**
* Renders the text value within the given context.
*
* @param context the context in which the text value is rendered
* @return the rendered text as a String
*/
String render(Context<T> context);
/**
* Creates a TextValue based on a placeholder text.
* Placeholders can be dynamically replaced with context-specific values.
*
* @param text the placeholder text to render
* @param <T> the type of the holder object for the context
* @return a TextValue instance representing the given placeholder text
*/
static <T> TextValue<T> placeholder(String text) {
return new PlaceholderTextValueImpl<>(text);
}
/**
* Creates a TextValue based on plain text.
*
* @param text the plain text to render
* @param <T> the type of the holder object for the context
* @return a TextValue instance representing the given plain text
*/
static <T> TextValue<T> plain(String text) {
return new PlainTextValueImpl<>(text);
}
/**
* Automatically creates a TextValue based on the given argument.
* If the argument contains placeholders (detected by a regex pattern),
* a PlaceholderTextValueImpl instance is created. Otherwise, a PlainTextValueImpl
* instance is created.
*
* @param arg the text to evaluate and create a TextValue from
* @param <T> the type of the holder object for the context
* @return a TextValue instance representing the given text, either as a placeholder or plain text
*/
static <T> TextValue<T> auto(String arg) {
if (pattern.matcher(arg).find())
return placeholder(arg);
else
return plain(arg);
}
}

View File

@@ -17,15 +17,21 @@
package net.momirealms.customfishing.api.mechanic.requirement; package net.momirealms.customfishing.api.mechanic.requirement;
import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.context.Context;
public interface Requirement { /**
* Interface representing a requirement that must be met in the custom fishing API.
* This can be used to define conditions that need to be satisfied within a given context.
*
* @param <T> the type parameter for the context
*/
public interface Requirement<T> {
/** /**
* Is condition met the requirement * Evaluates whether the requirement is met within the given context.
* *
* @param condition condition * @param context the context in which the requirement is evaluated
* @return meet or not * @return true if the requirement is met, false otherwise
*/ */
boolean isConditionMet(Condition condition); boolean isSatisfied(Context<T> context);
} }

View File

@@ -21,7 +21,7 @@ package net.momirealms.customfishing.api.mechanic.requirement;
* An abstract class representing a requirement expansion * An abstract class representing a requirement expansion
* Requirement expansions are used to define custom requirements for various functionalities. * Requirement expansions are used to define custom requirements for various functionalities.
*/ */
public abstract class RequirementExpansion { public abstract class RequirementExpansion<T> {
/** /**
* Get the version of this requirement expansion. * Get the version of this requirement expansion.
@@ -49,5 +49,5 @@ public abstract class RequirementExpansion {
* *
* @return The requirement factory. * @return The requirement factory.
*/ */
public abstract RequirementFactory getRequirementFactory(); public abstract RequirementFactory<T> getRequirementFactory();
} }

View File

@@ -22,19 +22,21 @@ import net.momirealms.customfishing.api.mechanic.action.Action;
import java.util.List; import java.util.List;
/** /**
* An interface for a requirement factory that builds requirements. * Interface representing a factory for creating requirements.
*
* @param <T> the type of object that the requirement will operate on
*/ */
public interface RequirementFactory { public interface RequirementFactory<T> {
/** /**
* Build a requirement with the given arguments, not met actions, and check action flag. * Build a requirement with the given arguments, not satisfied actions, and check run actions flag.
* *
* @param args The arguments used to build the requirement. * @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 notSatisfiedActions 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. * @param runActions Flag indicating whether to run the action if the requirement is not met.
* @return The built requirement. * @return The built requirement.
*/ */
Requirement build(Object args, List<Action> notMetActions, boolean advanced); Requirement<T> process(Object args, List<Action<T>> notSatisfiedActions, boolean runActions);
/** /**
* Build a requirement with the given arguments. * Build a requirement with the given arguments.
@@ -42,7 +44,7 @@ public interface RequirementFactory {
* @param args The arguments used to build the requirement. * @param args The arguments used to build the requirement.
* @return The built requirement. * @return The built requirement.
*/ */
default Requirement build(Object args) { default Requirement<T> process(Object args) {
return build(args, null, false); return process(args, List.of(), false);
} }
} }

View File

@@ -15,26 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.requirement;
import net.momirealms.customfishing.api.mechanic.condition.Condition; import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementFactory;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public interface RequirementManager { public interface RequirementManager<T> {
/**
* Legacy format support
* @param key key
* @param requirements requirements
* @param weight weight
* @return success or not
*/
@Deprecated
boolean putLegacyLootToMap(String key, Requirement[] requirements, double weight);
/** /**
* Registers a custom requirement type with its corresponding factory. * Registers a custom requirement type with its corresponding factory.
@@ -43,7 +31,7 @@ public interface RequirementManager {
* @param requirementFactory The factory responsible for creating instances of the requirement. * @param requirementFactory The factory responsible for creating instances of the requirement.
* @return True if registration was successful, false if the type is already registered. * @return True if registration was successful, false if the type is already registered.
*/ */
boolean registerRequirement(String type, RequirementFactory requirementFactory); boolean registerRequirement(@NotNull String type, @NotNull RequirementFactory<T> requirementFactory);
/** /**
* Unregisters a custom requirement type. * Unregisters a custom requirement type.
@@ -51,16 +39,17 @@ public interface RequirementManager {
* @param type The type identifier of the requirement to unregister. * @param type The type identifier of the requirement to unregister.
* @return True if unregistration was successful, false if the type is not registered. * @return True if unregistration was successful, false if the type is not registered.
*/ */
boolean unregisterRequirement(String type); boolean unregisterRequirement(@NotNull String type);
/** /**
* Retrieves an array of requirements based on a configuration section. * Retrieves an array of requirements based on a configuration section.
* *
* @param section The configuration section containing requirement definitions. * @param section The configuration section containing requirement definitions.
* @param advanced A flag indicating whether to use advanced requirements. * @param runActions A flag indicating whether to use advanced requirements.
* @return An array of Requirement objects based on the configuration section * @return An array of Requirement objects based on the configuration section
*/ */
@Nullable Requirement[] getRequirements(ConfigurationSection section, boolean advanced); @Nullable
Requirement<T>[] getRequirements(@NotNull Section section, boolean runActions);
/** /**
* If a requirement type exists * If a requirement type exists
@@ -68,7 +57,7 @@ public interface RequirementManager {
* @param type type * @param type type
* @return exists or not * @return exists or not
*/ */
boolean hasRequirement(String type); boolean hasRequirement(@NotNull String type);
/** /**
* Retrieves a Requirement object based on a configuration section and advanced flag. * Retrieves a Requirement object based on a configuration section and advanced flag.
@@ -78,10 +67,11 @@ public interface RequirementManager {
* value: xxx * value: xxx
* *
* @param section The configuration section containing requirement definitions. * @param section The configuration section containing requirement definitions.
* @param advanced A flag indicating whether to use advanced requirements. * @param runActions A flag indicating whether to use advanced requirements.
* @return A Requirement object based on the configuration section, or an EmptyRequirement if the section is null or invalid. * @return A Requirement object based on the configuration section, or an EmptyRequirement if the section is null or invalid.
*/ */
@NotNull Requirement getRequirement(ConfigurationSection section, boolean advanced); @NotNull
Requirement<T> getRequirement(@NotNull Section section, boolean runActions);
/** /**
* Gets a requirement based on the provided type and value. * Gets a requirement based on the provided type and value.
@@ -95,7 +85,8 @@ public interface RequirementManager {
* @param value The value associated with the requirement. * @param value The value associated with the requirement.
* @return A Requirement instance based on the type and value, or an EmptyRequirement if the type is invalid. * @return A Requirement instance based on the type and value, or an EmptyRequirement if the type is invalid.
*/ */
@NotNull Requirement getRequirement(String type, Object value); @NotNull
Requirement<T> getRequirement(@NotNull String type, @NotNull Object value);
/** /**
* Retrieves a RequirementFactory based on the specified requirement type. * Retrieves a RequirementFactory based on the specified requirement type.
@@ -103,19 +94,13 @@ public interface RequirementManager {
* @param type The requirement type for which to retrieve a factory. * @param type The requirement type for which to retrieve a factory.
* @return A RequirementFactory for the specified type, or null if no factory is found. * @return A RequirementFactory for the specified type, or null if no factory is found.
*/ */
@Nullable RequirementFactory getRequirementFactory(String type); @Nullable
RequirementFactory<T> getRequirementFactory(@NotNull String type);
/** static <T> boolean isSatisfied(Context<T> context, @Nullable Requirement<T>... requirements) {
* Checks if an array of requirements is met for a given condition.
*
* @param condition The Condition object to check against the requirements.
* @param requirements An array of Requirement instances to be evaluated.
* @return True if all requirements are met, false otherwise. Returns true if the requirements array is null.
*/
static boolean isRequirementMet(Condition condition, Requirement... requirements) {
if (requirements == null) return true; if (requirements == null) return true;
for (Requirement requirement : requirements) { for (Requirement<T> requirement : requirements) {
if (!requirement.isConditionMet(condition)) { if (!requirement.isSatisfied(context)) {
return false; return false;
} }
} }

View File

@@ -19,8 +19,9 @@ package net.momirealms.customfishing.api.mechanic.statistic;
import net.momirealms.customfishing.api.data.StatisticData; import net.momirealms.customfishing.api.data.StatisticData;
import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.entity.Player;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -50,23 +51,23 @@ public class Statistics {
* Adds an amount of loot to the statistics. * Adds an amount of loot to the statistics.
* *
* @param loot The loot item. * @param loot The loot item.
* @param condition The condition associated with the loot. * @param playerContext The condition associated with the loot.
* @param amount The amount of loot to add. * @param amount The amount of loot to add.
*/ */
public synchronized void addLootAmount(Loot loot, Condition condition, int amount) { public synchronized void addLootAmount(Loot loot, Context<Player> playerContext, int amount) {
if (amount < 1) { if (amount < 1) {
return; return;
} }
if (amount == 1) { if (amount == 1) {
addSingleLootAmount(loot, condition); addSingleLootAmount(loot, playerContext);
return; return;
} }
Integer previous = statisticMap.get(loot.getStatisticKey().getAmountKey()); Integer previous = statisticMap.get(loot.getStatisticKey().amountKey());
if (previous == null) previous = 0; if (previous == null) previous = 0;
int after = previous + amount; int after = previous + amount;
statisticMap.put(loot.getStatisticKey().getAmountKey(), after); statisticMap.put(loot.getStatisticKey().amountKey(), after);
total += amount; total += amount;
doSuccessTimesAction(previous, after, condition, loot); doSuccessTimesAction(previous, after, playerContext, loot);
} }
/** /**
@@ -74,16 +75,16 @@ public class Statistics {
* *
* @param previous The previous success times. * @param previous The previous success times.
* @param after The updated success times. * @param after The updated success times.
* @param condition The condition associated with the loot. * @param playerContext The condition associated with the loot.
* @param loot The loot item. * @param loot The loot item.
*/ */
private void doSuccessTimesAction(Integer previous, int after, Condition condition, Loot loot) { private void doSuccessTimesAction(Integer previous, int after, Context<Player> playerContext, Loot loot) {
HashMap<Integer, Action[]> actionMap = loot.getSuccessTimesActionMap(); HashMap<Integer, Action<Player>[]> actionMap = loot.getRecordActionMap();
if (actionMap != null) { if (actionMap != null) {
for (Map.Entry<Integer, Action[]> entry : actionMap.entrySet()) { for (Map.Entry<Integer, Action<Player>[]> entry : actionMap.entrySet()) {
if (entry.getKey() > previous && entry.getKey() <= after) { if (entry.getKey() > previous && entry.getKey() <= after) {
for (Action action : entry.getValue()) { for (Action<Player> action : entry.getValue()) {
action.trigger(condition); action.trigger(playerContext);
} }
} }
} }
@@ -101,18 +102,18 @@ public class Statistics {
* Adds a single loot amount to the statistics. * Adds a single loot amount to the statistics.
* *
* @param loot The loot item. * @param loot The loot item.
* @param condition The condition associated with the loot. * @param playerContext The condition associated with the loot.
*/ */
private void addSingleLootAmount(Loot loot, Condition condition) { private void addSingleLootAmount(Loot loot, Context<Player> playerContext) {
Integer previous = statisticMap.get(loot.getID()); Integer previous = statisticMap.get(loot.getID());
if (previous == null) previous = 0; if (previous == null) previous = 0;
int after = previous + 1; int after = previous + 1;
statisticMap.put(loot.getID(), after); statisticMap.put(loot.getID(), after);
total += 1; total += 1;
Action[] actions = loot.getSuccessTimesActionMap().get(after); Action<Player>[] actions = loot.getRecordActionMap().get(after);
if (actions != null) if (actions != null)
for (Action action : actions) { for (Action<Player> action : actions) {
action.trigger(condition); action.trigger(playerContext);
} }
} }

View File

@@ -1,20 +0,0 @@
package net.momirealms.customfishing.api.mechanic.statistic;
public class StatisticsKey {
private final String amountKey;
private final String sizeKey;
public StatisticsKey(String amountKey, String sizeKey) {
this.amountKey = amountKey;
this.sizeKey = sizeKey;
}
public String getAmountKey() {
return amountKey;
}
public String getSizeKey() {
return sizeKey;
}
}

View File

@@ -15,11 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.statistic;
public interface CommandManager { public record StatisticsKeys(String amountKey, String sizeKey) {
void load();
void unload();
} }

View File

@@ -15,9 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.statistic;
import net.momirealms.customfishing.api.mechanic.statistic.Statistics;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
@@ -31,7 +30,8 @@ public interface StatisticsManager {
* @param uuid The UUID of the player for whom statistics are retrieved. * @param uuid The UUID of the player for whom statistics are retrieved.
* @return The player's statistics or null if the player is not found. * @return The player's statistics or null if the player is not found.
*/ */
@Nullable Statistics getStatistics(UUID uuid); @Nullable
Statistics getStatistics(UUID uuid);
/** /**
* Get a list of strings associated with a specific key in a category map. * Get a list of strings associated with a specific key in a category map.
@@ -39,5 +39,6 @@ public interface StatisticsManager {
* @param key The key to look up in the category map. * @param key The key to look up in the category map.
* @return A list of strings associated with the key or null if the key is not found. * @return A list of strings associated with the key or null if the key is not found.
*/ */
@Nullable List<String> getCategory(String key); @Nullable
List<String> getCategory(String key);
} }

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.momirealms.customfishing.api.manager; package net.momirealms.customfishing.api.mechanic.totem;
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier; import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
import org.bukkit.Location; import org.bukkit.Location;

View File

@@ -17,7 +17,7 @@
package net.momirealms.customfishing.api.mechanic.totem.block.type; package net.momirealms.customfishing.api.mechanic.totem.block.type;
import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import java.io.Serializable; import java.io.Serializable;
@@ -41,7 +41,7 @@ public class EqualType implements TypeCondition, Serializable {
*/ */
@Override @Override
public boolean isMet(Block type) { public boolean isMet(Block type) {
return this.type.equals(CustomFishingPlugin.get().getBlockManager().getAnyPluginBlockID(type)); return this.type.equals(BukkitCustomFishingPlugin.get().getBlockManager().getAnyPluginBlockID(type));
} }
/** /**

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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();
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.scheduler;
import org.bukkit.Location;
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);
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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 "<font:" + font + ">" + text + "</font>";
}
}

View File

@@ -1,185 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.util;
import net.kyori.adventure.text.Component;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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();
Method createInvMethod = ReflectionUtils.bukkitClass.getMethod(
"createInventory",
InventoryHolder.class,
int.class,
isSpigot ? String.class : ReflectionUtils.componentClass
);
return (Inventory) createInvMethod.invoke(
null,
inventoryHolder,
size,
isSpigot ? CustomFishingPlugin.get().getAdventure().componentToLegacy(component) : CustomFishingPlugin.get().getAdventure().shadedComponentToOriginalComponent(component)
);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException exception) {
exception.printStackTrace();
return null;
}
}
/**
* 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();
Method createInvMethod = ReflectionUtils.bukkitClass.getMethod(
"createInventory",
InventoryHolder.class,
InventoryType.class,
isSpigot ? String.class : ReflectionUtils.componentClass
);
return (Inventory) createInvMethod.invoke(
null,
inventoryHolder,
type,
isSpigot ? CustomFishingPlugin.get().getAdventure().componentToLegacy(component) : CustomFishingPlugin.get().getAdventure().shadedComponentToOriginalComponent(component)
);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException exception) {
exception.printStackTrace();
return null;
}
}
/**
* 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 "";
}
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
dataOutput.writeInt(contents.length);
for (ItemStack itemStack : contents) {
dataOutput.writeObject(itemStack);
}
dataOutput.close();
byte[] byteArr = outputStream.toByteArray();
outputStream.close();
return Base64Coder.encodeLines(byteArr);
} catch (IOException e) {
LogUtils.warn("Encoding error", e);
}
return "";
}
/**
* 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) {
ItemStack[] itemStacks = null;
try {
itemStacks = stacksFromBase64(base64);
} catch (IllegalArgumentException exception) {
exception.printStackTrace();
}
return itemStacks;
}
private static ItemStack[] stacksFromBase64(String data) {
if (data == null || data.equals("")) return new ItemStack[]{};
ByteArrayInputStream inputStream;
try {
inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
} catch (IllegalArgumentException e) {
return new ItemStack[]{};
}
BukkitObjectInputStream dataInput = null;
ItemStack[] stacks = null;
try {
dataInput = new BukkitObjectInputStream(inputStream);
stacks = new ItemStack[dataInput.readInt()];
} catch (IOException e) {
e.printStackTrace();
}
if (stacks == null) return new ItemStack[]{};
for (int i = 0; i < stacks.length; i++) {
try {
stacks[i] = (ItemStack) dataInput.readObject();
} catch (IOException | ClassNotFoundException | NullPointerException e) {
try {
dataInput.close();
} catch (IOException exception) {
LogUtils.severe("Failed to read fishing bag data");
}
return null;
}
}
try {
dataInput.close();
} catch (IOException ignored) {
}
return stacks;
}
}

Some files were not shown because too many files have changed in this diff Show More