forked from Upstream/mmocore
Merge remote-tracking branch 'origin/master'
# Conflicts: # MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java # MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
This commit is contained in:
commit
446b68ea31
@ -365,10 +365,10 @@ public class MMOCore extends JavaPlugin {
|
||||
dropTableManager.initialize(clearBefore);
|
||||
statManager.initialize(clearBefore);
|
||||
professionManager.initialize(clearBefore);
|
||||
classManager.initialize(clearBefore);
|
||||
|
||||
InventoryManager.load();
|
||||
skillTreeManager.initialize(clearBefore);
|
||||
classManager.initialize(clearBefore);
|
||||
questManager.initialize(clearBefore);
|
||||
lootChests.initialize(clearBefore);
|
||||
restrictionManager.initialize(clearBefore);
|
||||
|
@ -4,6 +4,8 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
|
||||
import io.lumine.mythic.lib.player.skill.PassiveSkill;
|
||||
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
|
||||
import net.Indyuce.mmocore.party.provided.Party;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
@ -79,7 +81,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
private double mana, stamina, stellium;
|
||||
private Guild guild;
|
||||
private SkillCastingHandler skillCasting;
|
||||
private SkillTree cachedSkillTree;
|
||||
private final PlayerQuests questData;
|
||||
private final PlayerStats playerStats;
|
||||
private final List<UUID> friends = new ArrayList<>();
|
||||
@ -209,6 +210,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
return nodeLevelsString.entrySet();
|
||||
}
|
||||
|
||||
public Map<SkillTreeNode, Integer> getNodeLevels() {
|
||||
return nodeLevels;
|
||||
}
|
||||
|
||||
public boolean canIncrementNodeLevel(SkillTreeNode node) {
|
||||
NodeState nodeState = nodeStates.get(node);
|
||||
//Check the State of the node
|
||||
@ -292,6 +297,38 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
nodeLevels.put(node, nodeLevel);
|
||||
}
|
||||
|
||||
public void resetSkillTree(SkillTree skillTree) {
|
||||
for (SkillTreeNode node : skillTree.getNodes()) {
|
||||
node.getExperienceTable().reset(this,node);
|
||||
setNodeLevel(node, 0);
|
||||
}
|
||||
skillTree.setupNodeState(this);
|
||||
}
|
||||
|
||||
public Map<SkillTreeNode, NodeState> getNodeStates() {
|
||||
return nodeStates;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getNodeTimesClaimed() {
|
||||
Map<String, Integer> result = new HashMap<>();
|
||||
tableItemClaims.forEach((str, val) -> {
|
||||
if (str.startsWith(SkillTreeNode.getPrefix()))
|
||||
result.put(str, val);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public void resetNodeTimesClaimed() {
|
||||
Map<String, Integer> newTableItemClaims = new HashMap<>();
|
||||
tableItemClaims.forEach((str, val) -> {
|
||||
if (!str.startsWith(SkillTreeNode.getPrefix()))
|
||||
newTableItemClaims.put(str, val);
|
||||
});
|
||||
tableItemClaims.clear();
|
||||
tableItemClaims.putAll(newTableItemClaims);
|
||||
}
|
||||
|
||||
|
||||
public void addNodeLevel(SkillTreeNode node) {
|
||||
nodeLevels.put(node, nodeLevels.get(node) + 1);
|
||||
}
|
||||
@ -299,10 +336,12 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
// Remove from party
|
||||
AbstractParty party = getParty();
|
||||
if (party != null && party instanceof Party)
|
||||
((Party) party).removeMember(this);
|
||||
// Remove from party if it is MMO Party Module
|
||||
if(MMOCore.plugin.partyModule instanceof MMOCorePartyModule) {
|
||||
AbstractParty party = getParty();
|
||||
if (party != null && party instanceof Party)
|
||||
((Party) party).removeMember(this);
|
||||
}
|
||||
|
||||
// Close quest data
|
||||
questData.close();
|
||||
@ -354,19 +393,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
return Math.max(1, level);
|
||||
}
|
||||
|
||||
public void setCachedSkillTree(SkillTree cachedSkillTree) {
|
||||
this.cachedSkillTree = cachedSkillTree;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SkillTree getOpenedSkillTree() {
|
||||
if (cachedSkillTree == null) {
|
||||
Optional<SkillTree> optionnal = MMOCore.plugin.skillTreeManager.getAll().stream().findFirst();
|
||||
return optionnal.isPresent() ? optionnal.get() : null;
|
||||
}
|
||||
return cachedSkillTree;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AbstractParty getParty() {
|
||||
return MMOCore.plugin.partyModule.getParty(this);
|
||||
@ -415,13 +441,19 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
@Override
|
||||
public int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item) {
|
||||
String key = object.getKey() + "." + table.getId() + "." + item.getId();
|
||||
return getClaims(object.getKey() + "." + table.getId() + "." + item.getId());
|
||||
}
|
||||
|
||||
public int getClaims(String key) {
|
||||
return tableItemClaims.getOrDefault(key, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item, int times) {
|
||||
String key = object.getKey() + "." + table.getId() + "." + item.getId();
|
||||
setClaims(object.getKey() + "." + table.getId() + "." + item.getId(), times);
|
||||
}
|
||||
|
||||
public void setClaims(String key, int times) {
|
||||
tableItemClaims.put(key, times);
|
||||
}
|
||||
|
||||
|
@ -25,14 +25,16 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
import net.Indyuce.mmocore.experience.ExpCurve;
|
||||
import net.Indyuce.mmocore.experience.ExperienceObject;
|
||||
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||
import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
|
||||
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.md_5.bungee.api.ChatColor;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
@ -67,6 +69,8 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
private final CastingParticle castParticle;
|
||||
|
||||
private final int maxBoundActiveSkills, maxBoundPassiveSkills;
|
||||
|
||||
private final List<SkillTree> skillTrees = new ArrayList<>();
|
||||
private final List<PassiveSkill> classScripts = new LinkedList();
|
||||
private final Map<String, LinearValue> stats = new HashMap<>();
|
||||
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
|
||||
@ -97,7 +101,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
profileField.set(meta, gp);
|
||||
icon.setItemMeta(meta);
|
||||
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException
|
||||
| SecurityException exception) {
|
||||
| SecurityException exception) {
|
||||
throw new IllegalArgumentException("Could not apply playerhead texture: " + exception.getMessage());
|
||||
}
|
||||
|
||||
@ -125,6 +129,13 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from class '" + id + "': " + exception.getMessage());
|
||||
}
|
||||
this.expTable = expTable;
|
||||
if (config.contains("skill-trees"))
|
||||
for (String str : config.getStringList("skill-trees"))
|
||||
try {
|
||||
skillTrees.add(MMOCore.plugin.skillTreeManager.get(str));
|
||||
} catch (Exception e) {
|
||||
MMOCore.log(Level.WARNING, "Could not find skill tree with ID: " + str);
|
||||
}
|
||||
|
||||
if (config.contains("scripts"))
|
||||
for (String key : config.getConfigurationSection("scripts").getKeys(false))
|
||||
@ -243,7 +254,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
setOption(ClassOption.DISPLAY, false);
|
||||
setOption(ClassOption.DEFAULT, false);
|
||||
maxBoundActiveSkills = 6;
|
||||
maxBoundPassiveSkills=3;
|
||||
maxBoundPassiveSkills = 3;
|
||||
for (PlayerResource resource : PlayerResource.values())
|
||||
resourceHandlers.put(resource, new ResourceRegeneration(resource));
|
||||
}
|
||||
@ -302,6 +313,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
public int getMaxBoundActiveSkills() {
|
||||
return maxBoundActiveSkills;
|
||||
}
|
||||
|
||||
public int getMaxBoundPassiveSkills() {
|
||||
return maxBoundPassiveSkills;
|
||||
}
|
||||
@ -413,6 +425,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
return skills.containsKey(id);
|
||||
}
|
||||
|
||||
public List<SkillTree> getSkillTrees() {
|
||||
return skillTrees;
|
||||
}
|
||||
|
||||
public ClassSkill getSkill(RegisteredSkill skill) {
|
||||
return getSkill(skill.getHandler().getId());
|
||||
}
|
||||
|
@ -1,182 +1,264 @@
|
||||
package net.Indyuce.mmocore.api.player.profess;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import net.Indyuce.mmocore.tree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class SavedClassInformation {
|
||||
private final int level, skillPoints, attributePoints, attributeReallocationPoints;
|
||||
private final double experience;
|
||||
private final Map<String, Integer> attributes;
|
||||
private final Map<String, Integer> skills;
|
||||
private final int level, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints;
|
||||
private final double experience;
|
||||
private final Map<String, Integer> attributes;
|
||||
private final Map<String, Integer> skills;
|
||||
private final Map<String, Integer> skillTreePoints;
|
||||
private final Map<SkillTreeNode, Integer> nodeLevels;
|
||||
/**
|
||||
* Stores the tableItemsClaims values but only for skill tree node as it is class based.
|
||||
*/
|
||||
private final Map<String,Integer> nodeTimesClaimed;
|
||||
|
||||
public SavedClassInformation(ConfigurationSection config) {
|
||||
level = config.getInt("level");
|
||||
experience = config.getDouble("experience");
|
||||
skillPoints = config.getInt("skill-points");
|
||||
attributePoints = config.getInt("attribute-points");
|
||||
attributeReallocationPoints = config.getInt("attribute-realloc-points");
|
||||
public SavedClassInformation(ConfigurationSection config) {
|
||||
level = config.getInt("level");
|
||||
experience = config.getDouble("experience");
|
||||
skillPoints = config.getInt("skill-points");
|
||||
attributePoints = config.getInt("attribute-points");
|
||||
attributeReallocationPoints = config.getInt("attribute-realloc-points");
|
||||
skillReallocationPoints = config.getInt("skill-reallocation-points");
|
||||
skillTreeReallocationPoints = config.getInt("skill-tree-reallocation-points");
|
||||
attributes = new HashMap<>();
|
||||
if (config.contains("attribute"))
|
||||
config.getConfigurationSection("attribute").getKeys(false).forEach(key -> attributes.put(key, config.getInt("attribute." + key)));
|
||||
skills = new HashMap<>();
|
||||
if (config.contains("skill"))
|
||||
config.getConfigurationSection("skill").getKeys(false).forEach(key -> skills.put(key, config.getInt("skill." + key)));
|
||||
skillTreePoints = new HashMap<>();
|
||||
if (config.contains("skill-tree-points"))
|
||||
config.getConfigurationSection("skill-tree-points").getKeys(false).forEach(key -> skillTreePoints.put(key, config.getInt("skill-tree-points." + key)));
|
||||
nodeLevels = new HashMap<>();
|
||||
if (config.contains("node-levels"))
|
||||
config.getConfigurationSection("node-levels").getKeys(false).forEach(key -> nodeLevels.put(MMOCore.plugin.skillTreeManager.getNode(key), config.getInt("node-levels." + key)));
|
||||
nodeTimesClaimed = new HashMap<>();
|
||||
if (config.contains("node-times-claimed"))
|
||||
config.getConfigurationSection("node-times-claimed").getKeys(false).forEach(key -> nodeTimesClaimed.put(key, config.getInt("node-times-claimed." + key)));
|
||||
|
||||
attributes = new HashMap<>();
|
||||
if (config.contains("attribute"))
|
||||
config.getConfigurationSection("attribute").getKeys(false).forEach(key -> attributes.put(key, config.getInt("attribute." + key)));
|
||||
skills = new HashMap<>();
|
||||
if (config.contains("skill"))
|
||||
config.getConfigurationSection("skill").getKeys(false).forEach(key -> skills.put(key, config.getInt("skill." + key)));
|
||||
}
|
||||
}
|
||||
|
||||
public SavedClassInformation(JsonObject json) {
|
||||
level = json.get("level").getAsInt();
|
||||
experience = json.get("experience").getAsDouble();
|
||||
skillPoints = json.get("skill-points").getAsInt();
|
||||
attributePoints = json.get("attribute-points").getAsInt();
|
||||
attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt();
|
||||
public SavedClassInformation(JsonObject json) {
|
||||
level = json.get("level").getAsInt();
|
||||
experience = json.get("experience").getAsDouble();
|
||||
skillPoints = json.get("skill-points").getAsInt();
|
||||
attributePoints = json.get("attribute-points").getAsInt();
|
||||
attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt();
|
||||
skillReallocationPoints = json.get("skill-reallocation-points").getAsInt();
|
||||
skillTreeReallocationPoints = json.get("skill-tree-reallocation-points").getAsInt();
|
||||
attributes = new HashMap<>();
|
||||
if (json.has("attribute"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
|
||||
attributes.put(entry.getKey(), entry.getValue().getAsInt());
|
||||
skills = new HashMap<>();
|
||||
if (json.has("skill"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("skill").entrySet())
|
||||
skills.put(entry.getKey(), entry.getValue().getAsInt());
|
||||
skillTreePoints = new HashMap<>();
|
||||
if (json.has("skill-tree-points"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("skill-tree-points").entrySet())
|
||||
skillTreePoints.put(entry.getKey(), entry.getValue().getAsInt());
|
||||
nodeLevels = new HashMap<>();
|
||||
if (json.has("node-levels"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("node-levels").entrySet())
|
||||
nodeLevels.put(MMOCore.plugin.skillTreeManager.getNode(entry.getKey()), entry.getValue().getAsInt());
|
||||
nodeTimesClaimed=new HashMap<>();
|
||||
if (json.has("node-times-claimed"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("node-times-claimed").entrySet())
|
||||
nodeTimesClaimed.put(entry.getKey(), entry.getValue().getAsInt());
|
||||
|
||||
attributes = new HashMap<>();
|
||||
if (json.has("attribute"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
|
||||
attributes.put(entry.getKey(), entry.getValue().getAsInt());
|
||||
skills = new HashMap<>();
|
||||
if (json.has("skill"))
|
||||
for (Entry<String, JsonElement> entry : json.getAsJsonObject("skill").entrySet())
|
||||
skills.put(entry.getKey(), entry.getValue().getAsInt());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public SavedClassInformation(PlayerData player) {
|
||||
this(player.getLevel(), player.getExperience(), player.getSkillPoints(), player.getAttributePoints(), player.getAttributeReallocationPoints(),
|
||||
player.getAttributes().mapPoints(), player.mapSkillLevels());
|
||||
}
|
||||
public SavedClassInformation(PlayerData player) {
|
||||
this(player.getLevel(), player.getExperience(), player.getSkillPoints(), player.getAttributePoints(), player.getAttributeReallocationPoints()
|
||||
, player.getSkillTreeReallocationPoints(), player.getSkillReallocationPoints(),
|
||||
player.getAttributes().mapPoints(), player.mapSkillLevels(), player.getSkillTreePoints(), player.getNodeLevels(),player.getNodeTimesClaimed());
|
||||
}
|
||||
|
||||
public SavedClassInformation(PlayerDataManager.DefaultPlayerData data) {
|
||||
this(data.getLevel(), 0, data.getSkillPoints(), data.getAttributePoints(), data.getAttrReallocPoints());
|
||||
}
|
||||
public SavedClassInformation(PlayerDataManager.DefaultPlayerData data) {
|
||||
this(data.getLevel(), 0, data.getSkillPoints(), data.getAttributePoints(), data.getAttrReallocPoints(), data.getSkillTreeReallocPoints(), data.getSkillReallocPoints());
|
||||
}
|
||||
|
||||
public SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints) {
|
||||
this(level, experience, skillPoints, attributePoints, attributeReallocationPoints, new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
public SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints, int skillTreeReallocationPoints, int skillReallocationPoints) {
|
||||
this(level, experience, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints, new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>(),new HashMap<>());
|
||||
}
|
||||
|
||||
private SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints,
|
||||
Map<String, Integer> attributes, Map<String, Integer> skills) {
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.skillPoints = skillPoints;
|
||||
this.attributePoints = attributePoints;
|
||||
this.attributeReallocationPoints = attributeReallocationPoints;
|
||||
this.attributes = attributes;
|
||||
this.skills = skills;
|
||||
}
|
||||
public SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints, int skillTreeReallocationPoints, int skillReallocationPoints,
|
||||
Map<String, Integer> attributes, Map<String, Integer> skills, Map<String, Integer> skillTreePoints, Map<SkillTreeNode, Integer> nodeLevels,Map<String, Integer> nodeTimesClaimed) {
|
||||
this.level = level;
|
||||
this.skillPoints = skillPoints;
|
||||
this.attributePoints = attributePoints;
|
||||
this.attributeReallocationPoints = attributeReallocationPoints;
|
||||
this.skillTreeReallocationPoints = skillTreeReallocationPoints;
|
||||
this.skillReallocationPoints = skillReallocationPoints;
|
||||
this.experience = experience;
|
||||
this.attributes = attributes;
|
||||
this.skills = skills;
|
||||
this.skillTreePoints = skillTreePoints;
|
||||
this.nodeLevels = nodeLevels;
|
||||
this.nodeTimesClaimed=nodeTimesClaimed;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
public int getSkillPoints() {
|
||||
return skillPoints;
|
||||
}
|
||||
public int getSkillPoints() {
|
||||
return skillPoints;
|
||||
}
|
||||
|
||||
public int getAttributePoints() {
|
||||
return attributePoints;
|
||||
}
|
||||
public int getAttributePoints() {
|
||||
return attributePoints;
|
||||
}
|
||||
|
||||
public int getAttributeReallocationPoints() {
|
||||
return attributeReallocationPoints;
|
||||
}
|
||||
public int getAttributeReallocationPoints() {
|
||||
return attributeReallocationPoints;
|
||||
}
|
||||
|
||||
public Set<String> getSkillKeys() {
|
||||
return skills.keySet();
|
||||
}
|
||||
public Set<String> getSkillKeys() {
|
||||
return skills.keySet();
|
||||
}
|
||||
|
||||
public int getSkillLevel(RegisteredSkill skill) {
|
||||
return getSkillLevel(skill.getHandler().getId());
|
||||
}
|
||||
public int getSkillLevel(RegisteredSkill skill) {
|
||||
return getSkillLevel(skill.getHandler().getId());
|
||||
}
|
||||
|
||||
public int getSkillLevel(String id) {
|
||||
return skills.get(id);
|
||||
}
|
||||
public int getSkillLevel(String id) {
|
||||
return skills.get(id);
|
||||
}
|
||||
|
||||
public void registerSkillLevel(RegisteredSkill skill, int level) {
|
||||
registerSkillLevel(skill.getHandler().getId(), level);
|
||||
}
|
||||
public void registerSkillLevel(RegisteredSkill skill, int level) {
|
||||
registerSkillLevel(skill.getHandler().getId(), level);
|
||||
}
|
||||
|
||||
public void registerSkillLevel(String attribute, int level) {
|
||||
skills.put(attribute, level);
|
||||
}
|
||||
public int getSkillTreeReallocationPoints() {
|
||||
return skillTreeReallocationPoints;
|
||||
}
|
||||
|
||||
public Set<String> getAttributeKeys() {
|
||||
return attributes.keySet();
|
||||
}
|
||||
public int getSkillReallocationPoints() {
|
||||
return skillReallocationPoints;
|
||||
}
|
||||
|
||||
public int getAttributeLevel(PlayerAttribute attribute) {
|
||||
return getAttributeLevel(attribute.getId());
|
||||
}
|
||||
public void registerSkillLevel(String attribute, int level) {
|
||||
skills.put(attribute, level);
|
||||
}
|
||||
|
||||
public int getAttributeLevel(String id) {
|
||||
return attributes.get(id);
|
||||
}
|
||||
|
||||
public void registerAttributeLevel(PlayerAttribute attribute, int level) {
|
||||
registerAttributeLevel(attribute.getId(), level);
|
||||
}
|
||||
public Set<SkillTreeNode> getNodeKeys() {
|
||||
return nodeLevels.keySet();
|
||||
}
|
||||
|
||||
public void registerAttributeLevel(String attribute, int level) {
|
||||
attributes.put(attribute, level);
|
||||
}
|
||||
public int getNodeLevel(SkillTreeNode node) {
|
||||
return nodeLevels.get(node);
|
||||
}
|
||||
|
||||
public void load(PlayerClass profess, PlayerData player) {
|
||||
public Set<String> getSkillTreePointsKeys() {
|
||||
return skillTreePoints.keySet();
|
||||
}
|
||||
|
||||
/*
|
||||
* saves current class info inside a SavedClassInformation, only if the
|
||||
* class is a real class and not the default one.
|
||||
*/
|
||||
if (!player.getProfess().hasOption(ClassOption.DEFAULT) || MMOCore.plugin.configManager.saveDefaultClassInfo)
|
||||
player.applyClassInfo(player.getProfess(), new SavedClassInformation(player));
|
||||
public int getSkillTreePoints(String skillTreeId) {
|
||||
return skillTreePoints.get(skillTreeId);
|
||||
}
|
||||
|
||||
/*
|
||||
* resets information which much be reset after everything is saved.
|
||||
*/
|
||||
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
|
||||
player.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
|
||||
while (player.hasSkillBound(0))
|
||||
player.unbindSkill(0);
|
||||
public Set<String> getAttributeKeys() {
|
||||
return attributes.keySet();
|
||||
}
|
||||
|
||||
/*
|
||||
* reads this class info, applies it to the player. set class after
|
||||
* changing level so the player stats can be calculated based on new
|
||||
* level.
|
||||
*/
|
||||
player.setLevel(level);
|
||||
player.setExperience(experience);
|
||||
player.setSkillPoints(skillPoints);
|
||||
player.setAttributePoints(attributePoints);
|
||||
player.setAttributeReallocationPoints(attributeReallocationPoints);
|
||||
public int getAttributeLevel(String id) {
|
||||
return attributes.getOrDefault(id,0);
|
||||
}
|
||||
|
||||
skills.forEach(player::setSkillLevel);
|
||||
attributes.forEach((id, pts) -> player.getAttributes().setBaseAttribute(id, pts));
|
||||
public void registerAttributeLevel(PlayerAttribute attribute, int level) {
|
||||
registerAttributeLevel(attribute.getId(), level);
|
||||
}
|
||||
|
||||
/*
|
||||
* unload current class information and set the new profess once
|
||||
* everything is changed
|
||||
*/
|
||||
player.setClass(profess);
|
||||
player.unloadClassInfo(profess);
|
||||
public void registerAttributeLevel(String attribute, int level) {
|
||||
attributes.put(attribute, level);
|
||||
}
|
||||
|
||||
// Updates level on exp bar
|
||||
player.refreshVanillaExp();
|
||||
}
|
||||
public void load(PlayerClass profess, PlayerData player) {
|
||||
|
||||
/*
|
||||
* saves current class info inside a SavedClassInformation, only if the
|
||||
* class is a real class and not the default one.
|
||||
*/
|
||||
if (!player.getProfess().hasOption(ClassOption.DEFAULT) || MMOCore.plugin.configManager.saveDefaultClassInfo)
|
||||
player.applyClassInfo(player.getProfess(), new SavedClassInformation(player));
|
||||
|
||||
/*
|
||||
* resets information which much be reset after everything is saved.
|
||||
*/
|
||||
|
||||
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
|
||||
player.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
|
||||
|
||||
// We reset the experience table for each skill tree node to remove the perm stat.
|
||||
for (SkillTree skillTree : player.getProfess().getSkillTrees())
|
||||
for (SkillTreeNode node : skillTree.getNodes())
|
||||
node.getExperienceTable().reset(player, node);
|
||||
player.getNodeLevels().clear();
|
||||
player.getNodeStates().clear();
|
||||
|
||||
while (player.hasSkillBound(0))
|
||||
player.unbindSkill(0);
|
||||
|
||||
/*
|
||||
* reads this class info, applies it to the player. set class after
|
||||
* changing level so the player stats can be calculated based on new
|
||||
* level.
|
||||
*/
|
||||
player.setLevel(level);
|
||||
player.setExperience(experience);
|
||||
player.setSkillPoints(skillPoints);
|
||||
player.setAttributePoints(attributePoints);
|
||||
player.setAttributeReallocationPoints(attributeReallocationPoints);
|
||||
player.setSkillTreeReallocationPoints(skillTreeReallocationPoints);
|
||||
player.setSkillReallocationPoints(skillReallocationPoints);
|
||||
|
||||
(skills).forEach(player::setSkillLevel);
|
||||
attributes.forEach((id, pts) -> player.getAttributes().setBaseAttribute(id, pts));
|
||||
skillTreePoints.forEach((skillTree, point) -> player.setSkillTreePoints(skillTree, point));
|
||||
//Setup node levels and node state.
|
||||
nodeLevels.forEach((node, level) -> player.setNodeLevel(node, level));
|
||||
for(SkillTree skillTree: profess.getSkillTrees())
|
||||
skillTree.setupNodeState(player);
|
||||
|
||||
//Add the values to the times claimed table and claims the corresponding stat triggers.
|
||||
nodeTimesClaimed.forEach((str,val)->player.setClaims(str,val));
|
||||
//We claim back the stats triggers for all the skill tree nodes of the new class.
|
||||
for(SkillTree skillTree:profess.getSkillTrees())
|
||||
for(SkillTreeNode node:skillTree.getNodes())
|
||||
node.getExperienceTable().claimStatTriggers(player,node);
|
||||
|
||||
/*
|
||||
* unload current class information and set the new profess once
|
||||
* everything is changed
|
||||
*/
|
||||
player.setClass(profess);
|
||||
player.unloadClassInfo(profess);
|
||||
|
||||
// Updates level on exp bar
|
||||
player.refreshVanillaExp();
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,14 @@ import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public class StatTrigger extends Trigger {
|
||||
private final String stat;
|
||||
private final double amount;
|
||||
private final ModifierType type;
|
||||
private double totalAmount;
|
||||
private final UUID uuid =UUID.randomUUID();
|
||||
|
||||
public StatTrigger(MMOLineConfig config) {
|
||||
super(config);
|
||||
@ -35,7 +37,7 @@ public class StatTrigger extends Trigger {
|
||||
@Override
|
||||
public void apply(PlayerData player) {
|
||||
totalAmount+=amount;
|
||||
new StatModifier("trigger",stat,totalAmount,type).register(player.getMMOPlayerData());
|
||||
new StatModifier("trigger."+uuid.toString(),stat,totalAmount,type).register(player.getMMOPlayerData());
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +48,6 @@ public class StatTrigger extends Trigger {
|
||||
*/
|
||||
public void remove(PlayerData playerData) {
|
||||
totalAmount-=amount;
|
||||
new StatModifier("trigger", stat, totalAmount, type).register(playerData.getMMOPlayerData());
|
||||
new StatModifier("trigger."+uuid.toString(), stat, totalAmount, type).register(playerData.getMMOPlayerData());
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmocore.command;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
@ -21,18 +22,22 @@ public class SkillTreeCommand extends BukkitCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, String s, String[] args) {
|
||||
if (!(sender instanceof Player))
|
||||
if (!(sender instanceof Player player))
|
||||
return false;
|
||||
PlayerData data = PlayerData.get((Player) sender);
|
||||
PlayerData data = PlayerData.get(player);
|
||||
MMOCommandEvent event = new MMOCommandEvent(data, "skilltree");
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return true;
|
||||
if (MMOCore.plugin.skillTreeManager.getAll().size() != 0) {
|
||||
if (data.getProfess().getSkillTrees().size() != 0) {
|
||||
InventoryManager.TREE_VIEW.newInventory(data).open();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
else {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("no-skill-tree").send(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,9 +76,6 @@ public class ExperienceTable {
|
||||
public void claimStatTriggers(PlayerData data, ExperienceObject object) {
|
||||
for (ExperienceItem item : items) {
|
||||
int timesClaimed = data.getClaims(object, this, item);
|
||||
//MMOCore.log(object.getKey() + "." + getId() + "." + item.getId());
|
||||
//data.getItemClaims().keySet().forEach(str->MMOCore.log(str));
|
||||
//MMOCore.log(timesClaimed+"");
|
||||
for (int i = 0; i < timesClaimed; i++)
|
||||
item.applyStatTriggers(data);
|
||||
|
||||
|
@ -59,9 +59,9 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
|
||||
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
|
||||
holders.register("realloc-points", inv.getPlayerData().getSkillTreeReallocationPoints());
|
||||
int maxPointSpent=inv.getSkillTree().getMaxPointSpent();
|
||||
holders.register("max-point-spent",maxPointSpent==Integer.MAX_VALUE?"∞":maxPointSpent);
|
||||
holders.register("point-spent",inv.getPlayerData().getPointSpent(inv.getSkillTree()));
|
||||
int maxPointSpent = inv.getSkillTree().getMaxPointSpent();
|
||||
holders.register("max-point-spent", maxPointSpent == Integer.MAX_VALUE ? "∞" : maxPointSpent);
|
||||
holders.register("point-spent", inv.getPlayerData().getPointSpent(inv.getSkillTree()));
|
||||
|
||||
return holders;
|
||||
}
|
||||
@ -101,10 +101,10 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
@Override
|
||||
public ItemStack display(SkillTreeInventory inv, int n) {
|
||||
int index = inv.getEditable().getByFunction("skill-tree").getSlots().size() * inv.treeListPage + n;
|
||||
if (!MMOCore.plugin.skillTreeManager.has(index)) {
|
||||
if (inv.skillTrees.size() <= index) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
SkillTree skillTree = MMOCore.plugin.skillTreeManager.get(index);
|
||||
SkillTree skillTree = inv.skillTrees.get(index);
|
||||
//We display with the material corresponding to the skillTree
|
||||
ItemStack item = super.display(inv, n, skillTree.getItem());
|
||||
|
||||
@ -129,13 +129,13 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
@Override
|
||||
public Placeholders getPlaceholders(SkillTreeInventory inv, int n) {
|
||||
int index = inv.getEditable().getByFunction("skill-tree").getSlots().size() * inv.treeListPage + n;
|
||||
SkillTree skillTree = MMOCore.plugin.skillTreeManager.get(index);
|
||||
SkillTree skillTree = inv.skillTrees.get(index);
|
||||
Placeholders holders = new Placeholders();
|
||||
holders.register("name", skillTree.getName());
|
||||
holders.register("id", skillTree.getId());
|
||||
int maxPointSpent=inv.getSkillTree().getMaxPointSpent();
|
||||
holders.register("max-point-spent",maxPointSpent==Integer.MAX_VALUE?"∞":maxPointSpent);
|
||||
holders.register("point-spent",inv.getPlayerData().getPointSpent(inv.getSkillTree()));
|
||||
int maxPointSpent = inv.getSkillTree().getMaxPointSpent();
|
||||
holders.register("max-point-spent", maxPointSpent == Integer.MAX_VALUE ? "∞" : maxPointSpent);
|
||||
holders.register("point-spent", inv.getPlayerData().getPointSpent(inv.getSkillTree()));
|
||||
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
|
||||
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
|
||||
return holders;
|
||||
@ -249,9 +249,9 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
holders.register("max-children", node.getMaxChildren());
|
||||
holders.register("size", node.getSize());
|
||||
}
|
||||
int maxPointSpent=inv.getSkillTree().getMaxPointSpent();
|
||||
holders.register("max-point-spent",maxPointSpent==Integer.MAX_VALUE?"∞":maxPointSpent);
|
||||
holders.register("point-spent",inv.getPlayerData().getPointSpent(inv.getSkillTree()));
|
||||
int maxPointSpent = inv.getSkillTree().getMaxPointSpent();
|
||||
holders.register("max-point-spent", maxPointSpent == Integer.MAX_VALUE ? "∞" : maxPointSpent);
|
||||
holders.register("point-spent", inv.getPlayerData().getPointSpent(inv.getSkillTree()));
|
||||
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
|
||||
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
|
||||
return holders;
|
||||
@ -266,14 +266,16 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
private final int width, height;
|
||||
private int treeListPage;
|
||||
private final int maxTreeListPage;
|
||||
private final SkillTree skillTree;
|
||||
private final List<SkillTree> skillTrees;
|
||||
private SkillTree skillTree;
|
||||
private final List<Integer> slots;
|
||||
|
||||
public SkillTreeInventory(PlayerData playerData, EditableInventory editable) {
|
||||
super(playerData, editable);
|
||||
|
||||
skillTree = playerData.getOpenedSkillTree();
|
||||
maxTreeListPage = (MMOCore.plugin.skillTreeManager.getAll().size() - 1) / editable.getByFunction("skill-tree").getSlots().size();
|
||||
skillTrees = playerData.getProfess().getSkillTrees();
|
||||
skillTree = skillTrees.get(0);
|
||||
maxTreeListPage = (skillTrees.size() - 1) / editable.getByFunction("skill-tree").getSlots().size();
|
||||
//We get the width and height of the GUI(corresponding to the slots given)
|
||||
slots = editable.getByFunction("skill-tree-node").getSlots();
|
||||
minSlot = 64;
|
||||
@ -381,12 +383,7 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
//We remove all the nodeStates progress
|
||||
playerData.giveSkillTreePoints(skillTree.getId(), reallocated);
|
||||
playerData.giveSkillTreeReallocationPoints(-1);
|
||||
for (SkillTreeNode node : skillTree.getNodes()) {
|
||||
node.getExperienceTable().reset(playerData,node);
|
||||
playerData.setNodeLevel(node, 0);
|
||||
playerData.setNodeState(node, NodeState.LOCKED);
|
||||
|
||||
}
|
||||
playerData.resetSkillTree(skillTree);
|
||||
skillTree.setupNodeState(playerData);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("reallocated-points", "points", "" + playerData.getSkillTreePoint(skillTree.getId()), "skill-tree", skillTree.getName()).send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.RESET_SKILL_TREE).playTo(player);
|
||||
@ -400,10 +397,9 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
if (item.getFunction().equals("skill-tree")) {
|
||||
String id = event.getClickedItem().getItemMeta().getPersistentDataContainer().get(
|
||||
new NamespacedKey(MMOCore.plugin, "skill-tree-id"), PersistentDataType.STRING);
|
||||
playerData.setCachedSkillTree(MMOCore.plugin.skillTreeManager.get(id));
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.CHANGE_SKILL_TREE).playTo(player);
|
||||
|
||||
newInventory(playerData).open();
|
||||
skillTree=MMOCore.plugin.skillTreeManager.get(id);
|
||||
open();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
@ -418,7 +414,7 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
SkillTreeNode node = skillTree.getNode(new IntegerCoordinates(x, y));
|
||||
if(playerData.getPointSpent(skillTree)>= skillTree.getMaxPointSpent()) {
|
||||
if (playerData.getPointSpent(skillTree) >= skillTree.getMaxPointSpent()) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("max-points-reached").send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
|
||||
event.setCancelled(true);
|
||||
|
@ -231,6 +231,9 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
classinfo.addProperty("skill-points", info.getSkillPoints());
|
||||
classinfo.addProperty("attribute-points", info.getAttributePoints());
|
||||
classinfo.addProperty("attribute-realloc-points", info.getAttributeReallocationPoints());
|
||||
classinfo.addProperty("skill-reallocation-points",info.getSkillReallocationPoints());
|
||||
classinfo.addProperty("skill-tree-reallocation-points",info.getSkillTreeReallocationPoints());
|
||||
|
||||
JsonObject skillinfo = new JsonObject();
|
||||
for (String skill : info.getSkillKeys())
|
||||
skillinfo.addProperty(skill, info.getSkillLevel(skill));
|
||||
@ -240,6 +243,16 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
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));
|
||||
classinfo.add("node-levels", nodeLevelsInfo);
|
||||
|
||||
JsonObject skillTreePointsInfo = new JsonObject();
|
||||
for (String skillTreeId : info.getSkillTreePointsKeys())
|
||||
attributeinfo.addProperty(skillTreeId, info.getSkillTreePoints(skillTreeId));
|
||||
classinfo.add("skill-tree-points", skillTreePointsInfo);
|
||||
|
||||
json.add(c, classinfo);
|
||||
}
|
||||
|
||||
|
@ -174,11 +174,15 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
config.set("class-info." + key + ".skill-points", info.getSkillPoints());
|
||||
config.set("class-info." + key + ".attribute-points", info.getAttributePoints());
|
||||
config.set("class-info." + key + ".attribute-realloc-points", info.getAttributeReallocationPoints());
|
||||
config.set("class-info." + key + ".skill-tree-reallocation-points", info.getSkillTreeReallocationPoints());
|
||||
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.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.getSkillTreePointsKeys().forEach(skillTreeId -> config.set("class-info." + key + ".skill-tree-points." + skillTreeId, info.getAttributeLevel(skillTreeId)));
|
||||
}
|
||||
|
||||
|
||||
file.save();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import com.alessiodp.parties.api.interfaces.PartyPlayer;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.party.AbstractParty;
|
||||
import net.Indyuce.mmocore.party.PartyModule;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -14,12 +15,13 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PartiesPartyModule implements PartyModule {
|
||||
private final PartiesAPI api = Parties.getApi();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractParty getParty(PlayerData playerData) {
|
||||
Party party = api.getParty(playerData.getUniqueId());
|
||||
PartiesAPI api= Parties.getApi();
|
||||
PartyPlayer partyPlayer = api.getPartyPlayer(playerData.getUniqueId());
|
||||
Party party = api.getParty(partyPlayer.getPartyId());
|
||||
return party == null ? null : new CustomParty(party);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ 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.AutomaticSkillTree;
|
||||
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
@ -29,7 +28,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
|
||||
/**
|
||||
* The lore corresponding to each level
|
||||
*/
|
||||
private final Map<Integer,List<String>> lores = new HashMap<>();
|
||||
private final Map<Integer, List<String>> lores = new HashMap<>();
|
||||
|
||||
private final ExperienceTable experienceTable;
|
||||
|
||||
@ -53,11 +52,11 @@ 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) {
|
||||
lores.put(Integer.parseInt(key), config.getStringList("lores." + key));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new RuntimeException("You must only specifiy integers in lores.");
|
||||
}
|
||||
}
|
||||
@ -69,11 +68,19 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
|
||||
|
||||
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 with an automaticTree we set them up
|
||||
if ((!(tree instanceof AutomaticSkillTree))) {
|
||||
Validate.isTrue(config.contains("coordinates.x") && config.contains("coordinates.y"), "No coordinates specified");
|
||||
coordinates = new IntegerCoordinates(config.getInt("coordinates.x"), config.getInt("coordinates.y"));
|
||||
}
|
||||
//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";
|
||||
}
|
||||
|
||||
|
||||
@ -158,7 +165,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "node_" + getFullId().replace("-", "_");
|
||||
return getPrefix() + ":" + getFullId().replace("-", "_");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -210,9 +217,9 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
|
||||
public List<String> getLore(PlayerData playerData) {
|
||||
Placeholders holders = getPlaceholders(playerData);
|
||||
List<String> parsedLore = new ArrayList<>();
|
||||
if(!lores.containsKey(playerData.getNodeLevel(this)))
|
||||
if (!lores.containsKey(playerData.getNodeLevel(this)))
|
||||
return parsedLore;
|
||||
List<String> lore= lores.get(playerData.getNodeLevel(this));
|
||||
List<String> lore = lores.get(playerData.getNodeLevel(this));
|
||||
lore.forEach(string -> parsedLore.add(
|
||||
MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string))));
|
||||
return parsedLore;
|
||||
|
@ -1,212 +0,0 @@
|
||||
package net.Indyuce.mmocore.tree.skilltree;
|
||||
|
||||
import net.Indyuce.mmocore.tree.IntegerCoordinates;
|
||||
import net.Indyuce.mmocore.tree.ParentType;
|
||||
import net.Indyuce.mmocore.tree.SkillTreeNode;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Skill Trees where you only need to fill the strong and soft
|
||||
*/
|
||||
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<>();
|
||||
|
||||
public AutomaticSkillTree(ConfigurationSection config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenPostLoaded(ConfigurationSection config) {
|
||||
|
||||
|
||||
//We setup the children and parents for each node.
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
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);
|
||||
getNode(parent).addChild(node);
|
||||
}
|
||||
}
|
||||
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);
|
||||
getNode(parent).addChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//We find the root of the tree which is
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
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(roots.get(0));
|
||||
//We recursively setup all the coordinates of the tree nodes
|
||||
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(roots.get(0)).getLeftBranches();
|
||||
minY = 0;
|
||||
maxX = nodeBranches.get(roots.get(0)).getRightBranches();
|
||||
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
if (node.getCoordinates().getY() > maxY)
|
||||
maxY = node.getCoordinates().getY();
|
||||
}
|
||||
|
||||
//Eventually we setup the skill tree info related to coordinates
|
||||
super.coordinatesSetup();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive algorithm to automatically calculate the integercoordinates each node should have to have a good display.
|
||||
* It also fills the list pathToParents representing all the coordinates corresponding to a path between 2 nodes (for the GUI)
|
||||
*
|
||||
* @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);
|
||||
int yOffset = childrenSize == 1 || child.getChildren().size()== 1 ? 1 : 2;
|
||||
|
||||
if (childrenSize % 2 == 1 && i == 0) {
|
||||
child.setCoordinates(new IntegerCoordinates(x, y - yOffset));
|
||||
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 - yOffset));
|
||||
leftOffset += 2 + nodeBranches.get(child).getWidth();
|
||||
} else {
|
||||
child.setCoordinates(new IntegerCoordinates(x + rightOffset + 2 + nodeBranches.get(child).getWidth(), y - yOffset));
|
||||
rightOffset += 2 + nodeBranches.get(child).getWidth();
|
||||
}
|
||||
|
||||
//We setup the path to parent variable (Used for the GUI)
|
||||
int childX = child.getCoordinates().getX();
|
||||
int childY = child.getCoordinates().getY();
|
||||
|
||||
int parentX = node.getCoordinates().getX();
|
||||
int parentY = node.getCoordinates().getY();
|
||||
int offset = childX > parentX ? -1 : 1;
|
||||
while (childY + 1 != parentY) {
|
||||
paths.add(new IntegerCoordinates(childX, childY + 1));
|
||||
childY++;
|
||||
|
||||
}
|
||||
while (childX != parentX) {
|
||||
paths.add(new IntegerCoordinates(childX, childY + 1));
|
||||
childX += offset;
|
||||
}
|
||||
|
||||
|
||||
//We setup the coordinates for the associated child
|
||||
setupCoordinates(child);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Branches getBranches(SkillTreeNode node) {
|
||||
return nodeBranches.get(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively sed to setup all the right and left branches of the node to later determine its coordinates for GUI display
|
||||
*/
|
||||
public void setupTreeWidth(SkillTreeNode node) {
|
||||
|
||||
int childrenSize = node.getChildren().size();
|
||||
int leftBranches = 0;
|
||||
int rightBranches = 0;
|
||||
for (int i = 0; i < childrenSize; i++) {
|
||||
SkillTreeNode child = node.getChildren().get(i);
|
||||
setupTreeWidth(child);
|
||||
//If there is an odd number ob branches the first one will be at the center so we add to the left and to the right
|
||||
if (childrenSize % 2 == 1 && i == 0) {
|
||||
|
||||
leftBranches += nodeBranches.get(child).getLeftBranches();
|
||||
rightBranches += nodeBranches.get(child).getRightBranches();
|
||||
} else if (i % 2 == 0) {
|
||||
leftBranches += nodeBranches.get(child).getWidth();
|
||||
} else {
|
||||
rightBranches += nodeBranches.get(child).getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
nodeBranches.put(node, new Branches(leftBranches, rightBranches));
|
||||
}
|
||||
|
||||
private class Branches {
|
||||
private final int leftBranches, rightBranches;
|
||||
|
||||
public Branches(int leftBranches, int rightBranches) {
|
||||
this.leftBranches = leftBranches;
|
||||
this.rightBranches = rightBranches;
|
||||
}
|
||||
|
||||
public int getLeftBranches() {
|
||||
return leftBranches;
|
||||
}
|
||||
|
||||
public int getRightBranches() {
|
||||
return rightBranches;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return leftBranches + rightBranches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Branches branches = (Branches) o;
|
||||
return leftBranches == branches.leftBranches && rightBranches == branches.rightBranches;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Branches{" +
|
||||
"leftBranches=" + leftBranches +
|
||||
", rightBranches=" + rightBranches +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(leftBranches, rightBranches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
package net.Indyuce.mmocore.tree.skilltree;
|
||||
|
||||
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 org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -56,56 +58,75 @@ public class LinkedSkillTree extends SkillTree {
|
||||
Validate.notNull(root, "Their must be a node(the root of the tree) at the coordinates (0,0) ");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setupNodeStateFrom(SkillTreeNode node, PlayerData playerData) {
|
||||
public void setupNodeState(PlayerData playerData) {
|
||||
//Values are labelled as unlockable
|
||||
for (SkillTreeNode root : roots)
|
||||
playerData.setNodeState(root, NodeState.UNLOCKABLE);
|
||||
|
||||
int x = node.getCoordinates().getX();
|
||||
int y = node.getCoordinates().getY();
|
||||
List<IntegerCoordinates> checkCoordinates = Arrays.asList(new IntegerCoordinates(x + 1, y),
|
||||
new IntegerCoordinates(x - 1, y), new IntegerCoordinates(x, y + 1), new IntegerCoordinates(x, y - 1));
|
||||
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 isUnlockable = false;
|
||||
for (IntegerCoordinates coordinates : checkCoordinates) {
|
||||
if (isNode(coordinates))
|
||||
if (isNode(coordinates) && playerData.getNodeState(getNode(coordinates)) == NodeState.UNLOCKED && numberNeighbours(coordinates, playerData) <= getNode(coordinates).getMaxChildren())
|
||||
isUnlockable = true;
|
||||
}
|
||||
if (isUnlockable)
|
||||
//All the nodes with level >0 are unlocked
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
if (playerData.getNodeLevel(node) > 0)
|
||||
playerData.setNodeState(node, NodeState.UNLOCKED);
|
||||
}
|
||||
//Setup unlockable nodes
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
if (isUnlockable(node, playerData) && !playerData.hasNodeState(node))
|
||||
playerData.setNodeState(node, NodeState.UNLOCKABLE);
|
||||
else {
|
||||
List<SkillTreeNode> parents = new ArrayList<>();
|
||||
parents.add(node);
|
||||
boolean isFullyLocked = isFullyLockedFrom(node, parents, playerData);
|
||||
|
||||
if (isFullyLocked)
|
||||
playerData.setNodeState(node, NodeState.FULLY_LOCKED);
|
||||
else
|
||||
playerData.setNodeState(node, NodeState.LOCKED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//We call the recursive algorithm on the rest of the points. Doesn't call the algorithm if already loaded.
|
||||
for (IntegerCoordinates coordinates : checkCoordinates) {
|
||||
if (isNode(coordinates) && !playerData.hasNodeState(getNode(coordinates)))
|
||||
setupNodeStateFrom(getNode(coordinates), playerData);
|
||||
labelLockedNodes(playerData);
|
||||
|
||||
//We label all the remaining nodes to FULLY LOCKED
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
if (!playerData.hasNodeState(node))
|
||||
playerData.setNodeState(node, NodeState.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();
|
||||
for (SkillTreeNode node : unlockableNodes) {
|
||||
labelLockedNodesFrom(playerData, node);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
labelLockedNodesFrom(data, getNode(coor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Counts the number of Unlocked Nieghbourgs of a node for a certain playerData
|
||||
private int numberNeighbours(IntegerCoordinates coor, PlayerData playerData) {
|
||||
private List<IntegerCoordinates> getCheckCoordinates(IntegerCoordinates coor) {
|
||||
return Arrays.asList(new IntegerCoordinates(coor.getX() + 1, coor.getY()),
|
||||
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())
|
||||
isUnlockable = true;
|
||||
}
|
||||
return isUnlockable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of unlocked neighbours of a node for a certain playerData
|
||||
**/
|
||||
private int countUnlockedNeighbours(IntegerCoordinates coor, PlayerData playerData) {
|
||||
int number = 0;
|
||||
int x = coor.getX();
|
||||
int y = coor.getY();
|
||||
List<IntegerCoordinates> checkCoordinates = Arrays.asList(new IntegerCoordinates(x + 1, y),
|
||||
new IntegerCoordinates(x - 1, y), new IntegerCoordinates(x, y + 1), new IntegerCoordinates(x, y - 1));
|
||||
for (IntegerCoordinates coordinates : checkCoordinates) {
|
||||
for (IntegerCoordinates coordinates : getCheckCoordinates(coor)) {
|
||||
if (isNode(coordinates) && playerData.getNodeLevel(getNode(coordinates)) > 0)
|
||||
number++;
|
||||
}
|
||||
@ -113,40 +134,4 @@ public class LinkedSkillTree extends SkillTree {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A recursive algorithm to see if a node is fully locked or not in a linked skill tree
|
||||
*/
|
||||
public boolean isFullyLockedFrom(SkillTreeNode current, List<SkillTreeNode> parents, PlayerData playerData) {
|
||||
if (!parents.contains(current) && (playerData.getNodeState(current) == NodeState.UNLOCKABLE || playerData.getNodeState(current) == NodeState.UNLOCKED)) {
|
||||
//If the node is unlocked either we say it is not fully locked if a path can be found either wer return true is not path can be found down this way
|
||||
if (numberNeighbours(current.getCoordinates(), playerData) <= getNode(current.getCoordinates()).getMaxChildren()) {
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
//We verify that the node is unlocked or unlockable and can have links the first node
|
||||
|
||||
int x = current.getCoordinates().getX();
|
||||
int y = current.getCoordinates().getY();
|
||||
List<IntegerCoordinates> checkCoordinates = Arrays.asList(new IntegerCoordinates(x + 1, y),
|
||||
new IntegerCoordinates(x - 1, y), new IntegerCoordinates(x, y + 1), new IntegerCoordinates(x, y - 1));
|
||||
//We filter coordinates with only nodes that are not parents and not fully locked
|
||||
//We also need to have the number of neighbour <=max-child(max-child=1 -> can have 1 neighbour but if it has 2 it will make the other branches fully blocked
|
||||
checkCoordinates = checkCoordinates.stream().filter(coor -> isNode(coor)
|
||||
&& playerData.getNodeState(getNode(coor)) != NodeState.FULLY_LOCKED
|
||||
&& !parents.contains(getNode(coor))
|
||||
).collect(Collectors.toList());
|
||||
|
||||
boolean isFullyLocked = true;
|
||||
|
||||
parents.add(current);
|
||||
for (IntegerCoordinates coordinates : checkCoordinates) {
|
||||
if (!isFullyLockedFrom(getNode(coordinates), parents, playerData)) {
|
||||
isFullyLocked = false;
|
||||
//Very important to break to stop the recursion algorithm once one unlockable point has been found
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isFullyLocked;
|
||||
}
|
||||
}
|
||||
|
@ -157,12 +157,9 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
|
||||
try {
|
||||
String string = config.getString("type");
|
||||
Validate.notNull(string, "You must precise a type for the skill tree.");
|
||||
Validate.isTrue(string.equals("automatic") || string.equals("linked") || string.equals("custom"), "You must precise the type of the skill tree in the yml!" +
|
||||
"\nAllowed values: 'automatic','linked','custom'");
|
||||
if (string.equals("automatic")) {
|
||||
skillTree = new AutomaticSkillTree(config);
|
||||
skillTree.postLoad();
|
||||
}
|
||||
Validate.isTrue(string.equals("linked") || string.equals("custom"), "You must precise the type of the skill tree in the yml!" +
|
||||
"\nAllowed values: 'linked','custom'");
|
||||
|
||||
if (string.equals("linked")) {
|
||||
skillTree = new LinkedSkillTree(config);
|
||||
skillTree.postLoad();
|
||||
|
@ -12,25 +12,25 @@ items:
|
||||
item: PLAYER_HEAD
|
||||
name: "Up"
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTk5YWFmMjQ1NmE2MTIyZGU4ZjZiNjI2ODNmMmJjMmVlZDlhYmI4MWZkNWJlYTFiNGMyM2E1ODE1NmI2NjkifX19
|
||||
slots: [ 52 ]
|
||||
slots: [ 50 ]
|
||||
down:
|
||||
function: down
|
||||
item: PLAYER_HEAD
|
||||
name: "Down"
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzkxMmQ0NWIxYzc4Y2MyMjQ1MjcyM2VlNjZiYTJkMTU3NzdjYzI4ODU2OGQ2YzFiNjJhNTQ1YjI5YzcxODcifX19
|
||||
slots: [ 51 ]
|
||||
slots: [ 49 ]
|
||||
right:
|
||||
function: right
|
||||
item: PLAYER_HEAD
|
||||
name: "Right"
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTNmYzUyMjY0ZDhhZDllNjU0ZjQxNWJlZjAxYTIzOTQ3ZWRiY2NjY2Y2NDkzNzMyODliZWE0ZDE0OTU0MWY3MCJ9fX0=
|
||||
slots: [ 50 ]
|
||||
slots: [ 51 ]
|
||||
left:
|
||||
function: left
|
||||
item: PLAYER_HEAD
|
||||
name: "Left"
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWYxMzNlOTE5MTlkYjBhY2VmZGMyNzJkNjdmZDg3YjRiZTg4ZGM0NGE5NTg5NTg4MjQ0NzRlMjFlMDZkNTNlNiJ9fX0=
|
||||
slots: [ 49 ]
|
||||
slots: [ 48 ]
|
||||
|
||||
skill-tree:
|
||||
name: '{skill-tree-node}'
|
||||
@ -49,14 +49,14 @@ items:
|
||||
|
||||
next-tree-list-page:
|
||||
function: 'next-tree-list-page'
|
||||
item: ARROW
|
||||
name: "Next Page"
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTk5YWFmMjQ1NmE2MTIyZGU4ZjZiNjI2ODNmMmJjMmVlZDlhYmI4MWZkNWJlYTFiNGMyM2E1ODE1NmI2NjkifX19
|
||||
slots: [ 36 ]
|
||||
|
||||
previous-tree-list-page:
|
||||
function: 'previous-tree-list-page'
|
||||
item: 'ARROW'
|
||||
name: "Previous Page"
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzkxMmQ0NWIxYzc4Y2MyMjQ1MjcyM2VlNjZiYTJkMTU3NzdjYzI4ODU2OGQ2YzFiNjJhNTQ1YjI5YzcxODcifX19
|
||||
slots: [ 0 ]
|
||||
|
||||
reallocation:
|
||||
@ -76,7 +76,7 @@ items:
|
||||
skill-tree-node:
|
||||
|
||||
function: 'skill-tree-node'
|
||||
slots: [2,3,4,5,6,7,8,11,12,13,14,15,16,17,20,21,22,23,24,25,26,29,30,31,32,33,34,35,38,39,40,41,42,43,44]
|
||||
slots: [1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,37,38,39,40,41,42,43,44]
|
||||
#The lore that will be displayed after the lore of the node
|
||||
lore:
|
||||
- '&7Current State: &6{current-state}'
|
||||
|
@ -185,4 +185,5 @@ upgrade-skill-node: '&eYour skill node &6{skill-node} &eis now Level &6{level}&e
|
||||
skill-node-max-level-hit: '&cYou already hit the max level for that skill node.'
|
||||
not-enough-skill-tree-points: '&cYou need one skill tree point.'
|
||||
reallocated-points: '&eYou successfully reset the skill tree {skill-tree}. &eYou now have &6{points} &eskill tree points.'
|
||||
not-skill-tree-reallocation-point: '&cYou do not have 1 skill tree reallocation point.'
|
||||
not-skill-tree-reallocation-point: '&cYou do not have 1 skill tree reallocation point.'
|
||||
no-skill-tree: '&cYour class doesn''t have any skill tree.'
|
Loading…
Reference in New Issue
Block a user