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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,4 +32,8 @@ public interface HookMechanic
|
||||
boolean isHooked();
|
||||
|
||||
void destroy();
|
||||
|
||||
void freeze();
|
||||
|
||||
void unfreeze(Effect finalEffect);
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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()))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -21,5 +21,5 @@ import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
|
||||
public interface GameFactory {
|
||||
|
||||
GameInstance setArgs(Section section);
|
||||
Game create(String id, Section section);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user