diff --git a/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java b/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java index b8e89547..8adeace1 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java +++ b/api/src/main/java/net/momirealms/customfishing/api/event/FishHookLandEvent.java @@ -33,6 +33,7 @@ public class FishHookLandEvent extends PlayerEvent { private final Target target; private final FishHook fishHook; private final Effect effect; + private boolean isFirst; /** * Constructs a new FishHookLandEvent. @@ -42,11 +43,12 @@ public class FishHookLandEvent extends PlayerEvent { * @param hook The fishing hook entity. * @param initialEffect The initial effect */ - public FishHookLandEvent(@NotNull Player who, Target target, FishHook hook, Effect initialEffect) { + public FishHookLandEvent(@NotNull Player who, Target target, FishHook hook, boolean isFirst, Effect initialEffect) { super(who); this.target = target; this.fishHook = hook; this.effect = initialEffect; + this.isFirst = isFirst; } /** @@ -71,8 +73,18 @@ public class FishHookLandEvent extends PlayerEvent { return handlerList; } + /** + * Is the first try of one fishing catch + * + * @return is first try + */ + public boolean isFirst() { + return isFirst; + } + /** * Get the fishing effect + * It's not advised to modify this value without checking "isFirst()" since this event can be trigger multiple times in one fishing catch * * @return fishing effect */ diff --git a/api/src/main/java/net/momirealms/customfishing/api/manager/EffectManager.java b/api/src/main/java/net/momirealms/customfishing/api/manager/EffectManager.java index 7637040b..caccbfd4 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/manager/EffectManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/manager/EffectManager.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.api.manager; import net.momirealms.customfishing.api.common.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; @@ -97,6 +98,8 @@ public interface EffectManager { */ @NotNull EffectModifier[] getEffectModifiers(ConfigurationSection section); + BaseEffect getBaseEffect(ConfigurationSection section); + /** * Parses a ConfigurationSection to create an EffectModifier based on the specified type and configuration. *

diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java index 12bf065d..2ce5b509 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/condition/FishingPreparation.java @@ -17,114 +17,17 @@ package net.momirealms.customfishing.api.mechanic.condition; -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; -import net.momirealms.customfishing.api.CustomFishingPlugin; -import net.momirealms.customfishing.api.mechanic.GlobalSettings; -import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; -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.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; +public abstract class FishingPreparation extends Condition { -public class FishingPreparation extends Condition { - - private boolean hasBait = false; - private boolean hasHook = false; - private @Nullable ItemStack baitItemStack; - private final @NotNull ItemStack rodItemStack; - private final List effects; - private boolean canFish = true; - - public FishingPreparation(Player player, CustomFishingPlugin plugin) { + public FishingPreparation(Player player) { super(player); - - PlayerInventory playerInventory = player.getInventory(); - ItemStack mainHandItem = playerInventory.getItemInMainHand(); - ItemStack offHandItem = playerInventory.getItemInOffHand(); - - this.effects = new ArrayList<>(); - boolean rodOnMainHand = mainHandItem.getType() == Material.FISHING_ROD; - this.rodItemStack = rodOnMainHand ? mainHandItem : offHandItem; - String rodItemID = plugin.getItemManager().getAnyPluginItemID(this.rodItemStack); - EffectCarrier rodEffect = plugin.getEffectManager().getEffectCarrier("rod", rodItemID); - if (rodEffect != null) effects.add(rodEffect); - super.insertArg("{rod}", rodItemID); - - NBTItem nbtItem = new NBTItem(rodItemStack); - NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); - if (cfCompound != null && cfCompound.hasTag("hook_id")) { - String hookID = cfCompound.getString("hook_id"); - super.insertArg("{hook}", hookID); - this.hasHook = true; - EffectCarrier carrier = plugin.getEffectManager().getEffectCarrier("hook", hookID); - if (carrier != null) { - this.effects.add(carrier); - } - } - - String baitItemID = plugin.getItemManager().getAnyPluginItemID(rodOnMainHand ? offHandItem : mainHandItem); - EffectCarrier baitEffect = plugin.getEffectManager().getEffectCarrier("bait", baitItemID); - - if (baitEffect != null) { - this.baitItemStack = rodOnMainHand ? offHandItem : mainHandItem; - this.effects.add(baitEffect); - this.hasBait = true; - super.insertArg("{bait}", baitItemID); - } - - if (plugin.getBagManager().isEnabled()) { - Inventory fishingBag = plugin.getBagManager().getOnlineBagInventory(player.getUniqueId()); - HashSet uniqueUtils = new HashSet<>(4); - if (fishingBag != null) { - this.insertArg("{in-bag}", "true"); - for (int i = 0; i < fishingBag.getSize(); i++) { - ItemStack itemInBag = fishingBag.getItem(i); - String bagItemID = plugin.getItemManager().getAnyPluginItemID(itemInBag); - if (!hasBait) { - EffectCarrier effect = plugin.getEffectManager().getEffectCarrier("bait", bagItemID); - if (effect != null) { - this.hasBait = true; - this.baitItemStack = itemInBag; - this.effects.add(effect); - super.insertArg("{bait}", bagItemID); - continue; - } - } - EffectCarrier utilEffect = plugin.getEffectManager().getEffectCarrier("util", bagItemID); - if (utilEffect != null && !uniqueUtils.contains(bagItemID)) { - effects.add(utilEffect); - uniqueUtils.add(bagItemID); - } - } - this.delArg("{in-bag}"); - } - } - - for (String enchant : plugin.getIntegrationManager().getEnchantments(rodItemStack)) { - EffectCarrier enchantEffect = plugin.getEffectManager().getEffectCarrier("enchant", enchant); - if (enchantEffect != null) { - this.effects.add(enchantEffect); - } - } - - for (EffectCarrier effectCarrier : effects) { - if (!effectCarrier.isConditionMet(this)) { - this.canFish = false; - return; - } - } } /** @@ -133,9 +36,7 @@ public class FishingPreparation extends Condition { * @return The ItemStack representing the fishing rod. */ @NotNull - public ItemStack getRodItemStack() { - return rodItemStack; - } + public abstract ItemStack getRodItemStack(); /** * Retrieves the ItemStack representing the bait (if available). @@ -143,50 +44,26 @@ public class FishingPreparation extends Condition { * @return The ItemStack representing the bait, or null if no bait is set. */ @Nullable - public ItemStack getBaitItemStack() { - return baitItemStack; - } + public abstract ItemStack getBaitItemStack(); /** * Checks if player meet the requirements for fishing gears * * @return True if can fish, false otherwise. */ - public boolean canFish() { - return this.canFish; - } + public abstract boolean canFish(); /** * Merges a FishingEffect into this fishing rod, applying effect modifiers. * * @param effect The FishingEffect to merge into this rod. */ - public void mergeEffect(FishingEffect effect) { - for (EffectModifier modifier : GlobalSettings.getEffectModifiers()) { - modifier.modify(effect, this); - } - for (EffectCarrier effectCarrier : effects) { - for (EffectModifier modifier : effectCarrier.getEffectModifiers()) { - modifier.modify(effect, this); - } - } - } + public abstract void mergeEffect(FishingEffect effect); /** * Triggers actions associated with a specific action trigger. * * @param actionTrigger The action trigger that initiates the actions. */ - public void triggerActions(ActionTrigger actionTrigger) { - GlobalSettings.triggerRodActions(actionTrigger, this); - if (hasBait) GlobalSettings.triggerBaitActions(actionTrigger, this); - if (hasHook) GlobalSettings.triggerHookActions(actionTrigger, this); - for (EffectCarrier effectCarrier : effects) { - Action[] actions = effectCarrier.getActions(actionTrigger); - if (actions != null) - for (Action action : actions) { - action.trigger(this); - } - } - } + public abstract void triggerActions(ActionTrigger actionTrigger); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/BaseEffect.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/BaseEffect.java new file mode 100644 index 00000000..53c716a8 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/BaseEffect.java @@ -0,0 +1,36 @@ +package net.momirealms.customfishing.api.mechanic.effect; + +import net.momirealms.customfishing.api.mechanic.misc.Value; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class BaseEffect { + + private final Value waitTime; + private final Value waitTimeMultiplier; + private final Value difficulty; + private final Value difficultyMultiplier; + private final Value gameTime; + private final Value gameTimeMultiplier; + + public BaseEffect(Value waitTime, Value waitTimeMultiplier, Value difficulty, Value difficultyMultiplier, Value gameTime, Value gameTimeMultiplier) { + this.waitTime = waitTime; + this.waitTimeMultiplier = waitTimeMultiplier; + this.difficulty = difficulty; + this.difficultyMultiplier = difficultyMultiplier; + this.gameTime = gameTime; + this.gameTimeMultiplier = gameTimeMultiplier; + } + + public Effect build(Player player, Map values) { + return new FishingEffect( + waitTime.get(player, values), + waitTimeMultiplier.get(player, values), + difficulty.get(player, values), + difficultyMultiplier.get(player, values), + gameTime.get(player, values), + gameTimeMultiplier.get(player, values) + ); + } +} diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java index a0d72540..a63f7e90 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/Effect.java @@ -18,7 +18,7 @@ package net.momirealms.customfishing.api.mechanic.effect; import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.mechanic.loot.WeightModifier; +import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import java.util.List; diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java index 26d0dd5d..f8408f48 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/effect/FishingEffect.java @@ -18,7 +18,7 @@ package net.momirealms.customfishing.api.mechanic.effect; import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.mechanic.loot.WeightModifier; +import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import java.util.ArrayList; import java.util.List; @@ -41,6 +41,18 @@ public class FishingEffect implements Effect { private final List> weightModifier = new ArrayList<>(); private final List> weightModifierIgnored = new ArrayList<>(); + public FishingEffect(double waitTime, double waitTimeMultiplier, double difficulty, double difficultyMultiplier, double gameTime, double gameTimeMultiplier) { + this.waitTime = waitTime; + this.waitTimeMultiplier = waitTimeMultiplier; + this.difficulty = difficulty; + this.difficultyMultiplier = difficultyMultiplier; + this.gameTime = gameTime; + this.gameTimeMultiplier = gameTimeMultiplier; + } + + public FishingEffect() { + } + /** * Sets whether lava fishing is enabled. * diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java index 1e2288dd..0b7419a3 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/CFLoot.java @@ -20,6 +20,7 @@ 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; @@ -39,8 +40,8 @@ public class CFLoot implements Loot { private boolean instanceGame; private double score; private String[] lootGroup; - private String filePath; private StatisticsKey statisticsKey; + private BaseEffect effect; public CFLoot(String id, LootType type) { this.id = id; @@ -71,7 +72,6 @@ public class CFLoot implements Loot { * @return The builder. */ public Builder filePath(String path) { - this.loot.filePath = path; return this; } @@ -174,6 +174,17 @@ public class CFLoot implements Loot { 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. * @@ -230,41 +241,21 @@ public class CFLoot implements Loot { } } - /** - * Check if this loot has an instance game. - * - * @return True if it's an instance game, false otherwise. - */ @Override public boolean instanceGame() { return this.instanceGame; } - /** - * Get the unique ID of this loot. - * - * @return The unique ID. - */ @Override public String getID() { return this.id; } - /** - * Get the type of this loot. - * - * @return The loot type. - */ @Override public LootType getType() { return this.type; } - /** - * Get the nickname of this loot. - * - * @return The nickname. - */ @Override public @NotNull String getNick() { return this.nick; @@ -275,81 +266,41 @@ public class CFLoot implements Loot { return this.statisticsKey; } - /** - * Check if this loot should be shown in the finder. - * - * @return True if it should be shown, false otherwise. - */ @Override public boolean showInFinder() { return this.showInFinder; } - /** - * Get the score of this loot. - * - * @return The score. - */ @Override public double getScore() { return this.score; } - /** - * Check if games are disabled for this loot. - * - * @return True if games are disabled, false otherwise. - */ @Override public boolean disableGame() { return this.disableGame; } - /** - * Check if statistics are disabled for this loot. - * - * @return True if statistics are disabled, false otherwise. - */ @Override public boolean disableStats() { return this.disableStats; } - /** - * Check if the loot disables global actions - */ @Override public boolean disableGlobalAction() { return this.disableGlobalAction; } - /** - * Get the loot group of this loot. - * - * @return The loot group. - */ @Override public String[] getLootGroup() { return lootGroup; } - /** - * Get the actions triggered by a specific action trigger. - * - * @param actionTrigger The action trigger. - * @return The actions triggered by the given trigger. - */ @Override public Action[] getActions(ActionTrigger actionTrigger) { return actionMap.get(actionTrigger); } - /** - * Trigger actions associated with a specific action trigger. - * - * @param actionTrigger The action trigger. - * @param condition The condition under which the actions are triggered. - */ @Override public void triggerActions(ActionTrigger actionTrigger, Condition condition) { Action[] actions = getActions(actionTrigger); @@ -360,30 +311,16 @@ public class CFLoot implements Loot { } } - /** - * Get the file path of the loot registered by CustomFishing - * @return file path - */ - public String getFilePath() { - return filePath; + @Override + public BaseEffect getBaseEffect() { + return effect; } - /** - * Get the actions triggered by a specific number of successes. - * - * @param times The number of successes. - * @return The actions triggered by the specified number of successes. - */ @Override public Action[] getSuccessTimesActions(int times) { return successTimesActionMap.get(times); } - /** - * Get a map of actions triggered by different numbers of successes. - * - * @return A map of actions triggered by success times. - */ @Override public HashMap getSuccessTimesActionMap() { return successTimesActionMap; diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java index 9d9ba243..020c4991 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/Loot.java @@ -20,8 +20,10 @@ 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 org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -104,6 +106,7 @@ public interface Loot { * @param actionTrigger The action trigger. * @return The actions triggered by the given trigger. */ + @Nullable Action[] getActions(ActionTrigger actionTrigger); /** @@ -114,6 +117,13 @@ public interface Loot { */ void triggerActions(ActionTrigger actionTrigger, Condition condition); + /** + * Get effects that bond to this loot + * + * @return effects + */ + BaseEffect getBaseEffect(); + /** * Get the actions triggered by a specific number of successes. * diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/Value.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/Value.java index a15a3fc4..1dbea0c4 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/Value.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/Value.java @@ -19,7 +19,9 @@ package net.momirealms.customfishing.api.mechanic.misc; import org.bukkit.entity.Player; +import java.util.Map; + public interface Value { - double get(Player player); + double get(Player player, Map values); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/WeightModifier.java similarity index 93% rename from api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java rename to api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/WeightModifier.java index 7ce3a71c..d481639a 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/loot/WeightModifier.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/WeightModifier.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package net.momirealms.customfishing.api.mechanic.loot; +package net.momirealms.customfishing.api.mechanic.misc; import org.bukkit.entity.Player; diff --git a/build.gradle.kts b/build.gradle.kts index 7a7623ca..24a7de54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { allprojects { - version = "2.1.1" + version = "2.1.2" apply() apply(plugin = "java") diff --git a/plugin/src/main/java/net/momirealms/customfishing/command/sub/DebugCommand.java b/plugin/src/main/java/net/momirealms/customfishing/command/sub/DebugCommand.java index d151b122..e5890557 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/command/sub/DebugCommand.java +++ b/plugin/src/main/java/net/momirealms/customfishing/command/sub/DebugCommand.java @@ -33,6 +33,7 @@ import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation; 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 net.momirealms.customfishing.mechanic.fishing.FishingPreparationImpl; import net.momirealms.customfishing.util.ConfigUtils; import net.momirealms.customfishing.util.NBTUtils; import org.bukkit.Material; @@ -143,7 +144,7 @@ public class DebugCommand { return; } FishingEffect initialEffect = CustomFishingPlugin.get().getEffectManager().getInitialEffect(); - FishingPreparation fishingPreparation = new FishingPreparation(player, CustomFishingPlugin.get()); + FishingPreparation fishingPreparation = new FishingPreparationImpl(player, CustomFishingPlugin.get()); boolean inLava = (boolean) arg.getOrDefault("lava fishing", false); fishingPreparation.insertArg("{lava}", String.valueOf(inLava)); fishingPreparation.mergeEffect(initialEffect); diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java index a84d0b24..edb23fde 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java @@ -490,9 +490,9 @@ public class ActionManagerImpl implements ActionManager { return condition -> { if (Math.random() > chance) return; if (CustomFishingPlugin.get().getVersionManager().isSpigot()) { - condition.getPlayer().getLocation().getWorld().spawn(condition.getPlayer().getLocation(), ExperienceOrb.class, e -> e.setExperience((int) value.get(condition.getPlayer()))); + condition.getPlayer().getLocation().getWorld().spawn(condition.getPlayer().getLocation(), ExperienceOrb.class, e -> e.setExperience((int) value.get(condition.getPlayer(), condition.getArgs()))); } else { - condition.getPlayer().giveExp((int) value.get(condition.getPlayer()), true); + condition.getPlayer().giveExp((int) value.get(condition.getPlayer(), condition.getArgs()), true); AdventureManagerImpl.getInstance().sendSound(condition.getPlayer(), Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1); } }; @@ -505,7 +505,7 @@ public class ActionManagerImpl implements ActionManager { return condition -> { if (Math.random() > chance) return; Player player = condition.getPlayer(); - player.setFoodLevel((int) (player.getFoodLevel() + value.get(player))); + player.setFoodLevel((int) (player.getFoodLevel() + value.get(player, condition.getArgs()))); }; }); registerAction("saturation", (args, chance) -> { @@ -513,7 +513,7 @@ public class ActionManagerImpl implements ActionManager { return condition -> { if (Math.random() > chance) return; Player player = condition.getPlayer(); - player.setSaturation((float) (player.getSaturation() + value.get(player))); + player.setSaturation((float) (player.getSaturation() + value.get(player, condition.getArgs()))); }; }); } @@ -523,7 +523,7 @@ public class ActionManagerImpl implements ActionManager { var value = ConfigUtils.getValue(args); return condition -> { if (Math.random() > chance) return; - condition.getPlayer().giveExp((int) value.get(condition.getPlayer())); + condition.getPlayer().giveExp((int) value.get(condition.getPlayer(), condition.getArgs())); AdventureManagerImpl.getInstance().sendSound(condition.getPlayer(), Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1); }; }); @@ -722,14 +722,14 @@ public class ActionManagerImpl implements ActionManager { var value = ConfigUtils.getValue(args); return condition -> { if (Math.random() > chance) return; - VaultHook.getEconomy().depositPlayer(condition.getPlayer(), value.get(condition.getPlayer())); + VaultHook.getEconomy().depositPlayer(condition.getPlayer(), value.get(condition.getPlayer(), condition.getArgs())); }; }); registerAction("take-money", (args, chance) -> { var value = ConfigUtils.getValue(args); return condition -> { if (Math.random() > chance) return; - VaultHook.getEconomy().withdrawPlayer(condition.getPlayer(), value.get(condition.getPlayer())); + VaultHook.getEconomy().withdrawPlayer(condition.getPlayer(), value.get(condition.getPlayer(), condition.getArgs())); }; }); } @@ -930,7 +930,7 @@ public class ActionManagerImpl implements ActionManager { return condition -> { if (Math.random() > chance) return; Player player = condition.getPlayer(); - player.setLevel((int) Math.max(0, player.getLevel() + value.get(condition.getPlayer()))); + player.setLevel((int) Math.max(0, player.getLevel() + value.get(condition.getPlayer(), condition.getArgs()))); }; }); } @@ -1024,7 +1024,7 @@ public class ActionManagerImpl implements ActionManager { return condition -> { if (Math.random() > chance) return; Optional.ofNullable(plugin.getIntegrationManager().getLevelPlugin(pluginName)).ifPresentOrElse(it -> { - it.addXp(condition.getPlayer(), target, value.get(condition.getPlayer())); + it.addXp(condition.getPlayer(), target, value.get(condition.getPlayer(), condition.getArgs())); }, () -> LogUtils.warn("Plugin (" + pluginName + "'s) level is not compatible. Please double check if it's a problem caused by pronunciation.")); }; } else { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/effect/EffectManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/effect/EffectManagerImpl.java index a724d6b0..fc0f978b 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/effect/EffectManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/effect/EffectManagerImpl.java @@ -22,12 +22,15 @@ import net.momirealms.customfishing.api.common.Key; import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.manager.EffectManager; import net.momirealms.customfishing.api.mechanic.GlobalSettings; +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 net.momirealms.customfishing.api.mechanic.loot.WeightModifier; +import net.momirealms.customfishing.api.mechanic.misc.Value; +import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.api.util.LogUtils; +import net.momirealms.customfishing.mechanic.misc.value.PlainValue; import net.momirealms.customfishing.util.ConfigUtils; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; @@ -240,6 +243,26 @@ public class EffectManagerImpl implements EffectManager { return modifiers.toArray(new EffectModifier[0]); } + @Override + public BaseEffect getBaseEffect(ConfigurationSection section) { + if (section == null) return new BaseEffect( + new PlainValue(0), new PlainValue(1d), + new PlainValue(0), new PlainValue(1d), + new PlainValue(0), new PlainValue(1d) + ); + Value waitTime = section.contains("wait-time") ? ConfigUtils.getValue(section.get("wait-time")) : new PlainValue(0); + Value difficulty = section.contains("difficulty") ? ConfigUtils.getValue(section.get("difficulty")) : new PlainValue(0); + Value gameTime = section.contains("game-time") ? ConfigUtils.getValue(section.get("game-time")) : new PlainValue(0); + Value waitTimeMultiplier = section.contains("wait-time-multiplier") ? ConfigUtils.getValue(section.get("wait-time-multiplier")) : new PlainValue(1); + Value difficultyMultiplier = section.contains("difficulty-multiplier") ? ConfigUtils.getValue(section.get("difficulty-multiplier")) : new PlainValue(1); + Value gameTimeMultiplier = section.contains("game-time-multiplier") ? ConfigUtils.getValue(section.get("game-time-multiplier")) : new PlainValue(1); + return new BaseEffect( + waitTime, waitTimeMultiplier, + difficulty, difficultyMultiplier, + gameTime, gameTimeMultiplier + ); + } + private void loadGlobalEffects() { YamlConfiguration config = plugin.getConfig("config.yml"); ConfigurationSection section = config.getConfigurationSection("mechanics.global-effects"); @@ -285,67 +308,67 @@ public class EffectManagerImpl implements EffectManager { case "wait-time" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setWaitTime(effect.getWaitTime() + value.get(condition.getPlayer())); + effect.setWaitTime(effect.getWaitTime() + value.get(condition.getPlayer(), condition.getArgs())); }); } case "hook-time", "wait-time-multiplier" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setWaitTimeMultiplier(effect.getWaitTimeMultiplier() + value.get(condition.getPlayer()) - 1); + effect.setWaitTimeMultiplier(effect.getWaitTimeMultiplier() + value.get(condition.getPlayer(), condition.getArgs()) - 1); }); } case "difficulty" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setDifficulty(effect.getDifficulty() + value.get(condition.getPlayer())); + effect.setDifficulty(effect.getDifficulty() + value.get(condition.getPlayer(), condition.getArgs())); }); } case "difficulty-multiplier", "difficulty-bonus" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setDifficultyMultiplier(effect.getDifficultyMultiplier() + value.get(condition.getPlayer()) - 1); + effect.setDifficultyMultiplier(effect.getDifficultyMultiplier() + value.get(condition.getPlayer(), condition.getArgs()) - 1); }); } case "multiple-loot" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setMultipleLootChance(effect.getMultipleLootChance() + value.get(condition.getPlayer())); + effect.setMultipleLootChance(effect.getMultipleLootChance() + value.get(condition.getPlayer(), condition.getArgs())); }); } case "score" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setScore(effect.getScore() + value.get(condition.getPlayer())); + effect.setScore(effect.getScore() + value.get(condition.getPlayer(), condition.getArgs())); }); } case "score-bonus", "score-multiplier" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setScoreMultiplier(effect.getScoreMultiplier() + value.get(condition.getPlayer()) - 1); + effect.setScoreMultiplier(effect.getScoreMultiplier() + value.get(condition.getPlayer(), condition.getArgs()) - 1); }); } case "size" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setSize(effect.getSize() + value.get(condition.getPlayer())); + effect.setSize(effect.getSize() + value.get(condition.getPlayer(), condition.getArgs())); }); } case "size-bonus", "size-multiplier" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setSizeMultiplier(effect.getSizeMultiplier() + value.get(condition.getPlayer()) - 1); + effect.setSizeMultiplier(effect.getSizeMultiplier() + value.get(condition.getPlayer(), condition.getArgs()) - 1); }); } case "game-time" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setGameTime(effect.getGameTime() + value.get(condition.getPlayer())); + effect.setGameTime(effect.getGameTime() + value.get(condition.getPlayer(), condition.getArgs())); }); } case "game-time-bonus", "game-time-multiplier" -> { var value = ConfigUtils.getValue(section.get("value")); return ((effect, condition) -> { - effect.setGameTimeMultiplier(effect.getGameTimeMultiplier() + value.get(condition.getPlayer()) - 1); + effect.setGameTimeMultiplier(effect.getGameTimeMultiplier() + value.get(condition.getPlayer(), condition.getArgs()) - 1); }); } case "lava-fishing" -> { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java index 1b3f2c9a..f1c0e497 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java @@ -59,7 +59,6 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.*; -import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; @@ -309,7 +308,7 @@ public class FishingManagerImpl implements Listener, FishingManager { */ public void onCastRod(PlayerFishEvent event) { var player = event.getPlayer(); - var fishingPreparation = new FishingPreparation(player, plugin); + var fishingPreparation = new FishingPreparationImpl(player, plugin); if (!fishingPreparation.canFish()) { event.setCancelled(true); return; @@ -446,7 +445,7 @@ public class FishingManagerImpl implements Listener, FishingManager { } } else { // remove temp state if fishing game not exists - removeTempFishingState(player); + this.removeTempFishingState(player); var hook = event.getHook(); // If the game is disabled, then do success actions success(temp, hook); @@ -791,7 +790,6 @@ public class FishingManagerImpl implements Listener, FishingManager { @Override public boolean startFishingGame(Player player, Condition condition, Effect effect) { Map gameWithWeight = plugin.getGameManager().getGameWithWeight(condition); - plugin.debug(gameWithWeight.toString()); String random = WeightUtils.getRandom(gameWithWeight); Pair gamePair = plugin.getGameManager().getGameInstance(random); if (random == null) { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingPreparationImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingPreparationImpl.java new file mode 100644 index 00000000..76a54c58 --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingPreparationImpl.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.mechanic.fishing; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import net.momirealms.customfishing.api.CustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.GlobalSettings; +import net.momirealms.customfishing.api.mechanic.action.Action; +import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; +import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation; +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.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +public class FishingPreparationImpl extends FishingPreparation { + + private boolean hasBait = false; + private boolean hasHook = false; + private @Nullable ItemStack baitItemStack; + private final @NotNull ItemStack rodItemStack; + private final List effects; + private boolean canFish = true; + + public FishingPreparationImpl(Player player, CustomFishingPlugin plugin) { + super(player); + + PlayerInventory playerInventory = player.getInventory(); + ItemStack mainHandItem = playerInventory.getItemInMainHand(); + ItemStack offHandItem = playerInventory.getItemInOffHand(); + + this.effects = new ArrayList<>(); + boolean rodOnMainHand = mainHandItem.getType() == Material.FISHING_ROD; + this.rodItemStack = rodOnMainHand ? mainHandItem : offHandItem; + String rodItemID = plugin.getItemManager().getAnyPluginItemID(this.rodItemStack); + EffectCarrier rodEffect = plugin.getEffectManager().getEffectCarrier("rod", rodItemID); + if (rodEffect != null) effects.add(rodEffect); + super.insertArg("{rod}", rodItemID); + + NBTItem nbtItem = new NBTItem(rodItemStack); + NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); + if (cfCompound != null && cfCompound.hasTag("hook_id")) { + String hookID = cfCompound.getString("hook_id"); + super.insertArg("{hook}", hookID); + this.hasHook = true; + EffectCarrier carrier = plugin.getEffectManager().getEffectCarrier("hook", hookID); + if (carrier != null) { + this.effects.add(carrier); + } + } + + String baitItemID = plugin.getItemManager().getAnyPluginItemID(rodOnMainHand ? offHandItem : mainHandItem); + EffectCarrier baitEffect = plugin.getEffectManager().getEffectCarrier("bait", baitItemID); + + if (baitEffect != null) { + this.baitItemStack = rodOnMainHand ? offHandItem : mainHandItem; + this.effects.add(baitEffect); + this.hasBait = true; + super.insertArg("{bait}", baitItemID); + } + + if (plugin.getBagManager().isEnabled()) { + Inventory fishingBag = plugin.getBagManager().getOnlineBagInventory(player.getUniqueId()); + HashSet uniqueUtils = new HashSet<>(4); + if (fishingBag != null) { + this.insertArg("{in-bag}", "true"); + for (int i = 0; i < fishingBag.getSize(); i++) { + ItemStack itemInBag = fishingBag.getItem(i); + String bagItemID = plugin.getItemManager().getAnyPluginItemID(itemInBag); + if (!hasBait) { + EffectCarrier effect = plugin.getEffectManager().getEffectCarrier("bait", bagItemID); + if (effect != null) { + this.hasBait = true; + this.baitItemStack = itemInBag; + this.effects.add(effect); + super.insertArg("{bait}", bagItemID); + continue; + } + } + EffectCarrier utilEffect = plugin.getEffectManager().getEffectCarrier("util", bagItemID); + if (utilEffect != null && !uniqueUtils.contains(bagItemID)) { + effects.add(utilEffect); + uniqueUtils.add(bagItemID); + } + } + this.delArg("{in-bag}"); + } + } + + for (String enchant : plugin.getIntegrationManager().getEnchantments(rodItemStack)) { + EffectCarrier enchantEffect = plugin.getEffectManager().getEffectCarrier("enchant", enchant); + if (enchantEffect != null) { + this.effects.add(enchantEffect); + } + } + + for (EffectCarrier effectCarrier : effects) { + if (!effectCarrier.isConditionMet(this)) { + this.canFish = false; + return; + } + } + } + + /** + * Retrieves the ItemStack representing the fishing rod. + * + * @return The ItemStack representing the fishing rod. + */ + @NotNull + public ItemStack getRodItemStack() { + return rodItemStack; + } + + /** + * Retrieves the ItemStack representing the bait (if available). + * + * @return The ItemStack representing the bait, or null if no bait is set. + */ + @Nullable + public ItemStack getBaitItemStack() { + return baitItemStack; + } + + /** + * Checks if player meet the requirements for fishing gears + * + * @return True if can fish, false otherwise. + */ + public boolean canFish() { + return this.canFish; + } + + /** + * Merges a FishingEffect into this fishing rod, applying effect modifiers. + * + * @param effect The FishingEffect to merge into this rod. + */ + public void mergeEffect(FishingEffect effect) { + for (EffectModifier modifier : GlobalSettings.getEffectModifiers()) { + modifier.modify(effect, this); + } + for (EffectCarrier effectCarrier : effects) { + for (EffectModifier modifier : effectCarrier.getEffectModifiers()) { + modifier.modify(effect, this); + } + } + } + + /** + * Triggers actions associated with a specific action trigger. + * + * @param actionTrigger The action trigger that initiates the actions. + */ + public void triggerActions(ActionTrigger actionTrigger) { + GlobalSettings.triggerRodActions(actionTrigger, this); + if (hasBait) GlobalSettings.triggerBaitActions(actionTrigger, this); + if (hasHook) GlobalSettings.triggerHookActions(actionTrigger, this); + for (EffectCarrier effectCarrier : effects) { + Action[] actions = effectCarrier.getActions(actionTrigger); + if (actions != null) + for (Action action : actions) { + action.trigger(this); + } + } + } +} diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java index c25e7c3f..718b2436 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/HookCheckTimerTask.java @@ -19,7 +19,6 @@ package net.momirealms.customfishing.mechanic.fishing; import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; -import net.momirealms.customcrops.api.CustomCropsPlugin; import net.momirealms.customfishing.adventure.AdventureManagerImpl; import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.event.FishHookLandEvent; @@ -27,10 +26,10 @@ import net.momirealms.customfishing.api.event.LavaFishingEvent; import net.momirealms.customfishing.api.mechanic.TempFishingState; import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation; +import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.FishingEffect; import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.scheduler.CancellableTask; -import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.setting.CFConfig; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -39,7 +38,6 @@ import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.FishHook; import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.Vector; @@ -59,6 +57,7 @@ public class HookCheckTimerTask implements Runnable { private final FishHook fishHook; private final FishingPreparation fishingPreparation; private final FishingEffect initialEffect; + private Effect tempEffect; private final int lureLevel; private boolean firstTime; private boolean fishHooked; @@ -90,76 +89,117 @@ public class HookCheckTimerTask implements Runnable { this.hookMovementTask = CustomFishingPlugin.get().getScheduler().runTaskSyncTimer(this, fishHook.getLocation(), 1, 1); this.lureLevel = fishingPreparation.getRodItemStack().getEnchantmentLevel(Enchantment.LURE); this.firstTime = true; + this.tempEffect = new FishingEffect(); } + @Override public void run() { if ( - !fishHook.isValid() + !this.fishHook.isValid() //|| (fishHook.getHookedEntity() != null && fishHook.getHookedEntity().getType() != EntityType.ARMOR_STAND) ) { // This task would be cancelled when hook is removed this.destroy(); return; } - if (fishHook.isOnGround()) { - inWater = false; + if (this.fishHook.isOnGround()) { + this.inWater = false; return; } - if (fishHook.getLocation().getBlock().getType() == Material.LAVA) { - inWater = false; + if (this.fishHook.getLocation().getBlock().getType() == Material.LAVA) { + this.inWater = false; // if player can fish in lava if (firstTime) { - this.fishingPreparation.setLocation(fishHook.getLocation()); - this.fishingPreparation.mergeEffect(initialEffect); + this.firstTime = false; + + this.fishingPreparation.setLocation(this.fishHook.getLocation()); + this.fishingPreparation.mergeEffect(this.initialEffect); if (!initialEffect.canLavaFishing()) { this.destroy(); return; } + + FishHookLandEvent event = new FishHookLandEvent(this.fishingPreparation.getPlayer(), FishHookLandEvent.Target.LAVA, this.fishHook, true, this.initialEffect); + Bukkit.getPluginManager().callEvent(event); + this.fishingPreparation.insertArg("{lava}", "true"); this.fishingPreparation.triggerActions(ActionTrigger.LAND); - FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.LAVA, fishHook, initialEffect); - Bukkit.getPluginManager().callEvent(event); - this.firstTime = false; - this.setTempState(); } + // simulate fishing mechanic - if (fishHooked) { - jumpTimer++; - if (jumpTimer < 4) + if (this.fishHooked) { + this.jumpTimer++; + if (this.jumpTimer < 4) return; - jumpTimer = 0; - fishHook.setVelocity(new Vector(0,0.24,0)); + this.jumpTimer = 0; + this.fishHook.setVelocity(new Vector(0,0.24,0)); return; } - if (!reserve) { - if (jumpTimer < 5) { - jumpTimer++; - fishHook.setVelocity(new Vector(0,0.2 - jumpTimer * 0.02,0)); + + if (!this.reserve) { + // jump + if (this.jumpTimer < 5) { + this.jumpTimer++; + this.fishHook.setVelocity(new Vector(0,0.2 - this.jumpTimer * 0.02,0)); return; } - reserve = true; - if (this.loot != null) + + this.reserve = true; + + this.setNextLoot(); + if (this.loot != null) { + this.tempEffect = this.loot.getBaseEffect().build(fishingPreparation.getPlayer(), fishingPreparation.getArgs()); + this.tempEffect.merge(this.initialEffect); + this.setTempState(); this.startLavaFishingMechanic(); - this.makeHookStatic(fishHook.getLocation()); + } else { + this.tempEffect = new FishingEffect(); + this.tempEffect.merge(this.initialEffect); + this.manager.removeTempFishingState(fishingPreparation.getPlayer()); + CustomFishingPlugin.get().debug("No loot available for " + fishingPreparation.getPlayer().getName() + " at " + fishingPreparation.getLocation()); + } + + this.makeHookStatic(this.fishHook.getLocation()); } return; } - if (!inWater && fishHook.isInWater()) { - inWater = true; - this.fishingPreparation.setLocation(fishHook.getLocation()); - this.fishingPreparation.mergeEffect(initialEffect); + if (!this.inWater && this.fishHook.isInWater()) { + this.inWater = true; + + this.fishingPreparation.setLocation(this.fishHook.getLocation()); this.fishingPreparation.insertArg("{lava}", "false"); - this.fishingPreparation.insertArg("{open-water}", String.valueOf(fishHook.isInOpenWater())); - this.fishingPreparation.triggerActions(ActionTrigger.LAND); - FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.WATER, fishHook, initialEffect); - Bukkit.getPluginManager().callEvent(event); - this.setTempState(); - if (this.loot == null) { - fishHook.setWaitTime(Integer.MAX_VALUE); + this.fishingPreparation.insertArg("{open-water}", String.valueOf(this.fishHook.isInOpenWater())); + + if (this.firstTime) { + this.firstTime = false; + this.fishingPreparation.mergeEffect(this.initialEffect); + + FishHookLandEvent event = new FishHookLandEvent(this.fishingPreparation.getPlayer(), FishHookLandEvent.Target.WATER, this.fishHook, false, this.initialEffect); + Bukkit.getPluginManager().callEvent(event); + + this.fishingPreparation.triggerActions(ActionTrigger.LAND); + } else { - this.setWaitTime(); + FishHookLandEvent event = new FishHookLandEvent(this.fishingPreparation.getPlayer(), FishHookLandEvent.Target.WATER, this.fishHook, true, this.initialEffect); + Bukkit.getPluginManager().callEvent(event); } + + this.setNextLoot(); + if (this.loot == null) { + // prevent players from getting vanilla loots + this.fishHook.setWaitTime(Integer.MAX_VALUE); + this.tempEffect = new FishingEffect(); + this.tempEffect.merge(this.initialEffect); + this.manager.removeTempFishingState(fishingPreparation.getPlayer()); + CustomFishingPlugin.get().debug("No loot available for " + fishingPreparation.getPlayer().getName() + " at " + fishingPreparation.getLocation()); + } else { + this.tempEffect = this.loot.getBaseEffect().build(fishingPreparation.getPlayer(), fishingPreparation.getArgs()); + this.tempEffect.merge(this.initialEffect); + this.setWaitTime(); + this.setTempState(); + } + return; } } @@ -184,11 +224,8 @@ public class HookCheckTimerTask implements Runnable { } } - /** - * Sets temporary state and prepares for the next loot. - */ - private void setTempState() { - Loot nextLoot = CustomFishingPlugin.get().getLootManager().getNextLoot(initialEffect, fishingPreparation); + private void setNextLoot() { + Loot nextLoot = CustomFishingPlugin.get().getLootManager().getNextLoot(tempEffect, fishingPreparation); if (nextLoot == null) { this.loot = null; CustomFishingPlugin.get().debug("No loot available at " + fishingPreparation.getLocation()); @@ -196,16 +233,22 @@ public class HookCheckTimerTask implements Runnable { } this.loot = nextLoot; - fishingPreparation.insertArg("{nick}", nextLoot.getNick()); - fishingPreparation.insertArg("{loot}", nextLoot.getID()); - if (!nextLoot.disableStats()) { - fishingPreparation.insertArg("{statistics_size}", nextLoot.getStatisticKey().getSizeKey()); - fishingPreparation.insertArg("{statistics_amount}", nextLoot.getStatisticKey().getAmountKey()); + } + + /** + * Sets temporary state and prepares for the next loot. + */ + private void setTempState() { + fishingPreparation.insertArg("{nick}", loot.getNick()); + fishingPreparation.insertArg("{loot}", loot.getID()); + if (!loot.disableStats()) { + fishingPreparation.insertArg("{statistics_size}", loot.getStatisticKey().getSizeKey()); + fishingPreparation.insertArg("{statistics_amount}", loot.getStatisticKey().getAmountKey()); } manager.setTempFishingState(fishingPreparation.getPlayer(), new TempFishingState( - initialEffect, + tempEffect, fishingPreparation, - nextLoot + loot )); } @@ -225,15 +268,15 @@ public class HookCheckTimerTask implements Runnable { int random; if (CFConfig.overrideVanilla) { random = ThreadLocalRandom.current().nextInt(CFConfig.lavaMinTime, CFConfig.lavaMaxTime); - random *= initialEffect.getWaitTimeMultiplier(); - random += initialEffect.getWaitTime(); + random *= tempEffect.getWaitTimeMultiplier(); + random += tempEffect.getWaitTime(); random = Math.max(1, random); } else { random = ThreadLocalRandom.current().nextInt(CFConfig.lavaMinTime, CFConfig.lavaMaxTime); random -= lureLevel * 100; random = Math.max(CFConfig.lavaMinTime, random); - random *= initialEffect.getWaitTimeMultiplier(); - random += initialEffect.getWaitTime(); + random *= tempEffect.getWaitTimeMultiplier(); + random += tempEffect.getWaitTime(); random = Math.max(1, random); } @@ -309,10 +352,10 @@ public class HookCheckTimerTask implements Runnable { private void setWaitTime() { if (CFConfig.overrideVanilla) { double initialTime = ThreadLocalRandom.current().nextInt(CFConfig.waterMaxTime - CFConfig.waterMinTime + 1) + CFConfig.waterMinTime; - fishHook.setWaitTime(Math.max(1, (int) (initialTime * initialEffect.getWaitTimeMultiplier() + initialEffect.getWaitTime()))); + fishHook.setWaitTime(Math.max(1, (int) (initialTime * tempEffect.getWaitTimeMultiplier() + tempEffect.getWaitTime()))); } else { - fishHook.setMinWaitTime(Math.max(1, (int) (fishHook.getMinWaitTime() * initialEffect.getWaitTimeMultiplier() + initialEffect.getWaitTime()))); - fishHook.setMaxWaitTime(Math.max(2, (int) (fishHook.getMaxWaitTime() * initialEffect.getWaitTimeMultiplier() + initialEffect.getWaitTime()))); + fishHook.setMinWaitTime(Math.max(1, (int) (fishHook.getMinWaitTime() * tempEffect.getWaitTimeMultiplier() + tempEffect.getWaitTime()))); + fishHook.setMaxWaitTime(Math.max(2, (int) (fishHook.getMaxWaitTime() * tempEffect.getWaitTimeMultiplier() + tempEffect.getWaitTime()))); } } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java index 3f06a6e0..3101eb67 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java @@ -690,8 +690,9 @@ public class ItemManagerImpl implements ItemManager, Listener { if (enchantments.size() == 0 || amountPairs.size() == 0) return this; editors.put("enchantment-pool", (player, nbtItem, placeholders) -> { List> parsedAmountPair = new ArrayList<>(amountPairs.size()); + Map map = new HashMap<>(); for (Pair rawValue : amountPairs) { - parsedAmountPair.add(Pair.of(rawValue.left(), rawValue.right().get(player))); + parsedAmountPair.add(Pair.of(rawValue.left(), rawValue.right().get(player, map))); } int amount = WeightUtils.getRandom(parsedAmountPair); @@ -702,7 +703,7 @@ public class ItemManagerImpl implements ItemManager, Listener { List, Double>> cloned = new ArrayList<>(enchantments.size()); for (Pair, Value> rawValue : enchantments) { - cloned.add(Pair.of(rawValue.left(), rawValue.right().get(player))); + cloned.add(Pair.of(rawValue.left(), rawValue.right().get(player, map))); } int i = 0; diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java index 4d8a201c..c7cc88cc 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/loot/LootManagerImpl.java @@ -25,7 +25,7 @@ import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.loot.CFLoot; import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.LootType; -import net.momirealms.customfishing.api.mechanic.loot.WeightModifier; +import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey; import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.api.util.WeightUtils; @@ -270,6 +270,7 @@ public class LootManagerImpl implements LootManager { .showInFinder(section.getBoolean("show-in-fishfinder", CFConfig.globalShowInFinder)) .disableGlobalActions(section.getBoolean("disable-global-event", false)) .score(section.getDouble("score")) + .baseEffect(plugin.getEffectManager().getBaseEffect(section.getConfigurationSection("effects"))) .lootGroup(ConfigUtils.stringListArgs(section.get("group")).toArray(new String[0])) .nick(section.getString("nick", section.getString("display.name", key))) .addActions(plugin.getActionManager().getActionMap(section.getConfigurationSection("events"))) diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/ExpressionValue.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/ExpressionValue.java index f1e564eb..f0daf218 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/ExpressionValue.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/ExpressionValue.java @@ -21,7 +21,7 @@ import net.momirealms.customfishing.api.mechanic.misc.Value; import net.momirealms.customfishing.util.ConfigUtils; import org.bukkit.entity.Player; -import java.util.HashMap; +import java.util.Map; public class ExpressionValue implements Value { @@ -32,7 +32,7 @@ public class ExpressionValue implements Value { } @Override - public double get(Player player) { - return ConfigUtils.getExpressionValue(player, expression, new HashMap<>(0)); + public double get(Player player, Map values) { + return ConfigUtils.getExpressionValue(player, expression, values); } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/PlainValue.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/PlainValue.java index 31c37008..8c22a4c5 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/PlainValue.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/misc/value/PlainValue.java @@ -20,6 +20,8 @@ package net.momirealms.customfishing.mechanic.misc.value; import net.momirealms.customfishing.api.mechanic.misc.Value; import org.bukkit.entity.Player; +import java.util.Map; + public class PlainValue implements Value { private final double value; @@ -29,7 +31,7 @@ public class PlainValue implements Value { } @Override - public double get(Player player) { + public double get(Player player, Map values) { return value; } } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/ConditionalElement.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/ConditionalElement.java index 520cd67e..0f60dfd3 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/ConditionalElement.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/ConditionalElement.java @@ -18,7 +18,7 @@ package net.momirealms.customfishing.mechanic.requirement; import net.momirealms.customfishing.api.common.Pair; -import net.momirealms.customfishing.api.mechanic.loot.WeightModifier; +import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import org.bukkit.entity.Player; diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java index 5fcaa747..32401f03 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/requirement/RequirementManagerImpl.java @@ -367,10 +367,9 @@ public class RequirementManagerImpl implements RequirementManager { }); } - @SuppressWarnings("all") private void registerGroupRequirement() { registerRequirement("group", (args, actions, advanced) -> { - List arg = (List) args; + HashSet arg = new HashSet<>(ConfigUtils.stringListArgs(args)); return condition -> { String lootID = condition.getArg("{loot}"); Loot loot = plugin.getLootManager().getLoot(lootID); @@ -387,7 +386,7 @@ public class RequirementManagerImpl implements RequirementManager { }; }); registerRequirement("!group", (args, actions, advanced) -> { - List arg = (List) args; + HashSet arg = new HashSet<>(ConfigUtils.stringListArgs(args)); return condition -> { String lootID = condition.getArg("{loot}"); Loot loot = plugin.getLootManager().getLoot(lootID); @@ -409,10 +408,9 @@ public class RequirementManagerImpl implements RequirementManager { }); } - @SuppressWarnings("unchecked") private void registerLootRequirement() { registerRequirement("loot", (args, actions, advanced) -> { - List arg = (List) args; + HashSet arg = new HashSet<>(ConfigUtils.stringListArgs(args)); return condition -> { String lootID = condition.getArg("{loot}"); if (arg.contains(lootID)) return true; @@ -421,7 +419,7 @@ public class RequirementManagerImpl implements RequirementManager { }; }); registerRequirement("!loot", (args, actions, advanced) -> { - List arg = (List) args; + HashSet arg = new HashSet<>(ConfigUtils.stringListArgs(args)); return condition -> { String lootID = condition.getArg("{loot}"); if (!arg.contains(lootID)) return true; diff --git a/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java b/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java index 516450d7..b3f4b513 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java +++ b/plugin/src/main/java/net/momirealms/customfishing/util/ConfigUtils.java @@ -19,8 +19,8 @@ package net.momirealms.customfishing.util; import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.common.Tuple; -import net.momirealms.customfishing.api.mechanic.loot.WeightModifier; import net.momirealms.customfishing.api.mechanic.misc.Value; +import net.momirealms.customfishing.api.mechanic.misc.WeightModifier; import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl; import net.momirealms.customfishing.mechanic.misc.value.ExpressionValue; diff --git a/plugin/src/main/resources/contents/item/default.yml b/plugin/src/main/resources/contents/item/default.yml index 6dcc2b50..dde3b933 100644 --- a/plugin/src/main/resources/contents/item/default.yml +++ b/plugin/src/main/resources/contents/item/default.yml @@ -260,7 +260,7 @@ tuna_fish_silver_star: - 'size: {size}cm' custom-model-data: 50002 group: - - sliver_star + - silver_star - ocean events: success: @@ -331,7 +331,7 @@ pike_fish_silver_star: - 'size: {size}cm' custom-model-data: 50005 group: - - sliver_star + - silver_star - ocean events: success: @@ -407,7 +407,7 @@ gold_fish_silver_star: size: 3~4 custom-model-data: 50008 group: - - sliver_star + - silver_star - river events: success: diff --git a/plugin/src/main/resources/market.yml b/plugin/src/main/resources/market.yml index bf3c5983..3b948728 100644 --- a/plugin/src/main/resources/market.yml +++ b/plugin/src/main/resources/market.yml @@ -60,6 +60,10 @@ sell-all-icons: command_action: type: command value: 'money give {player} {money}' +# Require the economy plugin to hook into Vault +# money_action: +# type: give-money +# value: '{money}' deny-icon: material: REDSTONE_BLOCK display: @@ -112,6 +116,10 @@ sell-icons: command_action: type: command value: 'money give {player} {money}' +# Require the economy plugin to hook into Vault +# money_action: +# type: give-money +# value: '{money}' deny-icon: material: REDSTONE_BLOCK display: