From a5ab2c926929d3ae0bd24c1fa2db3916123c67a3 Mon Sep 17 00:00:00 2001 From: Ka0rX Date: Mon, 13 Jun 2022 20:38:34 +0200 Subject: [PATCH] Debug Automatic WayPoints --- .../mmocore/api/player/PlayerData.java | 54 ++++++- .../admin/SkillTreePointsCommandTreeNode.java | 4 +- .../Indyuce/mmocore/gui/SkillTreeViewer.java | 4 +- .../mmocore/tree/IntegerCoordinates.java | 1 - .../Indyuce/mmocore/tree/SkillTreeNode.java | 69 ++++++-- .../tree/skilltree/AutomaticSkillTree.java | 63 ++++---- .../mmocore/tree/skilltree/SkillTree.java | 45 +++--- .../tree/skilltree/display/DisplayInfo.java | 2 + .../default/skilltree/autocombat.yml | 143 ++++++++++++++++ .../resources/default/skilltree/combat.yml | 152 ++++++++++++++++-- 10 files changed, 449 insertions(+), 88 deletions(-) create mode 100644 src/main/resources/default/skilltree/autocombat.yml diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index be67bdf3..f5cfb9a9 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -3,9 +3,11 @@ package net.Indyuce.mmocore.api.player; import io.lumine.mythic.lib.api.player.MMOPlayerData; import io.lumine.mythic.lib.player.TemporaryPlayerData; import io.lumine.mythic.lib.player.cooldown.CooldownMap; +import io.lumine.mythic.lib.player.modifier.PlayerModifier; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.SoundEvent; +import net.Indyuce.mmocore.api.quest.trigger.Trigger; import net.Indyuce.mmocore.player.Unlockable; import net.Indyuce.mmocore.tree.IntegerCoordinates; import net.Indyuce.mmocore.tree.NodeState; @@ -78,7 +80,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc */ @Nullable private PlayerClass profess; - private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints,skillTreeReallocationPoints;// skillReallocationPoints, + private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints;// skillReallocationPoints, private double experience; private double mana, stamina, stellium; private Guild guild; @@ -217,12 +219,26 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc return skillTreePoints.containsKey(treeId); } + + public void removeModifiersFrom(SkillTree skillTree) { + for (SkillTreeNode node : skillTree.getNodes()) { + for (int i = 0; i < node.getMaxLevel(); i++) { + List modifiers = node.getModifiers(i); + if (modifiers != null) { + for (PlayerModifier modifier : modifiers) { + modifier.unregister(getMMOPlayerData()); + } + } + } + } + } + public boolean canIncrementNodeLevel(SkillTreeNode node) { NodeState nodeState = nodeStates.get(node); //Check the State of the node if (nodeState != NodeState.UNLOCKED && nodeState != NodeState.UNLOCKABLE) return false; - return getNodeLevel(node) 0 || skillTreePoints.get("global") > 0); + return getNodeLevel(node) < node.getMaxLevel() && (skillTreePoints.get(node.getTree().getId()) > 0 || skillTreePoints.get("global") > 0); } /** @@ -231,14 +247,37 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc */ public void incrementNodeLevel(SkillTreeNode node) { setNodeLevel(node, getNodeLevel(node) + 1); + //Triggers the triggers of the node + List triggers = node.getTriggers(getNodeLevel(node)); + if (triggers != null) { + for (Trigger trigger : triggers) { + trigger.apply(this); + } + + } + + //Applies player modifiers + List modifiers = node.getModifiers(getNodeLevel(node)); + + if (modifiers != null) { + Bukkit.broadcastMessage("Modifier: "+modifiers.size()); + for (PlayerModifier modifier : modifiers) { + modifier.register(getMMOPlayerData()); + } + } + + Bukkit.broadcastMessage(playerStats.getStat(StatType.HEALTH_REGENERATION)+""); + if (nodeStates.get(node) == NodeState.UNLOCKABLE) setNodeState(node, NodeState.UNLOCKED); if (skillTreePoints.get(node.getTree().getId()) > 0) withdrawSkillTreePoints(node.getTree().getId(), 1); else withdrawSkillTreePoints("global", 1); - //We unload the nodeStates map and reload it completely - nodeStates= new HashMap<>(); + //We unload the nodeStates map (for the skill tree) and reload it completely + for (SkillTreeNode node1 : node.getTree().getNodes()) { + nodeStates.remove(node1); + } node.getTree().setupNodeState(this); } @@ -250,13 +289,18 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc SkillTree skillTree = node.getTree(); DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize()); + return skillTree.getIcon(displayInfo); } public Icon getIcon(SkillTree skillTree, IntegerCoordinates coordinates) { + if (skillTree.isNode(coordinates)) { SkillTreeNode node = skillTree.getNode(coordinates); + if (nodeStates.get(node) == null) { + skillTree.getNodes().forEach(nodee -> Bukkit.broadcastMessage(nodee.getId() + " " + nodeStates.get(nodee))); + } DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize()); return skillTree.getIcon(displayInfo); } @@ -399,7 +443,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc } public void giveSkillTreeReallocationPoints(int amount) { - skillTreeReallocationPoints+=amount; + skillTreeReallocationPoints += amount; } @Override diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillTreePointsCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillTreePointsCommandTreeNode.java index 40dc9ab0..a75511be 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillTreePointsCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillTreePointsCommandTreeNode.java @@ -20,8 +20,8 @@ import java.util.stream.Collectors; public class SkillTreePointsCommandTreeNode extends CommandTreeNode { BiFunction get; - public SkillTreePointsCommandTreeNode(CommandTreeNode parent, TriConsumer give, - TriConsumer set, BiFunction get) { + public SkillTreePointsCommandTreeNode(CommandTreeNode parent, TriConsumer set, + TriConsumer give, BiFunction get) { super(parent, "skill-tree-points"); addChild(new ActionCommandTreeNode(this, "give", give)); addChild(new ActionCommandTreeNode(this, "set", set)); diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java b/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java index ab0f2bfb..ebcaa83e 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java @@ -181,7 +181,7 @@ public class SkillTreeViewer extends EditableInventory { //If it is path we remove the display name and the lore. else { meta.setLore(new ArrayList<>()); - meta.setDisplayName(""); + meta.setDisplayName(" "); } meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); PersistentDataContainer container = meta.getPersistentDataContainer(); @@ -297,6 +297,8 @@ public class SkillTreeViewer extends EditableInventory { //We remove all the nodeStates progress playerData.giveSkillTreePoints(skillTree.getId(), reallocated); playerData.giveSkillTreeReallocationPoints(-1); + //We unregister all the modifiers or the player + playerData.removeModifiersFrom(skillTree); for (SkillTreeNode node : skillTree.getNodes()) { playerData.setNodeLevel(node, 0); playerData.setNodeState(node, NodeState.LOCKED); diff --git a/src/main/java/net/Indyuce/mmocore/tree/IntegerCoordinates.java b/src/main/java/net/Indyuce/mmocore/tree/IntegerCoordinates.java index f5bb5427..544c8e6f 100644 --- a/src/main/java/net/Indyuce/mmocore/tree/IntegerCoordinates.java +++ b/src/main/java/net/Indyuce/mmocore/tree/IntegerCoordinates.java @@ -23,7 +23,6 @@ public class IntegerCoordinates { public int getX() { return x; } - public int getY() { return y; } diff --git a/src/main/java/net/Indyuce/mmocore/tree/SkillTreeNode.java b/src/main/java/net/Indyuce/mmocore/tree/SkillTreeNode.java index 87721873..6e9a386e 100644 --- a/src/main/java/net/Indyuce/mmocore/tree/SkillTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/tree/SkillTreeNode.java @@ -2,7 +2,10 @@ package net.Indyuce.mmocore.tree; import com.gmail.nossr50.mcmmo.acf.annotation.HelpSearchTags; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.api.MMOLineConfig; import io.lumine.mythic.lib.player.modifier.PlayerModifier; +import io.lumine.mythic.lib.util.configobject.ConfigObject; +import io.lumine.mythic.lib.util.configobject.LineConfigObject; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.quest.trigger.Trigger; @@ -17,6 +20,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; import java.util.*; +import java.util.logging.Level; //We must use generics to get the type of the corresponding tree public class SkillTreeNode implements Unlockable { @@ -30,8 +34,8 @@ public class SkillTreeNode implements Unlockable { private final HashMap> lores = new HashMap<>(); //TODO modifiers depending on level with drop tables - private final HashMap> modifiers = new HashMap<>(); - private final HashMap> triggers = new HashMap<>(); + private final HashMap> modifiers = new HashMap<>(); + private final HashMap> triggers = new HashMap<>(); //The max level the skill tree node can have and the max amount of children it can have. private final int maxLevel, maxChildren, size; private final ArrayList children = new ArrayList<>(); @@ -43,7 +47,7 @@ public class SkillTreeNode implements Unlockable { private final HashMap softParents = new HashMap<>(); - private final HashMap strongParents = new HashMap<>(); + private final HashMap strongParents = new HashMap<>(); public SkillTreeNode(SkillTree tree, ConfigurationSection config) { @@ -59,7 +63,7 @@ public class SkillTreeNode implements Unlockable { for (String state : Objects.requireNonNull(config.getConfigurationSection("lores")).getKeys(false)) { NodeState nodeState = NodeState.valueOf(MMOCoreUtils.toEnumName(state)); if (nodeState == NodeState.UNLOCKED) { - //TODO: Message could'nt load ... instead of exception + //TODO: Message could'nt load ... instead of exce/*99+*-*99**9+-ption ConfigurationSection section = config.getConfigurationSection("lores." + state); for (String level : section.getKeys(false)) { lores.put(new NodeContext(nodeState, Integer.parseInt(level)), section.getStringList(level)); @@ -68,6 +72,45 @@ public class SkillTreeNode implements Unlockable { lores.put(new NodeContext(nodeState, 0), config.getStringList("lores." + state)); } } + //We load the triggers + if (config.contains("triggers")) { + try { + ConfigurationSection section = config.getConfigurationSection("triggers"); + for (String level : section.getKeys(false)) { + int value = Integer.parseInt(level); + for (String str : section.getStringList(level)) { + Trigger trigger = MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(str)); + if (!triggers.containsKey(value)) { + triggers.put(value, new ArrayList<>()); + } + triggers.get(value).add(trigger); + } + } + } catch (NumberFormatException e) { + MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't load triggers for the skill node " + tree.getId() + "." + id + " :Problem with the Number Format."); + } + } + //We load the player Modifiers + if (config.contains("modifiers")) { + try { + ConfigurationSection section = config.getConfigurationSection("modifiers"); + for (String level : section.getKeys(false)) { + int value = Integer.parseInt(level); + for (String str : section.getStringList(level)) { + PlayerModifier modifier = MythicLib.plugin.getModifiers().loadPlayerModifier(new LineConfigObject(new MMOLineConfig(str))); + if (!modifiers.containsKey(value)) { + modifiers.put(value, new ArrayList<>()); + } + modifiers.get(value).add(modifier); + } + } + + } catch (NumberFormatException e) { + MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't load modifiers for the skill node " + tree.getId() + "." + id+ " :Problem with the Number Format."); + } + } + + maxLevel = config.contains("max-level") ? config.getInt("max-level") : 1; maxChildren = config.contains("max-children") ? config.getInt("max-children") : 1; //If coordinates are precised adn we are not wiht an automaticTree we set them up @@ -90,6 +133,11 @@ public class SkillTreeNode implements Unlockable { return tree; } + + public void setIsRoot() { + isRoot = true; + } + public boolean isRoot() { return isRoot; } @@ -148,19 +196,19 @@ public class SkillTreeNode implements Unlockable { } public String getName() { - return MythicLib.plugin.parseColors( name); + return MythicLib.plugin.parseColors(name); } public IntegerCoordinates getCoordinates() { return coordinates; } - public Set getModifiers(int level) { + public List getModifiers(int level) { return modifiers.get(level); } - public Set getTriggers(int level) { + public List getTriggers(int level) { return triggers.get(level); } @@ -244,15 +292,14 @@ public class SkillTreeNode implements Unlockable { public List getLore(PlayerData playerData) { Placeholders holders = getPlaceholders(playerData); List parsedLore = new ArrayList<>(); - NodeContext context= new NodeContext(playerData.getNodeState(this),playerData.getNodeLevel(this)); + NodeContext context = new NodeContext(playerData.getNodeState(this), playerData.getNodeLevel(this)); lores.get(context).forEach(string -> parsedLore.add( - MythicLib.plugin.parseColors( holders.apply(playerData.getPlayer(), string)))); + MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string)))); return parsedLore; } - /** * @param namespacedKey Something like "skill_tree:tree_name_1_5" * @return The corresponding skill tree node @@ -315,6 +362,4 @@ public class SkillTreeNode implements Unlockable { } - - } diff --git a/src/main/java/net/Indyuce/mmocore/tree/skilltree/AutomaticSkillTree.java b/src/main/java/net/Indyuce/mmocore/tree/skilltree/AutomaticSkillTree.java index a90b5cce..0e6cd986 100644 --- a/src/main/java/net/Indyuce/mmocore/tree/skilltree/AutomaticSkillTree.java +++ b/src/main/java/net/Indyuce/mmocore/tree/skilltree/AutomaticSkillTree.java @@ -1,5 +1,6 @@ package net.Indyuce.mmocore.tree.skilltree; +import com.guillaumevdn.questcreator.integration.mythicmobs.v4.element.ElementMythicMobsObjective; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.tree.IntegerCoordinates; import net.Indyuce.mmocore.tree.ParentType; @@ -16,8 +17,7 @@ import java.util.logging.Level; /** * Skill Trees where you only need to fill the strong and soft */ -public class AutomaticSkillTree extends SkillTree { - private SkillTreeNode root; +public class AutomaticSkillTree extends SkillTree { //Hash map to store the number of left and right branches of each node private final HashMap nodeBranches = new HashMap<>(); @@ -31,17 +31,17 @@ public class AutomaticSkillTree extends SkillTree { //We setup the children and parents for each node. - for(SkillTreeNode node:nodes.values()) { - ConfigurationSection section = config.getConfigurationSection("nodes."+node.getId() + ".children.soft"); - if(section!=null) { + for (SkillTreeNode node : nodes.values()) { + ConfigurationSection section = config.getConfigurationSection("nodes." + node.getId() + ".children.soft"); + if (section != null) { for (String child : section.getKeys(false)) { node.addChild(getNode(child)); getNode(child).addParent(node, section.getInt(child), ParentType.SOFT); } } - section = config.getConfigurationSection("nodes."+node.getId() + ".children.strong"); + section = config.getConfigurationSection("nodes." + node.getId() + ".children.strong"); - if(section!=null) { + if (section != null) { for (String child : section.getKeys(false)) { node.addChild(getNode(child)); getNode(child).addParent(node, section.getInt(child), ParentType.STRONG); @@ -51,23 +51,24 @@ public class AutomaticSkillTree extends SkillTree { } //We find the root of the tree wich is for (SkillTreeNode node : nodes.values()) { - if (node.getSoftParents().size() == 0&&node.getStrongParents().size()==0) { - Validate.isTrue(root == null, "You can't have 2 roots on one automatic skill tree. You have "+(root!=null?root.getName():"")+" and "+node.getName()+"."); - root = node; - - + if (node.getSoftParents().size() == 0 && node.getStrongParents().size() == 0) { + Validate.isTrue(roots.size() == 0, "You can't have 2 roots on one automatic skill tree. You have " + (roots.size() != 0 ? roots.get(0).getName() : "") + " and " + node.getName() + "."); + //We mark the node as a root also + roots.add(node); + node.setIsRoot(); } } + //We setup the width of all the nodes recursively - setupTreeWidth(root); + setupTreeWidth(roots.get(0)); //We recursively setup all the coordinates of the tree nodes - root.setCoordinates(new IntegerCoordinates(0, 0)); - setupCoordinates(root); + roots.get(0).setCoordinates(new IntegerCoordinates(0, 0)); + setupCoordinates(roots.get(0)); //We get and cache the values of minX,minY,maxX and maxY - minX = nodeBranches.get(root).getLeftBranches(); + minX = nodeBranches.get(roots.get(0)).getLeftBranches(); minY = 0; - maxX = nodeBranches.get(root).getRightBranches(); + maxX = nodeBranches.get(roots.get(0)).getRightBranches(); for (SkillTreeNode node : nodes.values()) { if (node.getCoordinates().getY() > maxY) @@ -86,26 +87,29 @@ public class AutomaticSkillTree extends SkillTree { * @param node the root */ private void setupCoordinates(SkillTreeNode node) { + if (node.isRoot()) { + node.setCoordinates(new IntegerCoordinates(0, 2)); + } int childrenSize = node.getChildren().size(); + int x = node.getCoordinates().getX(); - ; int y = node.getCoordinates().getY(); - ; + int leftOffset = 0; int rightOffset = 0; for (int i = 0; i < childrenSize; i++) { SkillTreeNode child = node.getChildren().get(i); - if (childrenSize % 2 == 0 && i == 0) { - child.setCoordinates(new IntegerCoordinates(x, y + 2)); + if (childrenSize % 2 == 1 && i == 0) { + child.setCoordinates(new IntegerCoordinates(x, y - 2)); leftOffset += 2 + nodeBranches.get(child).getLeftBranches(); rightOffset += 2 + nodeBranches.get(child).getRightBranches(); } else if (i % 2 == 0) { - child.setCoordinates(new IntegerCoordinates(x - leftOffset - 2 - nodeBranches.get(child).getWidth(), y + 2)); - for(SkillTreeNode skillTree : nodeBranches.keySet()) - leftOffset += 2 + nodeBranches.get(child).getWidth(); + child.setCoordinates(new IntegerCoordinates(x - leftOffset - 2 - nodeBranches.get(child).getWidth(), y - 2)); + for (SkillTreeNode skillTree : nodeBranches.keySet()) + leftOffset += 2 + nodeBranches.get(child).getWidth(); } else { - child.setCoordinates(new IntegerCoordinates(x + rightOffset + 2 + nodeBranches.get(child).getWidth(), y + 2)); + child.setCoordinates(new IntegerCoordinates(x + rightOffset + 2 + nodeBranches.get(child).getWidth(), y - 2)); rightOffset += 2 + nodeBranches.get(child).getWidth(); } @@ -113,11 +117,12 @@ public class AutomaticSkillTree extends SkillTree { int childX = child.getCoordinates().getX(); int childY = child.getCoordinates().getY(); - int parentX = node.getSoftParents().size()!=0?((SkillTreeNode)node.getSoftParents().toArray()[0]).getCoordinates().getX():((SkillTreeNode)node.getStrongParents().toArray()[0]).getCoordinates().getX(); - paths.add(new IntegerCoordinates(childX, childY - 1)); + int parentX=node.getCoordinates().getX(); + + paths.add(new IntegerCoordinates(childX, childY + 1)); int offset = childX > parentX ? -1 : 1; while (childX != parentX) { - paths.add(new IntegerCoordinates(childX, childY - 2)); + paths.add(new IntegerCoordinates(childX, childY + 2)); childX += offset; } @@ -155,7 +160,7 @@ public class AutomaticSkillTree extends SkillTree { } } - nodeBranches.put(node,new Branches(leftBranches,rightBranches)); + nodeBranches.put(node, new Branches(leftBranches, rightBranches)); } private class Branches { diff --git a/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java b/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java index 62f6f75b..01a6a013 100644 --- a/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java +++ b/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java @@ -2,6 +2,7 @@ package net.Indyuce.mmocore.tree.skilltree; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.util.PostLoadObject; +import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.manager.registry.RegisterObject; @@ -39,7 +40,7 @@ import java.util.logging.Level; */ public abstract class SkillTree extends PostLoadObject implements RegisterObject { private final String id, name; - private final List lore=new ArrayList<>(); + private final List lore = new ArrayList<>(); private final Material item; //2 different maps to get the nodes @@ -51,13 +52,13 @@ public abstract class SkillTree extends PostLoadObject implements RegisterObject //Caches the height of the skill tree protected int minX, minY, maxX, maxY; protected final HashMap icons = new HashMap<>(); - protected final HashSet roots = new HashSet<>(); + protected final List roots = new ArrayList<>(); public SkillTree(ConfigurationSection config) { super(config); this.id = Objects.requireNonNull(config.getString("id"), "Could not find skill tree id"); this.name = MythicLib.plugin.parseColors(Objects.requireNonNull(config.getString("name"), "Could not find skill tree name")); - Objects.requireNonNull(config.getStringList("lore"),"Could not find skill tree lore").forEach(str->lore.add(MythicLib.plugin.parseColors(str ))); + Objects.requireNonNull(config.getStringList("lore"), "Could not find skill tree lore").forEach(str -> lore.add(MythicLib.plugin.parseColors(str))); this.item = Material.valueOf(MMOCoreUtils.toEnumName(Objects.requireNonNull(config.getString("item")))); Validate.isTrue(config.isConfigurationSection("nodes"), "Could not find any nodes in the tree"); for (String key : config.getConfigurationSection("nodes").getKeys(false)) { @@ -84,19 +85,14 @@ public abstract class SkillTree extends PostLoadObject implements RegisterObject for (String key : config.getConfigurationSection("icons").getKeys(false)) { if (key.equalsIgnoreCase("path")) { icons.put(DisplayInfo.pathInfo, new Icon(config.getConfigurationSection("icons." + key))); + continue; } for (String size : config.getConfigurationSection("icons." + key).getKeys(false)) { - if(key.equalsIgnoreCase("path")) { - DisplayInfo displayInfo = DisplayInfo.pathInfo; - Icon icon = new Icon(config.getConfigurationSection("icons." + key)); - icons.put(displayInfo, icon); + DisplayInfo displayInfo = new DisplayInfo(NodeState.valueOf(MMOCoreUtils.toEnumName(key)), Integer.parseInt(size)); + Icon icon = new Icon(config.getConfigurationSection("icons." + key + "." + size)); + icons.put(displayInfo, icon); - } - else { - DisplayInfo displayInfo = new DisplayInfo(NodeState.valueOf(MMOCoreUtils.toEnumName(key)), Integer.parseInt(size)); - Icon icon = new Icon(config.getConfigurationSection("icons." + key + "." + size)); - icons.put(displayInfo, icon); - }} + } } } catch (Exception e) { Bukkit.getLogger().log(Level.WARNING, "Couldn't load icons for the skill tree " + id); @@ -120,8 +116,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisterObject protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection); public Icon getIcon(DisplayInfo info) { - Validate.isTrue(icons.containsKey(info),"The icon corresponding to "+(info.getNodeState()==null? "path": "node-state: "+info.getNodeState() - +" ,size: "+info.getSize())+" doesn't exist in the icons of the skill-tree yml." ); + Validate.isTrue(icons.containsKey(info), "The icon corresponding to " + info + " doesn't exist for the skill tree " + id + "."); return icons.get(info); } @@ -181,19 +176,23 @@ public abstract class SkillTree extends PostLoadObject implements RegisterObject } + public List getRoots() { + return roots; + } + /** * Update recursively the state of all the nodes that are children of this node (Used when we change the state of a node) */ public void setupNodeStateFrom(SkillTreeNode node, PlayerData playerData) { - if (playerData.getNodeLevel(node) > 0) { + if (playerData.getNodeLevel(node) > 0) { playerData.setNodeState(node, NodeState.UNLOCKED); } else if (playerData.getNodeLevel(node) == 0 && node.isRoot()) { playerData.setNodeState(node, NodeState.UNLOCKABLE); } else { - boolean isUnlockableFromStrongParent = true; - boolean isUnlockableFromSoftParent = false; - boolean isFullyLockedFromStrongParent = false; - boolean isFullyLockedFromSoftParent = true; + boolean isUnlockableFromStrongParent = node.getStrongParents().size()==0?true:true; + boolean isUnlockableFromSoftParent = node.getSoftParents().size()==0?true:false; + boolean isFullyLockedFromStrongParent = node.getStrongParents().size()==0?false:false; + boolean isFullyLockedFromSoftParent = node.getSoftParents().size()==0?false:true; for (SkillTreeNode strongParent : node.getStrongParents()) { if (playerData.getNodeLevel(strongParent) < node.getParentNeededLevel(strongParent)) { @@ -209,6 +208,9 @@ public abstract class SkillTree extends PostLoadObject implements RegisterObject if (numberChildren >= strongParent.getMaxChildren() || playerData.getNodeState(strongParent) == NodeState.FULLY_LOCKED) isFullyLockedFromStrongParent = true; } + + + for (SkillTreeNode softParent : node.getSoftParents()) { if (playerData.getNodeLevel(softParent) > node.getParentNeededLevel(softParent)) { isUnlockableFromSoftParent = true; @@ -219,8 +221,9 @@ public abstract class SkillTree extends PostLoadObject implements RegisterObject if (playerData.getNodeLevel(child) > 0) numberChildren++; if (numberChildren < softParent.getMaxChildren() && playerData.getNodeState(softParent) != NodeState.FULLY_LOCKED) - isFullyLockedFromStrongParent = false; + isFullyLockedFromSoftParent = false; } + boolean isFullyLocked = isFullyLockedFromSoftParent || isFullyLockedFromStrongParent; boolean isUnlockable = isUnlockableFromSoftParent && isUnlockableFromStrongParent; if (isFullyLocked) diff --git a/src/main/java/net/Indyuce/mmocore/tree/skilltree/display/DisplayInfo.java b/src/main/java/net/Indyuce/mmocore/tree/skilltree/display/DisplayInfo.java index b5431885..2c991640 100644 --- a/src/main/java/net/Indyuce/mmocore/tree/skilltree/display/DisplayInfo.java +++ b/src/main/java/net/Indyuce/mmocore/tree/skilltree/display/DisplayInfo.java @@ -42,6 +42,8 @@ public class DisplayInfo { if(!(obj instanceof DisplayInfo)) return false; DisplayInfo displayInfo= (DisplayInfo) obj; + if(nodeState==null) + return displayInfo.getNodeState()==null; return nodeState==displayInfo.getNodeState()&&size==displayInfo.getSize(); } diff --git a/src/main/resources/default/skilltree/autocombat.yml b/src/main/resources/default/skilltree/autocombat.yml new file mode 100644 index 00000000..9fb30c62 --- /dev/null +++ b/src/main/resources/default/skilltree/autocombat.yml @@ -0,0 +1,143 @@ +id: autocombat +name: AutoCombat +type: automatic +item: GOLDEN_AXE +lore: +- '&6This autoskill tree is used for combat abilities!' + +nodes: + strength: + name: 'Combat strength' + children: + strong: + force: 2 + + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + #modifers + + force: + name: 'Force' + size: 1 + max-children: 1 + children: + strong: + weaponry: 1 + archery: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + + weaponry: + name: 'Weaponry' + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + + archery: + name: 'Archery' + + max-level: 2 + size: 1 + children: + strong: + archery2: 2 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + archery2: + name: 'Archery2' + + max-level: 2 + size: 1 + children: + strong: + archery3: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + archery3: + name: 'Archery3' + + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + + + +icons: + unlocked: + 1: + item: 'GREEN_DYE' + locked: + 1: + item: "BROWN_DYE" + unlockable: + 1: + item: "BLUE_DYE" + fully-locked: + 1: + item: "BLACK_DYE" + path: + item: "WHITE_DYE" diff --git a/src/main/resources/default/skilltree/combat.yml b/src/main/resources/default/skilltree/combat.yml index fc591627..d04474ff 100644 --- a/src/main/resources/default/skilltree/combat.yml +++ b/src/main/resources/default/skilltree/combat.yml @@ -1,34 +1,152 @@ id: 'combat' -name: 'Combat Skill Tree' - - -#The type of the Skill tree, can be : -#'linked'->You must only precise nodes coordinates. 2 adjacent nodes will be affiliated. The root is at coordinates 0,0. -#'automatic'-> You must only precise the children(there can more than 1) of each node. Each node can only have one parent and the root has none. -# The display coordinates will be automatically calculated to have a good render. -#'custom'-> You must precise coordinates and children for each node, each node can have multiple parents and children. -# The coordinates are only used for display on the GUI but will not have any impact on the affiliation between nodes. - +name: '&4Combat' +lore: +- '&6This skill tree is used for combat abilities!' type: 'linked' - -#The item that will represent the skill tree in the GUI -item: 'DIAMOND_SWORD' - +item: 'DIAMOND_AXE' nodes: strength: name: 'Combat strength' - #Coordinates of the node coordinates: x: 0 y: 0 - strength2: - name: 'Combat strength 2' + + max-level: 2 + is-root: true + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + #modifers + + force: + name: 'Force' + size: 1 + max-children: 1 coordinates: x: 1 y: 0 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + + weaponry: + name: 'Weaponry' + coordinates: + x: 2 + y: 0 + + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + + archery: + name: 'Archery' + coordinates: + x: 1 + y: 1 + + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + archery2: + name: 'Archery2' + coordinates: + x: 1 + y: 2 + + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' + archery3: + name: 'Archery3' + coordinates: + x: 1 + y: 3 + + max-level: 2 + size: 1 + lores: + unlocked: + 1 : + - "&eYou are level 1" + 2: + - "&eYou are level 2" + locked: + - "&4This skill is locked" + unlockable: + - "&aThis skill is unlockable" + fully-locked: + - '&aThis is skill is fully locked' paths: coordinates: x: 2 y: 2 +icons: + unlocked: + 1: + item: 'GREEN_DYE' + locked: + 1: + item: "BROWN_DYE" + unlockable: + 1: + item: "BLUE_DYE" + fully-locked: + 1: + item: "BLACK_DYE" + path: + item: "WHITE_DYE"