mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2025-12-19 15:09:24 +00:00
checkpoint - 18
This commit is contained in:
@@ -21,6 +21,7 @@ dependencies {
|
||||
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
|
||||
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
|
||||
compileOnly("me.clip:placeholderapi:${rootProject.properties["placeholder_api_version"]}")
|
||||
compileOnly("com.github.Xiao-MoMi:Sparrow-Heart:${rootProject.properties["sparrow_heart_version"]}")
|
||||
}
|
||||
|
||||
java {
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
|
||||
package net.momirealms.customfishing.api.event;
|
||||
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.FishingPreparation;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
@@ -48,9 +46,10 @@ public class RodCastEvent extends PlayerEvent implements Cancellable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancelling this event would not cancel the bukkit PlayerFishEvent
|
||||
* Cancelling this event would disable CustomFishing mechanics
|
||||
* If you want to prevent players from casting, use {@link #getBukkitPlayerFishEvent()} instead
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
* @param cancel true if you want to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
@@ -61,19 +60,23 @@ public class RodCastEvent extends PlayerEvent implements Cancellable {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link FishingGears}
|
||||
*
|
||||
* @return fishing gears
|
||||
*/
|
||||
public FishingGears getGears() {
|
||||
return gears;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original PlayerFishEvent that triggered the rod cast.
|
||||
* Gets the original PlayerFishEvent that triggered the {@link RodCastEvent}.
|
||||
*
|
||||
* @return The original PlayerFishEvent.
|
||||
*/
|
||||
|
||||
@@ -81,7 +81,7 @@ public interface ActionManager<T> extends Reloadable {
|
||||
* @return An array of parsed actions.
|
||||
*/
|
||||
@NotNull
|
||||
Action<T>[] parseActions(@NotNull Section section);
|
||||
Action<T>[] parseActions(Section section);
|
||||
|
||||
/**
|
||||
* Parses an action from the given type and arguments.
|
||||
|
||||
@@ -21,6 +21,7 @@ import net.momirealms.customfishing.common.config.ConfigLoader;
|
||||
import net.momirealms.customfishing.common.config.node.Node;
|
||||
import net.momirealms.customfishing.common.item.Item;
|
||||
import net.momirealms.customfishing.common.plugin.feature.Reloadable;
|
||||
import net.momirealms.customfishing.common.util.Pair;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -34,6 +35,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -56,8 +58,12 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
protected boolean overrideVanillaWaitTime;
|
||||
protected int waterMinTime;
|
||||
protected int waterMaxTime;
|
||||
protected boolean enableLavaFishing;
|
||||
protected int lavaMinTime;
|
||||
protected int lavaMaxTime;
|
||||
protected boolean enableVoidFishing;
|
||||
protected int voidMinTime;
|
||||
protected int voidMaxTime;
|
||||
protected boolean restrictedSizeRange;
|
||||
protected List<String> durabilityLore;
|
||||
protected boolean allowMultipleTotemType;
|
||||
@@ -66,6 +72,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
protected Requirement<Player>[] mechanicRequirements;
|
||||
protected boolean enableBag;
|
||||
|
||||
|
||||
protected ConfigManager(BukkitCustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
instance = this;
|
||||
@@ -127,6 +134,10 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return instance.waterMaxTime;
|
||||
}
|
||||
|
||||
public static boolean enableLavaFishing() {
|
||||
return instance.enableLavaFishing;
|
||||
}
|
||||
|
||||
public static int lavaMinTime() {
|
||||
return instance.lavaMinTime;
|
||||
}
|
||||
@@ -135,6 +146,18 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return instance.lavaMaxTime;
|
||||
}
|
||||
|
||||
public static boolean enableVoidFishing() {
|
||||
return instance.enableVoidFishing;
|
||||
}
|
||||
|
||||
public static int voidMinTime() {
|
||||
return instance.voidMinTime;
|
||||
}
|
||||
|
||||
public static int voidMaxTime() {
|
||||
return instance.voidMaxTime;
|
||||
}
|
||||
|
||||
public static boolean restrictedSizeRange() {
|
||||
return instance.restrictedSizeRange;
|
||||
}
|
||||
@@ -312,4 +335,8 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
public Map<String, Node<ConfigParserFunction>> getFormatFunctions() {
|
||||
return formatFunctions;
|
||||
}
|
||||
|
||||
public abstract List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops);
|
||||
|
||||
public abstract List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops);
|
||||
}
|
||||
|
||||
@@ -98,4 +98,11 @@ public class ContextKeys<T> {
|
||||
public final int hashCode() {
|
||||
return Objects.hashCode(this.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContextKeys{" +
|
||||
"key='" + key + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,4 +90,12 @@ public final class PlayerContextImpl implements Context<Player> {
|
||||
public Player getHolder() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlayerContext{" +
|
||||
"args=" + args +
|
||||
", player=" + player +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +1,143 @@
|
||||
package net.momirealms.customfishing.api.mechanic.fishing;
|
||||
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
|
||||
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.loot.Loot;
|
||||
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask;
|
||||
import net.momirealms.customfishing.common.util.TriConsumer;
|
||||
import net.momirealms.customfishing.common.util.TriFunction;
|
||||
import net.momirealms.sparrow.heart.SparrowHeart;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CustomFishingHook {
|
||||
|
||||
private static final Consumer<FishHook> hookConsumer = defaultHookLogics();
|
||||
private FishHook hook;
|
||||
private final FishHook hook;
|
||||
private final SchedulerTask task;
|
||||
private final FishingGears gears;
|
||||
private HookMechanic hookMechanic;
|
||||
private Loot nextLoot;
|
||||
private Context<Player> context;
|
||||
|
||||
public static Consumer<FishHook> defaultHookLogics() {
|
||||
return fishHook -> {
|
||||
|
||||
private static TriFunction<FishHook, Context<Player>, Effect, List<HookMechanic>> mechanicProviders = defaultMechanicProviders();
|
||||
|
||||
public static TriFunction<FishHook, Context<Player>, Effect, List<HookMechanic>> defaultMechanicProviders() {
|
||||
return (h, c, e) -> {
|
||||
ArrayList<HookMechanic> mechanics = new ArrayList<>();
|
||||
mechanics.add(new VanillaMechanic(h, c));
|
||||
if (ConfigManager.enableLavaFishing()) mechanics.add(new LavaFishingMechanic(h, e, c));
|
||||
if (ConfigManager.enableVoidFishing()) mechanics.add(new VoidFishingMechanic(h, e, c));
|
||||
return mechanics;
|
||||
};
|
||||
};
|
||||
|
||||
public static void mechanicProviders(TriFunction<FishHook, Context<Player>, Effect, List<HookMechanic>> mechanicProviders) {
|
||||
CustomFishingHook.mechanicProviders = mechanicProviders;
|
||||
}
|
||||
|
||||
public CustomFishingHook(FishHook hook, FishingGears gears, Context<Player> context, List<HookMechanic> enabledMechanics) {
|
||||
public CustomFishingHook(FishHook hook, FishingGears gears, Context<Player> context) {
|
||||
this.gears = gears;
|
||||
this.hook = hook;
|
||||
// once it becomes a custom hook, the wait time is controlled by plugin
|
||||
this.context = context;
|
||||
|
||||
Effect effect = Effect.newInstance();
|
||||
// The effects impact mechanism at this stage
|
||||
for (EffectModifier modifier : gears.effectModifiers()) {
|
||||
for (TriConsumer<Effect, Context<Player>, Integer> consumer : modifier.modifiers()) {
|
||||
consumer.accept(effect, context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<HookMechanic> enabledMechanics = mechanicProviders.apply(hook, context, effect);
|
||||
this.task = BukkitCustomFishingPlugin.getInstance().getScheduler().sync().runRepeating(() -> {
|
||||
// destroy if hook is invalid
|
||||
if (hook.isValid()) {
|
||||
if (!hook.isValid()) {
|
||||
BukkitCustomFishingPlugin.getInstance().getFishingManager().destroy(hook.getOwnerUniqueId());
|
||||
return;
|
||||
}
|
||||
for (HookMechanic mechanic : enabledMechanics) {
|
||||
// find the first available mechanic
|
||||
if (mechanic.canStart()) {
|
||||
if (hookMechanic != mechanic) {
|
||||
if (hookMechanic != null) hookMechanic.destroy();
|
||||
hookMechanic = mechanic;
|
||||
if (this.hookMechanic != mechanic) {
|
||||
if (this.hookMechanic != null) this.hookMechanic.destroy();
|
||||
this.hookMechanic = mechanic;
|
||||
// to update some properties
|
||||
mechanic.preStart();
|
||||
|
||||
Effect tempEffect = effect.copy();
|
||||
|
||||
for (EffectModifier modifier : gears.effectModifiers()) {
|
||||
for (TriConsumer<Effect, Context<Player>, Integer> consumer : modifier.modifiers()) {
|
||||
consumer.accept(tempEffect, context, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// get the next loot
|
||||
Loot loot = BukkitCustomFishingPlugin.getInstance().getLootManager().getNextLoot(effect, context);
|
||||
if (loot == null) {
|
||||
// TODO warn
|
||||
BukkitCustomFishingPlugin.getInstance().debug("No loot available for player " + context.getHolder().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
this.nextLoot = loot;
|
||||
BukkitCustomFishingPlugin.getInstance().debug("Next loot: " + loot.id());
|
||||
// get its basic properties
|
||||
Effect baseEffect = loot.baseEffect().toEffect(context);
|
||||
tempEffect.combine(baseEffect);
|
||||
|
||||
// apply the gears' effects
|
||||
for (EffectModifier modifier : gears.effectModifiers()) {
|
||||
for (TriConsumer<Effect, Context<Player>, Integer> consumer : modifier.modifiers()) {
|
||||
consumer.accept(tempEffect, context, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// start the mechanic
|
||||
mechanic.start(tempEffect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}, 1, 1, hook.getLocation());
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
public void destroy() {
|
||||
task.cancel();
|
||||
if (hook.isValid()) hook.remove();
|
||||
if (hookMechanic != null) hookMechanic.destroy();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FishHook getHookEntity() {
|
||||
return hook;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public HookMechanic getCurrentHookMechanic() {
|
||||
return hookMechanic;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Loot getNextLoot() {
|
||||
return nextLoot;
|
||||
}
|
||||
|
||||
public void onReelIn() {
|
||||
if (hookMechanic != null) {
|
||||
if (!hookMechanic.isHooked()) {
|
||||
destroy();
|
||||
System.out.println("fail");
|
||||
} else {
|
||||
System.out.println("succeed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBite() {
|
||||
gears.bite();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,16 @@ import java.util.function.Consumer;
|
||||
|
||||
public class FishingGears {
|
||||
|
||||
private static BiConsumer<Context<Player>, FishingGears> fishingGearsGetter = defaultFishingGearsGetter();
|
||||
private static BiConsumer<Context<Player>, FishingGears> fishingGearsConsumers = defaultFishingGearsConsumers();
|
||||
private final HashMap<GearType, Collection<ItemStack>> gears = new HashMap<>();
|
||||
private final ArrayList<EffectModifier> modifiers = new ArrayList<>();
|
||||
|
||||
public static void fishingGearsGetter(BiConsumer<Context<Player>, FishingGears> fishingGearsGetter) {
|
||||
FishingGears.fishingGearsGetter = fishingGearsGetter;
|
||||
public static void fishingGearsConsumers(BiConsumer<Context<Player>, FishingGears> fishingGearsConsumers) {
|
||||
FishingGears.fishingGearsConsumers = fishingGearsConsumers;
|
||||
}
|
||||
|
||||
public FishingGears(Context<Player> context) {
|
||||
fishingGearsGetter.accept(context, this);
|
||||
fishingGearsConsumers.accept(context, this);
|
||||
}
|
||||
|
||||
public void cast() {
|
||||
@@ -40,6 +40,38 @@ public class FishingGears {
|
||||
}
|
||||
}
|
||||
|
||||
public void reel() {
|
||||
for (Map.Entry<GearType, Collection<ItemStack>> entry : gears.entrySet()) {
|
||||
for (ItemStack itemStack : entry.getValue()) {
|
||||
entry.getKey().reelFunction.accept(itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void succeed() {
|
||||
for (Map.Entry<GearType, Collection<ItemStack>> entry : gears.entrySet()) {
|
||||
for (ItemStack itemStack : entry.getValue()) {
|
||||
entry.getKey().successFunction.accept(itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fail() {
|
||||
for (Map.Entry<GearType, Collection<ItemStack>> entry : gears.entrySet()) {
|
||||
for (ItemStack itemStack : entry.getValue()) {
|
||||
entry.getKey().failureFunction.accept(itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void bite() {
|
||||
for (Map.Entry<GearType, Collection<ItemStack>> entry : gears.entrySet()) {
|
||||
for (ItemStack itemStack : entry.getValue()) {
|
||||
entry.getKey().biteFunction.accept(itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<EffectModifier> effectModifiers() {
|
||||
return modifiers;
|
||||
@@ -50,7 +82,7 @@ public class FishingGears {
|
||||
return gears.getOrDefault(type, List.of());
|
||||
}
|
||||
|
||||
public static BiConsumer<Context<Player>, FishingGears> defaultFishingGearsGetter() {
|
||||
public static BiConsumer<Context<Player>, FishingGears> defaultFishingGearsConsumers() {
|
||||
return (context, fishingGears) -> {
|
||||
Player player = context.getHolder();
|
||||
PlayerInventory playerInventory = player.getInventory();
|
||||
@@ -120,37 +152,43 @@ public class FishingGears {
|
||||
public static final GearType ROD = new GearType("rod",
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> BukkitCustomFishingPlugin.getInstance().getItemManager().decreaseDurability(itemStack)),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> BukkitCustomFishingPlugin.getInstance().getItemManager().decreaseDurability(itemStack, 1, false)),
|
||||
(itemStack -> {}));
|
||||
|
||||
public static final GearType BAIT = new GearType("bait",
|
||||
(itemStack -> itemStack.setAmount(itemStack.getAmount() - 1)),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}));
|
||||
|
||||
public static final GearType HOOK = new GearType("hook",
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}));
|
||||
|
||||
public static final GearType UTIL = new GearType("util",
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}),
|
||||
(itemStack -> {}));
|
||||
|
||||
private final String type;
|
||||
private Consumer<ItemStack> castFunction;
|
||||
private Consumer<ItemStack> reelFunction;
|
||||
private Consumer<ItemStack> biteFunction;
|
||||
private Consumer<ItemStack> successFunction;
|
||||
private Consumer<ItemStack> failureFunction;
|
||||
|
||||
public GearType(String type, Consumer<ItemStack> castFunction, Consumer<ItemStack> reelFunction, Consumer<ItemStack> successFunction, Consumer<ItemStack> failureFunction) {
|
||||
public GearType(String type, Consumer<ItemStack> castFunction, Consumer<ItemStack> reelFunction, Consumer<ItemStack> biteFunction, Consumer<ItemStack> successFunction, Consumer<ItemStack> failureFunction) {
|
||||
this.type = type;
|
||||
this.castFunction = castFunction;
|
||||
this.reelFunction = reelFunction;
|
||||
this.biteFunction = biteFunction;
|
||||
this.successFunction = successFunction;
|
||||
this.failureFunction = failureFunction;
|
||||
}
|
||||
@@ -163,6 +201,10 @@ public class FishingGears {
|
||||
this.reelFunction = reelFunction;
|
||||
}
|
||||
|
||||
public void biteFunction(Consumer<ItemStack> biteFunction) {
|
||||
this.biteFunction = biteFunction;
|
||||
}
|
||||
|
||||
public void successFunction(Consumer<ItemStack> successFunction) {
|
||||
this.successFunction = successFunction;
|
||||
}
|
||||
@@ -183,5 +225,10 @@ public class FishingGears {
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
|
||||
package net.momirealms.customfishing.api.mechanic.fishing;
|
||||
|
||||
import net.momirealms.customfishing.common.plugin.feature.Reloadable;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface FishingManager {
|
||||
public interface FishingManager extends Reloadable {
|
||||
|
||||
Optional<CustomFishingHook> getFishHook(Player player);
|
||||
|
||||
Optional<FishHook> getFishHook(Player player);
|
||||
|
||||
Optional<FishHook> getFishHook(UUID player);
|
||||
Optional<CustomFishingHook> getFishHook(UUID player);
|
||||
|
||||
Optional<Player> getOwner(FishHook hook);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.momirealms.customfishing.api.mechanic.fishing.hook;
|
||||
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import org.bukkit.entity.FishHook;
|
||||
|
||||
public interface HookMechanic
|
||||
{
|
||||
|
||||
@@ -1,6 +1,49 @@
|
||||
package net.momirealms.customfishing.api.mechanic.fishing.hook;
|
||||
|
||||
public class LavaFishingMechanic {
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class LavaFishingMechanic implements HookMechanic {
|
||||
|
||||
private final FishHook hook;
|
||||
private final Effect gearsEffect;
|
||||
private final Context<Player> context;
|
||||
|
||||
public LavaFishingMechanic(FishHook hook, Effect gearsEffect, Context<Player> context) {
|
||||
this.hook = hook;
|
||||
this.gearsEffect = gearsEffect;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart() {
|
||||
if (!(boolean) gearsEffect.properties().getOrDefault(EffectProperties.LAVA_FISHING, false)) {
|
||||
return false;
|
||||
}
|
||||
return hook.getLocation().getY() <= hook.getWorld().getMinHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStart() {
|
||||
this.context.arg(ContextKeys.SURROUNDING, EffectProperties.LAVA_FISHING.key());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Effect finalEffect) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHooked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,72 @@
|
||||
package net.momirealms.customfishing.api.mechanic.fishing.hook;
|
||||
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
|
||||
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask;
|
||||
import net.momirealms.sparrow.heart.SparrowHeart;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class VanillaMechanic implements HookMechanic {
|
||||
|
||||
private final FishHook hook;
|
||||
private final Context<Player> context;
|
||||
private SchedulerTask task;
|
||||
private boolean isHooked = false;
|
||||
|
||||
public VanillaMechanic(FishHook hook, Context<Player> context) {
|
||||
this.hook = hook;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart() {
|
||||
return false;
|
||||
return hook.isInWater();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preStart() {
|
||||
|
||||
this.context.arg(ContextKeys.SURROUNDING, EffectProperties.WATER_FISHING.key());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Effect finalEffect) {
|
||||
setWaitTime(hook, finalEffect);
|
||||
this.task = BukkitCustomFishingPlugin.getInstance().getScheduler().sync().runRepeating(() -> {
|
||||
if (isHooked) {
|
||||
if (!isHooked()) {
|
||||
isHooked = false;
|
||||
setWaitTime(hook, finalEffect);
|
||||
}
|
||||
} else {
|
||||
if (isHooked()) {
|
||||
isHooked = true;
|
||||
}
|
||||
}
|
||||
}, 1, 1, hook.getLocation());
|
||||
}
|
||||
|
||||
private void setWaitTime(FishHook hook, Effect effect) {
|
||||
BukkitCustomFishingPlugin.getInstance().getScheduler().sync().runLater(() -> {
|
||||
int before = hook.getWaitTime();
|
||||
int after = (int) Math.max(1, before * effect.waitTimeMultiplier() + effect.waitTimeAdder());
|
||||
BukkitCustomFishingPlugin.getInstance().debug("Wait time: " + before + " -> " + after + " ticks");
|
||||
hook.setWaitTime(after);
|
||||
}, 1, hook.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHooked() {
|
||||
return false;
|
||||
return SparrowHeart.getInstance().isFishingHookBit(hook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
if (this.task != null) this.task.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
|
||||
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface ItemManager extends Reloadable {
|
||||
@Nullable
|
||||
Item dropItemLoot(@NotNull Context<Player> context);
|
||||
|
||||
void decreaseDurability(ItemStack itemStack);
|
||||
void decreaseDurability(ItemStack itemStack, int amount, boolean incorrectUsage);
|
||||
|
||||
ItemFactory<CustomFishingPlugin, RtagItem, ItemStack> getFactory();
|
||||
|
||||
|
||||
@@ -62,9 +62,13 @@ public class MechanicType {
|
||||
return Objects.equals(type, mechanicType.type);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,5 @@ public interface LootManager extends Reloadable {
|
||||
Map<String, Double> getWeightedLoots(Context<Player> context);
|
||||
|
||||
@Nullable
|
||||
Loot
|
||||
getNextLoot(Effect effect, Context<Player> context);
|
||||
Loot getNextLoot(Effect effect, Context<Player> context);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.momirealms.customfishing.api.mechanic.requirement;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ConditionalElement<E, T> {
|
||||
|
||||
private final E element;
|
||||
private final Map<String, ConditionalElement<E, T>> subElements;
|
||||
private final Requirement<T>[] requirements;
|
||||
|
||||
public ConditionalElement(E element, Map<String, ConditionalElement<E, T>> subElements, Requirement<T>[] requirements) {
|
||||
this.element = element;
|
||||
this.subElements = subElements;
|
||||
this.requirements = requirements;
|
||||
}
|
||||
|
||||
public E getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public Requirement<T>[] getRequirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
public Map<String, ConditionalElement<E, T>> getSubElements() {
|
||||
return subElements;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public interface RequirementManager<T> extends Reloadable {
|
||||
* @return An array of Requirement objects based on the configuration section.
|
||||
*/
|
||||
@NotNull
|
||||
Requirement<T>[] parseRequirements(@NotNull Section section, boolean runActions);
|
||||
Requirement<T>[] parseRequirements(Section section, boolean runActions);
|
||||
|
||||
/**
|
||||
* Retrieves a Requirement object based on a configuration section and advanced flag.
|
||||
|
||||
@@ -15,7 +15,6 @@ subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://jitpack.io/") // sparrow-heart, rtag
|
||||
maven("https://repo.xenondevs.xyz/releases") // invui
|
||||
maven("https://papermc.io/repo/repository/maven-public/") // paper
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") // spigot
|
||||
|
||||
@@ -102,6 +102,10 @@ public class VersionHelper {
|
||||
return version >= 20.0;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_20_5() {
|
||||
return version >= 20.5;
|
||||
}
|
||||
|
||||
public boolean isNewerThan1_20_5() {
|
||||
return version >= 20.5;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,17 @@ public class AbstractItem<R, I> implements Item<I> {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> damage(Integer data) {
|
||||
factory.damage(item, data);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> damage() {
|
||||
return factory.damage(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> customModelData(Integer data) {
|
||||
factory.customModelData(item, data);
|
||||
|
||||
@@ -9,6 +9,10 @@ public interface Item<I> {
|
||||
|
||||
Optional<Integer> customModelData();
|
||||
|
||||
Item<I> damage(Integer data);
|
||||
|
||||
Optional<Integer> damage();
|
||||
|
||||
Item<I> displayName(String displayName);
|
||||
|
||||
Optional<String> displayName();
|
||||
|
||||
@@ -56,4 +56,8 @@ public abstract class ItemFactory<P extends CustomFishingPlugin, R, I> {
|
||||
protected abstract Optional<Boolean> glint(R item);
|
||||
|
||||
protected abstract void glint(R item, Boolean glint);
|
||||
|
||||
protected abstract Optional<Integer> damage(R item);
|
||||
|
||||
protected abstract void damage(R item, Integer damage);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.momirealms.customfishing.common.util;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface TriFunction<T, U, V, R> {
|
||||
R apply(T var1, U var2, V var3);
|
||||
|
||||
default <W> TriFunction<T, U, V, W> andThen(Function<? super R, ? extends W> after) {
|
||||
Objects.requireNonNull(after);
|
||||
return (t, u, v) -> {
|
||||
return after.apply(this.apply(t, u, v));
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,11 @@ import java.util.Map;
|
||||
/**
|
||||
* Utility class for selecting random items based on weights.
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class WeightUtils {
|
||||
|
||||
private WeightUtils() {}
|
||||
|
||||
/**
|
||||
* Get a random item from a list of pairs, each associated with a weight.
|
||||
*
|
||||
|
||||
@@ -9,6 +9,7 @@ repositories {
|
||||
maven("https://repo.auxilor.io/repository/maven-public/") // eco
|
||||
maven("https://nexus.betonquest.org/repository/betonquest/") // betonquest
|
||||
maven("https://repo.dmulloy2.net/repository/public/") // betonquest needs packet wrapper?
|
||||
maven("https://maven.enginehub.org/repo/") // worldguard
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -38,9 +38,11 @@ public class CustomFishingItemProvider implements ItemProvider {
|
||||
public ItemStack buildItem(@NotNull Player player, @NotNull String id) {
|
||||
String[] split = id.split(":", 2);
|
||||
String finalID;
|
||||
if (split.length != 2) {
|
||||
if (split.length == 1) {
|
||||
// CustomFishing:ID
|
||||
finalID = split[0];
|
||||
} else {
|
||||
// CustomFishing:TYPE:ID
|
||||
finalID = split[1];
|
||||
}
|
||||
ItemStack itemStack = BukkitCustomFishingPlugin.getInstance().getItemManager().buildInternal(Context.player(player), finalID);
|
||||
|
||||
@@ -4,6 +4,10 @@ plugins {
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://repo.xenondevs.xyz/releases") // invui
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// platform
|
||||
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
|
||||
|
||||
BIN
core/libs/Sparrow-Heart-0.19.jar
Normal file
BIN
core/libs/Sparrow-Heart-0.19.jar
Normal file
Binary file not shown.
@@ -14,6 +14,7 @@ import net.momirealms.customfishing.bukkit.config.BukkitConfigManager;
|
||||
import net.momirealms.customfishing.bukkit.effect.BukkitEffectManager;
|
||||
import net.momirealms.customfishing.bukkit.entity.BukkitEntityManager;
|
||||
import net.momirealms.customfishing.bukkit.event.BukkitEventManager;
|
||||
import net.momirealms.customfishing.bukkit.fishing.BukkitFishingManager;
|
||||
import net.momirealms.customfishing.bukkit.gui.ChatCatcherManager;
|
||||
import net.momirealms.customfishing.bukkit.hook.BukkitHookManager;
|
||||
import net.momirealms.customfishing.bukkit.integration.BukkitIntegrationManager;
|
||||
@@ -59,7 +60,6 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
|
||||
this.classPathAppender = new ReflectionClassPathAppender(this);
|
||||
this.logger = new JavaPluginLogger(getBoostrap().getLogger());
|
||||
this.dependencyManager = new DependencyManagerImpl(this);
|
||||
this.debugger = (s) -> {};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,6 +104,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
|
||||
this.statisticsManager = new BukkitStatisticsManager(this);
|
||||
this.effectManager = new BukkitEffectManager(this);
|
||||
this.hookManager = new BukkitHookManager(this);
|
||||
this.fishingManager = new BukkitFishingManager(this);
|
||||
this.bagManager = new BukkitBagManager(this);
|
||||
this.totemManager = new BukkitTotemManager(this);
|
||||
this.translationManager = new TranslationManager(this);
|
||||
@@ -138,7 +139,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
|
||||
this.placeholderManager.reload();
|
||||
this.configManager.reload();
|
||||
// after ConfigManager
|
||||
this.debugger = ConfigManager.debug() ? logger::info : (s) -> {};
|
||||
this.debugger = ConfigManager.debug() ? (s) -> logger.info("[DEBUG] " + s) : (s) -> {};
|
||||
|
||||
this.actionManager.reload();
|
||||
this.requirementManager.reload();
|
||||
@@ -149,6 +150,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
|
||||
this.statisticsManager.reload();
|
||||
this.bagManager.reload();
|
||||
this.storageManager.reload();
|
||||
this.fishingManager.reload();
|
||||
|
||||
this.itemManager.load();
|
||||
this.eventManager.load();
|
||||
|
||||
@@ -21,6 +21,8 @@ import net.momirealms.customfishing.common.util.ClassUtils;
|
||||
import net.momirealms.customfishing.common.util.ListUtils;
|
||||
import net.momirealms.customfishing.common.util.Pair;
|
||||
import net.momirealms.customfishing.common.util.RandomUtils;
|
||||
import net.momirealms.sparrow.heart.SparrowHeart;
|
||||
import net.momirealms.sparrow.heart.feature.armorstand.FakeArmorStand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -51,7 +53,6 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
public BukkitActionManager(BukkitCustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.registerBuiltInActions();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,6 +90,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
|
||||
@Override
|
||||
public Action<Player> parseAction(Section section) {
|
||||
if (section == null) return EmptyAction.INSTANCE;
|
||||
ActionFactory<Player> factory = getActionFactory(section.getString("type"));
|
||||
if (factory == null) {
|
||||
plugin.getPluginLogger().warn("Action type: " + section.getString("type") + " doesn't exist.");
|
||||
@@ -100,15 +102,16 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Action<Player>[] parseActions(@NotNull Section section) {
|
||||
public Action<Player>[] parseActions(Section section) {
|
||||
ArrayList<Action<Player>> actionList = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof Section innerSection) {
|
||||
Action<Player> action = parseAction(innerSection);
|
||||
if (action != null)
|
||||
actionList.add(action);
|
||||
if (section != null)
|
||||
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof Section innerSection) {
|
||||
Action<Player> action = parseAction(innerSection);
|
||||
if (action != null)
|
||||
actionList.add(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
return actionList.toArray(new Action[0]);
|
||||
}
|
||||
|
||||
@@ -136,6 +139,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
this.registerFishFindAction();
|
||||
this.registerPluginExpAction();
|
||||
this.registerSoundAction();
|
||||
this.registerHologramAction();
|
||||
this.registerTitleAction();
|
||||
}
|
||||
|
||||
@@ -390,7 +394,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
itemStack.setAmount(Math.max(0, itemStack.getAmount() + amount));
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at item-amount action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at item-amount action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -409,7 +413,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
// }
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at durability action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at durability action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -432,7 +436,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
}
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at give-item action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at give-item action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -543,7 +547,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
}
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at conditional action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at conditional action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -575,7 +579,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
}
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at priority action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at priority action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -611,7 +615,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
context.getHolder().addPotionEffect(potionEffect);
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at potion-effect action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at potion-effect action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -632,7 +636,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
AdventureHelper.playSound(audience, sound);
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at sound action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at sound action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -652,7 +656,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
}, () -> plugin.getPluginLogger().warn("Plugin (" + pluginName + "'s) level is not compatible. Please double check if it's a problem caused by pronunciation."));
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-exp action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-exp action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -677,7 +681,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
);
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -703,7 +707,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
);
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at random-title action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at random-title action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -735,12 +739,61 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
);
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title-nearby action which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title-nearby action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerHologramAction() {
|
||||
registerAction("hologram", ((args, chance) -> {
|
||||
if (args instanceof Section section) {
|
||||
TextValue<Player> text = TextValue.auto(section.getString("text", ""));
|
||||
MathValue<Player> duration = MathValue.auto(section.get("duration", 20));
|
||||
boolean position = section.getString("position", "other").equals("other");
|
||||
MathValue<Player> x = MathValue.auto(section.get("x", 0));
|
||||
MathValue<Player> y = MathValue.auto(section.get("y", 0));
|
||||
MathValue<Player> z = MathValue.auto(section.get("z", 0));
|
||||
int range = section.getInt("range", 16);
|
||||
return context -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player owner = context.getHolder();
|
||||
|
||||
Location location = position ? requireNonNull(context.arg(ContextKeys.LOCATION)).clone() : owner.getLocation().clone();
|
||||
location.add(x.evaluate(context), y.evaluate(context), z.evaluate(context));
|
||||
FakeArmorStand armorStand = SparrowHeart.getInstance().createFakeArmorStand(location);
|
||||
armorStand.invisible(true);
|
||||
armorStand.small(true);
|
||||
armorStand.name(AdventureHelper.miniMessageToJson(text.render(context)));
|
||||
ArrayList<Player> viewers = new ArrayList<>();
|
||||
if (range > 0) {
|
||||
for (Entity player : location.getWorld().getNearbyEntities(location, range, range, range, entity -> entity instanceof Player)) {
|
||||
double distance = LocationUtils.getDistance(player.getLocation(), location);
|
||||
if (distance <= range) {
|
||||
viewers.add((Player) player);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
viewers.add(owner);
|
||||
}
|
||||
for (Player player : viewers) {
|
||||
armorStand.spawn(player);
|
||||
}
|
||||
plugin.getScheduler().asyncLater(() -> {
|
||||
for (Player player : viewers) {
|
||||
if (player.isOnline() && player.isValid()) {
|
||||
armorStand.destroy(player);
|
||||
}
|
||||
}
|
||||
}, (long) (duration.evaluate(context) * 50), TimeUnit.MILLISECONDS);
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at hologram action which is expected to be `Section`");
|
||||
return EmptyAction.INSTANCE;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void registerFishFindAction() {
|
||||
registerAction("fish-finder", (args, chance) -> {
|
||||
return context -> {
|
||||
|
||||
@@ -20,6 +20,7 @@ package net.momirealms.customfishing.bukkit.block;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.integration.BlockProvider;
|
||||
import net.momirealms.customfishing.api.integration.ExternalProvider;
|
||||
import net.momirealms.customfishing.api.mechanic.block.*;
|
||||
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
@@ -92,6 +93,11 @@ public class BukkitBlockManager implements BlockManager, Listener {
|
||||
public void load() {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
|
||||
this.resetBlockDetectionOrder();
|
||||
for (BlockProvider provider : blockProviders.values()) {
|
||||
plugin.debug("Registered BlockProvider: " + provider.identifier());
|
||||
}
|
||||
plugin.debug("Loaded " + blocks.size() + " blocks");
|
||||
plugin.debug("Block order: " + Arrays.toString(Arrays.stream(blockDetectArray).map(ExternalProvider::identifier).toList().toArray(new String[0])));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -67,6 +67,7 @@ public class BukkitCompetitionManager implements CompetitionManager {
|
||||
1,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
plugin.debug("Loaded " + commandConfigMap.size() + " competitions");
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
|
||||
@@ -383,7 +383,8 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
}
|
||||
}
|
||||
|
||||
private List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops) {
|
||||
@Override
|
||||
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops) {
|
||||
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> result = new ArrayList<>();
|
||||
for (String op : ops) {
|
||||
String[] split = op.split(":", 2);
|
||||
@@ -392,7 +393,8 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops) {
|
||||
@Override
|
||||
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops) {
|
||||
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> result = new ArrayList<>();
|
||||
for (String gop : gops) {
|
||||
String[] split = gop.split(":", 2);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class BukkitEffectManager implements EffectManager {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
|
||||
plugin.debug("Loaded " + effectModifiers.size() + " effects");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,6 +59,14 @@ public class BukkitEntityManager implements EntityManager {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (EntityProvider provider : entityProviders.values()) {
|
||||
plugin.debug("Registered EntityProvider: " + provider.identifier());
|
||||
}
|
||||
plugin.debug("Loaded " + entities.size() + " entities");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
this.entities.clear();
|
||||
|
||||
@@ -4,43 +4,61 @@ import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.event.RodCastEvent;
|
||||
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.hook.VanillaMechanic;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
|
||||
import net.momirealms.customfishing.bukkit.util.EventUtils;
|
||||
import net.momirealms.customfishing.common.helper.VersionHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BukkitFishingManager implements FishingManager, Listener {
|
||||
|
||||
private BukkitCustomFishingPlugin plugin;
|
||||
private final ConcurrentHashMap<UUID, FishHook> castHooks = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<UUID, FishingGears> gears = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<UUID, CustomFishingHook> tasks = new ConcurrentHashMap<>();
|
||||
private final BukkitCustomFishingPlugin plugin;
|
||||
private final ConcurrentHashMap<UUID, CustomFishingHook> castHooks = new ConcurrentHashMap<>();
|
||||
|
||||
public BukkitFishingManager(BukkitCustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<FishHook> getFishHook(Player player) {
|
||||
return Optional.ofNullable(castHooks.get(player.getUniqueId()));
|
||||
public void unload() {
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<FishHook> getFishHook(UUID player) {
|
||||
public void load() {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CustomFishingHook> getFishHook(Player player) {
|
||||
return getFishHook(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CustomFishingHook> getFishHook(UUID player) {
|
||||
return Optional.ofNullable(castHooks.get(player));
|
||||
}
|
||||
|
||||
@@ -105,46 +123,87 @@ public class BukkitFishingManager implements FishingManager, Listener {
|
||||
private void selectState(PlayerFishEvent event) {
|
||||
switch (event.getState()) {
|
||||
case FISHING -> onCastRod(event);
|
||||
// case REEL_IN -> onReelIn(event);
|
||||
// case CAUGHT_ENTITY -> onCaughtEntity(event);
|
||||
// case CAUGHT_FISH -> onCaughtFish(event);
|
||||
// case BITE -> onBite(event);
|
||||
// case IN_GROUND -> onInGround(event);
|
||||
case REEL_IN -> onReelIn(event);
|
||||
case CAUGHT_ENTITY -> onCaughtEntity(event);
|
||||
case CAUGHT_FISH -> onCaughtFish(event);
|
||||
case BITE -> onBite(event);
|
||||
case IN_GROUND -> onInGround(event);
|
||||
}
|
||||
}
|
||||
|
||||
private void onCaughtEntity(PlayerFishEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
getFishHook(player).ifPresent(hook -> {
|
||||
Entity entity = event.getCaught();
|
||||
if (entity != null && entity.getPersistentDataContainer().get(
|
||||
Objects.requireNonNull(NamespacedKey.fromString("temp-entity", plugin.getBoostrap())),
|
||||
PersistentDataType.STRING
|
||||
) != null) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onReelIn(PlayerFishEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
getFishHook(player).ifPresent(hook -> {
|
||||
hook.onReelIn();
|
||||
});
|
||||
}
|
||||
|
||||
private void onBite(PlayerFishEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
getFishHook(player).ifPresent(hook -> {
|
||||
hook.onBite();
|
||||
});
|
||||
}
|
||||
|
||||
private void onCaughtFish(PlayerFishEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
getFishHook(player).ifPresent(hook -> {
|
||||
hook.onReelIn();
|
||||
});
|
||||
}
|
||||
|
||||
private void onCastRod(PlayerFishEvent event) {
|
||||
FishHook hook = event.getHook();
|
||||
Player player = event.getPlayer();
|
||||
Context<Player> context = Context.player(player);
|
||||
FishingGears gears = new FishingGears(context);
|
||||
this.gears.put(player.getUniqueId(), gears);
|
||||
|
||||
if (!RequirementManager.isSatisfied(context, ConfigManager.mechanicRequirements())) {
|
||||
this.destroy(player.getUniqueId());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
RodCastEvent rodCastEvent = new RodCastEvent(event, gears);
|
||||
Bukkit.getPluginManager().callEvent(rodCastEvent);
|
||||
if (rodCastEvent.isCancelled()) {
|
||||
if (EventUtils.fireAndCheckCancel(new RodCastEvent(event, gears))) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.debug(context.toString());
|
||||
gears.cast();
|
||||
this.castHooks.put(player.getUniqueId(), hook);
|
||||
CustomFishingHook customHook = new CustomFishingHook(hook, gears, context);
|
||||
this.castHooks.put(player.getUniqueId(), customHook);
|
||||
}
|
||||
|
||||
private void onInGround(PlayerFishEvent event) {
|
||||
if (VersionHelper.isVersionNewerThan1_20_5()) return;
|
||||
final Player player = event.getPlayer();
|
||||
if (player.getGameMode() != GameMode.CREATIVE) {
|
||||
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
||||
if (itemStack.getType() != Material.FISHING_ROD) itemStack = player.getInventory().getItemInOffHand();
|
||||
if (itemStack.getType() == Material.FISHING_ROD) {
|
||||
plugin.getItemManager().decreaseDurability(itemStack, 5, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(UUID uuid) {
|
||||
this.getFishHook(uuid).ifPresent(hook -> {
|
||||
hook.remove();
|
||||
hook.destroy();
|
||||
this.castHooks.remove(uuid);
|
||||
});
|
||||
this.gears.remove(uuid);
|
||||
CustomFishingHook task = this.tasks.remove(uuid);
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public class BukkitHookManager implements HookManager, Listener {
|
||||
@Override
|
||||
public void load() {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
|
||||
plugin.debug("Loaded " + hooks.size() + " hooks");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.momirealms.customfishing.bukkit.item;
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.event.FishingLootPreSpawnEvent;
|
||||
import net.momirealms.customfishing.api.event.FishingLootSpawnEvent;
|
||||
import net.momirealms.customfishing.api.integration.ExternalProvider;
|
||||
import net.momirealms.customfishing.api.integration.ItemProvider;
|
||||
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
@@ -10,6 +11,7 @@ import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
|
||||
import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem;
|
||||
import net.momirealms.customfishing.api.mechanic.item.ItemManager;
|
||||
import net.momirealms.customfishing.api.mechanic.item.MechanicType;
|
||||
import net.momirealms.customfishing.bukkit.integration.item.CustomFishingItemProvider;
|
||||
import net.momirealms.customfishing.bukkit.util.ItemUtils;
|
||||
import net.momirealms.customfishing.bukkit.util.LocationUtils;
|
||||
import net.momirealms.customfishing.common.item.Item;
|
||||
@@ -67,6 +69,7 @@ public class BukkitItemManager implements ItemManager, Listener {
|
||||
return "vanilla";
|
||||
}
|
||||
});
|
||||
this.registerItemProvider(new CustomFishingItemProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,6 +82,11 @@ public class BukkitItemManager implements ItemManager, Listener {
|
||||
public void load() {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
|
||||
this.resetItemDetectionOrder();
|
||||
for (ItemProvider provider : itemProviders.values()) {
|
||||
plugin.debug("Registered ItemProvider: " + provider.identifier());
|
||||
}
|
||||
plugin.debug("Loaded " + items.size() + " items");
|
||||
plugin.debug("Item order: " + Arrays.toString(Arrays.stream(itemDetectArray).map(ExternalProvider::identifier).toList().toArray(new String[0])));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,7 +228,7 @@ public class BukkitItemManager implements ItemManager, Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decreaseDurability(ItemStack itemStack) {
|
||||
public void decreaseDurability(ItemStack itemStack, int amount, boolean incorrectUsage) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -93,21 +93,38 @@ public class ComponentItemFactory extends BukkitItemFactory {
|
||||
|
||||
@Override
|
||||
protected boolean unbreakable(RtagItem item) {
|
||||
return false;
|
||||
return item.isUnbreakable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unbreakable(RtagItem item, boolean unbreakable) {
|
||||
|
||||
item.setUnbreakable(unbreakable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Boolean> glint(RtagItem item) {
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable((Boolean) item.getComponent(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void glint(RtagItem item, Boolean glint) {
|
||||
item.setComponent(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE, glint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> damage(RtagItem item) {
|
||||
if (!item.hasComponent(ComponentKeys.DAMAGE)) return Optional.empty();
|
||||
return Optional.ofNullable(
|
||||
(Integer) ComponentType.encodeJava(
|
||||
ComponentKeys.DAMAGE,
|
||||
item.getComponent(ComponentKeys.DAMAGE)
|
||||
).orElse(null)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void damage(RtagItem item, Integer damage) {
|
||||
if (damage == null) damage = 0;
|
||||
item.setComponent(ComponentKeys.DAMAGE, damage);
|
||||
}
|
||||
}
|
||||
@@ -70,21 +70,32 @@ public class UniversalItemFactory extends BukkitItemFactory {
|
||||
|
||||
@Override
|
||||
protected boolean unbreakable(RtagItem item) {
|
||||
return false;
|
||||
return item.isUnbreakable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unbreakable(RtagItem item, boolean unbreakable) {
|
||||
|
||||
item.setUnbreakable(unbreakable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Boolean> glint(RtagItem item) {
|
||||
return Optional.empty();
|
||||
return Optional.of(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void glint(RtagItem item, Boolean glint) {
|
||||
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> damage(RtagItem item) {
|
||||
if (!item.hasTag("Damage")) return Optional.empty();
|
||||
return Optional.of(item.get("Damage"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void damage(RtagItem item, Integer damage) {
|
||||
item.set(damage, "Damage");
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,30 @@
|
||||
package net.momirealms.customfishing.bukkit.loot;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.Loot;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.LootManager;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
|
||||
import net.momirealms.customfishing.common.util.Pair;
|
||||
import net.momirealms.customfishing.common.util.WeightUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class BukkitLootManager implements LootManager {
|
||||
|
||||
private final BukkitCustomFishingPlugin plugin;
|
||||
private final HashMap<String, Loot> lootMap = new HashMap<>();
|
||||
private final HashMap<String, List<String>> groupMembersMap = new HashMap<>();
|
||||
private final LinkedHashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> lootConditions = new LinkedHashMap<>();
|
||||
|
||||
public BukkitLootManager(BukkitCustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -28,11 +34,48 @@ public class BukkitLootManager implements LootManager {
|
||||
public void unload() {
|
||||
this.lootMap.clear();
|
||||
this.groupMembersMap.clear();
|
||||
this.lootConditions.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
plugin.debug("Loaded " + lootMap.size() + " loots");
|
||||
for (Map.Entry<String, List<String>> entry : groupMembersMap.entrySet()) {
|
||||
plugin.debug("Group: {" + entry.getKey() + "} Members: " + entry.getValue());
|
||||
}
|
||||
File file = new File(plugin.getDataFolder(), "loot-conditions.yml");
|
||||
if (!file.exists()) {
|
||||
plugin.getBoostrap().saveResource("loot-conditions.yml", false);
|
||||
}
|
||||
YamlDocument lootConditionsConfig = plugin.getConfigManager().loadData(file);
|
||||
for (Map.Entry<String, Object> entry : lootConditionsConfig.getStringRouteMappedValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof Section section) {
|
||||
lootConditions.put(entry.getKey(), parseLootConditions(section));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> parseLootConditions(Section section) {
|
||||
Section subSection = section.getSection("sub-groups");
|
||||
if (subSection == null) {
|
||||
return new ConditionalElement<>(
|
||||
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")),
|
||||
Map.of(),
|
||||
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
|
||||
);
|
||||
} else {
|
||||
HashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> subElements = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : subSection.getStringRouteMappedValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof Section innerSection) {
|
||||
subElements.put(entry.getKey(), parseLootConditions(innerSection));
|
||||
}
|
||||
}
|
||||
return new ConditionalElement<>(
|
||||
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")),
|
||||
subElements,
|
||||
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +116,33 @@ public class BukkitLootManager implements LootManager {
|
||||
@Nullable
|
||||
@Override
|
||||
public Loot getNextLoot(Effect effect, Context<Player> context) {
|
||||
return null;
|
||||
HashMap<String, Double> lootWeightMap = new HashMap<>();
|
||||
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement : lootConditions.values()) {
|
||||
modifyWeightMap(lootWeightMap, context, conditionalElement);
|
||||
}
|
||||
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperations()) {
|
||||
double previous = lootWeightMap.getOrDefault(pair.left(), 0d);
|
||||
if (previous > 0)
|
||||
lootWeightMap.put(pair.left(), pair.right().apply(context, previous));
|
||||
}
|
||||
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperationsIgnored()) {
|
||||
double previous = lootWeightMap.getOrDefault(pair.left(), 0d);
|
||||
lootWeightMap.put(pair.left(), pair.right().apply(context, previous));
|
||||
}
|
||||
String lootID = WeightUtils.getRandom(lootWeightMap);
|
||||
return getLoot(lootID).orElseThrow(() -> new RuntimeException("Could not find loot " + lootID));
|
||||
}
|
||||
|
||||
private void modifyWeightMap(Map<String, Double> weightMap, Context<Player> context, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement) {
|
||||
if (conditionalElement == null) return;
|
||||
if (RequirementManager.isSatisfied(context, conditionalElement.getRequirements())) {
|
||||
for (Pair<String, BiFunction<Context<Player>, Double, Double>> modifierPair : conditionalElement.getElement()) {
|
||||
double previous = weightMap.getOrDefault(modifierPair.left(), 0d);
|
||||
weightMap.put(modifierPair.left(), modifierPair.right().apply(context, previous));
|
||||
}
|
||||
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> sub : conditionalElement.getSubElements().values()) {
|
||||
modifyWeightMap(weightMap, context, sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -85,16 +86,17 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Requirement<Player>[] parseRequirements(@NotNull Section section, boolean runActions) {
|
||||
public Requirement<Player>[] parseRequirements(Section section, boolean runActions) {
|
||||
List<Requirement<Player>> requirements = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
|
||||
String typeOrName = entry.getKey();
|
||||
if (hasRequirement(typeOrName)) {
|
||||
requirements.add(parseRequirement(typeOrName, entry.getValue()));
|
||||
} else {
|
||||
requirements.add(parseRequirement(section.getSection(typeOrName), runActions));
|
||||
if (section != null)
|
||||
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
|
||||
String typeOrName = entry.getKey();
|
||||
if (hasRequirement(typeOrName)) {
|
||||
requirements.add(parseRequirement(typeOrName, entry.getValue()));
|
||||
} else {
|
||||
requirements.add(parseRequirement(section.getSection(typeOrName), runActions));
|
||||
}
|
||||
}
|
||||
}
|
||||
return requirements.toArray(new Requirement[0]);
|
||||
}
|
||||
|
||||
@@ -164,6 +166,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
this.registerInBagRequirement();
|
||||
this.registerCompetitionRequirement();
|
||||
this.registerPluginLevelRequirement();
|
||||
this.registerItemInHandRequirement();
|
||||
}
|
||||
|
||||
private void registerCompetitionRequirement() {
|
||||
@@ -191,7 +194,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at competition requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at competition requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -209,6 +212,28 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerItemInHandRequirement() {
|
||||
registerRequirement("item-in-hand", (args, actions, advanced) -> {
|
||||
if (args instanceof Section section) {
|
||||
boolean mainOrOff = section.getString("hand","main").equalsIgnoreCase("main");
|
||||
int amount = section.getInt("amount", 1);
|
||||
List<String> items = ListUtils.toList(section.get("item"));
|
||||
return context -> {
|
||||
ItemStack itemStack = mainOrOff ?
|
||||
context.getHolder().getInventory().getItemInMainHand()
|
||||
: context.getHolder().getInventory().getItemInOffHand();
|
||||
String id = plugin.getItemManager().getItemID(itemStack);
|
||||
if (items.contains(id) && itemStack.getAmount() >= amount) return true;
|
||||
if (advanced) ActionManager.trigger(context, actions);
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at item-in-hand requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPluginLevelRequirement() {
|
||||
registerRequirement("plugin-level", (args, actions, advanced) -> {
|
||||
if (args instanceof Section section) {
|
||||
@@ -227,7 +252,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-level requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-level requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -283,7 +308,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at || requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at || requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -304,7 +329,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at && requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at && requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -335,11 +360,19 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
}
|
||||
|
||||
private void registerInLavaRequirement() {
|
||||
// Deprecated requirement type
|
||||
registerRequirement("lava-fishing", (args, actions, advanced) -> {
|
||||
boolean inLava = (boolean) args;
|
||||
if (!inLava) {
|
||||
throw new IllegalArgumentException("");
|
||||
// in water
|
||||
return context -> {
|
||||
boolean in_water = Optional.ofNullable(context.arg(ContextKeys.SURROUNDING)).orElse("").equals(EffectProperties.WATER_FISHING.key());
|
||||
if (in_water) return true;
|
||||
if (advanced) ActionManager.trigger(context, actions);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
// in lava
|
||||
return context -> {
|
||||
boolean in_lava = Optional.ofNullable(context.arg(ContextKeys.SURROUNDING)).orElse("").equals(EffectProperties.LAVA_FISHING.key());
|
||||
if (in_lava) return true;
|
||||
@@ -768,7 +801,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at cooldown requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at cooldown requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -839,7 +872,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at < requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at < requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -853,7 +886,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at <= requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at <= requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -867,7 +900,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at != requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at != requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -881,7 +914,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at == requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at == requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -895,7 +928,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at >= requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at >= requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -909,7 +942,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at > requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at > requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -923,7 +956,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at regex requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at regex requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -937,7 +970,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at startsWith requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at startsWith requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -951,7 +984,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !startsWith requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !startsWith requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -965,7 +998,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at endsWith requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at endsWith requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -979,7 +1012,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !endsWith requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !endsWith requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -993,7 +1026,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at contains requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at contains requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -1007,7 +1040,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !contains requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !contains requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -1021,7 +1054,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at in-list requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at in-list requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -1035,7 +1068,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !in-list requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !in-list requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -1049,7 +1082,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at equals requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at equals requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
@@ -1063,7 +1096,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !equals requirement which should be Section");
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !equals requirement which is expected be `Section`");
|
||||
return EmptyRequirement.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -37,6 +37,9 @@ public class BukkitStatisticsManager implements StatisticsManager {
|
||||
@Override
|
||||
public void load() {
|
||||
this.loadCategoriesFromPluginFolder();
|
||||
for (Map.Entry<String, List<String>> entry : categoryMap.entrySet()) {
|
||||
plugin.debug("Category: {" + entry.getKey() + "} Members: " + entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -79,6 +79,7 @@ public class BukkitTotemManager implements TotemManager, Listener {
|
||||
activatedTotems.remove(simpleLocation);
|
||||
}
|
||||
}, 1, 1, TimeUnit.SECONDS);
|
||||
plugin.debug("Loaded " + id2Totem.size() + " totems");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.bukkit.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public class EventUtils {
|
||||
|
||||
public static void fireAndForget(Event event) {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
public static boolean fireAndCheckCancel(Event event) {
|
||||
if (!(event instanceof Cancellable cancellable))
|
||||
throw new IllegalArgumentException("Only cancellable events are allowed here");
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return cancellable.isCancelled();
|
||||
}
|
||||
}
|
||||
@@ -350,6 +350,12 @@ mechanics:
|
||||
# Lava fishing settings
|
||||
# To modify vanilla fishing time, you should edit paper-world-defaults.yml where there's a section called fishing-time-range
|
||||
lava-fishing:
|
||||
enable: true
|
||||
# ticks
|
||||
min-wait-time: 100
|
||||
max-wait-time: 600
|
||||
void-fishing:
|
||||
enable: true
|
||||
# ticks
|
||||
min-wait-time: 100
|
||||
max-wait-time: 600
|
||||
|
||||
@@ -16,8 +16,8 @@ jar_relocator_version=1.7
|
||||
h2_driver_version=2.2.224
|
||||
sqlite_driver_version=3.46.0.0
|
||||
adventure_bundle_version=4.17.0
|
||||
adventure_platform_version=4.3.2
|
||||
sparrow_heart_version=0.16
|
||||
adventure_platform_version=4.3.3
|
||||
sparrow_heart_version=0.20
|
||||
cloud_core_version=2.0.0-rc.2
|
||||
cloud_services_version=2.0.0-rc.2
|
||||
cloud_brigadier_version=2.0.0-beta.8
|
||||
@@ -38,8 +38,8 @@ caffeine_version=3.1.8
|
||||
rtag_version=1.5.3
|
||||
jedis_version=5.1.2
|
||||
exp4j_version=0.4.8
|
||||
placeholder_api_version=2.11.5
|
||||
invui_version=1.31
|
||||
placeholder_api_version=2.11.6
|
||||
invui_version=1.32
|
||||
vault_version=1.7
|
||||
guava_version=33.2.0-jre
|
||||
|
||||
|
||||
Reference in New Issue
Block a user