diff --git a/src/main/java/com/alttd/fishingevent/config/Config.java b/src/main/java/com/alttd/fishingevent/config/Config.java index 0a03db9..19f5c5c 100644 --- a/src/main/java/com/alttd/fishingevent/config/Config.java +++ b/src/main/java/com/alttd/fishingevent/config/Config.java @@ -1,12 +1,33 @@ package com.alttd.fishingevent.config; import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.npc.NPC; +import com.alttd.fishingevent.npc.NPCManager; +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.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 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; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; -import java.util.HashMap; +import java.util.*; +import java.util.stream.Collectors; -public class Config extends AbstractConfig{ +public class Config extends AbstractConfig { static Config config; private final Logger logger; @@ -36,14 +57,207 @@ public class Config extends AbstractConfig{ public static class RARITY_MULTIPLIERS { private static final String prefix = "rarity-multipliers."; - public static HashMap multiplierMap = new HashMap<>(); + public static HashMap MULTIPLIER_MAP = new HashMap<>(); @SuppressWarnings("unused") private static void load() { - multiplierMap.clear(); + MULTIPLIER_MAP.clear(); for (Rarity rarity : Rarity.values()) { - multiplierMap.put(rarity, (float) config.getDouble(prefix, rarity.configName(), 1)); + MULTIPLIER_MAP.put(rarity, (float) config.getDouble(prefix, rarity.configName(), 1)); } } } + + 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(); + + public static final HashMap NPC_MAP = new HashMap<>(); + + @SuppressWarnings("unused") + private static void load() { + NPCManager.deleteAllActiveGlobalNPC(NPCLib.getInstance()); + NPC_MAP.clear(); + ConfigurationSection configurationSection = config.getConfigurationSection("npc"); + if (configurationSection == null) + return; + Set npcKeys = configurationSection.getKeys(false); + for (String key : npcKeys) { + String npcPrefix = prefix + key + "."; + loadNPC(getNPCCreateData(npcPrefix, key), npcPrefix, key); + } + } + + private static NPCCreateData getNPCCreateData(String npcPrefix, String key) { + Skin skin = getSkin(npcPrefix); + String id = config.getString(npcPrefix, "id", key); + String name = config.getString(npcPrefix, "name", "default name"); + return new NPCCreateData(skin, id, name, + getMaterial(npcPrefix, "main-hand"), getMaterial(npcPrefix, "off-hand")); + } + + private static void loadNPC(NPCCreateData npcCreateData, String npcPrefix, String key) { + List materials = getMaterials(npcPrefix); + if (materials == null) { + config.logger.severe("No final quest materials found"); + return; + } + NPCType type; + String stringType = config.getString(npcPrefix, "type", NPCType.NONE.name()); + try { + type = NPCType.valueOf(stringType); + } catch (IllegalArgumentException e) { + config.logger.warning("Invalid NPCType: [%]", stringType); + return; + } + + NPC npc; + switch (type) { + case UPGRADE -> { + npc = new UpgradeNPC( + config.logger, + npcCreateData, + getUpgrades(npcPrefix) + ); + } + case TUTORIAL -> { + npc = new TutorialNPC( + config.logger, + npcCreateData, + getBook(npcPrefix) + ); + } + case PRIZE -> { + Optional> prizes = getPrizes(npcPrefix, key); + if (prizes.isEmpty()) { + config.logger.warning("Unable to create valid prizes for Prize npc: [%]", key); + return; + } + npc = new PrizeNPC( + config.logger, + npcCreateData, + prizes.get() + ); + } + default -> { + config.logger.warning("Found NPC Type NONE, please set a valid type"); + return; + } + } + + 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) + continue; + enchantments.add(enchant); + } + return enchantments; + } + + private static ItemStack getBook(String npcPrefix) { + ItemStack itemStack = new ItemStack(Material.BOOK); + BookMeta bookMeta = (BookMeta) itemStack.getItemMeta(); + bookMeta.displayName(MiniMessage.miniMessage().deserialize(config.getString(npcPrefix, "book.item-name", "book name"))); + bookMeta.lore(config.getStringList(npcPrefix, "book.item-lore", List.of("book", "lore")).stream() + .map(line -> MiniMessage.miniMessage().deserialize(line)) + .collect(Collectors.toList())); + bookMeta.author(MiniMessage.miniMessage().deserialize(config.getString(npcPrefix, "book.author-name", "Server"))) + .pages(config.getStringList(npcPrefix, "book.pages", List.of("example", "text")).stream() + .map(line -> MiniMessage.miniMessage().deserialize(line)) + .collect(Collectors.toList())); + itemStack.setItemMeta(bookMeta); + return itemStack; + } + + private static Optional> getPrizes(String npcPrefix, String npcKey) { + ConfigurationSection configurationSection = config.getConfigurationSection(npcPrefix + "prizes"); + if (configurationSection == null) + return Optional.empty(); + + ArrayList prizes = new ArrayList<>(); + for (String key : configurationSection.getKeys(false)) { + String prefix = npcPrefix + "prizes." + key + "."; + String stringMaterial = config.getString(prefix, "material", Material.STONE.name()); + Material material = Material.getMaterial(stringMaterial); + if (material == null) { + config.logger.warning("Invalid material [%] in prizes for NPC [%] at prize [%]", stringMaterial, npcKey, key); + continue; + } + + ItemStack itemStack = new ItemStack(material, config.getInt(prefix, "amount", 1)); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.displayName(MiniMessage.miniMessage().deserialize(config.getString(prefix, "item-name", "item name"))); + itemMeta.lore(config.getStringList(npcPrefix, "item-lore", List.of("item", "lore")).stream() + .map(line -> MiniMessage.miniMessage().deserialize(line)) + .collect(Collectors.toList())); + itemStack.setItemMeta(itemMeta); + + prizes.add( + new Prize(itemStack, + config.getString(prefix, "permission", "example.permission"), + config.getString(prefix, "prize-name", "Prize Name")) + ); + } + return Optional.of(prizes); + } + + private static List getMaterials(String npcPrefix) { + List materialStringList = config.getStringList(npcPrefix, "final-quest-requirements", List.of("DIRT")); + List materials = new ArrayList<>(); + for (String materialString : materialStringList) { + try { + materials.add(Material.getMaterial(materialString.toUpperCase())); + } catch (Exception ignored) { + config.logger.warning("Invalid material [%] for [%]", materialString, npcPrefix); + return null; + } + } + return materials; + } + + private static @Nullable Material getMaterial(String npcPrefix, String materialLocation) { + ConfigurationSection configurationSection = config.getConfigurationSection(npcPrefix); + String materialString = configurationSection.getString(materialLocation); + if (materialString != null) { + try { + return Material.getMaterial(materialString.toUpperCase()); + } catch (Exception ignored) { + config.logger.warning("Invalid material [%] for [%]", materialString, npcPrefix); + } + } + return null; + } + + private static Skin getSkin(String npcPrefix) { + String skinPrefix = npcPrefix + "skin."; + String texture = config.getString(skinPrefix, "texture", "empty"); + String signature = config.getString(skinPrefix, "signature", "empty"); + return new Skin(texture, signature); + } + } } diff --git a/src/main/java/com/alttd/fishingevent/config/Messages.java b/src/main/java/com/alttd/fishingevent/config/Messages.java index 1b2f0e8..ab336ad 100644 --- a/src/main/java/com/alttd/fishingevent/config/Messages.java +++ b/src/main/java/com/alttd/fishingevent/config/Messages.java @@ -3,6 +3,8 @@ package com.alttd.fishingevent.config; import com.alttd.fishingevent.FishingEvent; import com.alttd.fishingevent.util.Logger; +import java.util.List; + public class Messages extends AbstractConfig { static Messages config; private final Logger logger; @@ -60,4 +62,28 @@ public class Messages extends AbstractConfig { private static void load() { } } + + public static class NPC { + private static final String prefix = "npc."; + public static String ALREADY_HAVE_ROD = "You already have a fishing rod"; + + @SuppressWarnings("unused") + private static void load() { + ALREADY_HAVE_ROD = config.getString(prefix, "already-have-rod", ALREADY_HAVE_ROD); + } + } + + public static class ITEMS { + private static final String prefix = "items."; + public static String ROD_NAME = "'s Fishing Rod"; + public static List ROD_LORE = List.of( + "A Fishing Rod specifically crafted for:", + ""); + + @SuppressWarnings("unused") + private static void load() { + ROD_NAME = config.getString(prefix, "rod-name", ROD_NAME); + ROD_LORE = config.getStringList(prefix, "rod-lore", ROD_LORE); + } + } } diff --git a/src/main/java/com/alttd/fishingevent/fish/Fish.java b/src/main/java/com/alttd/fishingevent/fish/Fish.java index 10b20c4..3235c9b 100644 --- a/src/main/java/com/alttd/fishingevent/fish/Fish.java +++ b/src/main/java/com/alttd/fishingevent/fish/Fish.java @@ -64,7 +64,7 @@ public abstract class Fish { * @return points based on the length and rarity of this fish */ public int getPoints(float length) { - return Math.round(Config.RARITY_MULTIPLIERS.multiplierMap.get(getRarity()) * length); + return Math.round(Config.RARITY_MULTIPLIERS.MULTIPLIER_MAP.get(getRarity()) * length); } } diff --git a/src/main/java/com/alttd/fishingevent/gui/GUI.java b/src/main/java/com/alttd/fishingevent/gui/GUI.java new file mode 100644 index 0000000..eab0c5e --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/gui/GUI.java @@ -0,0 +1,42 @@ +package com.alttd.fishingevent.gui; + +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.UUID; + +public abstract class GUI { + HashMap GUIByUUID = new HashMap<>(); + protected final Inventory inventory; + protected final HashMap guiActions; + + public GUI(InventoryType type, Component name) { + inventory = Bukkit.createInventory(null, type, name); + guiActions = new HashMap<>(); + } + + public GUIAction getGuiAction(int slot) { + return guiActions.get(slot); + } + + public Inventory getInventory() { + return inventory; + } + + public void setItem(int slot, ItemStack stack, GUIAction action){ + this.inventory.setItem(slot, stack); + if (action != null){ + guiActions.put(slot, action); + } + } + + public void open(Player player) { + player.openInventory(inventory); + GUIByUUID.put(player.getUniqueId(), this); + } +} diff --git a/src/main/java/com/alttd/fishingevent/gui/GUIAction.java b/src/main/java/com/alttd/fishingevent/gui/GUIAction.java new file mode 100644 index 0000000..610a4c9 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/gui/GUIAction.java @@ -0,0 +1,7 @@ +package com.alttd.fishingevent.gui; + +import org.bukkit.entity.Player; + +public interface GUIAction { + void click(Player player); +} \ No newline at end of file diff --git a/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java b/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java new file mode 100644 index 0000000..a6754bf --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/gui/windows/UpgradeWindow.java @@ -0,0 +1,87 @@ +package com.alttd.fishingevent.gui.windows; + +import com.alttd.fishingevent.config.Config; +import com.alttd.fishingevent.gui.GUI; +import com.alttd.fishingevent.util.Logger; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; + +public class UpgradeWindow extends GUI { + + private final Logger logger; + + public UpgradeWindow(Player player, Component name, Logger logger) { + super(InventoryType.CHEST, name); + 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 + } + ItemStack fishingRod = optionalFishingRod.get(); + for (Enchantment enchantment : Config.UPGRADES.ENCHANTMENTS) { + Optional optionalEnchantmentItem = getEnchantmentItem(enchantment, fishingRod); + if (optionalEnchantmentItem.isEmpty()) + continue; + setItem(i, optionalEnchantmentItem.get(), clickingPlayer -> upgrade(clickingPlayer, enchantment)); + i++; + } + } + + private Optional getFishingRod(Player player) { + return Arrays.stream(player.getInventory().getStorageContents()) + .filter(Objects::nonNull) + .filter(itemStack -> itemStack.getType().equals(Material.FISHING_ROD)) + .findFirst(); + } + + private Optional getEnchantmentItem(Enchantment enchantment, ItemStack fishingRod) { + int enchantmentLevel = fishingRod.getEnchantmentLevel(enchantment); + if (enchantment.getMaxLevel() == enchantmentLevel) { + return Optional.empty(); + } + ItemStack itemStack = new ItemStack(Material.ENCHANTED_BOOK, 1); + itemStack.addEnchantment(enchantment, enchantmentLevel + 1); + return Optional.of(itemStack); + } + + private void upgrade(Player player, Enchantment enchantment) { + PlayerInventory inventory = player.getInventory(); + int fishingRodSlot = findFishingRodSlot(inventory); + ItemStack fishingRod = inventory.getItem(fishingRodSlot); + if (fishingRod == null) { + logger.warning("Fishing rod became null"); + return; + } + int enchantmentLevel = fishingRod.getEnchantmentLevel(enchantment); + fishingRod.addEnchantment(enchantment, enchantmentLevel + 1); + inventory.setItem(fishingRodSlot, fishingRod); + } + + private int findFishingRodSlot(Inventory inventory) { + ItemStack[] contents = inventory.getContents(); + + for (int i = 0; i < contents.length; i++) { + ItemStack item = contents[i]; + + if (item != null && item.getType().equals(Material.FISHING_ROD)) { + return i; + } + } + return -1; + } + + +} diff --git a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java index 6ee9ec1..383a5b8 100644 --- a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java +++ b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java @@ -83,6 +83,7 @@ public class CatchFish implements Listener { float length = fish.getLength(); item.setItemStack(fish.createItem(player, length)); + 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), diff --git a/src/main/java/com/alttd/fishingevent/npc/LibNPC.java b/src/main/java/com/alttd/fishingevent/npc/LibNPC.java new file mode 100644 index 0000000..4c356cb --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/LibNPC.java @@ -0,0 +1,76 @@ +package com.alttd.fishingevent.npc; + +import com.alttd.fishingevent.FishingEvent; +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 org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; +import java.util.function.BiConsumer; + +public abstract class LibNPC { + + public abstract String getName(); + private dev.sergiferry.playernpc.api.NPC.Global globalNPC = null; + + private Optional spawn(FishingEvent fishingEvent, String simpleId, org.bukkit.Location location, Skin skin, dev.sergiferry.playernpc.api.NPC.NameTag nameTag, BiConsumer rightClick, BiConsumer leftClick, dev.sergiferry.playernpc.api.NPC.Global.Visibility visibility) { + dev.sergiferry.playernpc.api.NPC.Global globalNPC = NPCLib.getInstance().generateGlobalNPC(fishingEvent, simpleId, location); + globalNPC.setVisibility(visibility); + globalNPC.addCustomClickAction(dev.sergiferry.playernpc.api.NPC.Interact.ClickType.RIGHT_CLICK, rightClick); + globalNPC.addCustomClickAction(dev.sergiferry.playernpc.api.NPC.Interact.ClickType.LEFT_CLICK, leftClick); + globalNPC.setGazeTrackingType(dev.sergiferry.playernpc.api.NPC.GazeTrackingType.PLAYER); + globalNPC.setSkin(skin.texture(), skin.signature()) + .update(); + globalNPC.setNameTag(nameTag, true) + .update(); + return Optional.of(globalNPC); + } + + public void defaultSpawnNPC(FishingEvent fishingEvent, Location location, NPCCreateData npcCreateData, Logger logger, NPC npc) { + dev.sergiferry.playernpc.api.NPC.NameTag nameTag = new dev.sergiferry.playernpc.api.NPC.NameTag("&6[Quest NPC] ", "&2" + npcCreateData.name(), ""); + logger.info(nameTag.getName()); + Optional tmp = spawn( + fishingEvent, npcCreateData.simpleId(), location, npcCreateData.skin(), nameTag, + (a, player) -> npc.rightClick(player), (a, player) -> npc.leftClick(player), + dev.sergiferry.playernpc.api.NPC.Global.Visibility.SELECTED_PLAYERS); + if (tmp.isEmpty()) { + return; + } + this.globalNPC = tmp.get(); + globalNPC.hide(); + if (npcCreateData.mainHand() != null) + globalNPC.setItemInMainHand(new ItemStack(npcCreateData.mainHand(), 1)); + if (npcCreateData.offHand() != null) + globalNPC.setItemInMainHand(new ItemStack(npcCreateData.offHand(), 1)); + } + + protected boolean showToPlayer(Player player) { + globalNPC.show(player); + return true; + } + + protected boolean hideFromPlayer(Player player) { + globalNPC.hide(player); + return true; + } + + protected void hide() { + globalNPC.hide(); + } + + protected void show() { + globalNPC.show(); + } + + protected void updateSkin(Player player) { + globalNPC.update(player); + } + + protected dev.sergiferry.playernpc.api.NPC.Global getGlobalNPC() { + return globalNPC; + } +} diff --git a/src/main/java/com/alttd/fishingevent/npc/NPC.java b/src/main/java/com/alttd/fishingevent/npc/NPC.java index 83253a2..b4851b4 100644 --- a/src/main/java/com/alttd/fishingevent/npc/NPC.java +++ b/src/main/java/com/alttd/fishingevent/npc/NPC.java @@ -1,4 +1,23 @@ package com.alttd.fishingevent.npc; +import com.alttd.fishingevent.FishingEvent; +import org.bukkit.Location; +import org.bukkit.entity.Player; + public interface NPC { + + void spawnNPC(FishingEvent fishingEvent, Location location); + + void leftClick(Player player); + + void rightClick(Player player); + + boolean showToPlayer(Player player); + + boolean hideFromPlayer(Player player); + + boolean isSpawned(FishingEvent fishingEvent); + + void updateSkin(Player player); + } diff --git a/src/main/java/com/alttd/fishingevent/npc/NPCManager.java b/src/main/java/com/alttd/fishingevent/npc/NPCManager.java new file mode 100644 index 0000000..2fa3e8b --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/NPCManager.java @@ -0,0 +1,33 @@ +package com.alttd.fishingevent.npc; + +import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.config.Config; +import com.alttd.fishingevent.config.NPCLocationConfig; +import com.alttd.fishingevent.util.Logger; +import dev.sergiferry.playernpc.api.NPCLib; + +import java.util.*; + +public class NPCManager { + + private static Set loaded = new HashSet<>(); + + public static void spawnNPCs(FishingEvent fishingEvent, Logger logger) { + NPCLocationConfig.NPC_LOCATION.ALL.forEach((name, location) -> { + NPC npc = Config.NPC_DATA.NPC_MAP.getOrDefault(name, null); + if (npc == null) { + logger.warning("Found npc location entry without matching npc for [%]", name); + return; + } + logger.info("Spawning daily NPC " + name); + npc.spawnNPC(fishingEvent, location); + loaded.add(npc); + }); + + } + + public static void deleteAllActiveGlobalNPC(NPCLib npcLib) { + npcLib.getAllGlobalNPCs().forEach(dev.sergiferry.playernpc.api.NPC.Global::destroy); + } + +} diff --git a/src/main/java/com/alttd/fishingevent/npc/NPCType.java b/src/main/java/com/alttd/fishingevent/npc/NPCType.java new file mode 100644 index 0000000..80de574 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/NPCType.java @@ -0,0 +1,8 @@ +package com.alttd.fishingevent.npc; + +public enum NPCType { + UPGRADE, + TUTORIAL, + PRIZE, + NONE; +} diff --git a/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java new file mode 100644 index 0000000..8a65c4c --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/types/PrizeNPC.java @@ -0,0 +1,66 @@ +package com.alttd.fishingevent.npc.types; + +import com.alttd.fishingevent.FishingEvent; +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 org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +public class PrizeNPC extends LibNPC implements NPC { + + private final NPCCreateData npcCreateData; + private final Logger logger; + private boolean isSpawned = false; + + public PrizeNPC(Logger logger, NPCCreateData npcCreateData, List prizes) { + this.npcCreateData = npcCreateData; + this.logger = logger; + } + + @Override + public String getName() { + return npcCreateData.name(); + } + + @Override + public void spawnNPC(FishingEvent fishingEvent, Location location) { + defaultSpawnNPC(fishingEvent, location, npcCreateData, logger, this); + isSpawned = true; + } + + @Override + public void leftClick(Player player) { + + } + + @Override + public void rightClick(Player player) { + + } + + @Override + public boolean showToPlayer(Player player) { + return super.showToPlayer(player); + } + + @Override + public boolean hideFromPlayer(Player player) { + return super.hideFromPlayer(player); + } + + @Override + public boolean isSpawned(FishingEvent fishingEvent) { + return isSpawned; + } + + @Override + public void updateSkin(Player player) { + super.updateSkin(player); + } +} diff --git a/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java new file mode 100644 index 0000000..e73c13c --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/types/TutorialNPC.java @@ -0,0 +1,89 @@ +package com.alttd.fishingevent.npc.types; + +import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.config.Config; +import com.alttd.fishingevent.config.Messages; +import com.alttd.fishingevent.npc.LibNPC; +import com.alttd.fishingevent.npc.NPC; +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.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.stream.Collectors; + +public class TutorialNPC extends LibNPC implements NPC { + + private final NPCCreateData npcCreateData; + private final Logger logger; + private boolean isSpawned = false; + private final ItemStack book; + + public TutorialNPC(Logger logger, NPCCreateData npcCreateData, ItemStack book) { + this.npcCreateData = npcCreateData; + this.logger = logger; + this.book = book; + } + + @Override + public String getName() { + return npcCreateData.name(); + } + + @Override + public void spawnNPC(FishingEvent fishingEvent, Location location) { + defaultSpawnNPC(fishingEvent, location, npcCreateData, logger, this); + isSpawned = true; + getGlobalNPC().addOpenBookClickAction(dev.sergiferry.playernpc.api.NPC.Interact.ClickType.LEFT_CLICK, book); + } + + @Override + public void leftClick(Player player) { + + } + + @Override + public void rightClick(Player player) { + if (player.getInventory().first(Material.FISHING_ROD) != -1) { + player.sendMiniMessage(Messages.NPC.ALREADY_HAVE_ROD, null); + return; + } + player.getInventory().addItem(getDefaultFishingRod(player)); + } + + private ItemStack getDefaultFishingRod(Player player) { + ItemStack itemStack = new ItemStack(Material.FISHING_ROD, 1); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.displayName(MiniMessage.miniMessage().deserialize(Messages.ITEMS.ROD_NAME, Placeholder.component("player", player.name()))); + itemMeta.lore(Messages.ITEMS.ROD_LORE.stream() + .map(line -> MiniMessage.miniMessage().deserialize(line, Placeholder.component("player", player.name()))) + .collect(Collectors.toList())); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + @Override + public boolean showToPlayer(Player player) { + return super.showToPlayer(player); + } + + @Override + public boolean hideFromPlayer(Player player) { + return super.hideFromPlayer(player); + } + + @Override + public boolean isSpawned(FishingEvent fishingEvent) { + return isSpawned; + } + + @Override + public void updateSkin(Player player) { + super.updateSkin(player); + } +} diff --git a/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java b/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java new file mode 100644 index 0000000..2291523 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/npc/types/UpgradeNPC.java @@ -0,0 +1,67 @@ +package com.alttd.fishingevent.npc.types; + +import com.alttd.fishingevent.FishingEvent; +import com.alttd.fishingevent.gui.windows.UpgradeWindow; +import com.alttd.fishingevent.npc.LibNPC; +import com.alttd.fishingevent.npc.NPC; +import com.alttd.fishingevent.util.Logger; +import com.alttd.fishingevent.util.NPCCreateData; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Location; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +import java.util.List; + +public class UpgradeNPC extends LibNPC implements NPC { + + private final NPCCreateData npcCreateData; + private final Logger logger; + private boolean isSpawned = false; + + public UpgradeNPC(Logger logger, NPCCreateData npcCreateData, List upgrades) { + this.npcCreateData = npcCreateData; + this.logger = logger; + } + + @Override + public String getName() { + return npcCreateData.name(); + } + + @Override + public void spawnNPC(FishingEvent fishingEvent, Location location) { + defaultSpawnNPC(fishingEvent, location, npcCreateData, logger, this); + isSpawned = true; + } + + @Override + public void leftClick(Player player) { + + } + + @Override + public void rightClick(Player player) { + + } + + @Override + public boolean showToPlayer(Player player) { + return super.showToPlayer(player); + } + + @Override + public boolean hideFromPlayer(Player player) { + return super.hideFromPlayer(player); + } + + @Override + public boolean isSpawned(FishingEvent fishingEvent) { + return isSpawned; + } + + @Override + public void updateSkin(Player player) { + super.updateSkin(player); + } +} diff --git a/src/main/java/com/alttd/fishingevent/objects/Prize.java b/src/main/java/com/alttd/fishingevent/objects/Prize.java new file mode 100644 index 0000000..32de6a4 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/objects/Prize.java @@ -0,0 +1,6 @@ +package com.alttd.fishingevent.objects; + +import org.bukkit.inventory.ItemStack; + +public record Prize(ItemStack itemStack, String permission, String name) { +} diff --git a/src/main/java/com/alttd/fishingevent/points/PointsManagement.java b/src/main/java/com/alttd/fishingevent/points/PointsManagement.java index 97fabc8..c989373 100644 --- a/src/main/java/com/alttd/fishingevent/points/PointsManagement.java +++ b/src/main/java/com/alttd/fishingevent/points/PointsManagement.java @@ -24,7 +24,7 @@ public class PointsManagement { } public synchronized int caughtFish(UUID uuid, Rarity rarity, float length) { - int pointsToAdd = (int) (Config.RARITY_MULTIPLIERS.multiplierMap.get(rarity) * length); + int pointsToAdd = (int) (Config.RARITY_MULTIPLIERS.MULTIPLIER_MAP.get(rarity) * length); pointsMap.addTo(uuid, pointsToAdd); return pointsToAdd; } diff --git a/src/main/java/com/alttd/fishingevent/util/NPCCreateData.java b/src/main/java/com/alttd/fishingevent/util/NPCCreateData.java new file mode 100644 index 0000000..c0f929b --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/util/NPCCreateData.java @@ -0,0 +1,7 @@ +package com.alttd.fishingevent.util; + +import org.bukkit.Material; +import org.jetbrains.annotations.Nullable; + +public record NPCCreateData(Skin skin, String simpleId, String name, @Nullable Material mainHand, @Nullable Material offHand) { +} diff --git a/src/main/java/com/alttd/fishingevent/util/Skin.java b/src/main/java/com/alttd/fishingevent/util/Skin.java new file mode 100644 index 0000000..0641c79 --- /dev/null +++ b/src/main/java/com/alttd/fishingevent/util/Skin.java @@ -0,0 +1,5 @@ +package com.alttd.fishingevent.util; + +public record Skin(String texture, String signature) { + +}