forked from Upstream/mmocore
Debug Automatic WayPoints
This commit is contained in:
parent
7fee8736ed
commit
a5ab2c9269
@ -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<PlayerModifier> 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)<node.getMaxLevel()&&(skillTreePoints.get(node.getTree().getId()) > 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 <T extends SkillTree> void incrementNodeLevel(SkillTreeNode node) {
|
||||
setNodeLevel(node, getNodeLevel(node) + 1);
|
||||
//Triggers the triggers of the node
|
||||
List<Trigger> triggers = node.getTriggers(getNodeLevel(node));
|
||||
if (triggers != null) {
|
||||
for (Trigger trigger : triggers) {
|
||||
trigger.apply(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Applies player modifiers
|
||||
List<PlayerModifier> 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
|
||||
|
@ -20,8 +20,8 @@ import java.util.stream.Collectors;
|
||||
public class SkillTreePointsCommandTreeNode extends CommandTreeNode {
|
||||
BiFunction<PlayerData, String,Integer> get;
|
||||
|
||||
public SkillTreePointsCommandTreeNode(CommandTreeNode parent, TriConsumer<PlayerData, Integer, String> give,
|
||||
TriConsumer<PlayerData, Integer, String> set, BiFunction<PlayerData, String,Integer> get) {
|
||||
public SkillTreePointsCommandTreeNode(CommandTreeNode parent, TriConsumer<PlayerData, Integer, String> set,
|
||||
TriConsumer<PlayerData, Integer, String> give, BiFunction<PlayerData, String,Integer> get) {
|
||||
super(parent, "skill-tree-points");
|
||||
addChild(new ActionCommandTreeNode(this, "give", give));
|
||||
addChild(new ActionCommandTreeNode(this, "set", set));
|
||||
|
@ -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);
|
||||
|
@ -23,7 +23,6 @@ public class IntegerCoordinates {
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
@ -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<NodeContext, List<String>> lores = new HashMap<>();
|
||||
|
||||
//TODO modifiers depending on level with drop tables
|
||||
private final HashMap<Integer, HashSet<PlayerModifier>> modifiers = new HashMap<>();
|
||||
private final HashMap<Integer, HashSet<Trigger>> triggers = new HashMap<>();
|
||||
private final HashMap<Integer, List<PlayerModifier>> modifiers = new HashMap<>();
|
||||
private final HashMap<Integer, List<Trigger>> 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<SkillTreeNode> children = new ArrayList<>();
|
||||
@ -43,7 +47,7 @@ public class SkillTreeNode implements Unlockable {
|
||||
|
||||
|
||||
private final HashMap<SkillTreeNode, Integer> softParents = new HashMap<>();
|
||||
private final HashMap<SkillTreeNode ,Integer> strongParents = new HashMap<>();
|
||||
private final HashMap<SkillTreeNode, Integer> 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<PlayerModifier> getModifiers(int level) {
|
||||
public List<PlayerModifier> getModifiers(int level) {
|
||||
return modifiers.get(level);
|
||||
}
|
||||
|
||||
|
||||
public Set<Trigger> getTriggers(int level) {
|
||||
public List<Trigger> getTriggers(int level) {
|
||||
return triggers.get(level);
|
||||
}
|
||||
|
||||
@ -244,15 +292,14 @@ public class SkillTreeNode implements Unlockable {
|
||||
public List<String> getLore(PlayerData playerData) {
|
||||
Placeholders holders = getPlaceholders(playerData);
|
||||
List<String> 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 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -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<SkillTreeNode, Branches> 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 {
|
||||
|
@ -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<String> lore=new ArrayList<>();
|
||||
private final List<String> 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<DisplayInfo, Icon> icons = new HashMap<>();
|
||||
protected final HashSet<SkillTreeNode> roots = new HashSet<>();
|
||||
protected final List<SkillTreeNode> 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<SkillTreeNode> 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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
143
src/main/resources/default/skilltree/autocombat.yml
Normal file
143
src/main/resources/default/skilltree/autocombat.yml
Normal file
@ -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"
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user