9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2026-01-06 15:51:50 +00:00

checkpoint - 26

This commit is contained in:
XiaoMoMi
2024-07-06 03:03:37 +08:00
parent 268387c91c
commit edbb0790b2
30 changed files with 1658 additions and 247 deletions

View File

@@ -27,6 +27,7 @@ import net.momirealms.customfishing.api.mechanic.effect.EffectManager;
import net.momirealms.customfishing.api.mechanic.entity.EntityManager;
import net.momirealms.customfishing.api.mechanic.event.EventManager;
import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
import net.momirealms.customfishing.api.mechanic.game.GameManager;
import net.momirealms.customfishing.api.mechanic.hook.HookManager;
import net.momirealms.customfishing.api.mechanic.item.ItemManager;
import net.momirealms.customfishing.api.mechanic.loot.LootManager;
@@ -79,6 +80,7 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin,
protected TranslationManager translationManager;
protected TotemManager totemManager;
protected FishingManager fishingManager;
protected GameManager gameManager;
public BukkitCustomFishingPlugin(Plugin boostrap) {
if (!boostrap.getName().equals("CustomFishing")) {
@@ -189,6 +191,10 @@ public abstract class BukkitCustomFishingPlugin implements CustomFishingPlugin,
return fishingManager;
}
public GameManager getGameManager() {
return gameManager;
}
public Plugin getBoostrap() {
return boostrap;
}

View File

@@ -129,7 +129,15 @@ public class ConfigType {
}
);
private static final ConfigType[] values = new ConfigType[] {ITEM, ENTITY, BLOCK, HOOK, ROD, BAIT, UTIL, TOTEM, ENCHANT};
public static final ConfigType MINI_GAME = of(
"minigame",
(id, section, functions) -> {
MiniGameConfigParser config = new MiniGameConfigParser(id, section);
BukkitCustomFishingPlugin.getInstance().getGameManager().registerGame(config.getGame());
}
);
private static final ConfigType[] values = new ConfigType[] {ITEM, ENTITY, BLOCK, HOOK, ROD, BAIT, UTIL, TOTEM, ENCHANT, MINI_GAME};
public static ConfigType[] values() {
return values;

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.config;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.game.Game;
import net.momirealms.customfishing.api.mechanic.game.GameFactory;
public class MiniGameConfigParser {
private final String id;
private Game game;
public MiniGameConfigParser(String id, Section section) {
this.id = id;
analyze(section);
}
private void analyze(Section section) {
String type = section.getString("game-type");
GameFactory factory = BukkitCustomFishingPlugin.getInstance().getGameManager().getGameFactory(type);
if (factory == null) {
throw new RuntimeException("Unknown game-type: " + type);
}
this.game = factory.create(id, section);
}
public Game getGame() {
return game;
}
}

View File

@@ -67,6 +67,10 @@ public class ContextKeys<T> {
public static final ContextKeys<Integer> AMOUNT = of("amount", Integer.class);
public static final ContextKeys<Double> WEIGHT = of("0", Double.class);
public static final ContextKeys<String> TIME_LEFT = of("time_left", String.class);
public static final ContextKeys<String> REASON = of("reason", String.class);
public static final ContextKeys<String> PROGRESS = of("progress", String.class);
public static final ContextKeys<Integer> CLICKS_LEFT = of("left_clicks", Integer.class);
public static final ContextKeys<Integer> REQUIRED_TIMES = of("clicks", Integer.class);
private final String key;
private final Class<T> type;

View File

@@ -31,6 +31,8 @@ import net.momirealms.customfishing.api.mechanic.fishing.hook.HookMechanic;
import net.momirealms.customfishing.api.mechanic.fishing.hook.LavaFishingMechanic;
import net.momirealms.customfishing.api.mechanic.fishing.hook.VanillaMechanic;
import net.momirealms.customfishing.api.mechanic.fishing.hook.VoidFishingMechanic;
import net.momirealms.customfishing.api.mechanic.game.Game;
import net.momirealms.customfishing.api.mechanic.game.GamingPlayer;
import net.momirealms.customfishing.api.mechanic.item.MechanicType;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.LootType;
@@ -67,6 +69,7 @@ public class CustomFishingHook {
private Effect tempFinalEffect;
private HookMechanic hookMechanic;
private Loot nextLoot;
private GamingPlayer gamingPlayer;
private static TriFunction<FishHook, Context<Player>, Effect, List<HookMechanic>> mechanicProviders = defaultMechanicProviders();
@@ -105,6 +108,9 @@ public class CustomFishingHook {
plugin.getFishingManager().destroy(hook.getOwnerUniqueId());
return;
}
if (isPlayingGame()) {
return;
}
if (this.hookMechanic != null) {
if (this.hookMechanic.shouldStop()) {
this.hookMechanic.destroy();
@@ -167,6 +173,11 @@ public class CustomFishingHook {
if (task != null) task.cancel();
if (hook.isValid()) hook.remove();
if (hookMechanic != null) hookMechanic.destroy();
if (gamingPlayer != null) gamingPlayer.destroy();
}
public Context<Player> getContext() {
return context;
}
@NotNull
@@ -185,6 +196,7 @@ public class CustomFishingHook {
}
public void onReelIn() {
if (isPlayingGame()) return;
if (hookMechanic != null) {
if (!hookMechanic.isHooked()) {
gears.trigger(ActionTrigger.REEL, context);
@@ -194,8 +206,7 @@ public class CustomFishingHook {
handleSuccessfulFishing();
end();
} else {
handleSuccessfulFishing();
end();
gameStart();
}
}
} else {
@@ -209,6 +220,7 @@ public class CustomFishingHook {
}
public void onBite() {
if (isPlayingGame()) return;
plugin.getEventManager().trigger(context, nextLoot.id(), MechanicType.getTypeByID(nextLoot.id()), ActionTrigger.BITE);
gears.trigger(ActionTrigger.BITE, context);
if (RequirementManager.isSatisfied(context, ConfigManager.autoFishingRequirements())) {
@@ -219,7 +231,46 @@ public class CustomFishingHook {
return;
}
if (nextLoot.instantGame()) {
gameStart();
}
}
public boolean isPlayingGame() {
return gamingPlayer != null && gamingPlayer.isValid();
}
public void handleGameResult() {
if (gamingPlayer == null || !gamingPlayer.isValid()) {
throw new RuntimeException("You can't call this method if the player is not playing the game");
}
if (gamingPlayer.isSuccessful()) {
handleSuccessfulFishing();
} else {
handleFailedFishing();
}
end();
}
public void cancelCurrentGame() {
if (gamingPlayer == null || !gamingPlayer.isValid()) {
throw new RuntimeException("You can't call this method if the player is not playing the game");
}
gamingPlayer.cancel();
gamingPlayer = null;
if (hookMechanic != null) {
hookMechanic.unfreeze(tempFinalEffect);
}
}
public void gameStart() {
if (gamingPlayer != null && gamingPlayer.isValid())
return;
Game nextGame = plugin.getGameManager().getNextGame(tempFinalEffect, context);
if (nextGame != null) {
nextGame.start(this, tempFinalEffect);
if (this.hookMechanic != null) {
this.hookMechanic.freeze();
}
}
}

View File

@@ -32,4 +32,8 @@ public interface HookMechanic
boolean isHooked();
void destroy();
void freeze();
void unfreeze(Effect finalEffect);
}

View File

@@ -54,6 +54,7 @@ public class LavaFishingMechanic implements HookMechanic {
private int currentState;
private int jumpTimer;
private boolean firstTime = true;
private boolean freeze = false;
public LavaFishingMechanic(FishHook hook, Effect gearsEffect, Context<Player> context) {
this.hook = hook;
@@ -168,7 +169,9 @@ public class LavaFishingMechanic implements HookMechanic {
}
}
} else if (timeUntilLured > 0) {
timeUntilLured--;
if (!freeze) {
timeUntilLured--;
}
if (this.timeUntilLured <= 0) {
this.fishAngle = RandomUtils.generateRandomFloat(0F, 360F);
this.timeUntilHooked = RandomUtils.generateRandomInt(20, 80);
@@ -196,6 +199,16 @@ public class LavaFishingMechanic implements HookMechanic {
}
}
@Override
public void freeze() {
freeze = true;
}
@Override
public void unfreeze(Effect effect) {
freeze = false;
}
private void setWaitTime(Effect effect) {
int before = ThreadLocalRandom.current().nextInt(ConfigManager.lavaMaxTime() - ConfigManager.lavaMinTime() + 1) + ConfigManager.lavaMinTime();
int after = Math.max(ConfigManager.lavaMinTime(), (int) (before * effect.waitTimeMultiplier() + effect.waitTimeAdder()));

View File

@@ -38,6 +38,7 @@ public class VanillaMechanic implements HookMechanic {
private final Context<Player> context;
private SchedulerTask task;
private boolean isHooked = false;
private int tempWaitTime;
public VanillaMechanic(FishHook hook, Context<Player> context) {
this.hook = hook;
@@ -103,6 +104,24 @@ public class VanillaMechanic implements HookMechanic {
if (this.task != null) this.task.cancel();
}
@Override
public void freeze() {
if (hook.getWaitTime() > 0) {
this.tempWaitTime = hook.getWaitTime();
}
hook.setWaitTime(Integer.MAX_VALUE);
}
@Override
public void unfreeze(Effect effect) {
if (this.tempWaitTime != 0) {
hook.setWaitTime(this.tempWaitTime);
this.tempWaitTime = 0;
} else {
setWaitTime(hook, effect);
}
}
public void onBite() {
EventUtils.fireAndForget(new FishingHookStateEvent(context.getHolder(), hook, FishingHookStateEvent.State.BITE));
}

View File

@@ -51,6 +51,7 @@ public class VoidFishingMechanic implements HookMechanic {
private boolean hooked;
private float fishAngle;
private int timer;
private boolean freeze;
public VoidFishingMechanic(FishHook hook, Effect gearsEffect, Context<Player> context) {
this.hook = hook;
@@ -136,7 +137,9 @@ public class VoidFishingMechanic implements HookMechanic {
EventUtils.fireAndForget(new FishingHookStateEvent(context.getHolder(), hook, FishingHookStateEvent.State.BITE));
}
} else if (timeUntilLured > 0) {
timeUntilLured--;
if (!freeze) {
timeUntilLured--;
}
f = 0.1F;
if (this.timeUntilLured < 20) {
f += (float) (20 - this.timeUntilLured) * 0.05F;
@@ -180,6 +183,16 @@ public class VoidFishingMechanic implements HookMechanic {
}
}
@Override
public void freeze() {
freeze = true;
}
@Override
public void unfreeze(Effect finalEffect) {
freeze = false;
}
private void setWaitTime(Effect effect) {
int before = ThreadLocalRandom.current().nextInt(ConfigManager.voidMaxTime() - ConfigManager.voidMinTime() + 1) + ConfigManager.voidMinTime();
int after = Math.max(ConfigManager.voidMinTime(), (int) (before * effect.waitTimeMultiplier() + effect.waitTimeAdder()));

View File

@@ -0,0 +1,29 @@
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
import java.util.function.BiFunction;
public abstract class AbstractGame implements Game {
private final GameBasics basics;
private final String id;
public AbstractGame(String id, GameBasics basics) {
this.basics = basics;
this.id = id;
}
@Override
public String id() {
return id;
}
@Override
public GamingPlayer start(CustomFishingHook hook, Effect effect) {
return gamingPlayerProvider().apply(hook, basics.toGameSetting(effect));
}
public abstract BiFunction<CustomFishingHook, GameSetting, AbstractGamingPlayer> gamingPlayerProvider();
}

View File

@@ -18,12 +18,12 @@
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
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.common.plugin.scheduler.SchedulerTask;
import org.bukkit.Material;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory;
import org.jetbrains.annotations.ApiStatus;
import java.util.concurrent.TimeUnit;
@@ -33,16 +33,15 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
protected long deadline;
protected boolean success;
protected SchedulerTask task;
protected Player player;
protected GameSettings settings;
protected FishHook fishHook;
protected GameSetting settings;
protected CustomFishingHook hook;
protected boolean isTimeOut;
private boolean valid = true;
private boolean firstFlag = true;
public AbstractGamingPlayer(Player player, FishHook hook, GameSettings settings) {
this.player = player;
this.fishHook = hook;
public AbstractGamingPlayer(CustomFishingHook hook, GameSetting settings) {
this.hook = hook;
this.settings = settings;
// this.manager = BukkitCustomFishingPlugin.getInstance().get();
this.deadline = (long) (System.currentTimeMillis() + settings.time() * 1000L);
this.arrangeTask();
}
@@ -51,11 +50,15 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
this.task = BukkitCustomFishingPlugin.getInstance().getScheduler().asyncRepeating(this, 50, 50, TimeUnit.MILLISECONDS);
}
@Override
public void destroy() {
if (task != null) task.cancel();
valid = false;
}
@Override
public void cancel() {
if (task != null) {
task.cancel();
}
destroy();
}
@Override
@@ -63,40 +66,55 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
return success;
}
@ApiStatus.Internal
public boolean internalRightClick() {
firstFlag = true;
return handleRightClick();
}
@Override
public boolean onRightClick() {
public boolean handleRightClick() {
endGame();
return true;
}
@ApiStatus.Internal
public boolean internalLeftClick() {
if (firstFlag) {
firstFlag = false;
return false;
}
return handleLeftClick();
}
@Override
public boolean onLeftClick() {
public boolean handleLeftClick() {
return false;
}
@Override
public boolean onChat(String message) {
public boolean handleChat(String message) {
return false;
}
@Override
public boolean onSwapHand() {
public boolean handleSwapHand() {
return false;
}
@Override
public boolean onJump() {
public boolean handleJump() {
return false;
}
@Override
public boolean onSneak() {
public boolean handleSneak() {
return false;
}
@Override
public Player getPlayer() {
return player;
return hook.getContext().getHolder();
}
@Override
@@ -109,16 +127,19 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
if (timeOutCheck()) {
return;
}
switchItemCheck();
onTick();
tick();
}
public void onTick() {
@Override
public boolean isValid() {
return valid;
}
protected abstract void tick();
protected void endGame() {
// this.manager.processGameResult(this);
hook.handleGameResult();
valid = false;
}
protected void setGameResult(boolean success) {
@@ -126,22 +147,13 @@ public abstract class AbstractGamingPlayer implements GamingPlayer, Runnable {
}
protected boolean timeOutCheck() {
if (System.currentTimeMillis() > deadline) {
long delta = deadline - System.currentTimeMillis();
if (delta <= 0) {
isTimeOut = true;
cancel();
endGame();
return true;
}
hook.getContext().arg(ContextKeys.TIME_LEFT, String.format("%.1f", (double) delta / 1000));
return false;
}
protected void switchItemCheck() {
PlayerInventory playerInventory = player.getInventory();
if (playerInventory.getItemInMainHand().getType() != Material.FISHING_ROD
&& playerInventory.getItemInOffHand().getType() != Material.FISHING_ROD
) {
cancel();
endGame();
}
}
}

View File

@@ -1,86 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ThreadLocalRandom;
public class BasicGameConfig {
private int minTime;
private int maxTime;
private int minDifficulty;
private int maxDifficulty;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final BasicGameConfig basicGameConfig;
public Builder() {
basicGameConfig = new BasicGameConfig();
}
@SuppressWarnings("UnusedReturnValue")
public Builder difficulty(int value) {
basicGameConfig.minDifficulty = (basicGameConfig.maxDifficulty = value);
return this;
}
@SuppressWarnings("UnusedReturnValue")
public Builder difficulty(int min, int max) {
basicGameConfig.minDifficulty = min;
basicGameConfig.maxDifficulty = max;
return this;
}
public Builder time(int value) {
basicGameConfig.minTime = (basicGameConfig.maxTime = value);
return this;
}
public Builder time(int min, int max) {
basicGameConfig.minTime = min;
basicGameConfig.maxTime = max;
return this;
}
public BasicGameConfig build() {
return basicGameConfig;
}
}
/**
* Generates random game settings based on specified time and difficulty ranges, adjusted by an effect's difficulty modifier.
*
* @param effect The effect to adjust the difficulty.
* @return A {@link GameSettings} object representing the generated game settings.
*/
@Nullable
public GameSettings getGameSetting(Effect effect) {
return new GameSettings(
ThreadLocalRandom.current().nextInt(minTime, maxTime + 1) * effect.gameTimeMultiplier() + effect.gameTimeAdder(),
(int) Math.min(100, Math.max(1, ThreadLocalRandom.current().nextInt(minDifficulty, maxDifficulty + 1) * effect.difficultyMultiplier() + effect.difficultyAdder()))
);
}
}

View File

@@ -17,10 +17,12 @@
package net.momirealms.customfishing.api.mechanic.game;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
public interface GameInstance {
public interface Game {
String id();
GamingPlayer start(Player player, FishHook hook, GameSettings settings);
GamingPlayer start(CustomFishingHook hook, Effect effect);
}

View File

@@ -0,0 +1,35 @@
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import org.jetbrains.annotations.NotNull;
public interface GameBasics {
int minTime();
int maxTime();
int minDifficulty();
int maxDifficulty();
static GameBasics.Builder builder() {
return new GameBasicsImpl.BuilderImpl();
}
@NotNull
GameSetting toGameSetting(Effect effect);
interface Builder {
Builder difficulty(int value);
Builder difficulty(int min, int max);
Builder time(int value);
Builder time(int min, int max);
GameBasics build();
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.common.util.RandomUtils;
import org.jetbrains.annotations.NotNull;
public record GameBasicsImpl(int minTime, int maxTime, int minDifficulty, int maxDifficulty) implements GameBasics {
public static class BuilderImpl implements Builder {
private int minTime;
private int maxTime;
private int minDifficulty;
private int maxDifficulty;
@Override
public Builder difficulty(int value) {
minDifficulty = (maxDifficulty = 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;
return this;
}
@Override
public GameBasics build() {
return new GameBasicsImpl(minTime, maxTime, minDifficulty, maxDifficulty);
}
}
@Override
@NotNull
public GameSetting toGameSetting(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()))
);
}
}

View File

@@ -21,5 +21,5 @@ import dev.dejvokep.boostedyaml.block.implementation.Section;
public interface GameFactory {
GameInstance setArgs(Section section);
Game create(String id, Section section);
}

View File

@@ -18,13 +18,14 @@
package net.momirealms.customfishing.api.mechanic.game;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.common.util.Pair;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.common.plugin.feature.Reloadable;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Optional;
public interface GameManager {
public interface GameManager extends Reloadable {
/**
* Registers a new game type with the specified type identifier.
@@ -49,23 +50,13 @@ public interface GameManager {
* @param type The type identifier of the game.
* @return The {@code GameFactory} for the specified game type, or {@code null} if not found.
*/
@Nullable GameFactory getGameFactory(String type);
/**
* Retrieves a game instance and its basic configuration associated with the specified key.
*
* @param key The key identifying the game instance.
* @return An {@code Optional} containing a {@code Pair} of the basic game configuration and the game instance
* if found, or an empty {@code Optional} if not found.
*/
@Nullable
Pair<BasicGameConfig, GameInstance> getGameInstance(String key);
GameFactory getGameFactory(String type);
/**
* Retrieves a map of game names and their associated weights based on the specified conditions.
*
* @param playerContext The condition to evaluate game weights.
* @return A {@code HashMap} containing game names as keys and their associated weights as values.
*/
HashMap<String, Double> getGameWithWeight(Context<Player> playerContext);
Optional<Game> getGame(String id);
boolean registerGame(Game game);
@Nullable
Game getNextGame(Effect effect, Context<Player> context);
}

View File

@@ -17,5 +17,5 @@
package net.momirealms.customfishing.api.mechanic.game;
public record GameSettings(double time, int difficulty) {
public record GameSetting(double time, int difficulty) {
}

View File

@@ -23,53 +23,28 @@ import org.jetbrains.annotations.Nullable;
public interface GamingPlayer {
/**
* Cancel the game
*/
boolean isValid();
void destroy();
void cancel();
boolean isSuccessful();
/**
* @return whether to cancel the event
*/
boolean onRightClick();
boolean handleRightClick();
/**
* @return whether to cancel the event
*/
boolean onSwapHand();
boolean handleSwapHand();
/**
* @return whether to cancel the event
*/
boolean onLeftClick();
boolean handleLeftClick();
/**
* @return whether to cancel the event
*/
boolean onChat(String message);
boolean handleChat(String message);
/**
* @return whether to cancel the event
*/
boolean onJump();
boolean handleJump();
/**
* @return whether to cancel the event
*/
boolean onSneak();
boolean handleSneak();
/**
* Get the player
*
* @return the player
*/
Player getPlayer();
/**
* @return effect reward based on game results
*/
@Nullable
Effect getEffectReward();
}

View File

@@ -30,7 +30,7 @@ import java.util.Optional;
public interface LootManager extends Reloadable {
void registerLoot(@NotNull Loot loot);
boolean registerLoot(@NotNull Loot loot);
@NotNull
List<String> getGroupMembers(String key);

View File

@@ -0,0 +1,173 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.api.util;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.common.helper.AdventureHelper;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class for generating offset characters based on a font configuration.
*/
@SuppressWarnings("DuplicatedCode")
public class OffsetUtils {
private OffsetUtils() {
throw new UnsupportedOperationException("This class cannot be instantiated");
}
private static String font;
private static String negative_1;
private static String negative_2;
private static String negative_4;
private static String negative_8;
private static String negative_16;
private static String negative_32;
private static String negative_64;
private static String negative_128;
private static String positive_1;
private static String positive_2;
private static String positive_4;
private static String positive_8;
private static String positive_16;
private static String positive_32;
private static String positive_64;
private static String positive_128;
@ApiStatus.Internal
public static void load(Section section) {
if (section != null) {
font = section.getString("font", "customfishing:offset_chars");
positive_1 = section.getString("1");
positive_2 = section.getString("2");
positive_4 = section.getString("4");
positive_8 = section.getString("8");
positive_16 = section.getString("16");
positive_32 = section.getString("32");
positive_64 = section.getString("64");
positive_128 = section.getString("128");
negative_1 = section.getString("-1");
negative_2 = section.getString("-2");
negative_4 = section.getString("-4");
negative_8 = section.getString("-8");
negative_16 = section.getString("-16");
negative_32 = section.getString("-32");
negative_64 = section.getString("-64");
negative_128 = section.getString("-128");
}
}
/**
* Get the shortest negative offset characters for a given number.
*
* @param n The number for which to generate offset characters.
* @return Offset characters as a string.
*/
public static String getShortestNegChars(int n) {
StringBuilder stringBuilder = new StringBuilder();
while (n >= 128) {
stringBuilder.append(negative_128);
n -= 128;
}
if (n - 64 >= 0) {
stringBuilder.append(negative_64);
n -= 64;
}
if (n - 32 >= 0) {
stringBuilder.append(negative_32);
n -= 32;
}
if (n - 16 >= 0) {
stringBuilder.append(negative_16);
n -= 16;
}
if (n - 8 >= 0) {
stringBuilder.append(negative_8);
n -= 8;
}
if (n - 4 >= 0) {
stringBuilder.append(negative_4);
n -= 4;
}
if (n - 2 >= 0) {
stringBuilder.append(negative_2);
n -= 2;
}
if (n - 1 >= 0) {
stringBuilder.append(negative_1);
}
return stringBuilder.toString();
}
/**
* Get the shortest positive offset characters for a given number.
*
* @param n The number for which to generate offset characters.
* @return Offset characters as a string.
*/
public static String getShortestPosChars(int n) {
StringBuilder stringBuilder = new StringBuilder();
while (n >= 128) {
stringBuilder.append(positive_128);
n -= 128;
}
if (n - 64 >= 0) {
stringBuilder.append(positive_64);
n -= 64;
}
if (n - 32 >= 0) {
stringBuilder.append(positive_32);
n -= 32;
}
if (n - 16 >= 0) {
stringBuilder.append(positive_16);
n -= 16;
}
if (n - 8 >= 0) {
stringBuilder.append(positive_8);
n -= 8;
}
if (n - 4 >= 0) {
stringBuilder.append(positive_4);
n -= 4;
}
if (n - 2 >= 0) {
stringBuilder.append(positive_2);
n -= 2;
}
if (n - 1 >= 0) {
stringBuilder.append(positive_1);
}
return stringBuilder.toString();
}
/**
* Get offset characters for a given number. This method selects between positive and negative
* offset characters based on the sign of the number.
*
* @param n The number for which to generate offset characters.
* @return Offset characters as a string.
*/
public static String getOffsetChars(int n) {
if (n > 0) {
return AdventureHelper.surroundWithMiniMessageFont(getShortestPosChars(n), font);
} else {
return AdventureHelper.surroundWithMiniMessageFont(getShortestNegChars(-n), font);
}
}
}