diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index 7b688d54..8c8e1d21 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -49,8 +49,8 @@ import net.Indyuce.mmocore.skilltree.IntegerCoordinates; import net.Indyuce.mmocore.skilltree.NodeStatus; import net.Indyuce.mmocore.skilltree.SkillTreeNode; import net.Indyuce.mmocore.skilltree.tree.SkillTree; -import net.Indyuce.mmocore.skilltree.tree.display.DisplayInfo; -import net.Indyuce.mmocore.skilltree.tree.display.Icon; +import net.Indyuce.mmocore.gui.skilltree.display.DisplayInfo; +import net.Indyuce.mmocore.gui.skilltree.display.Icon; import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.waypoint.WaypointOption; import net.md_5.bungee.api.ChatMessageType; @@ -308,27 +308,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc node.getTree().setupNodeStates(this); } - /** - * Returns the icon the node should have. - */ - public Icon getIcon(SkillTreeNode node) { - 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); - DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize()); - return skillTree.getIcon(displayInfo); - } - if (skillTree.isPath(coordinates)) return skillTree.getIcon(DisplayInfo.pathInfo); - return null; - } public int getSkillTreePoint(String treeId) { return skillTreePoints.getOrDefault(treeId, 0); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java similarity index 86% rename from MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java rename to MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java index 2c3d0208..5aeb7ac0 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillTreeViewer.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java @@ -1,24 +1,27 @@ -package net.Indyuce.mmocore.gui; +package net.Indyuce.mmocore.gui.skilltree; import io.lumine.mythic.lib.MythicLib; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.skilltree.NodeStatus; -import net.Indyuce.mmocore.skilltree.tree.SkillTree; -import net.Indyuce.mmocore.skilltree.tree.display.Icon; import net.Indyuce.mmocore.api.SoundEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.gui.api.EditableInventory; import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.InventoryClickContext; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; +import net.Indyuce.mmocore.gui.skilltree.display.*; import net.Indyuce.mmocore.skilltree.IntegerCoordinates; +import net.Indyuce.mmocore.skilltree.NodeStatus; import net.Indyuce.mmocore.skilltree.SkillTreeNode; +import net.Indyuce.mmocore.skilltree.SkillTreePath; +import net.Indyuce.mmocore.skilltree.tree.SkillTree; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -26,17 +29,39 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; public class SkillTreeViewer extends EditableInventory { - + protected final Map icons = new HashMap<>(); public SkillTreeViewer() { super("skill-tree"); } + @Override + public void reload(FileConfiguration config) { + super.reload(config); + //Loads all the pathDisplayInfo + for (PathStatus status : PathStatus.values()) + for (PathType pathType :PathType.values()){ + if(!config.contains("display.paths." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(pathType.name()))){ + MMOCore.log("display.paths." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(pathType.name())); + MMOCore.log("Missing path type: " + MMOCoreUtils.ymlName(pathType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name())); + continue; + } + icons.put(new PathDisplayInfo(pathType, status), new Icon(config.getConfigurationSection("display.paths." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(pathType.name())))); + } + //Loads all the nodeDisplayInfo + for (NodeStatus status : NodeStatus.values()) + for (NodeType nodeType :NodeType.values()){ + if(!config.contains("display.nodes." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(nodeType.name()))){ + MMOCore.log("Missing node type: " + MMOCoreUtils.ymlName(nodeType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name())); + continue; + } + icons.put(new NodeDisplayInfo(nodeType, status), new Icon(config.getConfigurationSection("display.nodes." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(nodeType.name())))); + } + } + @Override public InventoryItem load(String function, ConfigurationSection config) { if (function.equals("skill-tree")) { @@ -190,7 +215,7 @@ public class SkillTreeViewer extends EditableInventory { public ItemStack display(SkillTreeInventory inv, int n) { IntegerCoordinates coordinates = inv.getCoordinates(n); if (inv.getSkillTree().isNode(coordinates) || inv.getSkillTree().isPath(coordinates)) { - Icon icon = inv.getPlayerData().getIcon(inv.getSkillTree(), coordinates); + Icon icon = inv.getIcon(coordinates); ItemStack item = super.display(inv, n, icon.getMaterial(), icon.getCustomModelData()); ItemMeta meta = item.getItemMeta(); if (inv.getSkillTree().isNode(coordinates)) { @@ -313,6 +338,23 @@ public class SkillTreeViewer extends EditableInventory { return maxTreeListPage; } + public Icon getIcon(IntegerCoordinates coordinates) { + boolean hasNorthPath = skillTree.isPath(new IntegerCoordinates(coordinates.getX(), coordinates.getY() - 1)); + boolean hasSouthPath = skillTree.isPath(new IntegerCoordinates(coordinates.getX(), coordinates.getY() + 1)); + boolean hasEastPath = skillTree.isPath(new IntegerCoordinates(coordinates.getX() + 1, coordinates.getY())); + boolean hasWestPath = skillTree.isPath(new IntegerCoordinates(coordinates.getX() - 1, coordinates.getY())); + + if (skillTree.isNode(coordinates)) { + SkillTreeNode node = skillTree.getNode(coordinates); + NodeType nodeType = NodeType.getNodeType(hasNorthPath, hasEastPath, hasSouthPath, hasWestPath); + return icons.get(new NodeDisplayInfo(nodeType, playerData.getNodeState(node))); + } else { + PathType pathType = PathType.getPathType(hasNorthPath, hasEastPath, hasSouthPath, hasWestPath); + SkillTreePath path = skillTree.getPath(coordinates); + return icons.get(new PathDisplayInfo(pathType, path.getStatus(playerData))); + } + } + @Override public String calculateName() { return getEditable().getName().replace("{skill-tree-name}", skillTree.getName()).replace("{skill-tree-id}", skillTree.getId()); @@ -434,18 +476,15 @@ public class SkillTreeViewer extends EditableInventory { MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_UP).playTo(getPlayer()); open(); event.setCancelled(true); - return; } else if (playerData.getNodeState(node) == NodeStatus.LOCKED || playerData.getNodeState(node) == NodeStatus.FULLY_LOCKED) { MMOCore.plugin.configManager.getSimpleMessage("locked-node").send(player); MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer()); event.setCancelled(true); - return; } else if (playerData.getNodeLevel(node) >= node.getMaxLevel()) { MMOCore.plugin.configManager.getSimpleMessage("skill-node-max-level-hit").send(player); MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer()); event.setCancelled(true); - return; } //Else the player doesn't doesn't have the skill tree points @@ -453,7 +492,6 @@ public class SkillTreeViewer extends EditableInventory { MMOCore.plugin.configManager.getSimpleMessage("not-enough-skill-tree-points", "point", "" + node.getSkillTreePointsConsumed()).send(player); MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer()); event.setCancelled(true); - return; } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/DisplayInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/DisplayInfo.java new file mode 100644 index 00000000..9d4bdc49 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/DisplayInfo.java @@ -0,0 +1,7 @@ +package net.Indyuce.mmocore.gui.skilltree.display; + +/** + * The information needed to determine the display of a node/path depending on its context. + */ +public interface DisplayInfo { +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/display/Icon.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/Icon.java similarity index 88% rename from MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/display/Icon.java rename to MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/Icon.java index 7e41218e..db334f0f 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/display/Icon.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/Icon.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.skilltree.tree.display; +package net.Indyuce.mmocore.gui.skilltree.display; import io.lumine.mythic.lib.UtilityMethods; import org.bukkit.Material; @@ -23,7 +23,7 @@ public class Icon { public Icon(ConfigurationSection config) { this(Material.valueOf(Objects.requireNonNull(UtilityMethods.enumName( - config.getString("item")))), config.contains("model-data") ? config.getInt("model-data") : 0); + config.getString("item")))), config.contains("custom-model-data") ? config.getInt("custom-model-data") : 0); } public Icon(Material material, int customModelData) { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java new file mode 100644 index 00000000..f6398d1f --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java @@ -0,0 +1,49 @@ +package net.Indyuce.mmocore.gui.skilltree.display; + +import net.Indyuce.mmocore.skilltree.NodeStatus; + +import java.util.Objects; + +public class NodeDisplayInfo implements DisplayInfo{ + + private NodeStatus nodeStatus; + private NodeType nodeType; + + public NodeDisplayInfo(NodeType nodeType,NodeStatus nodeStatus) { + this.nodeStatus = nodeStatus; + this.nodeType = nodeType; + } + + public NodeStatus getNodeState() { + return nodeStatus; + } + + public NodeStatus getNodeStatus() { + return nodeStatus; + } + + public NodeType getNodeType() { + return nodeType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NodeDisplayInfo that = (NodeDisplayInfo) o; + return nodeStatus == that.nodeStatus && nodeType == that.nodeType; + } + + @Override + public int hashCode() { + return Objects.hash(nodeStatus, nodeType); + } + + @Override + public String toString() { + return "NodeDisplayInfo{" + + "nodeStatus=" + nodeStatus + + ", nodeType=" + nodeType + + '}'; + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeType.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeType.java new file mode 100644 index 00000000..80a7011f --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeType.java @@ -0,0 +1,45 @@ +package net.Indyuce.mmocore.gui.skilltree.display; + +public enum NodeType { + NORTH_EAST_SOUTH_WEST, + NORTH_EAST_SOUTH, + NORTH_EAST_WEST, + NORTH_SOUTH_WEST, + SOUTH_EAST_WEST, + NORTH_EAST, + NORTH_SOUTH, + NORTH_WEST, + SOUTH_EAST, + SOUTH_WEST, + EAST_WEST, + NO_PATH; + + public static NodeType getNodeType(boolean hasNorthPath, boolean hasEastPath, boolean hasSouthPath, boolean hasWestPath) { + if (hasNorthPath && hasEastPath && hasSouthPath && hasWestPath) { + return NORTH_EAST_SOUTH_WEST; + } else if (hasNorthPath && hasEastPath && hasSouthPath) { + return NORTH_EAST_SOUTH; + } else if (hasNorthPath && hasEastPath && hasWestPath) { + return NORTH_EAST_WEST; + } else if (hasNorthPath && hasSouthPath && hasWestPath) { + return NORTH_SOUTH_WEST; + } else if (hasSouthPath && hasEastPath && hasWestPath) { + return SOUTH_EAST_WEST; + } else if (hasNorthPath && hasEastPath) { + return NORTH_EAST; + } else if (hasNorthPath && hasSouthPath) { + return NORTH_SOUTH; + } else if (hasNorthPath && hasWestPath) { + return NORTH_WEST; + } else if (hasSouthPath && hasEastPath) { + return SOUTH_EAST; + } else if (hasSouthPath && hasWestPath) { + return SOUTH_WEST; + } else if (hasEastPath && hasWestPath) { + return EAST_WEST; + } + return NO_PATH; + } +} + + diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathDisplayInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathDisplayInfo.java new file mode 100644 index 00000000..158c4376 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathDisplayInfo.java @@ -0,0 +1,44 @@ +package net.Indyuce.mmocore.gui.skilltree.display; + +import java.util.Objects; + +public class PathDisplayInfo implements DisplayInfo{ + + private PathType pathType; + private PathStatus pathStatus; + + public PathDisplayInfo(PathType pathType, PathStatus pathStatus) { + this.pathType = pathType; + this.pathStatus = pathStatus; + } + + public PathType getPathType() { + return pathType; + } + + public PathStatus getPathStatus() { + return pathStatus; + } + + @Override + public int hashCode() { + return Objects.hash(pathType, pathStatus); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PathDisplayInfo that = (PathDisplayInfo) o; + return pathType == that.pathType && pathStatus == that.pathStatus; + } + + @Override + public String toString() { + return "PathDisplayInfo{" + + "pathType=" + pathType + + ", pathStatus=" + pathStatus + + '}'; + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathStatus.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathStatus.java new file mode 100644 index 00000000..2ef266c5 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathStatus.java @@ -0,0 +1,7 @@ +package net.Indyuce.mmocore.gui.skilltree.display; + +public enum PathStatus { + LOCKED, + FULLY_LOCKED, + UNLOCKED; +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathType.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathType.java new file mode 100644 index 00000000..79758a50 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/PathType.java @@ -0,0 +1,40 @@ +package net.Indyuce.mmocore.gui.skilltree.display; + +/** + * The direction of the path. + */ +public enum PathType { + + NORTH, + /** + * Goes to north then east/ goes to west then south. + */ + NORTH_EAST, + NORTH_WEST, + SOUTH_EAST, + SOUTH_WEST, + EAST, + + DEFAULT; + + public static PathType getPathType(boolean hasNorth,boolean hasEast,boolean hasSouth,boolean hasWest) { + if ((hasNorth || hasSouth) && !hasWest && hasEast) { + return NORTH; + } else if ((hasEast || hasWest)&& !hasNorth && !hasSouth) { + return EAST; + } else if (hasNorth && hasEast) { + return NORTH_EAST; + } + else if (hasNorth && hasWest) { + return NORTH_WEST; + } + else if (hasSouth && hasEast) { + return SOUTH_EAST; + } + else if (hasSouth && hasWest) { + return SOUTH_WEST; + } + return DEFAULT; + } + +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java index 47d0b33c..3186e776 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java @@ -6,6 +6,7 @@ import java.util.logging.Level; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.util.MMOCoreUtils; +import net.Indyuce.mmocore.gui.skilltree.SkillTreeViewer; import net.Indyuce.mmocore.gui.social.friend.EditableFriendList; import net.Indyuce.mmocore.gui.*; import net.Indyuce.mmocore.gui.social.friend.EditableFriendRemoval; diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java new file mode 100644 index 00000000..b094e397 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java @@ -0,0 +1,17 @@ +package net.Indyuce.mmocore.skilltree; + +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.gui.skilltree.display.PathStatus; +import net.Indyuce.mmocore.skilltree.tree.SkillTree; + +public record SkillTreePath(SkillTree tree, IntegerCoordinates coordinates, SkillTreeNode from, SkillTreeNode to) { + + public PathStatus getStatus(PlayerData playerData) { + if (playerData.getNodeState(from) == NodeStatus.UNLOCKED && playerData.getNodeState(to) == NodeStatus.UNLOCKED) { + return PathStatus.UNLOCKED; + } + return PathStatus.LOCKED; + } + + +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java index afc2db25..3b33d0f5 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java @@ -5,12 +5,15 @@ import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.util.PostLoadObject; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.gui.skilltree.display.DisplayInfo; +import net.Indyuce.mmocore.gui.skilltree.display.Icon; +import net.Indyuce.mmocore.gui.skilltree.display.NodeDisplayInfo; +import net.Indyuce.mmocore.gui.skilltree.display.NodeType; import net.Indyuce.mmocore.manager.registry.RegisteredObject; -import net.Indyuce.mmocore.skilltree.tree.display.DisplayInfo; -import net.Indyuce.mmocore.skilltree.tree.display.Icon; import net.Indyuce.mmocore.skilltree.IntegerCoordinates; import net.Indyuce.mmocore.skilltree.NodeStatus; import net.Indyuce.mmocore.skilltree.SkillTreeNode; +import net.Indyuce.mmocore.skilltree.SkillTreePath; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -42,16 +45,21 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje private final int customModelData; //2 different maps to get the nodes - - //Represents all the coordinates that will be displayed as a path (between 2 nodes of the tree) - protected final ArrayList paths = new ArrayList<>(); - //Represents all the nodes + /** + * Represents all the nodes + * Key: the coordinates of the node + * Value: the node + */ protected final Map coordinatesNodes = new HashMap<>(); + /** + * Represents all the paths between nodes. + */ + protected final Map coordinatesPaths = new HashMap<>(); + protected final Map nodes = new HashMap<>(); protected final int maxPointSpent; //Caches the height of the skill tree protected int minX, minY, maxX, maxY; - protected final HashMap icons = new HashMap<>(); protected final List roots = new ArrayList<>(); public SkillTree(ConfigurationSection config) { @@ -66,45 +74,30 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje this.maxPointSpent = config.getInt("max-point-spent", Integer.MAX_VALUE); for (String key : config.getConfigurationSection("nodes").getKeys(false)) { try { - - SkillTreeNode node = new SkillTreeNode(this, config.getConfigurationSection("nodes." + key)); + ConfigurationSection section = config.getConfigurationSection("nodes." + key); + SkillTreeNode node = new SkillTreeNode(this, section); nodes.put(node.getId(), node); - } catch (Exception e) { MMOCore.log("Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage()); } } - try { - if (config.contains("paths")) { - ConfigurationSection section = config.getConfigurationSection("paths"); - for (String key : section.getKeys(false)) { - if (section.contains(key + ".x") && section.contains(key + ".y")) { - paths.add(new IntegerCoordinates(section.getInt(key + ".x"), section.getInt(key + ".y"))); + for (String from : config.getConfigurationSection("nodes").getKeys(false)) { + ConfigurationSection section = config.getConfigurationSection("nodes." + from); + MMOCore.log("skilltree:" + id + " " + (section.contains("paths"))); + if (section.contains("paths")) { + for (String to : section.getConfigurationSection("paths").getKeys(false)) { + SkillTreeNode node1 = nodes.get(to); + if (node1 == null) { + MMOCore.log("Couldn't find node " + to + " for path in node " + from + "."); + continue; + } + for (String pathKey : section.getConfigurationSection("paths." + to).getKeys(false)) { + IntegerCoordinates coordinates = new IntegerCoordinates(section.getInt("paths." + to + "." + pathKey + ".x"), section.getInt("paths." + to + "." + pathKey + ".y")); + coordinatesPaths.put(coordinates, new SkillTreePath(this, coordinates, nodes.get(from), node1)); } - } } - } catch (Exception e) { - MMOCore.log(Level.WARNING, "Couldn't load paths for skill tree: " + id); - } - try { - //Load the icons of the skill tree. - 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)) { - DisplayInfo displayInfo = new DisplayInfo(NodeStatus.valueOf(UtilityMethods.enumName(key)), Integer.parseInt(size)); - Icon icon = new Icon(config.getConfigurationSection("icons." + key + "." + size)); - icons.put(displayInfo, icon); - - } - } - } catch (Exception e) { - MMOCore.log("Couldn't load icons for the skill tree " + id); - e.printStackTrace(); } } @@ -121,12 +114,28 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje @Override protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection); +/* - public Icon getIcon(DisplayInfo info) { - Validate.isTrue(icons.containsKey(info), "The icon corresponding to " + info + " doesn't exist for the skill tree " + id + "."); - return icons.get(info); + public Icon getIcon(SkillTreeNode node) { + 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); + DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize()); + return skillTree.getIcon(displayInfo); + } + if (skillTree.isPath(coordinates)) return skillTree.getIcon(DisplayInfo.pathInfo); + return null; + } + */ + public int getMaxX() { return maxX; } @@ -266,7 +275,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje } public boolean isPath(IntegerCoordinates coordinates) { - return paths.contains(coordinates); + return coordinatesPaths.keySet().contains(coordinates); } public Material getItem() { @@ -291,11 +300,17 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje return Objects.requireNonNull(coordinatesNodes.get(coords), "Could not find node in tree '" + id + "' with coordinates '" + coords.toString() + "'"); } + @NotNull + public SkillTreePath getPath(IntegerCoordinates coords) { + return Objects.requireNonNull(coordinatesPaths.get(coords), "Could not find path in tree '" + id + "' with coordinates '" + coords.toString() + "'"); + } + @NotNull public SkillTreeNode getNode(String name) { return Objects.requireNonNull(nodes.get(name), "Could not find node in tree '" + id + "' with name '" + name + "'"); } + public boolean isNode(String name) { return nodes.containsKey(name); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/display/DisplayInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/display/DisplayInfo.java deleted file mode 100644 index be3426ff..00000000 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/display/DisplayInfo.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.Indyuce.mmocore.skilltree.tree.display; - -import net.Indyuce.mmocore.skilltree.NodeStatus; - -import java.util.Objects; - -/** - * The information needed to determine the display type of a node - */ -public class DisplayInfo { - private NodeStatus nodeStatus; - private int size; - - //this NodeDisplayInfo represent a path - public static DisplayInfo pathInfo= new DisplayInfo(); - - - public DisplayInfo() { - } - - public DisplayInfo(NodeStatus nodeStatus, int size) { - this.nodeStatus = nodeStatus; - this.size = size; - } - - public NodeStatus getNodeState() { - return nodeStatus; - } - - public int getSize() { - return size; - } - - - @Override - public int hashCode() { - return Objects.hash(nodeStatus, size); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof DisplayInfo)) - return false; - DisplayInfo displayInfo= (DisplayInfo) obj; - if(nodeStatus ==null) - return displayInfo.getNodeState()==null; - return nodeStatus ==displayInfo.getNodeState()&&size==displayInfo.getSize(); - } - - @Override - public String toString() { - return "DisplayInfo{" + - "nodeState=" + nodeStatus + - ", size=" + size + - '}'; - } -} diff --git a/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml b/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml index ce9abe2c..55f0d2ae 100644 --- a/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml +++ b/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml @@ -99,4 +99,221 @@ items: - '&e◆Points spent for {skill-tree}&e:&6 {point-spent}' - '&e◆Current {skill-tree} &epoints: &6{skill-tree-points}' - '&e◆Current &6global&e points: &6{global-points}' +display: + paths: + unlocked: + north: + item: "WHITE_DYE" + custom-model-data: 0 + north-east: + item: "WHITE_DYE" + custom-model-data: 0 + north-west: + item: "WHITE_DYE" + custom-model-data: 0 + south-east: + item: "WHITE_DYE" + custom-model-data: 0 + south-west: + item: "WHITE_DYE" + custom-model-data: 0 + east: + item: "WHITE_DYE" + custom-model-data: 0 + default: + item: "WHITE_DYE" + custom-model-data: 0 + locked: + north: + item: "GRAY_DYE" + custom-model-data: 0 + north-east: + item: "GRAY_DYE" + custom-model-data: 0 + north-west: + item: "GRAY_DYE" + custom-model-data: 0 + south-east: + item: "GRAY_DYE" + custom-model-data: 0 + south-west: + item: "GRAY_DYE" + custom-model-data: 0 + east: + item: "GRAY_DYE" + custom-model-data: 0 + default: + item: "GRAY_DYE" + custom-model-data: 0 + fully-locked: + north: + item: "BLACK_DYE" + custom-model-data: 0 + north-east: + item: "BLACK_DYE" + custom-model-data: 0 + north-west: + item: "BLACK_DYE" + custom-model-data: 0 + south-east: + item: "BLACK_DYE" + custom-model-data: 0 + south-west: + item: "BLACK_DYE" + custom-model-data: 0 + east: + item: "BLACK_DYE" + custom-model-data: 0 + default: + item: "BLACK_DYE" + custom-model-data: 0 + nodes: + unlocked: + north-east-south-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + north-east-south: + item: "WHITE_CONCRETE" + custom-model-data: 0 + north-east-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + north-south-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + south-east-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + north-east: + item: "WHITE_CONCRETE" + custom-model-data: 0 + north-south: + item: "WHITE_CONCRETE" + custom-model-data: 0 + north-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + south-east: + item: "WHITE_CONCRETE" + custom-model-data: 0 + south-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + east-west: + item: "WHITE_CONCRETE" + custom-model-data: 0 + no-path: + item: "WHITE_CONCRETE" + custom-model-data: 0 + locked: + north-east-south-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + north-east-south: + item: "GRAY_CONCRETE" + custom-model-data: 0 + north-east-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + north-south-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + south-east-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + north-east: + item: "GRAY_CONCRETE" + custom-model-data: 0 + north-south: + item: "GRAY_CONCRETE" + custom-model-data: 0 + north-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + south-east: + item: "GRAY_CONCRETE" + custom-model-data: 0 + south-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + east-west: + item: "GRAY_CONCRETE" + custom-model-data: 0 + no-path: + item: "GRAY_CONCRETE" + custom-model-data: 0 + unlockable: + north-east-south-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + north-east-south: + item: "BLUE_CONCRETE" + custom-model-data: 0 + north-east-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + north-south-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + south-east-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + north-east: + item: "BLUE_CONCRETE" + custom-model-data: 0 + north-south: + item: "BLUE_CONCRETE" + custom-model-data: 0 + north-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + south-east: + item: "BLUE_CONCRETE" + custom-model-data: 0 + south-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + east-west: + item: "BLUE_CONCRETE" + custom-model-data: 0 + no-path: + item: "BLUE_CONCRETE" + custom-model-data: 0 + fully-locked: + north-east-south-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + north-east-south: + item: "BLACK_CONCRETE" + custom-model-data: 0 + north-east-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + north-south-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + south-east-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + north-east: + item: "BLACK_CONCRETE" + custom-model-data: 0 + north-south: + item: "BLACK_CONCRETE" + custom-model-data: 0 + north-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + south-east: + item: "BLACK_CONCRETE" + custom-model-data: 0 + south-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + east-west: + item: "BLACK_CONCRETE" + custom-model-data: 0 + no-path: + item: "BLACK_CONCRETE" + custom-model-data: 0