diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ItemConfigParser.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ItemConfigParser.java index 4f4f63a3..702eb798 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ItemConfigParser.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ItemConfigParser.java @@ -26,6 +26,7 @@ import net.momirealms.customfishing.api.mechanic.event.EventCarrier; import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem; import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.LootType; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.common.config.node.Node; import net.momirealms.customfishing.common.item.Item; import org.bukkit.entity.Player; @@ -41,6 +42,7 @@ public class ItemConfigParser { private final String id; private final String material; + private final MathValue amount; private final List, Context>>> tagConsumers = new ArrayList<>(); private final List> effectBuilderConsumers = new ArrayList<>(); private final List> lootBuilderConsumers = new ArrayList<>(); @@ -49,6 +51,7 @@ public class ItemConfigParser { public ItemConfigParser(String id, Section section, Map> functionMap) { this.id = id; this.material = section.getString("material"); + this.amount = MathValue.auto(section.get("amount", 1), true); if (!section.contains("tag")) section.set("tag", true); if (!section.contains("nick")) { if (section.contains("display.name")) { @@ -100,6 +103,7 @@ public class ItemConfigParser { return CustomFishingItem.builder() .material(material) .id(id) + .amount(amount) .tagConsumers(tagConsumers) .build(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/SingleItemParser.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/SingleItemParser.java index 074068bc..5f91f92d 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/SingleItemParser.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/SingleItemParser.java @@ -23,6 +23,7 @@ import net.momirealms.customfishing.api.mechanic.config.function.ItemParserFunct import net.momirealms.customfishing.api.mechanic.config.function.PriorityFunction; import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.common.config.node.Node; import net.momirealms.customfishing.common.item.Item; import org.bukkit.entity.Player; @@ -37,14 +38,17 @@ public class SingleItemParser { private final String id; private final String material; + private final MathValue amount; private final List, Context>>> tagConsumers = new ArrayList<>(); public SingleItemParser(String id, Section section, Map> functionMap) { this.id = id; if (section == null) { this.material = "AIR"; + this.amount = MathValue.plain(1); return; } + this.amount = MathValue.auto(section.get("amount", 1), true); this.material = section.getString("material"); analyze(section, functionMap); } @@ -73,6 +77,7 @@ public class SingleItemParser { return CustomFishingItem.builder() .material(material) .id(id) + .amount(amount) .tagConsumers(tagConsumers) .build(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/CustomFishingHook.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/CustomFishingHook.java index e6b8bf45..5a569dd6 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/CustomFishingHook.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/CustomFishingHook.java @@ -305,6 +305,7 @@ public class CustomFishingHook { plugin.debug("Next game: " + nextGame.id()); gamingPlayer = nextGame.start(this, tempFinalEffect); if (this.hookMechanic != null) { + BukkitCustomFishingPlugin.getInstance().debug("Freezing current mechanic"); this.hookMechanic.freeze(); } } else { @@ -393,8 +394,10 @@ public class CustomFishingHook { * Handles the escape action. */ public void onEscape() { - plugin.getEventManager().trigger(context, nextLoot.id(), MechanicType.LOOT, ActionTrigger.ESCAPE); - gears.trigger(ActionTrigger.ESCAPE, context); + if (!isPlayingGame()) { + plugin.getEventManager().trigger(context, nextLoot.id(), MechanicType.LOOT, ActionTrigger.ESCAPE); + gears.trigger(ActionTrigger.ESCAPE, context); + } } /** diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/hook/VanillaMechanic.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/hook/VanillaMechanic.java index 7ceb9f3c..77150013 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/hook/VanillaMechanic.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/fishing/hook/VanillaMechanic.java @@ -41,6 +41,7 @@ public class VanillaMechanic implements HookMechanic { private SchedulerTask task; private boolean isHooked = false; private int tempWaitTime; + private boolean freeze = false; public VanillaMechanic(FishHook hook, Context context) { this.hook = hook; @@ -82,6 +83,10 @@ public class VanillaMechanic implements HookMechanic { private void setWaitTime(FishHook hook, Effect effect) { BukkitCustomFishingPlugin.getInstance().getScheduler().sync().run(() -> { + if (freeze) { + hook.setWaitTime(Integer.MAX_VALUE); + return; + } if (!ConfigManager.overrideVanillaWaitTime()) { int before = Math.max(hook.getWaitTime(), 0); int after = (int) Math.max(100, before * effect.waitTimeMultiplier() + effect.waitTimeAdder()); @@ -119,6 +124,7 @@ public class VanillaMechanic implements HookMechanic { @Override public void freeze() { + freeze = true; if (hook.getWaitTime() > 0) { this.tempWaitTime = hook.getWaitTime(); } @@ -127,6 +133,7 @@ public class VanillaMechanic implements HookMechanic { @Override public void unfreeze(Effect effect) { + freeze = false; if (this.tempWaitTime != 0) { hook.setWaitTime(this.tempWaitTime); this.tempWaitTime = 0; diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGame.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGame.java index b82bdf8a..ff0958dc 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGame.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/AbstractGame.java @@ -60,7 +60,7 @@ public abstract class AbstractGame implements Game { */ @Override public GamingPlayer start(CustomFishingHook hook, Effect effect) { - return gamingPlayerProvider().apply(hook, basics.toGameSetting(effect)); + return gamingPlayerProvider().apply(hook, basics.toGameSetting(hook.getContext(), effect)); } /** diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasics.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasics.java index 1e7d67b5..13c9bf10 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasics.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasics.java @@ -17,7 +17,10 @@ package net.momirealms.customfishing.api.mechanic.game; +import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.effect.Effect; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; /** @@ -26,32 +29,18 @@ import org.jetbrains.annotations.NotNull; public interface GameBasics { /** - * Gets the minimum time for the game. + * Gets the time for the game. * * @return the minimum time in seconds. */ - int minTime(); + MathValue time(); /** - * Gets the maximum time for the game. - * - * @return the maximum time in seconds. - */ - int maxTime(); - - /** - * Gets the minimum difficulty for the game. + * Gets the difficulty for the game. * * @return the minimum difficulty level. */ - int minDifficulty(); - - /** - * Gets the maximum difficulty for the game. - * - * @return the maximum difficulty level. - */ - int maxDifficulty(); + MathValue difficulty(); /** * Creates a new builder for constructing {@link GameBasics} instances. @@ -65,11 +54,11 @@ public interface GameBasics { /** * Converts the game basics to a {@link GameSetting} instance based on the provided effect. * - * @param effect the effect to apply. + * @param context the context. + * @param effect the effect to apply. * @return the generated {@link GameSetting} instance. */ - @NotNull - GameSetting toGameSetting(Effect effect); + @NotNull GameSetting toGameSetting(Context context, Effect effect); /** * Builder interface for constructing {@link GameBasics} instances. @@ -82,16 +71,7 @@ public interface GameBasics { * @param value the difficulty level. * @return the current {@link Builder} instance. */ - Builder difficulty(int value); - - /** - * Sets the difficulty range for the game. - * - * @param min the minimum difficulty level. - * @param max the maximum difficulty level. - * @return the current {@link Builder} instance. - */ - Builder difficulty(int min, int max); + Builder difficulty(MathValue value); /** * Sets the time for the game. @@ -99,16 +79,7 @@ public interface GameBasics { * @param value the time in seconds. * @return the current {@link Builder} instance. */ - Builder time(int value); - - /** - * Sets the time range for the game. - * - * @param min the minimum time in seconds. - * @param max the maximum time in seconds. - * @return the current {@link Builder} instance. - */ - Builder time(int min, int max); + Builder time(MathValue value); /** * Builds and returns the {@link GameBasics} instance. diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasicsImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasicsImpl.java index 0e49943f..d3c4867f 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasicsImpl.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameBasicsImpl.java @@ -17,51 +17,42 @@ package net.momirealms.customfishing.api.mechanic.game; +import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.effect.Effect; -import net.momirealms.customfishing.common.util.RandomUtils; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -public record GameBasicsImpl(int minTime, int maxTime, int minDifficulty, int maxDifficulty) implements GameBasics { +public record GameBasicsImpl(MathValue time, MathValue difficulty) implements GameBasics { public static class BuilderImpl implements Builder { - private int minTime; - private int maxTime; - private int minDifficulty; - private int maxDifficulty; + private MathValue time; + private MathValue difficulty; + @Override - public Builder difficulty(int value) { - minDifficulty = (maxDifficulty = value); + public Builder difficulty(MathValue value) { + this.difficulty = value; return this; } + @Override - public Builder difficulty(int min, int max) { - minDifficulty = min; - maxDifficulty = max; - return this; - } - @Override - public Builder time(int value) { - minTime = (maxTime = value); - return this; - } - @Override - public Builder time(int min, int max) { - minTime = min; - maxTime = max; + public Builder time(MathValue value) { + this.time = value; return this; } + @Override public GameBasics build() { - return new GameBasicsImpl(minTime, maxTime, minDifficulty, maxDifficulty); + return new GameBasicsImpl(time, difficulty); } } - @Override @NotNull - public GameSetting toGameSetting(Effect effect) { + @Override + public GameSetting toGameSetting(Context context, Effect effect) { return new GameSetting( - RandomUtils.generateRandomInt(minTime, maxTime) * effect.gameTimeMultiplier() + effect.gameTimeAdder(), - (int) Math.min(100, Math.max(1, RandomUtils.generateRandomInt(minDifficulty, maxDifficulty) * effect.difficultyMultiplier() + effect.difficultyAdder())) + time.evaluate(context) * effect.gameTimeMultiplier() + effect.gameTimeAdder(), + Math.min(100, Math.max(1, difficulty.evaluate(context) * effect.difficultyMultiplier() + effect.difficultyAdder())) ); } } \ No newline at end of file diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameSetting.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameSetting.java index 738a6b92..6a003d2f 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameSetting.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/game/GameSetting.java @@ -23,5 +23,5 @@ package net.momirealms.customfishing.api.mechanic.game; * @param time The time allocated for the game, in seconds. * @param difficulty The difficulty level of the game. (1~100) */ -public record GameSetting(double time, int difficulty) { +public record GameSetting(double time, double difficulty) { } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItem.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItem.java index 144c52ee..a7560a17 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItem.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItem.java @@ -20,6 +20,7 @@ package net.momirealms.customfishing.api.mechanic.item; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; import net.momirealms.customfishing.api.mechanic.config.function.PriorityFunction; import net.momirealms.customfishing.api.mechanic.context.Context; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.common.item.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -48,6 +49,13 @@ public interface CustomFishingItem { */ String id(); + /** + * Returns the amount of the item + * + * @return the amount of the item + */ + MathValue amount(); + /** * Returns a list of tag consumers. Tag consumers are functions that take an {@link Item} and a {@link Context} * as parameters and perform some operation on them. @@ -96,6 +104,14 @@ public interface CustomFishingItem { */ Builder material(String material); + /** + * Sets the amount of the item + * + * @param amount amount + * @return the {@link Builder} instance for method chaining. + */ + Builder amount(MathValue amount); + /** * Sets the list of tag consumers for the {@link CustomFishingItem} being built. * Tag consumers are functions that take an {@link Item} and a {@link Context} as parameters and perform some operation on them. diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItemImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItemImpl.java index 7207ed71..deaed9a9 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItemImpl.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/item/CustomFishingItemImpl.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.api.mechanic.item; import net.momirealms.customfishing.api.mechanic.config.function.PriorityFunction; import net.momirealms.customfishing.api.mechanic.context.Context; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.common.item.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -34,13 +35,15 @@ public class CustomFishingItemImpl implements CustomFishingItem { private final String material; private final String id; + private final MathValue amount; private final List, Context>> tagConsumers; - public CustomFishingItemImpl(String id, String material, List, Context>> tagConsumers) { + public CustomFishingItemImpl(String id, String material, MathValue amount, List, Context>> tagConsumers) { this.material = material; this.id = id; this.tagConsumers = tagConsumers; + this.amount = amount; } @Override @@ -53,6 +56,11 @@ public class CustomFishingItemImpl implements CustomFishingItem { return id; } + @Override + public MathValue amount() { + return amount == null ? MathValue.plain(1) : amount; + } + @Override public List, Context>> tagConsumers() { return tagConsumers; @@ -62,6 +70,7 @@ public class CustomFishingItemImpl implements CustomFishingItem { private String material = DEFAULT_MATERIAL; private String id; + private MathValue amount; private final TreeSet, Context>>> tagConsumers = new TreeSet<>(); @Override @@ -76,6 +85,12 @@ public class CustomFishingItemImpl implements CustomFishingItem { return this; } + @Override + public Builder amount(MathValue amount) { + this.amount = requireNonNull(amount); + return this; + } + @Override public Builder tagConsumers(List, Context>>> tagConsumers) { this.tagConsumers.addAll(tagConsumers); @@ -84,7 +99,7 @@ public class CustomFishingItemImpl implements CustomFishingItem { @Override public CustomFishingItem build() { - return new CustomFishingItemImpl(requireNonNull(id), material, tagConsumers.stream().map(PriorityFunction::get).toList()); + return new CustomFishingItemImpl(requireNonNull(id), material, amount, tagConsumers.stream().map(PriorityFunction::get).toList()); } } } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/MathValue.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/MathValue.java index c7c6e5c3..ba1dc08d 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/MathValue.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/MathValue.java @@ -76,8 +76,19 @@ public interface MathValue { * @param the type of the holder object for the context * @return a MathValue instance representing the given ranged value */ - static MathValue ranged(String value) { - return new RangedMathValueImpl<>(value); + static MathValue rangedDouble(String value) { + return new RangedDoubleValueImpl<>(value); + } + + /** + * Creates a MathValue based on a range of values. + * + * @param value the ranged value to represent + * @param the type of the holder object for the context + * @return a MathValue instance representing the given ranged value + */ + static MathValue rangedInt(String value) { + return new RangedIntValueImpl<>(value); } /** @@ -91,9 +102,13 @@ public interface MathValue { * @throws IllegalArgumentException if the object type is not supported */ static MathValue auto(Object o) { + return auto(o, false); + } + + static MathValue auto(Object o, boolean intFirst) { if (o instanceof String s) { if (s.contains("~")) { - return ranged(s); + return intFirst ? (s.contains(".") ? rangedDouble(s) : rangedInt(s)) : rangedDouble(s); } try { return plain(Double.parseDouble(s)); diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedMathValueImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedDoubleValueImpl.java similarity index 69% rename from api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedMathValueImpl.java rename to api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedDoubleValueImpl.java index a8bd5fdc..f544bdb5 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedMathValueImpl.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedDoubleValueImpl.java @@ -20,29 +20,22 @@ package net.momirealms.customfishing.api.mechanic.misc.value; import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.common.util.RandomUtils; -public class RangedMathValueImpl implements MathValue { +public class RangedDoubleValueImpl implements MathValue { - private final double min; - private final double max; + private final MathValue min; + private final MathValue max; - public RangedMathValueImpl(String value) { + public RangedDoubleValueImpl(String value) { String[] split = value.split("~"); if (split.length != 2) { throw new IllegalArgumentException("Correct ranged format `a~b`"); } - double min = Double.parseDouble(split[0]); - double max = Double.parseDouble(split[1]); - if (min > max) { - double temp = max; - max = min; - min = temp; - } - this.min = min; - this.max = max; + this.min = MathValue.auto(split[0]); + this.max = MathValue.auto(split[1]); } @Override public double evaluate(Context context) { - return RandomUtils.generateRandomDouble(min, max); + return RandomUtils.generateRandomDouble(min.evaluate(context), max.evaluate(context)); } } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedIntValueImpl.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedIntValueImpl.java new file mode 100644 index 00000000..577df117 --- /dev/null +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/misc/value/RangedIntValueImpl.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) <2024> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.api.mechanic.misc.value; + +import net.momirealms.customfishing.api.mechanic.context.Context; +import net.momirealms.customfishing.common.util.RandomUtils; + +public class RangedIntValueImpl implements MathValue { + + private final MathValue min; + private final MathValue max; + + public RangedIntValueImpl(String value) { + String[] split = value.split("~"); + if (split.length != 2) { + throw new IllegalArgumentException("Correct ranged format `a~b`"); + } + this.min = MathValue.auto(split[0]); + this.max = MathValue.auto(split[1]); + } + + @Override + public double evaluate(Context context) { + return RandomUtils.generateRandomInt((int) min.evaluate(context), (int) max.evaluate(context)); + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java index 14bb99de..ef53ba7a 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/block/BukkitBlockManager.java @@ -26,7 +26,6 @@ import net.momirealms.customfishing.api.mechanic.config.ConfigManager; import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.context.ContextKeys; import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; -import net.momirealms.customfishing.common.util.Pair; import net.momirealms.customfishing.common.util.RandomUtils; import net.momirealms.customfishing.common.util.Tuple; import org.bukkit.*; @@ -322,14 +321,13 @@ public class BukkitBlockManager implements BlockManager, Listener { private void registerStorage() { this.registerBlockStateModifierBuilder("storage", (args) -> { if (args instanceof Section section) { - List, String, Pair, MathValue>>> contents = new ArrayList<>(); + List, String, MathValue>> contents = new ArrayList<>(); for (Map.Entry entry : section.getStringRouteMappedValues(false).entrySet()) { if (entry.getValue() instanceof Section inner) { String item = inner.getString("item"); - String[] split = inner.getString("amount","1~1").split("~"); - Pair, MathValue> amountPair = Pair.of(MathValue.auto(split[0]), MathValue.auto(split[1])); + MathValue amount = MathValue.auto(inner.getString("amount","1~1"), true); MathValue chance = MathValue.auto(inner.get("chance", 1d)); - contents.add(Tuple.of(chance, item, amountPair)); + contents.add(Tuple.of(chance, item, amount)); } } return (context, blockState) -> { @@ -345,7 +343,7 @@ public class BukkitBlockManager implements BlockManager, Listener { } private void setInventoryItems( - List, String, Pair, MathValue>>> contents, + List, String, MathValue>> contents, Context context, Inventory inventory ) { @@ -354,11 +352,11 @@ public class BukkitBlockManager implements BlockManager, Listener { unused.add(i); } Collections.shuffle(unused); - for (Tuple, String, Pair, MathValue>> tuple : contents) { + for (Tuple, String, MathValue> tuple : contents) { if (tuple.left().evaluate(context) > Math.random()) { ItemStack itemStack = plugin.getItemManager().buildAny(context, tuple.mid()); if (itemStack != null) { - itemStack.setAmount(RandomUtils.generateRandomInt((int) tuple.right().left().evaluate(context), (int) (tuple.right().right().evaluate(context)))); + itemStack.setAmount((int) tuple.right().evaluate(context)); inventory.setItem(unused.pop(), itemStack); } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/game/BukkitGameManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/game/BukkitGameManager.java index d723fbea..ca952489 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/game/BukkitGameManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/game/BukkitGameManager.java @@ -27,6 +27,7 @@ import net.momirealms.customfishing.api.mechanic.context.ContextKeys; import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook; import net.momirealms.customfishing.api.mechanic.game.*; +import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.api.mechanic.misc.value.TextValue; import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement; import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager; @@ -166,22 +167,10 @@ public class BukkitGameManager implements GameManager { } private GameBasics getGameBasics(Section section) { - GameBasics.Builder builder = GameBasics.builder(); - Object difficulty = section.get("difficulty", "20~80"); - if (difficulty instanceof String str) { - String[] split = str.split("~"); - builder.difficulty(Integer.parseInt(split[0]), Integer.parseInt(split[1])); - } else if (difficulty instanceof Integer integer) { - builder.difficulty(integer); - } - Object time = section.get("time", 15); - if (time instanceof String str) { - String[] split = str.split("~"); - builder.time(Integer.parseInt(split[0]), Integer.parseInt(split[1])); - } else if (time instanceof Integer integer) { - builder.time(integer); - } - return builder.build(); + return GameBasics.builder() + .difficulty(MathValue.auto(section.get("difficulty", "20~80"), false)) + .time(MathValue.auto(section.get("time", 15), false)) + .build(); } private void registerHoldGame() { @@ -205,6 +194,8 @@ public class BukkitGameManager implements GameManager { private final String font = section.getString("subtitle.font"); private final String barImage = section.getString("subtitle.bar"); private final String tip = section.getString("tip"); + private final boolean elasticity = section.getBoolean("arguments.elasticity", false); + private final double elasticityPower = section.getDouble("arguments.elasticity-power", 0.7); @Override public BiFunction gamingPlayerProvider() { @@ -257,9 +248,9 @@ public class BukkitGameManager implements GameManager { private void burst() { if (Math.random() < (judgement_position / barEffectiveWidth)) { - judgement_velocity = -1 - 0.8 * Math.random() * ((double) settings.difficulty() / 15); + judgement_velocity = -1 - 0.8 * Math.random() * (settings.difficulty() / 15); } else { - judgement_velocity = 1 + 0.8 * Math.random() * ((double) settings.difficulty() / 15); + judgement_velocity = 1 + 0.8 * Math.random() * (settings.difficulty() / 15); } } @@ -285,11 +276,19 @@ public class BukkitGameManager implements GameManager { private void calibrate() { if (fish_position < 0) { fish_position = 0; - fish_velocity = 0; + if (elasticity) { + fish_velocity = -fish_velocity * elasticityPower; + } else { + fish_velocity = 0; + } } if (fish_position + pointerIconWidth > barEffectiveWidth) { fish_position = barEffectiveWidth - pointerIconWidth; - fish_velocity = 0; + if (elasticity) { + fish_velocity = -fish_velocity * elasticityPower; + } else { + fish_velocity = 0; + } } if (judgement_position < 0) { judgement_position = 0; @@ -478,7 +477,7 @@ public class BukkitGameManager implements GameManager { public BiFunction gamingPlayerProvider() { return (customFishingHook, gameSetting) -> new AbstractGamingPlayer(customFishingHook, gameSetting) { private int clickedTimes; - private final int requiredTimes = settings.difficulty(); + private final int requiredTimes = (int) settings.difficulty(); @Override public void arrangeTask() { @@ -561,7 +560,7 @@ public class BukkitGameManager implements GameManager { @Override protected void tick() { if (struggling_time <= 0) { - if (Math.random() < ((double) settings.difficulty() / 4000)) { + if (Math.random() < (settings.difficulty() / 4000)) { struggling_time = (int) (10 + Math.random() * (settings.difficulty() / 4)); } } else { @@ -585,7 +584,7 @@ public class BukkitGameManager implements GameManager { private void pull() { played = true; if (struggling_time > 0) { - strain += (strugglingIncrease + ((double) settings.difficulty() / 50)); + strain += (strugglingIncrease + (settings.difficulty() / 50)); fish_position -= 1; } else { strain += normalIncrease; @@ -652,7 +651,7 @@ public class BukkitGameManager implements GameManager { @Override public void arrangeTask() { - requiredTimes = settings.difficulty() / 4; + requiredTimes = (int) (settings.difficulty() / 4) + 3; order = new int[requiredTimes]; for (int i = 0; i < requiredTimes; i++) { order[i] = ThreadLocalRandom.current().nextInt(0, easy ? 2 : 4); @@ -817,6 +816,8 @@ public class BukkitGameManager implements GameManager { private final int totalWidth = chances.size() * widthPerSection - 1; private final int pointerOffset = section.getInt("arguments.pointer-offset"); private final int pointerWidth = section.getInt("arguments.pointer-width"); + private final int maxSpeed = section.getInt("arguments.max-speed", 150); + private final int minSpeed = section.getInt("arguments.min-speed", 15); private final List title = ListUtils.toList(section.get("title")); private final String font = section.getString("subtitle.font"); private final String barImage = section.getString("subtitle.bar"); @@ -830,10 +831,18 @@ public class BukkitGameManager implements GameManager { private boolean face = true; private final TextValue sendTitle = TextValue.auto(title.get(RandomUtils.generateRandomInt(0, title.size() - 1))); + private static final int MIN_VALUE = 1; + private static final int MAX_VALUE = 100; + + private long mapValueToIntervalMicroseconds(int value) { + double frequency = minSpeed + ((double) (value - MIN_VALUE) / (MAX_VALUE - MIN_VALUE)) * (maxSpeed - minSpeed); + return (long) (1_000_000 / frequency); + } + @Override public void arrangeTask() { - var period = Math.min(200, ((double) 10*(200-settings.difficulty()))/((double) (1+4*settings.difficulty()))); - this.task = plugin.getScheduler().asyncRepeating(this, 10, (long) 10, TimeUnit.MILLISECONDS); + long period = mapValueToIntervalMicroseconds((int) settings.difficulty()); + this.task = plugin.getScheduler().asyncRepeating(this, period, period, TimeUnit.MICROSECONDS); } @Override diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java index 76f6f8ec..0bc2cae3 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/item/BukkitItemManager.java @@ -136,6 +136,7 @@ public class BukkitItemManager implements ItemManager, Listener { public ItemStack build(@NotNull Context context, @NotNull CustomFishingItem item) { ItemStack itemStack = getOriginalStack(context.getHolder(), item.material()); if (itemStack.getType() == Material.AIR) return itemStack; + itemStack.setAmount(Math.max(1, (int) item.amount().evaluate(context))); Item wrappedItemStack = factory.wrap(itemStack); for (BiConsumer, Context> consumer : item.tagConsumers()) { consumer.accept(wrappedItemStack, context); diff --git a/core/src/main/resources/contents/minigame/default.yml b/core/src/main/resources/contents/minigame/default.yml index 3a818534..0b0edf96 100644 --- a/core/src/main/resources/contents/minigame/default.yml +++ b/core/src/main/resources/contents/minigame/default.yml @@ -20,6 +20,8 @@ rainbow_1: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -39,6 +41,8 @@ rainbow_2: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 1 @@ -58,6 +62,8 @@ rainbow_3: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -77,6 +83,8 @@ rainbow_4: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -96,6 +104,8 @@ rainbow_5: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -115,6 +125,8 @@ rainbow_6: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -134,6 +146,8 @@ rainbow_7: pointer-offset: -119 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -158,6 +172,8 @@ accurate_click_bar_1_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -186,6 +202,8 @@ accurate_click_bar_1_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -214,6 +232,8 @@ accurate_click_bar_1_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -242,6 +262,8 @@ accurate_click_bar_2_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0.2 @@ -270,6 +292,8 @@ accurate_click_bar_2_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0.2 @@ -298,6 +322,8 @@ accurate_click_bar_2_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0.2 @@ -326,6 +352,8 @@ accurate_click_bar_3_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -354,6 +382,8 @@ accurate_click_bar_3_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -382,6 +412,8 @@ accurate_click_bar_3_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 16 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -410,6 +442,8 @@ accurate_click_bar_4_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -449,6 +483,8 @@ accurate_click_bar_4_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -488,6 +524,8 @@ accurate_click_bar_4_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -527,6 +565,8 @@ accurate_click_bar_5_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -566,6 +606,8 @@ accurate_click_bar_5_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -605,6 +647,8 @@ accurate_click_bar_5_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -644,6 +688,8 @@ accurate_click_bar_6_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0.1 2: 0.1 @@ -683,6 +729,8 @@ accurate_click_bar_6_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0.1 2: 0.1 @@ -722,6 +770,8 @@ accurate_click_bar_6_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 8 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0.1 2: 0.1 @@ -761,6 +811,8 @@ accurate_click_bar_7_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -822,6 +874,8 @@ accurate_click_bar_7_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -883,6 +937,8 @@ accurate_click_bar_7_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -944,6 +1000,8 @@ accurate_click_bar_8_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -1005,6 +1063,8 @@ accurate_click_bar_8_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -1066,6 +1126,8 @@ accurate_click_bar_8_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 0 2: 0 @@ -1127,6 +1189,8 @@ accurate_click_bar_9_easy: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -1188,6 +1252,8 @@ accurate_click_bar_9_normal: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -1249,6 +1315,8 @@ accurate_click_bar_9_hard: pointer-offset: -183 pointer-width: 5 width-per-section: 4 + max-speed: 150 + min-speed: 15 success-rate-sections: 1: 1 2: 0 @@ -1321,6 +1389,7 @@ hold_game_easy: water-resistance: 0.15 pulling-strength: 0.35 loosening-strength-loss: 0.25 + elasticity: false hold-time-requirements: - 3 - 3 @@ -1357,6 +1426,7 @@ hold_game_normal: water-resistance: 0.15 pulling-strength: 0.35 loosening-strength-loss: 0.25 + elasticity: false hold-time-requirements: - 3 - 3 @@ -1395,6 +1465,8 @@ hold_game_hard: water-resistance: 0.15 pulling-strength: 0.35 loosening-strength-loss: 0.25 + elasticity: false + elasticity-power: 0.7 hold-time-requirements: - 3 - 4 @@ -1445,6 +1517,8 @@ tension_game_easy: normal-pull-tension-increase: 1 struggling-tension-increase: 2 loosening-tension-loss: 2 + elasticity: false + elasticity-power: 0.7 tension: - '뀑' - '뀒' @@ -1482,6 +1556,8 @@ tension_game_normal: normal-pull-tension-increase: 1 struggling-tension-increase: 2 loosening-tension-loss: 2 + elasticity: false + elasticity-power: 0.7 tension: - '뀑' - '뀒'