Skill tree cleanup

This commit is contained in:
Indyuce 2022-12-24 15:26:22 +01:00
parent 0e8352a44a
commit 2bf0078c57
25 changed files with 359 additions and 388 deletions

View File

@ -34,16 +34,17 @@ import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import net.Indyuce.mmocore.party.provided.Party;
import net.Indyuce.mmocore.player.ClassDataContainer;
import net.Indyuce.mmocore.player.Unlockable;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
import net.Indyuce.mmocore.tree.IntegerCoordinates;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo;
import net.Indyuce.mmocore.tree.skilltree.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.tree.SkillTree;
import net.Indyuce.mmocore.skilltree.tree.display.DisplayInfo;
import net.Indyuce.mmocore.skilltree.tree.display.Icon;
import net.Indyuce.mmocore.waypoint.Waypoint;
import net.Indyuce.mmocore.waypoint.WaypointOption;
import net.md_5.bungee.api.ChatMessageType;
@ -63,7 +64,7 @@ import java.util.logging.Level;
import java.util.stream.Collectors;
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer {
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer, ClassDataContainer {
/**
* Corresponds to the MythicLib player data. It is used to keep
@ -72,7 +73,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
*/
private final MMOPlayerData mmoData;
/**
* Can be null, the {@link #getProfess()} method will return the
* player class, or the default one if this field is null.
@ -95,12 +95,17 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
private final PlayerAttributes attributes = new PlayerAttributes(this);
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
private final Map<PlayerActivity, Long> lastActivity = new HashMap<>();
/**
* Maps each skill tree to the number of points spent in it. Just in cache memory.
* Cached for easier access. Amount of points spent in each skill tree.
*/
private final HashMap<SkillTree, Integer> pointSpent = new HashMap<>();
private final Map<SkillTree, Integer> pointSpent = new HashMap<>();
/**
* Cached for easier access. Current status of each skill tree node.
*/
private final Map<SkillTreeNode, NodeStatus> nodeStates = new HashMap<>();
private final Map<SkillTreeNode, Integer> nodeLevels = new HashMap<>();
private final Map<SkillTreeNode, NodeState> nodeStates = new HashMap<>();
private final Map<String, Integer> skillTreePoints = new HashMap<>();
/**
@ -183,7 +188,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void setupSkillTree() {
// Node states setup
for (SkillTree skillTree : getProfess().getSkillTrees())
skillTree.setupNodeState(this);
skillTree.setupNodeStates(this);
// Stat triggers setup
if (!statsLoaded) {
@ -197,14 +202,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return pointSpent.getOrDefault(skillTree, 0);
}
public HashMap<SkillTree, Integer> getPointsSpent() {
return new HashMap<>(pointSpent);
}
public void clearPointsSpent() {
pointSpent.clear();
}
public void setSkillTreePoints(String treeId, int points) {
skillTreePoints.put(treeId, points);
}
@ -218,9 +215,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
}
/**
* We make a copy to assure that the object created is independent of the state of playerData.
* Make a copy to make sure that the object
* created is independent of the state of playerData.
*/
public Map<String, Integer> getSkillTreePoints() {
public Map<String, Integer> mapSkillTreePoints() {
return new HashMap(skillTreePoints);
}
@ -228,10 +226,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
skillTreePoints.clear();
}
public boolean containsSkillPointTreeId(String treeId) {
return skillTreePoints.containsKey(treeId);
}
public Set<Map.Entry<String, Integer>> getNodeLevelsEntrySet() {
HashMap<String, Integer> nodeLevelsString = new HashMap<>();
for (SkillTreeNode node : nodeLevels.keySet())
@ -249,36 +243,37 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void clearNodeLevels() {
nodeLevels.clear();
pointSpent.clear();
}
public boolean canIncrementNodeLevel(SkillTreeNode node) {
NodeState nodeState = nodeStates.get(node);
NodeStatus nodeStatus = nodeStates.get(node);
//Check the State of the node
if (nodeState != NodeState.UNLOCKED && nodeState != NodeState.UNLOCKABLE)
if (nodeStatus != NodeStatus.UNLOCKED && nodeStatus != NodeStatus.UNLOCKABLE)
return false;
return getNodeLevel(node) < node.getMaxLevel() && (skillTreePoints.getOrDefault(node.getTree().getId(), 0) > 0 || skillTreePoints.getOrDefault("global", 0) > 0);
}
/**
* Increments the node level by one, change the states of branches of the tree.
* Consumes skill tree points from the tree first and then consumes the global skill-tree points ('all')
* Consumes skill tree points from the tree first and then consumes the
* global skill-tree points ('all')
*/
public <T extends SkillTree> void incrementNodeLevel(SkillTreeNode node) {
public void incrementNodeLevel(SkillTreeNode node) {
setNodeLevel(node, getNodeLevel(node) + 1);
//Claims the nodes experience table.
node.getExperienceTable().claim(this, getNodeLevel(node), node);
if (nodeStates.get(node) == NodeState.UNLOCKABLE)
setNodeState(node, NodeState.UNLOCKED);
if (nodeStates.get(node) == NodeStatus.UNLOCKABLE)
setNodeState(node, NodeStatus.UNLOCKED);
if (skillTreePoints.get(node.getTree().getId()) > 0)
withdrawSkillTreePoints(node.getTree().getId(), 1);
else
withdrawSkillTreePoints("global", 1);
//We unload the nodeStates map (for the skill tree) and reload it completely
for (SkillTreeNode node1 : node.getTree().getNodes()) {
for (SkillTreeNode node1 : node.getTree().getNodes())
nodeStates.remove(node1);
}
node.getTree().setupNodeState(this);
node.getTree().setupNodeStates(this);
}
/**
@ -312,11 +307,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
skillTreePoints.put(treeId, skillTreePoints.get(treeId) - withdraw);
}
public void setNodeState(SkillTreeNode node, NodeState nodeState) {
nodeStates.put(node, nodeState);
public void setNodeState(SkillTreeNode node, NodeStatus nodeStatus) {
nodeStates.put(node, nodeStatus);
}
public NodeState getNodeState(SkillTreeNode node) {
public NodeStatus getNodeState(SkillTreeNode node) {
return nodeStates.get(node);
}
@ -340,10 +335,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
setNodeLevel(node, 0);
nodeStates.remove(node);
}
skillTree.setupNodeState(this);
skillTree.setupNodeStates(this);
}
public Map<SkillTreeNode, NodeState> getNodeStates() {
public Map<SkillTreeNode, NodeStatus> getNodeStates() {
return new HashMap<>(nodeStates);
}
@ -351,10 +346,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
nodeStates.clear();
}
@Override
public Map<String, Integer> getNodeTimesClaimed() {
Map<String, Integer> result = new HashMap<>();
tableItemClaims.forEach((str, val) -> {
if (str.startsWith(SkillTreeNode.getPrefix()))
if (str.startsWith(SkillTreeNode.KEY_PREFIX))
result.put(str, val);
});
return result;
@ -428,7 +424,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return Math.max(1, level);
}
@Nullable
public AbstractParty getParty() {
return MMOCore.plugin.partyModule.getParty(this);
@ -446,6 +441,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return classPoints;
}
@Override
public int getSkillPoints() {
return skillPoints;
}
@ -463,14 +459,17 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return sum;
}
@Override
public int getAttributePoints() {
return attributePoints;
}
@Override
public int getAttributeReallocationPoints() {
return attributeReallocationPoints;
}
@Override
public int getSkillTreeReallocationPoints() {
return skillTreeReallocationPoints;
}
@ -482,7 +481,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public int getClaims(String key) {
return tableItemClaims.getOrDefault(key, 0);
}
@Override
@ -492,10 +490,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void setClaims(String key, int times) {
tableItemClaims.put(key, times);
}
public Map<String, Integer> getItemClaims() {
return tableItemClaims;
}
@ -507,10 +503,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return getProfess().getExpCurve().getExperience(getLevel() + 1);
}
// public int getSkillReallocationPoints() {
// return skillReallocationPoints;
// }
public boolean isOnline() {
return mmoData.isOnline();
}
@ -521,7 +513,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
/**
* @return If the item is unlocked by the player
* @deprecated Not used yet
*/
@Deprecated
public boolean hasUnlocked(Unlockable unlockable) {
return unlockedItems.contains(unlockable.getUnlockNamespacedKey());
}
@ -530,7 +524,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* Unlocks an item for the player
*
* @return If the item was already unlocked when calling this method
* @deprecated Not used yet
*/
@Deprecated
public boolean unlock(Unlockable unlockable) {
return unlockedItems.add(unlockable.getUnlockNamespacedKey());
}
@ -575,10 +571,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
getPlayer().setExp(Math.max(0, Math.min(1, (float) experience / (float) getLevelUpExperience())));
}
// public void setSkillReallocationPoints(int value) {
// skillReallocationPoints = Math.max(0, value);
// }
public void setAttributePoints(int value) {
attributePoints = Math.max(0, value);
}
@ -615,10 +607,12 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return classSlots.keySet();
}
@Nullable
public SavedClassInformation getClassInfo(PlayerClass profess) {
return getClassInfo(profess.getId());
}
@Nullable
public SavedClassInformation getClassInfo(String profess) {
return classSlots.get(profess);
}
@ -647,7 +641,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
waypoints.remove(waypoint.getId());
}
/**
* @deprecated Provide a heal reason with {@link #heal(double, PlayerResourceUpdateEvent.UpdateReason)}
*/
@ -1009,7 +1002,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message));
}
@Deprecated
public void setAttribute(PlayerAttribute attribute, int value) {
setAttribute(attribute.getId(), value);
@ -1020,8 +1012,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
attributes.setBaseAttribute(id, value);
}
@Deprecated
public Map<String, Integer> mapAttributePoints() {
@Override
public Map<String, Integer> mapAttributeLevels() {
return getAttributes().mapPoints();
}

View File

@ -31,12 +31,9 @@ import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.ComboMap;
import net.Indyuce.mmocore.skill.cast.KeyCombo;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;

View File

@ -18,9 +18,9 @@ public class PlayerStats {
private final PlayerData data;
/**
* Util class to easily manipulate the MMOLib stat map
* Util class to easily manipulate the MythicLib stat map
*
* @param data Playerdata
* @param data Player
*/
public PlayerStats(PlayerData data) {
this.data = data;
@ -39,12 +39,13 @@ public class PlayerStats {
return getMap().getInstance(stat.name());
}
@Deprecated
public StatInstance getInstance(String stat) {
return getMap().getInstance(stat);
}
public double getStat(String stat) {
return getInstance(stat).getTotal();
return getMap().getInstance(stat).getTotal();
}
/**
@ -67,7 +68,7 @@ public class PlayerStats {
/**
* Used to update MMOCore stat modifiers due to class and send them over to
* MMOLib. Must be ran everytime the player levels up or changes class.
* MythicLib. Must be ran everytime the player levels up or changes class.
* <p>
* This is also called when reloading the plugin to make class setup easier,
* see {@link PlayerData#update()} for more info
@ -96,11 +97,9 @@ public class PlayerStats {
*
* This updates the player's PASSIVE skills
*/
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
if(!MMOCore.plugin.configManager.passiveSkillNeedBound) {
if (!MMOCore.plugin.configManager.passiveSkillNeedBound) {
skillMap.removeModifiers("MMOCorePassiveSkill");
for (ClassSkill skill : data.getProfess().getSkills())
if (skill.getSkill().getTrigger().isPassive())

View File

@ -1,16 +1,11 @@
package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import java.util.Collection;
import java.util.UUID;
public class StatTrigger extends Trigger {
@ -40,7 +35,6 @@ public class StatTrigger extends Trigger {
new StatModifier("trigger."+uuid.toString(),stat,totalAmount,type).register(player.getMMOPlayerData());
}
/**
* Removes the effect of the trigger to the player by registering the
* opposite amount. (Little corrective term for the relative to have the inverse.

View File

@ -4,7 +4,7 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;

View File

@ -29,7 +29,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode {
}
PlayerData data = PlayerData.get((Player) sender);
StatInstance instance = data.getStats().getInstance(UtilityMethods.enumName(args[2]));
StatInstance instance = data.getMMOPlayerData().getStatMap().getInstance(UtilityMethods.enumName(args[2]));
sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):");
for (String key : instance.getKeys()) {
StatModifier mod = instance.getModifier(key);

View File

@ -27,6 +27,9 @@ public interface ExperienceObject extends ExperienceDispenser {
ExpCurve getExpCurve();
/**
* Should throw an error if called when
* {@link #hasExperienceTable()} returns false
*
* @return Table read when leveling up
*/
@NotNull

View File

@ -1,9 +1,9 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.Indyuce.mmocore.manager.registry.MMOCoreRegister;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;

View File

@ -6,6 +6,7 @@ import net.Indyuce.mmocore.api.event.AsyncPlayerDataLoadEvent;
import net.Indyuce.mmocore.api.event.PlayerDataLoadEvent;
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.player.DefaultPlayerData;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.ConfigurationSection;
@ -16,7 +17,7 @@ import java.util.*;
public abstract class PlayerDataManager {
private final static Map<UUID, PlayerData> data = Collections.synchronizedMap(new HashMap<>());
private DefaultPlayerData defaultData = new DefaultPlayerData(1, 0, 0, 0, 0, 0, 0);
private DefaultPlayerData defaultData = DefaultPlayerData.DEFAULT;
public PlayerData get(OfflinePlayer player) {
return get(player.getUniqueId());
@ -125,67 +126,5 @@ public abstract class PlayerDataManager {
*/
public abstract void saveData(PlayerData data);
public class DefaultPlayerData {
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints, skillReallocPoints, skillTreeReallocPoints;
public DefaultPlayerData(ConfigurationSection config) {
level = config.getInt("level", 1);
classPoints = config.getInt("class-points");
skillPoints = config.getInt("skill-points");
attributePoints = config.getInt("attribute-points");
attrReallocPoints = config.getInt("attribute-realloc-points");
skillReallocPoints = config.getInt("skill-realloc-points", 0);
skillTreeReallocPoints = config.getInt("skill-tree-realloc-points", 0);
}
public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints, int skillReallocPoints, int skillTreeReallocPoints) {
this.level = level;
this.classPoints = classPoints;
this.skillPoints = skillPoints;
this.attributePoints = attributePoints;
this.attrReallocPoints = attrReallocPoints;
this.skillReallocPoints = skillReallocPoints;
this.skillTreeReallocPoints = skillTreeReallocPoints;
}
public int getLevel() {
return level;
}
public int getSkillPoints() {
return skillPoints;
}
public int getSkillTreeReallocPoints() {
return skillTreeReallocPoints;
}
public int getClassPoints() {
return classPoints;
}
public int getAttrReallocPoints() {
return attrReallocPoints;
}
public int getAttributePoints() {
return attributePoints;
}
public int getSkillReallocPoints() {
return skillReallocPoints;
}
public void apply(PlayerData player) {
player.setLevel(level);
player.setClassPoints(classPoints);
player.setSkillPoints(skillPoints);
player.setAttributePoints(attributePoints);
player.setAttributeReallocationPoints(attrReallocPoints);
player.setSkillTreeReallocationPoints(skillTreeReallocPoints);
player.setSkillReallocationPoints(skillReallocPoints);
}
}
}

View File

@ -13,8 +13,8 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.apache.commons.lang.Validate;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
@ -154,9 +154,9 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
data.setLevel(getDefaultData().getLevel());
data.setClassPoints(getDefaultData().getClassPoints());
data.setSkillPoints(getDefaultData().getSkillPoints());
data.setSkillReallocationPoints(getDefaultData().getSkillReallocPoints());
data.setSkillReallocationPoints(getDefaultData().getSkillReallocationPoints());
data.setAttributePoints(getDefaultData().getAttributePoints());
data.setAttributeReallocationPoints(getDefaultData().getAttrReallocPoints());
data.setAttributeReallocationPoints(getDefaultData().getAttributeReallocationPoints());
data.setExperience(0);
data.getQuestData().updateBossBar();
@ -205,7 +205,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
request.addJSONArray("bound_skills", boundSkills);
request.addJSONObject("skills", data.mapSkillLevels().entrySet());
request.addJSONObject("times_claimed", data.getItemClaims().entrySet());
request.addJSONObject("skill_tree_points", data.getSkillTreePoints().entrySet());
request.addJSONObject("skill_tree_points", data.mapSkillTreePoints().entrySet());
request.addJSONObject("skill_tree_levels", data.getNodeLevelsEntrySet());
request.addData("attributes", data.getAttributes().toJsonString());
request.addData("professions", data.getCollectionSkills().toJsonString());
@ -234,19 +234,19 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
for (String skill : info.getSkillKeys())
skillinfo.addProperty(skill, info.getSkillLevel(skill));
classinfo.add("skill", skillinfo);
JsonObject attributeinfo = new JsonObject();
JsonObject attributeInfo = new JsonObject();
for (String attribute : info.getAttributeKeys())
attributeinfo.addProperty(attribute, info.getAttributeLevel(attribute));
classinfo.add("attribute", attributeinfo);
attributeInfo.addProperty(attribute, info.getAttributeLevel(attribute));
classinfo.add("attribute", attributeInfo);
JsonObject nodeLevelsInfo = new JsonObject();
for (SkillTreeNode node : info.getNodeKeys())
attributeinfo.addProperty(node.getFullId(), info.getNodeLevel(node));
for (String node : info.getNodeKeys())
nodeLevelsInfo.addProperty(node, info.getNodeLevel(node));
classinfo.add("node-levels", nodeLevelsInfo);
JsonObject skillTreePointsInfo = new JsonObject();
for (String skillTreeId : info.getSkillTreePointsKeys())
attributeinfo.addProperty(skillTreeId, info.getSkillTreePoints(skillTreeId));
skillTreePointsInfo.addProperty(skillTreeId, info.getSkillTreePoints(skillTreeId));
classinfo.add("skill-tree-points", skillTreePointsInfo);
json.add(c, classinfo);

View File

@ -10,7 +10,7 @@ import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.manager.data.DataProvider;
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
@ -35,10 +35,10 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
data.setSkillPoints(config.getInt("skill-points", getDefaultData().getSkillPoints()));
data.setSkillReallocationPoints(config.getInt("skill-reallocation-points", getDefaultData().getSkillReallocPoints()));
data.setSkillTreeReallocationPoints(config.getInt("skill-tree-reallocation-points", getDefaultData().getSkillTreeReallocPoints()));
data.setSkillReallocationPoints(config.getInt("skill-reallocation-points", getDefaultData().getSkillReallocationPoints()));
data.setSkillTreeReallocationPoints(config.getInt("skill-tree-reallocation-points", getDefaultData().getSkillTreeReallocationPoints()));
data.setAttributePoints(config.getInt("attribute-points", getDefaultData().getAttributePoints()));
data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points", getDefaultData().getAttrReallocPoints()));
data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points", getDefaultData().getAttributeReallocationPoints()));
data.setLevel(config.getInt("level", getDefaultData().getLevel()));
data.setExperience(config.getInt("experience"));
if (config.contains("class"))
@ -138,7 +138,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
config.set("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
config.set("last-login", data.getLastLogin());
config.set("guild", data.hasGuild() ? data.getGuild().getId() : null);
data.getSkillTreePoints().forEach((key1, value) -> config.set("skill-tree-points." + key1, value));
data.mapSkillTreePoints().forEach((key1, value) -> config.set("skill-tree-points." + key1, value));
config.set("skill-tree-reallocation-points", data.getSkillTreeReallocationPoints());
config.set("skill", null);
config.set("mana", data.getMana());
@ -178,11 +178,10 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
config.set("class-info." + key + ".skill-reallocation-points", info.getSkillReallocationPoints());
info.getSkillKeys().forEach(skill -> config.set("class-info." + key + ".skill." + skill, info.getSkillLevel(skill)));
info.getAttributeKeys().forEach(attribute -> config.set("class-info." + key + ".attribute." + attribute, info.getAttributeLevel(attribute)));
info.getNodeKeys().forEach(node -> config.set("class-info." + key + ".node-levels." + node.getFullId(), info.getNodeLevel(node)));
info.getNodeKeys().forEach(node -> config.set("class-info." + key + ".node-levels." + node, info.getNodeLevel(node)));
info.getSkillTreePointsKeys().forEach(skillTreeId -> config.set("class-info." + key + ".skill-tree-points." + skillTreeId, info.getAttributeLevel(skillTreeId)));
}
file.save();
}

View File

@ -0,0 +1,45 @@
package net.Indyuce.mmocore.player;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import java.util.List;
import java.util.Map;
/**
* All the class-specific information i.e information being saved
* in {@link SavedClassInformation} when a player changes its current
* class.
*/
public interface ClassDataContainer {
int getLevel();
double getExperience();
int getSkillPoints();
int getAttributePoints();
int getAttributeReallocationPoints();
int getSkillReallocationPoints();
int getSkillTreeReallocationPoints();
Map<String, Integer> mapAttributeLevels();
Map<String, Integer> mapSkillLevels();
Map<String, Integer> mapSkillTreePoints();
List<ClassSkill> getBoundSkills();
List<PassiveSkill> getBoundPassiveSkills();
Map<SkillTreeNode, Integer> getNodeLevels();
Map<String, Integer> getNodeTimesClaimed();
}

View File

@ -0,0 +1,121 @@
package net.Indyuce.mmocore.player;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.bukkit.configuration.ConfigurationSection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DefaultPlayerData implements ClassDataContainer {
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints, skillReallocPoints, skillTreeReallocPoints;
public static final DefaultPlayerData DEFAULT = new DefaultPlayerData(1, 0, 0, 0, 0, 0, 0);
public DefaultPlayerData(ConfigurationSection config) {
level = config.getInt("level", 1);
classPoints = config.getInt("class-points");
skillPoints = config.getInt("skill-points");
attributePoints = config.getInt("attribute-points");
attrReallocPoints = config.getInt("attribute-realloc-points");
skillReallocPoints = config.getInt("skill-realloc-points", 0);
skillTreeReallocPoints = config.getInt("skill-tree-realloc-points", 0);
}
public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints, int skillReallocPoints, int skillTreeReallocPoints) {
this.level = level;
this.classPoints = classPoints;
this.skillPoints = skillPoints;
this.attributePoints = attributePoints;
this.attrReallocPoints = attrReallocPoints;
this.skillReallocPoints = skillReallocPoints;
this.skillTreeReallocPoints = skillTreeReallocPoints;
}
public int getLevel() {
return level;
}
@Override
public double getExperience() {
return 0;
}
@Override
public int getSkillPoints() {
return skillPoints;
}
public int getClassPoints() {
return classPoints;
}
@Override
public int getAttributePoints() {
return attributePoints;
}
@Override
public int getAttributeReallocationPoints() {
return attrReallocPoints;
}
@Override
public int getSkillReallocationPoints() {
return skillReallocPoints;
}
@Override
public int getSkillTreeReallocationPoints() {
return skillTreeReallocPoints;
}
@Override
public Map<String, Integer> mapSkillLevels() {
return new HashMap<>();
}
@Override
public Map<String, Integer> mapSkillTreePoints() {
return new HashMap<>();
}
@Override
public Map<SkillTreeNode, Integer> getNodeLevels() {
return new HashMap<>();
}
@Override
public Map<String, Integer> getNodeTimesClaimed() {
return new HashMap<>();
}
@Override
public Map<String, Integer> mapAttributeLevels() {
return new HashMap<>();
}
@Override
public List<ClassSkill> getBoundSkills() {
return new ArrayList<>();
}
@Override
public List<PassiveSkill> getBoundPassiveSkills() {
return new ArrayList<>();
}
public void apply(PlayerData player) {
player.setLevel(level);
player.setClassPoints(classPoints);
player.setSkillPoints(skillPoints);
player.setAttributePoints(attributePoints);
player.setAttributeReallocationPoints(attrReallocPoints);
player.setSkillTreeReallocationPoints(skillTreeReallocPoints);
player.setSkillReallocationPoints(skillReallocPoints);
}
}

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.tree;
package net.Indyuce.mmocore.skilltree;
import org.apache.commons.lang.Validate;

View File

@ -1,6 +1,7 @@
package net.Indyuce.mmocore.tree;
package net.Indyuce.mmocore.skilltree;
public enum NodeStatus {
public enum NodeState {
/**
* The player does not have access to this skill tree node just yet.
*/

View File

@ -0,0 +1,7 @@
package net.Indyuce.mmocore.skilltree;
public enum ParentType {
SOFT,
STRONG
}

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.tree;
package net.Indyuce.mmocore.skilltree;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore;
@ -8,8 +8,7 @@ import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.player.Unlockable;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
@ -18,8 +17,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
//We must use generics to get the type of the corresponding tree
public class SkillTreeNode implements Unlockable, ExperienceObject {
// We must use generics to get the type of the corresponding tree
public class SkillTreeNode implements ExperienceObject {
private final SkillTree tree;
private final String name, id;
private IntegerCoordinates coordinates;
@ -32,9 +31,9 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
private final ExperienceTable experienceTable;
//The max level the skill tree node can have and the max amount of children it can have.
// 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<>();
private final List<SkillTreeNode> children = new ArrayList<>();
/**
* Associates the required level to each parent.
@ -42,8 +41,13 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
* You only need to have the requirement for one of your softParents
* but you need to fulfill the requirements of all of your strong parents.
**/
private final HashMap<SkillTreeNode, Integer> softParents = new HashMap<>();
private final HashMap<SkillTreeNode, Integer> strongParents = new HashMap<>();
private final Map<SkillTreeNode, Integer> softParents = new HashMap<>();
private final Map<SkillTreeNode, Integer> strongParents = new HashMap<>();
/**
* Prefix used in node key
*/
public static final String KEY_PREFIX = "node";
public SkillTreeNode(SkillTree tree, ConfigurationSection config) {
Validate.notNull(config, "Config cannot be null");
@ -52,43 +56,30 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
size = Objects.requireNonNull(config.getInt("size"));
isRoot = config.getBoolean("is-root", false);
if (config.contains("lores")) {
for (String key : config.getConfigurationSection("lores").getKeys(false)) {
if (config.contains("lores"))
for (String key : config.getConfigurationSection("lores").getKeys(false))
try {
lores.put(Integer.parseInt(key), config.getStringList("lores." + key));
} catch (NumberFormatException e) {
throw new RuntimeException("You must only specifiy integers in lores.");
}
}
}
String expTableId = config.getString("experience-table");
Validate.notNull(expTableId, "You must specify an exp table for " + getFullId() + ".");
this.experienceTable = MMOCore.plugin.experience.getTableOrThrow(expTableId);
maxLevel = config.contains("max-level") ? config.getInt("max-level") : 1;
maxChildren = config.contains("max-children") ? config.getInt("max-children") : 1;
//If coordinates are precised and we are not with an automaticTree we set them up
// If coordinates are precised and we are not with an automaticTree we set them up
Validate.isTrue(config.contains("coordinates.x") && config.contains("coordinates.y"), "No coordinates specified");
coordinates = new IntegerCoordinates(config.getInt("coordinates.x"), config.getInt("coordinates.y"));
}
/**
* Prefix used in the key
*
* @return
*/
public static String getPrefix() {
return "node";
}
public SkillTree getTree() {
return tree;
}
public void setIsRoot() {
isRoot = true;
}
@ -97,7 +88,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
return isRoot;
}
//Used when postLoaded
// Used when postLoaded
public void addParent(SkillTreeNode parent, int requiredLevel, ParentType parentType) {
if (parentType == ParentType.SOFT)
softParents.put(parent, requiredLevel);
@ -125,7 +116,6 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
return maxLevel;
}
public int getMaxChildren() {
return maxChildren;
}
@ -138,7 +128,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
return strongParents.keySet();
}
public ArrayList<SkillTreeNode> getChildren() {
public List<SkillTreeNode> getChildren() {
return children;
}
@ -146,11 +136,17 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
return size;
}
/**
* @return The node identifier relative to its skill tree, like "extra_strength"
*/
public String getId() {
return id;
}
/**
* @return Full node identifier, containing both the node identifier AND
* the skill tree identifier, like "combat_extra_strength"
*/
public String getFullId() {
return tree.getId() + "_" + id;
}
@ -165,7 +161,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
@Override
public String getKey() {
return getPrefix() + ":" + getFullId().replace("-", "_");
return KEY_PREFIX + ":" + getFullId().replace("-", "_");
}
@Nullable
@ -185,11 +181,6 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
return experienceTable != null;
}
@Override
public String getUnlockNamespacedKey() {
return "skill_tree:" + tree.getId() + "_" + coordinates.getX() + "_" + coordinates.getY();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -226,28 +217,6 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
}
/**
* @param namespacedKey Something like "skill_tree:tree_name_1_5"
* @return The corresponding skill tree node
* @throws RuntimeException If the string cannot be parsed, if the specified
* skill tree does not exist or if the skill tree has no such node
*/
@NotNull
public static SkillTreeNode getFromNamespacedKey(String namespacedKey) {
String[] split = namespacedKey.substring(11).split("_");
int n = split.length;
IntegerCoordinates coords = new IntegerCoordinates(Integer.valueOf(split[n - 2]), Integer.valueOf(split[n - 1]));
StringBuilder treeIdBuilder = new StringBuilder();
for (int i = 0; i < n - 2; i++) {
if (i > 0)
treeIdBuilder.append("_");
treeIdBuilder.append(split[i]);
}
String treeId = treeIdBuilder.toString();
return MMOCore.plugin.skillTreeManager.get(treeId).getNode(coords);
}
@Override
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, @NotNull EXPSource source) {
throw new RuntimeException("Attributes don't have experience");
@ -257,43 +226,4 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
public boolean shouldHandle(PlayerData playerData) {
throw new RuntimeException("Attributes don't have experience");
}
public class NodeContext {
private final NodeState nodeState;
private final int nodeLevel;
public NodeContext(NodeState nodeState, int nodeLevel) {
this.nodeState = nodeState;
this.nodeLevel = nodeLevel;
}
public NodeState getNodeState() {
return nodeState;
}
public int getNodeLevel() {
return nodeLevel;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NodeContext that = (NodeContext) o;
return nodeLevel == that.nodeLevel && nodeState == that.nodeState;
}
@Override
public String toString() {
return "NodeContext{" +
"nodeState=" + nodeState +
", nodeLevel=" + nodeLevel +
'}';
}
@Override
public int hashCode() {
return Objects.hash(nodeState, nodeLevel);
}
}
}

View File

@ -1,42 +1,35 @@
package net.Indyuce.mmocore.tree.skilltree;
package net.Indyuce.mmocore.skilltree.tree;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.tree.ParentType;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import net.Indyuce.mmocore.skilltree.ParentType;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import java.util.logging.Level;
public class CustomSkillTree extends SkillTree {
public CustomSkillTree(ConfigurationSection config) {
super(config);
//We setup the coordinate map because coordinates are given in the yml for linked skill tree
// Setup the coordinate map because coordinates are given in the yml for linked skill tree
super.coordinatesSetup();
}
@Override
protected void whenPostLoaded(@NotNull ConfigurationSection config) {
//We setup the children and parents for each node.
// Setup the children and parents for each node.
for (SkillTreeNode node : nodes.values()) {
ConfigurationSection section = config.getConfigurationSection("nodes."+node.getId() + ".parents.soft");
ConfigurationSection section = config.getConfigurationSection("nodes." + node.getId() + ".parents.soft");
if (section != null) {
for (String parent : section.getKeys(false)) {
node.addParent(getNode(parent),section.getInt(parent),ParentType.SOFT);
node.addParent(getNode(parent), section.getInt(parent), ParentType.SOFT);
getNode(parent).addChild(node);
}
}
section = config.getConfigurationSection("nodes."+node.getId() + ".parents.strong");
section = config.getConfigurationSection("nodes." + node.getId() + ".parents.strong");
if (section != null) {
for (String parent : section.getKeys(false)) {
node.addParent(getNode(parent),section.getInt(parent),ParentType.STRONG);
node.addParent(getNode(parent), section.getInt(parent), ParentType.STRONG);
getNode(parent).addChild(node);
}
}
@ -44,17 +37,15 @@ public class CustomSkillTree extends SkillTree {
setupRoots();
}
private void setupRoots() {
//We find the roots of the tree which don't have any parents
// Find the tree roots which don't have any parents
for (SkillTreeNode node : nodes.values()) {
if (node.getSoftParents().size()+node.getStrongParents().size() == 0) {
//We mark the node as a root also
if (node.getSoftParents().size() + node.getStrongParents().size() == 0) {
// We mark the node as a root also
roots.add(node);
node.setIsRoot();
}
}
}
}

View File

@ -1,39 +1,35 @@
package net.Indyuce.mmocore.tree.skilltree;
package net.Indyuce.mmocore.skilltree.tree;
import io.lumine.mythic.lib.skill.Skill;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.tree.IntegerCoordinates;
import net.Indyuce.mmocore.tree.ParentType;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.IntegerCoordinates;
import net.Indyuce.mmocore.skilltree.NodeStatus;
import net.Indyuce.mmocore.skilltree.ParentType;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* For linked skillTrees there is no notion of children and parents you must have some neighbours unlocked in order to
* be unlockable. All the relationships in the tree are defined by the coordinates you nodes have.
* For linked skillTrees there is no notion of children and
* parents you must have some neighbours unlocked in order to
* be unlockable. All the relationships in the tree are
* defined by the coordinates you nodes have.
*/
public class LinkedSkillTree extends SkillTree {
public LinkedSkillTree(ConfigurationSection config) {
super(config);
//We setup the coordinate map because coordinates are given in the yml for linked skill tree
// Setup the coordinate map because coordinates are given in the yml for linked skill tree
coordinatesSetup();
}
@Override
protected void whenPostLoaded(@NotNull ConfigurationSection config) {
//We setup the children and parents if a node precise a required level for upgrade.
//If it is not filled the algorithm will put the required level to 1
// Setup the children and parents if a node precise a required level for upgrade.
// If it is not filled the algorithm will put the required level to 1
for (SkillTreeNode node : nodes.values()) {
if (config.contains(node.getId() + ".children")) {
ConfigurationSection section = config.getConfigurationSection(node.getId() + ".children.soft");
@ -59,37 +55,36 @@ public class LinkedSkillTree extends SkillTree {
}
@Override
public void setupNodeState(PlayerData playerData) {
//Values are labelled as unlockable
for (SkillTreeNode root : roots)
playerData.setNodeState(root, NodeState.UNLOCKABLE);
public void setupNodeStates(PlayerData playerData) {
//All the nodes with level >0 are unlocked
// Values are labelled as unlockable
for (SkillTreeNode root : roots)
playerData.setNodeState(root, NodeStatus.UNLOCKABLE);
// All the nodes with level >0 are unlocked
for (SkillTreeNode node : nodes.values()) {
if (playerData.getNodeLevel(node) > 0)
playerData.setNodeState(node, NodeState.UNLOCKED);
playerData.setNodeState(node, NodeStatus.UNLOCKED);
}
//Setup unlockable nodes
// Setup unlockable nodes
for (SkillTreeNode node : nodes.values()) {
if (isUnlockable(node, playerData) && !playerData.hasNodeState(node))
playerData.setNodeState(node, NodeState.UNLOCKABLE);
playerData.setNodeState(node, NodeStatus.UNLOCKABLE);
}
labelLockedNodes(playerData);
//We label all the remaining nodes to FULLY LOCKED
for (SkillTreeNode node : nodes.values()) {
// Label all the remaining nodes to FULLY LOCKED
for (SkillTreeNode node : nodes.values())
if (!playerData.hasNodeState(node))
playerData.setNodeState(node, NodeState.FULLY_LOCKED);
}
playerData.setNodeState(node, NodeStatus.FULLY_LOCKED);
}
/**
* We recursively label all the locked nodes who are connected to an unlockable node.
**/
private void labelLockedNodes(PlayerData playerData) {
List<SkillTreeNode> unlockableNodes = nodes.values().stream().filter(node -> playerData.getNodeState(node) == NodeState.UNLOCKABLE).toList();
List<SkillTreeNode> unlockableNodes = nodes.values().stream().filter(node -> playerData.getNodeState(node) == NodeStatus.UNLOCKABLE).toList();
for (SkillTreeNode node : unlockableNodes) {
labelLockedNodesFrom(playerData, node);
}
@ -98,7 +93,7 @@ public class LinkedSkillTree extends SkillTree {
private void labelLockedNodesFrom(PlayerData data, SkillTreeNode node) {
for (IntegerCoordinates coor : getCheckCoordinates(node.getCoordinates())) {
if (isNode(coor) && !data.hasNodeState(getNode(coor))) {
data.setNodeState(getNode(coor), NodeState.LOCKED);
data.setNodeState(getNode(coor), NodeStatus.LOCKED);
labelLockedNodesFrom(data, getNode(coor));
}
}
@ -109,13 +104,12 @@ public class LinkedSkillTree extends SkillTree {
new IntegerCoordinates(coor.getX() - 1, coor.getY()), new IntegerCoordinates(coor.getX(), coor.getY() + 1), new IntegerCoordinates(coor.getX(), coor.getY() - 1));
}
private boolean isUnlockable(SkillTreeNode node, PlayerData playerData) {
boolean isUnlockable = false;
for (IntegerCoordinates coordinates : getCheckCoordinates(node.getCoordinates())) {
if (isNode(coordinates))
if (isNode(coordinates) && playerData.getNodeState(getNode(coordinates)) == NodeState.UNLOCKED && countUnlockedNeighbours(coordinates, playerData) <= getNode(coordinates).getMaxChildren())
if (isNode(coordinates) && playerData.getNodeState(getNode(coordinates)) == NodeStatus.UNLOCKED && countUnlockedNeighbours(coordinates, playerData) <= getNode(coordinates).getMaxChildren())
isUnlockable = true;
}
return isUnlockable;
@ -132,6 +126,4 @@ public class LinkedSkillTree extends SkillTree {
}
return number;
}
}

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.tree.skilltree;
package net.Indyuce.mmocore.skilltree.tree;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
@ -6,11 +6,11 @@ import io.lumine.mythic.lib.api.util.PostLoadObject;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.registry.RegisteredObject;
import net.Indyuce.mmocore.tree.IntegerCoordinates;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo;
import net.Indyuce.mmocore.tree.skilltree.display.Icon;
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 org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -93,7 +93,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
continue;
}
for (String size : config.getConfigurationSection("icons." + key).getKeys(false)) {
DisplayInfo displayInfo = new DisplayInfo(NodeState.valueOf(UtilityMethods.enumName(key)), Integer.parseInt(size));
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);
@ -178,7 +178,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
/**
* Recursively go through the skill trees to update the the node states
*/
public void setupNodeState(PlayerData playerData) {
public void setupNodeStates(PlayerData playerData) {
for (SkillTreeNode root : roots)
setupNodeStateFrom(root, playerData);
}
@ -188,13 +188,14 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
}
/**
* Update recursively the state of all the nodes that are children of this node (Used when we change the state of a node)
* 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) {
private void setupNodeStateFrom(SkillTreeNode node, PlayerData playerData) {
if (playerData.getNodeLevel(node) > 0) {
playerData.setNodeState(node, NodeState.UNLOCKED);
playerData.setNodeState(node, NodeStatus.UNLOCKED);
} else if (playerData.getNodeLevel(node) == 0 && node.isRoot()) {
playerData.setNodeState(node, NodeState.UNLOCKABLE);
playerData.setNodeState(node, NodeStatus.UNLOCKABLE);
} else {
boolean isUnlockableFromStrongParent = node.getStrongParents().size() == 0 ? true : true;
boolean isUnlockableFromSoftParent = node.getSoftParents().size() == 0 ? true : false;
@ -212,7 +213,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
numberChildren++;
//We must check if the parent is Fully Locked or not and if it can unlock a new node(with its max children constraint)
if (numberChildren >= strongParent.getMaxChildren() || playerData.getNodeState(strongParent) == NodeState.FULLY_LOCKED)
if (numberChildren >= strongParent.getMaxChildren() || playerData.getNodeState(strongParent) == NodeStatus.FULLY_LOCKED)
isFullyLockedFromStrongParent = true;
}
@ -226,18 +227,18 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
for (SkillTreeNode child : softParent.getChildren())
if (playerData.getNodeLevel(child) > 0)
numberChildren++;
if (numberChildren < softParent.getMaxChildren() && playerData.getNodeState(softParent) != NodeState.FULLY_LOCKED)
if (numberChildren < softParent.getMaxChildren() && playerData.getNodeState(softParent) != NodeStatus.FULLY_LOCKED)
isFullyLockedFromSoftParent = false;
}
boolean isFullyLocked = isFullyLockedFromSoftParent || isFullyLockedFromStrongParent;
boolean isUnlockable = isUnlockableFromSoftParent && isUnlockableFromStrongParent;
if (isFullyLocked)
playerData.setNodeState(node, NodeState.FULLY_LOCKED);
playerData.setNodeState(node, NodeStatus.FULLY_LOCKED);
else if (isUnlockable)
playerData.setNodeState(node, NodeState.UNLOCKABLE);
playerData.setNodeState(node, NodeStatus.UNLOCKABLE);
else
playerData.setNodeState(node, NodeState.LOCKED);
playerData.setNodeState(node, NodeStatus.LOCKED);
}
//We recursively call the algorithm for all the children of the current node
for (SkillTreeNode child : node.getChildren())

View File

@ -1,6 +1,6 @@
package net.Indyuce.mmocore.tree.skilltree.display;
package net.Indyuce.mmocore.skilltree.tree.display;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.skilltree.NodeStatus;
import java.util.Objects;
@ -8,7 +8,7 @@ import java.util.Objects;
* The information needed to determine the display type of a node
*/
public class DisplayInfo {
private NodeState nodeState;
private NodeStatus nodeStatus;
private int size;
//this NodeDisplayInfo represent a path
@ -18,13 +18,13 @@ public class DisplayInfo {
public DisplayInfo() {
}
public DisplayInfo(NodeState nodeState, int size) {
this.nodeState = nodeState;
public DisplayInfo(NodeStatus nodeStatus, int size) {
this.nodeStatus = nodeStatus;
this.size = size;
}
public NodeState getNodeState() {
return nodeState;
public NodeStatus getNodeState() {
return nodeStatus;
}
public int getSize() {
@ -34,7 +34,7 @@ public class DisplayInfo {
@Override
public int hashCode() {
return Objects.hash(nodeState, size);
return Objects.hash(nodeStatus, size);
}
@Override
@ -42,15 +42,15 @@ public class DisplayInfo {
if(!(obj instanceof DisplayInfo))
return false;
DisplayInfo displayInfo= (DisplayInfo) obj;
if(nodeState==null)
if(nodeStatus ==null)
return displayInfo.getNodeState()==null;
return nodeState==displayInfo.getNodeState()&&size==displayInfo.getSize();
return nodeStatus ==displayInfo.getNodeState()&&size==displayInfo.getSize();
}
@Override
public String toString() {
return "DisplayInfo{" +
"nodeState=" + nodeState +
"nodeState=" + nodeStatus +
", size=" + size +
'}';
}

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.tree.skilltree.display;
package net.Indyuce.mmocore.skilltree.tree.display;
import io.lumine.mythic.lib.UtilityMethods;
import org.bukkit.Material;
@ -20,9 +20,10 @@ public class Icon {
public int getCustomModelData() {
return customModelData;
}
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("model-data") ? config.getInt("model-data") : 0);
}
public Icon(Material material, int customModelData) {
@ -30,7 +31,6 @@ public class Icon {
this.customModelData = customModelData;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@ -1,5 +0,0 @@
package net.Indyuce.mmocore.tree;
public enum ParentType {
SOFT,STRONG;
}

View File

@ -1,28 +0,0 @@
package net.Indyuce.mmocore.tree.modifier;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import org.apache.commons.lang.NotImplementedException;
public class UnlockSkillModifier extends PlayerModifier {
private RegisteredSkill unlocked = null;
public UnlockSkillModifier(String key, EquipmentSlot slot, ModifierSource source) {
super(key, slot, source);
}
@Override
public void register(MMOPlayerData mmoPlayerData) {
PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
// playerData.unlock(unlocked);
}
@Override
public void unregister(MMOPlayerData mmoPlayerData) {
throw new NotImplementedException("");
}
}

View File

@ -1,7 +0,0 @@
package net.Indyuce.mmocore.tree.skilltree;
public enum SkillTreeType {
AUTOMATIC_SKILL_TREE(),
LINKED_SKILL_TREE,
CUSTOM_SKILL_TREE;
}