diff --git a/build.gradle b/build.gradle index c8b9ac54..f0c3454b 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '1.2.17.2' +version = '1.2.18' repositories { mavenCentral() diff --git a/src/main/java/net/momirealms/customfishing/integration/quest/BetonQuestCFQuest.java b/src/main/java/net/momirealms/customfishing/integration/quest/BetonQuestCFQuest.java index b76d498b..9d57d0cb 100644 --- a/src/main/java/net/momirealms/customfishing/integration/quest/BetonQuestCFQuest.java +++ b/src/main/java/net/momirealms/customfishing/integration/quest/BetonQuestCFQuest.java @@ -17,5 +17,137 @@ package net.momirealms.customfishing.integration.quest; -public class BetonQuestCFQuest { -} +import net.momirealms.customfishing.api.event.FishResultEvent; +import net.momirealms.customfishing.object.fishing.FishResult; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import pl.betoncraft.betonquest.BetonQuest; +import pl.betoncraft.betonquest.Instruction; +import pl.betoncraft.betonquest.api.Objective; +import pl.betoncraft.betonquest.config.Config; +import pl.betoncraft.betonquest.exceptions.InstructionParseException; +import pl.betoncraft.betonquest.exceptions.QuestRuntimeException; +import pl.betoncraft.betonquest.objectives.FishObjective; +import pl.betoncraft.betonquest.utils.LogUtils; +import pl.betoncraft.betonquest.utils.PlayerConverter; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Locale; +import java.util.logging.Level; + +public class BetonQuestCFQuest extends Objective implements Listener { + + private final HashSet loot_ids = new HashSet<>(); + private final int amount; + private final boolean notify; + private final int notifyInterval; + + public BetonQuestCFQuest(Instruction instruction) throws InstructionParseException { + super(instruction); + this.template = FishData.class; + this.notifyInterval = instruction.getInt(instruction.getOptional("notify"), 1); + this.notify = instruction.hasArgument("notify") || this.notifyInterval > 1; + this.amount = instruction.getInt(instruction.getOptional("amount"), 1); + Collections.addAll(this.loot_ids, instruction.getArray()); + } + + public static void register() { + BetonQuest.getInstance().registerObjectives("customfishing", BetonQuestCFQuest.class); + } + + @Override + public void start() { + Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance()); + } + + @Override + public void stop() { + HandlerList.unregisterAll(this); + } + + @Override + public String getDefaultDataInstruction() { + return null; + } + + @Override + public String getProperty(String name, String playerID) { + return switch (name.toLowerCase(Locale.ROOT)) { + case "amount" -> + Integer.toString(this.amount - ((FishObjective.FishData) this.dataMap.get(playerID)).getAmount()); + case "left" -> Integer.toString(((FishObjective.FishData) this.dataMap.get(playerID)).getAmount()); + case "total" -> Integer.toString(this.amount); + default -> ""; + }; + } + + private boolean isValidPlayer(Player player) { + if (player == null) { + return false; + } else { + return player.isOnline() && player.isValid(); + } + } + + @EventHandler + public void onFish(FishResultEvent event) { + if (event.getResult() != FishResult.FAILURE) { + String playerID = PlayerConverter.getID(event.getPlayer()); + if (this.containsPlayer(playerID)) { + if (this.loot_ids.contains(event.getLoot_id())) { + if (this.checkConditions(playerID)) { + if (!isValidPlayer(event.getPlayer())) { + return; + } + FishData fishData = (FishData) this.dataMap.get(playerID); + fishData.catchFish(event.isDouble() ? 1 : 2); + if (fishData.finished()) { + this.completeObjective(playerID); + } + else if (this.notify && fishData.getAmount() % this.notifyInterval == 0) { + try { + Config.sendNotify(this.instruction.getPackage().getName(), playerID, "loot_to_fish", new String[]{String.valueOf(fishData.getAmount())}, "loot_to_fish,info"); + } catch (QuestRuntimeException e1) { + try { + LogUtils.getLogger().log(Level.WARNING, "The notify system was unable to play a sound for the 'loot_to_fish' category in '" + this.instruction.getObjective().getFullID() + "'. Error was: '" + e1.getMessage() + "'"); + } catch (InstructionParseException e2) { + LogUtils.logThrowableReport(e2); + } + } + } + } + } + } + } + } + + public static class FishData extends Objective.ObjectiveData { + private int amount; + + public FishData(String instruction, String playerID, String objID) { + super(instruction, playerID, objID); + this.amount = Integer.parseInt(instruction); + } + + public void catchFish(int caughtAmount) { + this.amount -= caughtAmount; + this.update(); + } + + public int getAmount() { + return this.amount; + } + + public String toString() { + return String.valueOf(this.amount); + } + + public boolean finished() { + return this.amount <= 0; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customfishing/manager/BagDataManager.java b/src/main/java/net/momirealms/customfishing/manager/BagDataManager.java index 191f104d..1d700f31 100644 --- a/src/main/java/net/momirealms/customfishing/manager/BagDataManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/BagDataManager.java @@ -107,8 +107,8 @@ public class BagDataManager extends Function { else { PlayerBagData playerBagData = dataCache.get(owner.getUniqueId()); if (playerBagData == null) { - AdventureUtil.consoleMessage("[CustomFishing] Unexpected data for " + owner.getName()); - tryOpen(owner, viewer, readData(owner)); + AdventureUtil.consoleMessage("[CustomFishing] Bag data is not loaded for player " + owner.getName()); + return; } else { tryOpen(owner, viewer, playerBagData); @@ -128,16 +128,17 @@ public class BagDataManager extends Function { @Override public void onJoin(Player player) { - Bukkit.getScheduler().runTaskAsynchronously(CustomFishing.plugin, () -> { + Bukkit.getScheduler().runTaskLaterAsynchronously(CustomFishing.plugin, () -> { readData(player); - }); + }, 20); } - public PlayerBagData readData(Player player) { + public void readData(Player player) { Inventory inventory = CustomFishing.plugin.getDataManager().getDataStorageInterface().loadBagData(player); - PlayerBagData playerBagData = new PlayerBagData(player, inventory); - dataCache.put(player.getUniqueId(), playerBagData); - return playerBagData; + if (inventory != null) { + PlayerBagData playerBagData = new PlayerBagData(player, inventory); + dataCache.put(player.getUniqueId(), playerBagData); + } } @Override diff --git a/src/main/java/net/momirealms/customfishing/manager/BonusManager.java b/src/main/java/net/momirealms/customfishing/manager/BonusManager.java index de6d3666..8ce60476 100644 --- a/src/main/java/net/momirealms/customfishing/manager/BonusManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/BonusManager.java @@ -81,7 +81,7 @@ public class BonusManager extends Function { YamlConfiguration config = YamlConfiguration.loadConfiguration(file); Set keys = config.getKeys(false); for (String key : keys) { - Item item = new Item(Material.valueOf(config.getString(key + ".material", "PAPER").toUpperCase())); + Item item = new Item(Material.valueOf(config.getString(key + ".material", "PAPER").toUpperCase()), key); setItemProperties(config, key, item); UTILITEMS.put(key, ItemStackUtil.addIdentifier(ItemStackUtil.getFromItem(item), "util", key)); } @@ -140,7 +140,7 @@ public class BonusManager extends Function { YamlConfiguration config = YamlConfiguration.loadConfiguration(file); Set keys = config.getKeys(false); for (String key : keys) { - Item item = new Item(Material.valueOf(config.getString(key + ".material", "PAPER").toUpperCase())); + Item item = new Item(Material.valueOf(config.getString(key + ".material", "PAPER").toUpperCase()), key); setItemProperties(config, key, item); BAITITEMS.put(key, ItemStackUtil.addIdentifier(ItemStackUtil.getFromItem(item), "bait", key)); if (config.contains(key + ".modifier")) { @@ -194,7 +194,7 @@ public class BonusManager extends Function { YamlConfiguration config = YamlConfiguration.loadConfiguration(file); Set keys = config.getKeys(false); for (String key : keys) { - Item item = new Item(Material.FISHING_ROD); + Item item = new Item(Material.FISHING_ROD, key); setItemProperties(config, key, item); RODITEMS.put(key, ItemStackUtil.addIdentifier(ItemStackUtil.getFromItem(item), "rod", key)); if (config.contains(key + ".modifier")) { @@ -230,5 +230,8 @@ public class BonusManager extends Function { Map nbt = config.getConfigurationSection(key + ".nbt").getValues(false); item.setNbt(nbt); } + if (config.contains(key + ".head64")) { + item.setHead64(config.getString(key + ".head64")); + } } } diff --git a/src/main/java/net/momirealms/customfishing/manager/FishingManager.java b/src/main/java/net/momirealms/customfishing/manager/FishingManager.java index e8502f13..0714d61f 100644 --- a/src/main/java/net/momirealms/customfishing/manager/FishingManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/FishingManager.java @@ -518,7 +518,7 @@ public class FishingManager extends Function { sendSuccessTitle(player, droppedItem.getNick()); } - private ItemStack getCustomFishingLootItemStack(DroppedItem droppedItem, Player player) { + public ItemStack getCustomFishingLootItemStack(DroppedItem droppedItem, Player player) { String key = droppedItem.getMaterial(); ItemStack drop = CustomFishing.plugin.getIntegrationManager().build(key); @@ -529,6 +529,14 @@ public class FishingManager extends Function { ItemStackUtil.addRandomDamage(drop); if (ConfigManager.preventPickUp) ItemStackUtil.addOwner(drop, player.getName()); + if (drop.getType() == Material.PLAYER_HEAD) { + NBTItem nbtItem = new NBTItem(drop); + NBTCompound nbtCompound = nbtItem.getCompound("SkullOwner"); + if (nbtCompound != null && !nbtCompound.hasTag("Id")) { + nbtCompound.setUUID("Id", UUID.randomUUID()); + drop.setItemMeta(nbtItem.getItem().getItemMeta()); + } + } ItemStackUtil.addExtraMeta(drop, droppedItem); if (ConfigManager.addTagToFish) ItemStackUtil.addIdentifier(drop, "loot", droppedItem.getKey()); } diff --git a/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java b/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java index 30325180..9a47628e 100644 --- a/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java @@ -28,6 +28,7 @@ import net.momirealms.customfishing.integration.item.*; import net.momirealms.customfishing.integration.mob.MythicMobsMobImpl; import net.momirealms.customfishing.integration.papi.PlaceholderManager; import net.momirealms.customfishing.integration.quest.BattlePassCFQuest; +import net.momirealms.customfishing.integration.quest.BetonQuestCFQuest; import net.momirealms.customfishing.integration.quest.ClueScrollCFQuest; import net.momirealms.customfishing.integration.season.CustomCropsSeasonImpl; import net.momirealms.customfishing.integration.season.RealisticSeasonsImpl; @@ -218,7 +219,7 @@ public class IntegrationManager extends Function { hookMessage("ClueScrolls"); } if (Bukkit.getPluginManager().isPluginEnabled("BetonQuest")) { - + BetonQuestCFQuest.register(); hookMessage("BetonQuest"); } if (Bukkit.getPluginManager().isPluginEnabled("BattlePass")) { diff --git a/src/main/java/net/momirealms/customfishing/manager/LootManager.java b/src/main/java/net/momirealms/customfishing/manager/LootManager.java index 7b8119f9..274f0dd1 100644 --- a/src/main/java/net/momirealms/customfishing/manager/LootManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/LootManager.java @@ -204,7 +204,7 @@ public class LootManager extends Function { if (material.contains(":")) { continue; } - Item item = new Item(Material.valueOf(material.toUpperCase())); + Item item = new Item(Material.valueOf(material.toUpperCase()), key); BonusManager.setItemProperties(config, key, item); if (item.getMaterial() == Material.AIR) LOOTITEMS.put(key, new ItemStack(Material.AIR)); else LOOTITEMS.put(key, ItemStackUtil.getFromItem(item)); diff --git a/src/main/java/net/momirealms/customfishing/manager/SellManager.java b/src/main/java/net/momirealms/customfishing/manager/SellManager.java index 20c609fc..ac59678e 100644 --- a/src/main/java/net/momirealms/customfishing/manager/SellManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/SellManager.java @@ -141,9 +141,9 @@ public class SellManager extends Function { @Override public void onJoin(Player player) { - Bukkit.getScheduler().runTaskAsynchronously(CustomFishing.plugin, () -> { + Bukkit.getScheduler().runTaskLaterAsynchronously(CustomFishing.plugin, () -> { CustomFishing.plugin.getDataManager().getDataStorageInterface().loadSellCache(player); - }); + }, 20); } private void loadConfig() { @@ -160,7 +160,7 @@ public class SellManager extends Function { soundSource = Sound.Source.valueOf(config.getString("sounds.type","player").toUpperCase()); if (config.contains("decorative-icons")){ config.getConfigurationSection("decorative-icons").getKeys(false).forEach(key -> { - Item item = new Item(Material.valueOf(config.getString("decorative-icons." + key + ".material", "PAPER").toUpperCase())); + Item item = new Item(Material.valueOf(config.getString("decorative-icons." + key + ".material", "PAPER").toUpperCase()), key); if (config.contains("decorative-icons." + key + ".display.name")) item.setName(config.getString("decorative-icons." + key + ".display.name")); if (config.contains("decorative-icons." + key + ".display.lore")) item.setLore(config.getStringList("decorative-icons." + key + ".display.lore")); if (config.contains("decorative-icons." + key + ".custom-model-data")) item.setCustomModelData(config.getInt("decorative-icons." + key + ".custom-model-data")); @@ -171,11 +171,11 @@ public class SellManager extends Function { }); } - sellIcon = new Item(Material.valueOf(config.getString("functional-icons.sell.material", "PAPER").toUpperCase())); + sellIcon = new Item(Material.valueOf(config.getString("functional-icons.sell.material", "PAPER").toUpperCase()), "sellIcon"); if (config.contains("functional-icons.sell.display.name")) sellIcon.setName(config.getString("functional-icons.sell.display.name")); if (config.contains("functional-icons.sell.display.lore")) sellIcon.setLore(config.getStringList("functional-icons.sell.display.lore")); if (config.contains("functional-icons.sell.custom-model-data")) sellIcon.setCustomModelData(config.getInt("functional-icons.sell.custom-model-data")); - denyIcon = new Item(Material.valueOf(config.getString("functional-icons.deny.material", "PAPER").toUpperCase())); + denyIcon = new Item(Material.valueOf(config.getString("functional-icons.deny.material", "PAPER").toUpperCase()), "denyIcon"); if (config.contains("functional-icons.deny.display.name")) denyIcon.setName(config.getString("functional-icons.deny.display.name")); if (config.contains("functional-icons.deny.display.lore")) denyIcon.setLore(config.getStringList("functional-icons.deny.display.lore")); if (config.contains("functional-icons.deny.custom-model-data")) denyIcon.setCustomModelData(config.getInt("functional-icons.deny.custom-model-data")); @@ -212,6 +212,10 @@ public class SellManager extends Function { public void openGuiForPlayer(Player player) { player.closeInventory(); + if (!playerCache.containsKey(player.getUniqueId())) { + AdventureUtil.consoleMessage("Sell cache is not loaded for player " + player.getName()); + return; + } Inventory inventory = Bukkit.createInventory(player, guiSize, "{CustomFishing_Sell}"); for (Map.Entry entry : guiItems.entrySet()) { inventory.setItem(entry.getKey(), entry.getValue()); diff --git a/src/main/java/net/momirealms/customfishing/object/loot/Item.java b/src/main/java/net/momirealms/customfishing/object/loot/Item.java index 735b9505..58b62c27 100644 --- a/src/main/java/net/momirealms/customfishing/object/loot/Item.java +++ b/src/main/java/net/momirealms/customfishing/object/loot/Item.java @@ -26,17 +26,20 @@ import java.util.Map; public class Item { + private final String key; private final Material material; private String name; private List lore; private List itemFlags; private int customModelData; private boolean unbreakable; + private String head64; private List enchantment; private Map nbt; - public Item(Material material) { + public Item(Material material, String key) { this.material = material; + this.key = key; } public Material getMaterial() { @@ -99,8 +102,20 @@ public class Item { this.nbt = nbt; } + public String getHead64() { + return head64; + } + + public void setHead64(String head64) { + this.head64 = head64; + } + + public String getKey() { + return key; + } + public Item cloneWithPrice(double price){ - Item newItem = new Item(this.material); + Item newItem = new Item(this.material, this.key); if (this.lore != null){ List lore = new ArrayList<>(); for (String text : this.lore) { diff --git a/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java b/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java index c4e956e6..daa0e95d 100644 --- a/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java +++ b/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java @@ -19,6 +19,8 @@ package net.momirealms.customfishing.util; import de.tr7zw.changeme.nbtapi.NBTCompound; import de.tr7zw.changeme.nbtapi.NBTItem; +import de.tr7zw.changeme.nbtapi.NBTListCompound; +import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customfishing.CustomFishing; @@ -82,6 +84,11 @@ public class ItemStackUtil { lore.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize("" + line))); }); } + if (item.getHead64() != null) { + NBTCompound nbtCompound = nbtItem.addCompound("SkullOwner"); + NBTListCompound texture = nbtCompound.addCompound("Properties").getCompoundList("textures").addCompound(); + texture.setString("Value", item.getHead64()); + } if (item.getNbt() != null) NBTUtil.setTags(item.getNbt(), nbtItem); return nbtItem.getItem(); } @@ -132,8 +139,7 @@ public class ItemStackUtil { if (loot == null) return; } if (!(loot instanceof DroppedItem droppedItem)) return; - String key = droppedItem.getMaterial(); - ItemStack itemStack = CustomFishing.plugin.getIntegrationManager().build(key); + ItemStack itemStack = CustomFishing.plugin.getFishingManager().getCustomFishingLootItemStack(droppedItem, player); if (itemStack.getType() == Material.AIR) return; itemStack.setAmount(amount); player.getInventory().addItem(itemStack); @@ -166,35 +172,6 @@ public class ItemStackUtil { YamlConfiguration yamlConfiguration = new YamlConfiguration(); yamlConfiguration.set(fileName + ".material", itemStack.getType().toString()); - ItemMeta itemMeta = itemStack.getItemMeta(); - if (itemMeta.hasCustomModelData()) { - yamlConfiguration.set(fileName + ".custom-model-data", itemMeta.getCustomModelData()); - } - if (itemMeta.isUnbreakable()) { - yamlConfiguration.set(fileName + ".unbreakable", itemMeta.isUnbreakable()); - } - if (itemMeta.hasEnchants()) { - Map map = new HashMap<>(); - itemMeta.getEnchants().forEach((enchantment, level) -> { - map.put(String.valueOf(enchantment.getKey()), level); - }); - yamlConfiguration.createSection(fileName + ".enchantments", map); - } - if (itemMeta instanceof EnchantmentStorageMeta enchantmentStorageMeta){ - Map map = new HashMap<>(); - enchantmentStorageMeta.getStoredEnchants().forEach(((enchantment, level) -> { - map.put(String.valueOf(enchantment.getKey()), level); - })); - yamlConfiguration.createSection(fileName + ".enchantments", map); - } - if (itemMeta.getItemFlags().size() > 0){ - ArrayList itemFlags = new ArrayList<>(); - itemStack.getItemFlags().forEach(itemFlag -> { - itemFlags.add(itemFlag.name()); - }); - yamlConfiguration.set(fileName + ".item_flags", itemFlags); - } - NBTItem nbtItem = new NBTItem(itemStack); Map map0 = compoundToMap(nbtItem); @@ -252,11 +229,6 @@ public class ItemStackUtil { public static Map compoundToMap(NBTCompound nbtCompound){ Map map = new HashMap<>(); nbtCompound.getKeys().forEach(key -> { - if (key.equals("Enchantments") - || key.equals("HideFlags") - || key.equals("CustomModelData") - || key.equals("StoredEnchantments") - || key.equals("Unbreakable")) return; switch (nbtCompound.getType(key)){ case NBTTagByte -> map.put(key, "(Byte) " + nbtCompound.getByte(key)); case NBTTagInt -> map.put(key, "(Int) " + nbtCompound.getInteger(key)); @@ -274,6 +246,40 @@ public class ItemStackUtil { case NBTTagList -> { List list = new ArrayList<>(); switch (nbtCompound.getListType(key)) { + case NBTTagCompound -> nbtCompound.getCompoundList(key).forEach(a -> list.add(compoundToMap(a))); + case NBTTagInt -> nbtCompound.getIntegerList(key).forEach(a -> list.add("(Int) " + a)); + case NBTTagDouble -> nbtCompound.getDoubleList(key).forEach(a -> list.add("(Double) " + a)); + case NBTTagString -> nbtCompound.getStringList(key).forEach(a -> list.add("(String) " + a)); + case NBTTagFloat -> nbtCompound.getFloatList(key).forEach(a -> list.add("(Float) " + a)); + case NBTTagLong -> nbtCompound.getLongList(key).forEach(a -> list.add("(Long) " + a)); + case NBTTagIntArray -> nbtCompound.getIntArrayList(key).forEach(a -> list.add("(IntArray) " + Arrays.toString(a))); + default -> nbtCompound.getUUIDList(key).forEach(a -> list.add("(UUID) " + a)); + } + map.put(key, list); + } + } + }); + return map; + } + + + public static Map compoundToMap(ReadWriteNBT nbtCompound){ + Map map = new HashMap<>(); + nbtCompound.getKeys().forEach(key -> { + switch (nbtCompound.getType(key)){ + case NBTTagByte -> map.put(key, "(Byte) " + nbtCompound.getByte(key)); + case NBTTagInt -> map.put(key, "(Int) " + nbtCompound.getInteger(key)); + case NBTTagDouble -> map.put(key, "(Double) " + nbtCompound.getDouble(key)); + case NBTTagLong -> map.put(key, "(Long) " + nbtCompound.getLong(key)); + case NBTTagFloat -> map.put(key, "(Float) " + nbtCompound.getFloat(key)); + case NBTTagShort -> map.put(key, "(Short) " + nbtCompound.getShort(key)); + case NBTTagString -> map.put(key, "(String) " + nbtCompound.getString(key)); + case NBTTagByteArray -> map.put(key, "(ByteArray) " + Arrays.toString(nbtCompound.getByteArray(key))); + case NBTTagIntArray -> map.put(key, "(IntArray) " + Arrays.toString(nbtCompound.getIntArray(key))); + case NBTTagList -> { + List list = new ArrayList<>(); + switch (nbtCompound.getListType(key)) { + case NBTTagCompound -> nbtCompound.getCompoundList(key).forEach(a -> list.add(compoundToMap(a))); case NBTTagInt -> nbtCompound.getIntegerList(key).forEach(a -> list.add("(Int) " + a)); case NBTTagDouble -> nbtCompound.getDoubleList(key).forEach(a -> list.add("(Double) " + a)); case NBTTagString -> nbtCompound.getStringList(key).forEach(a -> list.add("(String) " + a)); diff --git a/src/main/java/net/momirealms/customfishing/util/NBTUtil.java b/src/main/java/net/momirealms/customfishing/util/NBTUtil.java index 45159450..c5af04ee 100644 --- a/src/main/java/net/momirealms/customfishing/util/NBTUtil.java +++ b/src/main/java/net/momirealms/customfishing/util/NBTUtil.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.util; import de.tr7zw.changeme.nbtapi.NBTCompound; import de.tr7zw.changeme.nbtapi.NBTItem; +import de.tr7zw.changeme.nbtapi.NBTListCompound; import org.bukkit.configuration.MemorySection; import org.bukkit.inventory.ItemStack; @@ -41,10 +42,12 @@ public class NBTUtil { NBTCompound newCompound = nbtCompound.addCompound(key); setTags(memorySection.getValues(false), newCompound); } - else if (map.get(key) instanceof List list){ + else if (map.get(key) instanceof List list){ for (Object o : list) { if (o instanceof String value) { setListValue(key, value, nbtCompound); + } else if (o instanceof Map map1) { + setCompoundList(key, map1, nbtCompound); } } } @@ -54,6 +57,11 @@ public class NBTUtil { } } + private static void setCompoundList(String key, Map map, NBTCompound nbtCompound) { + NBTListCompound nbtListCompound = nbtCompound.getCompoundList(key).addCompound(); + setTags((Map) map, nbtListCompound); + } + private static void setListValue(String key, String value, NBTCompound nbtCompound) { if (value.startsWith("(String) ")) { nbtCompound.getStringList(key).add(value.substring(9));