diff --git a/src/main/java/com/alttd/fishingevent/config/Config.java b/src/main/java/com/alttd/fishingevent/config/Config.java index 19f5c5c..103c127 100644 --- a/src/main/java/com/alttd/fishingevent/config/Config.java +++ b/src/main/java/com/alttd/fishingevent/config/Config.java @@ -7,16 +7,17 @@ import com.alttd.fishingevent.npc.NPCType; import com.alttd.fishingevent.npc.types.PrizeNPC; import com.alttd.fishingevent.npc.types.TutorialNPC; import com.alttd.fishingevent.npc.types.UpgradeNPC; +import com.alttd.fishingevent.objects.EnchantmentData; +import com.alttd.fishingevent.objects.EnchantmentTrack; import com.alttd.fishingevent.objects.Prize; import com.alttd.fishingevent.objects.Rarity; import com.alttd.fishingevent.util.Logger; import com.alttd.fishingevent.util.NPCCreateData; import com.alttd.fishingevent.util.Skin; import dev.sergiferry.playernpc.api.NPCLib; -import net.kyori.adventure.inventory.Book; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Material; -import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; @@ -68,25 +69,6 @@ public class Config extends AbstractConfig { } } - public static class UPGRADES { - private static final String prefix = "upgrades."; - public static HashSet ENCHANTMENTS = new HashSet<>(); - - @SuppressWarnings("unused") - private static void load() { - ENCHANTMENTS.clear(); - ENCHANTMENTS.addAll(config.getList(prefix, "enchantments", List.of()).stream().map(enchantment -> { - NamespacedKey namespacedKey = NamespacedKey.fromString(enchantment); - if (namespacedKey == null) { - config.logger.warning("Found invalid enchantment [%]", enchantment); - return null; - } - return Enchantment.getByKey(namespacedKey); - }).collect(Collectors.toSet())); - ENCHANTMENTS.remove(null); - } - } - public static class NPC_DATA { private static final String prefix = "npc."; private static final MiniMessage minimessage = MiniMessage.miniMessage(); @@ -133,10 +115,15 @@ public class Config extends AbstractConfig { NPC npc; switch (type) { case UPGRADE -> { + Optional> upgrades = getUpgrades(npcPrefix); + if (upgrades.isEmpty()) { + config.logger.warning("Unable to create valid upgrades for Upgrade npc: [%]", key); + return; + } npc = new UpgradeNPC( config.logger, npcCreateData, - getUpgrades(npcPrefix) + upgrades.get() ); } case TUTORIAL -> { @@ -167,16 +154,36 @@ public class Config extends AbstractConfig { NPC_MAP.put(key, npc); } - private static List getUpgrades(String npcPrefix) { - ArrayList enchantments = new ArrayList<>(); - List enchants = config.getStringList(npcPrefix, "enchants", List.of(Enchantment.LUCK.toString())); - for (String enchantString : enchants) { - Enchantment enchant = Enchantment.getByName(enchantString); - if (enchant == null) + private static Optional> getUpgrades(String npcPrefix) { + ArrayList enchantmentTracks = new ArrayList<>(); + ConfigurationSection primSection = config.getConfigurationSection(npcPrefix + "enchants"); + if (primSection == null) + return Optional.empty(); + for (String trackKey : primSection.getKeys(false)) { + Int2ObjectOpenHashMap enchantmentDataMap = new Int2ObjectOpenHashMap<>(); + String enchantPrefix = npcPrefix + "enchants." + trackKey + "."; + + ConfigurationSection secSection = config.getConfigurationSection(enchantPrefix + "enchants"); + if (secSection == null) { + config.logger.warning("Invalid section for enchant track [%]", trackKey); continue; - enchantments.add(enchant); + } + for (String enchantmentKey : secSection.getKeys(false)) { + String enchantString = config.getString(enchantPrefix + enchantmentKey + ".", "type", Enchantment.LUCK.getName()); + Enchantment enchantment = Enchantment.getByName(enchantString); + if (enchantment == null) { + config.logger.warning("Found invalid enchant [%]", enchantString); + continue; + } + new EnchantmentData(enchantment, + config.getInt(enchantPrefix + enchantmentKey + ".", "level", 1), + config.getInt(enchantPrefix + enchantmentKey + ".", "price", 1)); + } + enchantmentTracks.add(new EnchantmentTrack(config.getString(enchantPrefix, "internal-name", "ex1"), + MiniMessage.miniMessage().deserialize(config.getString(enchantPrefix, "display-name", "Ex1")), + enchantmentDataMap)); } - return enchantments; + return Optional.of(enchantmentTracks); } private static ItemStack getBook(String npcPrefix) { @@ -219,8 +226,9 @@ public class Config extends AbstractConfig { prizes.add( new Prize(itemStack, - config.getString(prefix, "permission", "example.permission"), - config.getString(prefix, "prize-name", "Prize Name")) + config.getString(prefix, "permission", "example.permission"), + config.getString(prefix, "prize-name", "Prize Name"), + config.getInt(prefix, "prize-price", 1)) ); } return Optional.of(prizes); diff --git a/src/main/java/com/alttd/fishingevent/config/Messages.java b/src/main/java/com/alttd/fishingevent/config/Messages.java index ab336ad..d4b5679 100644 --- a/src/main/java/com/alttd/fishingevent/config/Messages.java +++ b/src/main/java/com/alttd/fishingevent/config/Messages.java @@ -47,11 +47,17 @@ public class Messages extends AbstractConfig { public static class GUI { private static final String prefix = "gui."; - public static String TITLE = "Fishing Event turn in"; + public static String NO_FISHING_ROD = "You need to have a fishing rod to use this NPC"; + public static String UPGRADE_GUI_NAME = "Upgrade GUI"; + public static String PRIZES_GUI_NAME = "Prizes GUI"; + public static String NOT_INITIALIZED = "There was an error initializing this GUI, please contact staff"; @SuppressWarnings("unused") private static void load() { - TITLE = config.getString(prefix, "title", TITLE); + NO_FISHING_ROD = config.getString(prefix, "no-fishing-rod", NO_FISHING_ROD); + UPGRADE_GUI_NAME = config.getString(prefix, "upgrade-gui-name", UPGRADE_GUI_NAME); + PRIZES_GUI_NAME = config.getString(prefix, "prizes-gui-name", PRIZES_GUI_NAME); + NOT_INITIALIZED = config.getString(prefix, "not-initialized", NOT_INITIALIZED); } } @@ -66,10 +72,12 @@ public class Messages extends AbstractConfig { public static class NPC { private static final String prefix = "npc."; public static String ALREADY_HAVE_ROD = "You already have a fishing rod"; + public static String UPGRADE_NPC_LEFT_CLICK_MESSAGE = "Hey . If you want to catch better fish I can upgrade your fishing rod for you! I don't work free though, if you need Fish Points you can get some by selling your catches!"; @SuppressWarnings("unused") private static void load() { ALREADY_HAVE_ROD = config.getString(prefix, "already-have-rod", ALREADY_HAVE_ROD); + UPGRADE_NPC_LEFT_CLICK_MESSAGE = config.getString(prefix, "upgrade-npc-left-click-message", UPGRADE_NPC_LEFT_CLICK_MESSAGE); } } @@ -86,4 +94,14 @@ public class Messages extends AbstractConfig { ROD_LORE = config.getStringList(prefix, "rod-lore", ROD_LORE); } } + + public static class OTHER_ERRORS { + private static final String prefix = "other-errors."; + public static String UNABLE_TO_CREATE_FISH = "Unable to create fish, please contact a staff member"; + + @SuppressWarnings("unused") + private static void load() { + UNABLE_TO_CREATE_FISH = config.getString(prefix, "unable-to-create-fish", UNABLE_TO_CREATE_FISH); + } + } } diff --git a/src/main/java/com/alttd/fishingevent/fish/Fish.java b/src/main/java/com/alttd/fishingevent/fish/Fish.java index 3235c9b..59d6004 100644 --- a/src/main/java/com/alttd/fishingevent/fish/Fish.java +++ b/src/main/java/com/alttd/fishingevent/fish/Fish.java @@ -1,21 +1,35 @@ package com.alttd.fishingevent.fish; +import com.alttd.fishingevent.FishingEvent; import com.alttd.fishingevent.config.Config; import com.alttd.fishingevent.config.Fishes; import com.alttd.fishingevent.objects.Rarity; +import com.alttd.fishingevent.util.Logger; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public abstract class Fish { + protected final FishingEvent fishingEvent; + protected final Logger logger; + + Fish(FishingEvent fishingEvent, Logger logger) { + this.fishingEvent = fishingEvent; + this.logger = logger; + } + /** * Get an the fish item for a specific player * @param player Player to get the item for @@ -42,7 +56,7 @@ public abstract class Fish { public abstract Rarity getRarity(); - public ItemStack createItem(Player player, double length) { + public Optional createItem(Player player, double length, int points) { ItemStack fishItem = getFishItem(player); ItemMeta itemMeta = fishItem.getItemMeta(); TagResolver resolver = TagResolver.resolver( @@ -53,9 +67,21 @@ public abstract class Fish { itemMeta.lore(fishLore(resolver)); itemMeta.displayName(fishName()); + NamespacedKey namespacedKey; + try { + namespacedKey = NamespacedKey.fromString("points", fishingEvent); + } catch (Exception e) { + logger.warning("Unable to create namespaced key for fish"); + return Optional.empty(); + } + if (namespacedKey == null) { + logger.warning("Created null namespaced key for fish"); + return Optional.empty(); + } + itemMeta.getPersistentDataContainer().set(namespacedKey, PersistentDataType.INTEGER, points); fishItem.setItemMeta(itemMeta); - return fishItem; + return Optional.of(fishItem); } /** diff --git a/src/main/java/com/alttd/fishingevent/gui/GUI.java b/src/main/java/com/alttd/fishingevent/gui/GUI.java index eab0c5e..c5b7ca3 100644 --- a/src/main/java/com/alttd/fishingevent/gui/GUI.java +++ b/src/main/java/com/alttd/fishingevent/gui/GUI.java @@ -35,8 +35,13 @@ public abstract class GUI { } } - public void open(Player player) { + public abstract boolean canOpen(); + + public boolean open(Player player) { + if (!canOpen()) + return false; player.openInventory(inventory); GUIByUUID.put(player.getUniqueId(), this); + return true; } } diff --git a/src/main/java/com/alttd/fishingevent/gui/windows/PrizesWindow.java b/src/main/java/com/alttd/fishingevent/gui/windows/PrizesWindow.java new file mode 100644 index 0000000..a0c8fe5 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/gui/windows/PrizesWindow.java @@ -0,0 +1,36 @@ +package com.alttd.fishingevent.gui.windows; + +import com.alttd.fishingevent.config.Messages; +import com.alttd.fishingevent.gui.GUI; +import com.alttd.fishingevent.objects.Prize; +import com.alttd.fishingevent.util.Logger; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; + +import java.util.List; + +public class PrizesWindow extends GUI { + + private final Logger logger; + + public PrizesWindow(Player player, Logger logger, List prizes) { + super(InventoryType.CHEST, MiniMessage.miniMessage().deserialize(Messages.GUI.PRIZES_GUI_NAME)); + this.logger = logger; + int i = 0; + for (Prize prize : prizes) { + setItem(i, prize.itemStack().clone(), clickingPlayer -> buy(clickingPlayer, prize)); + i++; + } + } + + private void buy(Player player, Prize prize) { + player.sendMiniMessage("Buying is not implemented yet", null); + //TODO implement selling + } + + @Override + public boolean canOpen() { + return true; + } +} diff --git a/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java b/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java index a6754bf..3e5bdcf 100644 --- a/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java +++ b/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java @@ -1,10 +1,17 @@ package com.alttd.fishingevent.gui.windows; +import com.alttd.fishingevent.FishingEvent; import com.alttd.fishingevent.config.Config; +import com.alttd.fishingevent.config.Messages; import com.alttd.fishingevent.gui.GUI; +import com.alttd.fishingevent.objects.EnchantmentData; +import com.alttd.fishingevent.objects.EnchantmentTrack; +import com.alttd.fishingevent.points.PointsManagement; import com.alttd.fishingevent.util.Logger; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; @@ -12,32 +19,51 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import java.util.Arrays; +import java.util.List; import java.util.Objects; import java.util.Optional; public class UpgradeWindow extends GUI { private final Logger logger; + private boolean canOpen = false; + private final FishingEvent fishingEvent; - public UpgradeWindow(Player player, Component name, Logger logger) { - super(InventoryType.CHEST, name); + public UpgradeWindow(FishingEvent fishingEvent, Player player, Logger logger, List enchantmentTracks) { + super(InventoryType.CHEST, MiniMessage.miniMessage().deserialize(Messages.GUI.UPGRADE_GUI_NAME)); + this.fishingEvent = fishingEvent; this.logger = logger; int i = 0; Optional optionalFishingRod = getFishingRod(player); if (optionalFishingRod.isEmpty()) { - logger.debug("[%] has no fishing rod", player.getName()); - return; //TODO do something to tell the player they need a rod + player.sendMiniMessage(Messages.GUI.NO_FISHING_ROD, null); + return; } ItemStack fishingRod = optionalFishingRod.get(); - for (Enchantment enchantment : Config.UPGRADES.ENCHANTMENTS) { - Optional optionalEnchantmentItem = getEnchantmentItem(enchantment, fishingRod); + for (EnchantmentTrack enchantmentTrack : enchantmentTracks) { + int trackLevel = getTrackLevel(enchantmentTrack, fishingRod); + Optional optionalEnchantmentItem = getEnchantmentItem(enchantmentTrack, trackLevel); if (optionalEnchantmentItem.isEmpty()) continue; - setItem(i, optionalEnchantmentItem.get(), clickingPlayer -> upgrade(clickingPlayer, enchantment)); + setItem(i, optionalEnchantmentItem.get(), clickingPlayer -> upgrade(clickingPlayer, enchantmentTrack, trackLevel)); i++; } + canOpen = true; + } + + private int getTrackLevel(EnchantmentTrack enchantmentTrack, ItemStack fishingRod) { + Optional namespacedKey = getNamespacedKey(fishingEvent, enchantmentTrack.getInternalName()); + if (namespacedKey.isEmpty()) { + return -1; + } + Integer trackLevel = fishingRod.getItemMeta().getPersistentDataContainer().get(namespacedKey.get(), PersistentDataType.INTEGER); + if (trackLevel == null) + trackLevel = 0; + return trackLevel; } private Optional getFishingRod(Player player) { @@ -47,17 +73,46 @@ public class UpgradeWindow extends GUI { .findFirst(); } - private Optional getEnchantmentItem(Enchantment enchantment, ItemStack fishingRod) { - int enchantmentLevel = fishingRod.getEnchantmentLevel(enchantment); - if (enchantment.getMaxLevel() == enchantmentLevel) { + private Optional getEnchantmentItem(EnchantmentTrack enchantmentTrack, int trackLevel) { + if (enchantmentTrack.getMaxLevel() == trackLevel) { return Optional.empty(); } ItemStack itemStack = new ItemStack(Material.ENCHANTED_BOOK, 1); - itemStack.addEnchantment(enchantment, enchantmentLevel + 1); + Optional optionalEnchantmentData = enchantmentTrack.nextEnchantment(trackLevel); + if (optionalEnchantmentData.isEmpty()) + return Optional.empty(); + EnchantmentData enchantmentData = optionalEnchantmentData.get(); + itemStack.addEnchantment(enchantmentData.enchantment(), enchantmentData.level()); return Optional.of(itemStack); } - private void upgrade(Player player, Enchantment enchantment) { + private Optional getNamespacedKey(FishingEvent fishingEvent, String name) { + try { + NamespacedKey namespacedKey = NamespacedKey.fromString(name, fishingEvent); + if (namespacedKey != null) + return Optional.of(namespacedKey); + } catch (Exception e) { + logger.warning("Error while creating namespaced key for enchant [%]", name); + return Optional.empty(); + } + logger.warning("Error while creating namespaced key for enchant [%]", name); + return Optional.empty(); + } + + private void upgrade(Player player, EnchantmentTrack enchantmentTrack, int trackLevel) { + int playerPoints = PointsManagement.getInstance().getPoints(player.getUniqueId()); + Optional optionalEnchantmentData = enchantmentTrack.nextEnchantment(trackLevel); + if (optionalEnchantmentData.isEmpty()) { + //TODO error no next enchant prob? + return; + } + + EnchantmentData enchantmentData = optionalEnchantmentData.get(); + if (playerPoints < enchantmentData.price()) { + //TODO tell player not enough points + return; + } + PlayerInventory inventory = player.getInventory(); int fishingRodSlot = findFishingRodSlot(inventory); ItemStack fishingRod = inventory.getItem(fishingRodSlot); @@ -65,11 +120,35 @@ public class UpgradeWindow extends GUI { logger.warning("Fishing rod became null"); return; } - int enchantmentLevel = fishingRod.getEnchantmentLevel(enchantment); - fishingRod.addEnchantment(enchantment, enchantmentLevel + 1); + + try { + PointsManagement.getInstance().removePoints(player.getUniqueId(), enchantmentData.price()); + } catch (IllegalArgumentException e) { + //TODO tell player not enough points + return; + } + + if (!updateEnchantment(fishingRod, enchantmentData, enchantmentTrack, trackLevel + 1)) { + PointsManagement.getInstance().addPoints(player.getUniqueId(), enchantmentData.price()); + //TODO error + return; + } + inventory.setItem(fishingRodSlot, fishingRod); } + private boolean updateEnchantment(ItemStack fishingRod, EnchantmentData enchantmentData, EnchantmentTrack enchantmentTrack, int newTrackLevel) { + fishingRod.addEnchantment(enchantmentData.enchantment(), enchantmentData.level()); + ItemMeta itemMeta = fishingRod.getItemMeta(); + PersistentDataContainer persistentDataContainer = itemMeta.getPersistentDataContainer(); + Optional namespacedKey = getNamespacedKey(fishingEvent, enchantmentTrack.getInternalName()); + if (namespacedKey.isEmpty()) + return false; + persistentDataContainer.set(namespacedKey.get(), PersistentDataType.INTEGER, newTrackLevel); + fishingRod.setItemMeta(itemMeta); + return true; + } + private int findFishingRodSlot(Inventory inventory) { ItemStack[] contents = inventory.getContents(); @@ -84,4 +163,8 @@ public class UpgradeWindow extends GUI { } + @Override + public boolean canOpen() { + return canOpen; + } } diff --git a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java index 383a5b8..a819003 100644 --- a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java +++ b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java @@ -1,5 +1,6 @@ package com.alttd.fishingevent.listeners; +import com.alttd.fishingevent.config.Messages; import com.alttd.fishingevent.fish.Fish; import com.alttd.fishingevent.fish_generator.FishGenerator; import com.alttd.fishingevent.points.PointsManagement; @@ -82,11 +83,17 @@ public class CatchFish implements Listener { Fish fish = optionalFish.get(); float length = fish.getLength(); - item.setItemStack(fish.createItem(player, length)); + int pointsValue = pointsManagement.calculatePoints(fish.getRarity(), length); + Optional fishItem = fish.createItem(player, length, pointsValue); + if (fishItem.isEmpty()) { + player.sendMiniMessage(Messages.OTHER_ERRORS.UNABLE_TO_CREATE_FISH, null); + event.setCancelled(true); + return; + } + item.setItemStack(fishItem.get()); item.setOwner(player.getUniqueId()); - int addedPoints = pointsManagement.caughtFish(player.getUniqueId(), fish.getRarity(), length); logger.debug("[%] caught a [%] with length [%] and rarity [%] for [%] points", player.getName(), fish.normalFishName(), String.format("%.2f", length), - fish.getRarity().displayName(), String.valueOf(addedPoints)); + fish.getRarity().displayName(), String.valueOf(pointsValue)); } } diff --git a/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java index 8a65c4c..89f39c1 100644 --- a/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java +++ b/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java @@ -1,14 +1,19 @@ package com.alttd.fishingevent.npc.types; import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.config.Messages; +import com.alttd.fishingevent.gui.windows.PrizesWindow; +import com.alttd.fishingevent.gui.windows.UpgradeWindow; import com.alttd.fishingevent.npc.LibNPC; import com.alttd.fishingevent.npc.NPC; import com.alttd.fishingevent.objects.Prize; import com.alttd.fishingevent.util.Logger; import com.alttd.fishingevent.util.NPCCreateData; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; import java.util.List; @@ -17,10 +22,13 @@ public class PrizeNPC extends LibNPC implements NPC { private final NPCCreateData npcCreateData; private final Logger logger; private boolean isSpawned = false; + private final List prizes; + private FishingEvent fishingEvent = null; public PrizeNPC(Logger logger, NPCCreateData npcCreateData, List prizes) { this.npcCreateData = npcCreateData; this.logger = logger; + this.prizes = prizes; } @Override @@ -31,17 +39,28 @@ public class PrizeNPC extends LibNPC implements NPC { @Override public void spawnNPC(FishingEvent fishingEvent, Location location) { defaultSpawnNPC(fishingEvent, location, npcCreateData, logger, this); + this.fishingEvent = fishingEvent; isSpawned = true; } @Override public void leftClick(Player player) { - + player.sendMiniMessage(Messages.NPC.UPGRADE_NPC_LEFT_CLICK_MESSAGE, Placeholder.component("player", player.name())); } @Override public void rightClick(Player player) { - + if (fishingEvent == null) { + player.sendMiniMessage(Messages.GUI.NOT_INITIALIZED, null); + return; + } + PrizesWindow prizesWindow = new PrizesWindow(player, logger, prizes); + new BukkitRunnable() { + @Override + public void run() { + prizesWindow.open(player); + } + }.runTaskAsynchronously(fishingEvent); } @Override diff --git a/src/main/java/com/alttd/fishingevent/npc/types/SellNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/SellNPC.java new file mode 100644 index 0000000..1490b53 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/types/SellNPC.java @@ -0,0 +1,4 @@ +package com.alttd.fishingevent.npc.types; + +public class SellNPC { +} diff --git a/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java index e73c13c..fc4a366 100644 --- a/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java +++ b/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java @@ -44,7 +44,7 @@ public class TutorialNPC extends LibNPC implements NPC { @Override public void leftClick(Player player) { - + //Leave empty since we're overwriting the left click action when spawning the npc } @Override diff --git a/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java index 2291523..19ef56a 100644 --- a/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java +++ b/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java @@ -1,15 +1,17 @@ package com.alttd.fishingevent.npc.types; import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.config.Messages; import com.alttd.fishingevent.gui.windows.UpgradeWindow; import com.alttd.fishingevent.npc.LibNPC; import com.alttd.fishingevent.npc.NPC; +import com.alttd.fishingevent.objects.EnchantmentTrack; import com.alttd.fishingevent.util.Logger; import com.alttd.fishingevent.util.NPCCreateData; -import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.Location; -import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; import java.util.List; @@ -18,10 +20,13 @@ public class UpgradeNPC extends LibNPC implements NPC { private final NPCCreateData npcCreateData; private final Logger logger; private boolean isSpawned = false; + private final List enchantmentTracks; + private FishingEvent fishingEvent = null; - public UpgradeNPC(Logger logger, NPCCreateData npcCreateData, List upgrades) { + public UpgradeNPC(Logger logger, NPCCreateData npcCreateData, List enchantmentTracks) { this.npcCreateData = npcCreateData; this.logger = logger; + this.enchantmentTracks = enchantmentTracks; } @Override @@ -32,17 +37,32 @@ public class UpgradeNPC extends LibNPC implements NPC { @Override public void spawnNPC(FishingEvent fishingEvent, Location location) { defaultSpawnNPC(fishingEvent, location, npcCreateData, logger, this); + this.fishingEvent = fishingEvent; isSpawned = true; } @Override public void leftClick(Player player) { - + player.sendMiniMessage(Messages.NPC.UPGRADE_NPC_LEFT_CLICK_MESSAGE, Placeholder.component("player", player.name())); } @Override public void rightClick(Player player) { - + if (fishingEvent == null) { + player.sendMiniMessage(Messages.GUI.NOT_INITIALIZED, null); + return; + } + UpgradeWindow upgradeWindow = new UpgradeWindow(fishingEvent, player, logger, enchantmentTracks); + if (!upgradeWindow.canOpen()) { + player.sendMiniMessage(Messages.GUI.NO_FISHING_ROD, null); + return; + } + new BukkitRunnable() { + @Override + public void run() { + upgradeWindow.open(player); + } + }.runTaskAsynchronously(fishingEvent); } @Override diff --git a/src/main/java/com/alttd/fishingevent/objects/EnchantmentData.java b/src/main/java/com/alttd/fishingevent/objects/EnchantmentData.java new file mode 100644 index 0000000..0467163 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/objects/EnchantmentData.java @@ -0,0 +1,6 @@ +package com.alttd.fishingevent.objects; + +import org.bukkit.enchantments.Enchantment; + +public record EnchantmentData(Enchantment enchantment, int level, int price) { +} diff --git a/src/main/java/com/alttd/fishingevent/objects/EnchantmentTrack.java b/src/main/java/com/alttd/fishingevent/objects/EnchantmentTrack.java new file mode 100644 index 0000000..523497c --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/objects/EnchantmentTrack.java @@ -0,0 +1,38 @@ +package com.alttd.fishingevent.objects; + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.kyori.adventure.text.Component; + +import java.util.Optional; + +public class EnchantmentTrack { + + private final Component name; + private final Int2ObjectOpenHashMap enchantmentMap; + private final String internalName; + + public EnchantmentTrack(String internalName, Component name, Int2ObjectOpenHashMap enchantmentMap) { + this.internalName = internalName.toLowerCase(); + this.name = name; + this.enchantmentMap = enchantmentMap; + } + + public Optional nextEnchantment(int trackLevel) { + if (enchantmentMap.containsKey(trackLevel + 1)) { + return Optional.of(enchantmentMap.get(trackLevel + 1)); + } + return Optional.empty(); + } + + public Component getName() { + return name; + } + + public String getInternalName() { + return internalName; + } + + public int getMaxLevel() { + return enchantmentMap.keySet().stream().max(Integer::compare).orElse(0); + } +} diff --git a/src/main/java/com/alttd/fishingevent/objects/Prize.java b/src/main/java/com/alttd/fishingevent/objects/Prize.java index 32de6a4..3ad3657 100644 --- a/src/main/java/com/alttd/fishingevent/objects/Prize.java +++ b/src/main/java/com/alttd/fishingevent/objects/Prize.java @@ -2,5 +2,5 @@ package com.alttd.fishingevent.objects; import org.bukkit.inventory.ItemStack; -public record Prize(ItemStack itemStack, String permission, String name) { +public record Prize(ItemStack itemStack, String permission, String name, int price) { } diff --git a/src/main/java/com/alttd/fishingevent/points/PointsManagement.java b/src/main/java/com/alttd/fishingevent/points/PointsManagement.java index c989373..5f3e62e 100644 --- a/src/main/java/com/alttd/fishingevent/points/PointsManagement.java +++ b/src/main/java/com/alttd/fishingevent/points/PointsManagement.java @@ -23,10 +23,12 @@ public class PointsManagement { return instance; } - public synchronized int caughtFish(UUID uuid, Rarity rarity, float length) { - int pointsToAdd = (int) (Config.RARITY_MULTIPLIERS.MULTIPLIER_MAP.get(rarity) * length); - pointsMap.addTo(uuid, pointsToAdd); - return pointsToAdd; + public int calculatePoints(Rarity rarity, float length) { + return (int) (Config.RARITY_MULTIPLIERS.MULTIPLIER_MAP.get(rarity) * length); + } + + public synchronized int addPoints(UUID uuid, int points) { + return pointsMap.addTo(uuid, points); } public synchronized int getPoints(UUID uuid) {