Skill Tree Debug

This commit is contained in:
Ka0rX 2022-08-18 16:56:51 +02:00
parent 5cc49fd3ef
commit e51ae7cf9e
13 changed files with 603 additions and 26 deletions

View File

@ -100,7 +100,16 @@ public class SkillTreeViewer extends EditableInventory {
ItemMeta meta = item.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.setDisplayName(skillTree.getName());
meta.setLore(skillTree.getLore());
Placeholders holders= getPlaceholders(inv,n);
List<String> lore = new ArrayList<>();
getLore().forEach(string -> {
if (string.contains("{tree-lore}")) {
lore.addAll(skillTree.getLore());
}
else
lore.add(holders.apply(inv.getPlayer(),string));
});
meta.setLore(lore);
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(new NamespacedKey(MMOCore.plugin, "skill-tree-id"), PersistentDataType.STRING, skillTree.getId());
item.setItemMeta(meta);
@ -114,6 +123,8 @@ public class SkillTreeViewer extends EditableInventory {
Placeholders holders = new Placeholders();
holders.register("name", skillTree.getName());
holders.register("id", skillTree.getId());
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
return holders;
}
}
@ -376,6 +387,10 @@ public class SkillTreeViewer extends EditableInventory {
PersistentDataContainer container = event.getItemStack().getItemMeta().getPersistentDataContainer();
int x = container.get(new NamespacedKey(MMOCore.plugin, "coordinates.x"), PersistentDataType.INTEGER);
int y = container.get(new NamespacedKey(MMOCore.plugin, "coordinates.y"), PersistentDataType.INTEGER);
if(!skillTree.isNode(new IntegerCoordinates(x,y))) {
event.setCancelled(true);
return;
}
SkillTreeNode node = skillTree.getNode(new IntegerCoordinates(x, y));
if (playerData.canIncrementNodeLevel(node)) {
playerData.incrementNodeLevel(node);

View File

@ -76,6 +76,8 @@ public class ConfigManager {
}
if(!new File(MMOCore.plugin.getDataFolder()+"/skilltree").exists()) {
loadDefaultFile("skilltree","combat.yml");
loadDefaultFile("skilltree","autocombat.yml");
loadDefaultFile("skilltree","customcombat.yml");
}
loadDefaultFile("attributes.yml");

View File

@ -12,16 +12,16 @@ import java.util.stream.Collectors;
public class SkillTreeManager extends MMOCoreRegister<SkillTree> {
private final HashMap<String,SkillTreeNode> skillTreeNodes = new HashMap<>();
private final HashMap<String, SkillTreeNode> skillTreeNodes = new HashMap<>();
@Override
public void register(SkillTree tree){
public void register(SkillTree tree) {
super.register(tree);
tree.getNodes().forEach((node)->skillTreeNodes.put(node.getFullId(),node));
tree.getNodes().forEach((node) -> skillTreeNodes.put(node.getFullId(), node));
}
public boolean has(int index) {
return index>=0 &&index<registered.values().stream().collect(Collectors.toList()).size();
return index >= 0 && index < registered.values().stream().collect(Collectors.toList()).size();
}
@ -35,7 +35,7 @@ public class SkillTreeManager extends MMOCoreRegister<SkillTree> {
* @return The list of all the roots (e.g the nodes without any parents
*/
public List<SkillTreeNode> getRootNodes() {
return skillTreeNodes.values().stream().filter(treeNode -> treeNode.getSoftParents().size()==0).collect(Collectors.toList());
return skillTreeNodes.values().stream().filter(treeNode -> treeNode.getSoftParents().size() == 0).collect(Collectors.toList());
}
public Collection<SkillTreeNode> getAllNodes() {
@ -71,7 +71,9 @@ public class SkillTreeManager extends MMOCoreRegister<SkillTree> {
load(child);
}
} else {
register(SkillTree.loadSkillTree(YamlConfiguration.loadConfiguration(file)));
SkillTree skillTree = SkillTree.loadSkillTree(YamlConfiguration.loadConfiguration(file));
if (skillTree != null)
register(skillTree);
}
}
}

View File

@ -49,11 +49,21 @@ public class MySQLDataProvider extends MMODataSource implements DataProvider {
exception.printStackTrace();
}
});
// Add 'skill_tree_realloc_points' if it doesn't exist
getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'skill_tree_realloc_points'", result -> {
// Add 'skill_reallocation_points' if it doesn't exist
getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'skill_reallocation_points'", result -> {
try {
if (!result.next())
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN is_saved TINYINT");
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN skill_reallocation_points INT(11)");
} catch (SQLException exception) {
exception.printStackTrace();
}
});
// Add 'skill_tree_reallocation_points' if it doesn't exist
getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'skill_tree_reallocation_points'", result -> {
try {
if (!result.next())
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN skill_tree_reallocation_points INT(11)");
} catch (SQLException exception) {
exception.printStackTrace();
}
@ -62,7 +72,16 @@ public class MySQLDataProvider extends MMODataSource implements DataProvider {
getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'skill_tree_points'", result -> {
try {
if (!result.next())
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN is_saved TINYINT");
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN skill_tree_points LONGTEXT");
} catch (SQLException exception) {
exception.printStackTrace();
}
});
// Add 'skill_tree_levels' if it doesn't exist
getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'skill_tree_levels'", result -> {
try {
if (!result.next())
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN skill_tree_levels LONGTEXT");
} catch (SQLException exception) {
exception.printStackTrace();
}

View File

@ -12,7 +12,10 @@ import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
@ -61,6 +64,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
data.setClassPoints(result.getInt("class_points"));
data.setSkillPoints(result.getInt("skill_points"));
data.setSkillReallocationPoints(result.getInt("skill_reallocation_points"));
data.setSkillTreeReallocationPoints(result.getInt("skill_tree_reallocation_points"));
data.setAttributePoints(result.getInt("attribute_points"));
data.setAttributeReallocationPoints(result.getInt("attribute_realloc_points"));
data.setLevel(result.getInt("level"));
@ -72,6 +76,22 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
}
if(!isEmpty(result.getString("skill_tree_points"))) {
JsonObject json = new JsonParser().parse(result.getString("skill_tree_points")).getAsJsonObject();
for(SkillTree skillTree: MMOCore.plugin.skillTreeManager.getAll()) {
data.setSkillTreePoints(skillTree.getId(),json.has(skillTree.getId())?json.get(skillTree.getId()).getAsInt():0);
}
data.setSkillTreePoints("global",json.has("global")?json.get("global").getAsInt():0);
}
if(!isEmpty(result.getString("skill_tree_levels"))) {
JsonObject json = new JsonParser().parse(result.getString("skill_tree_levels")).getAsJsonObject();
for(SkillTreeNode skillTreeNode: MMOCore.plugin.skillTreeManager.getAllNodes()) {
data.setNodeLevel(skillTreeNode,json.has(skillTreeNode.getFullId())?json.get(skillTreeNode.getFullId()).getAsInt():0);
}
}
data.setupNodeState();
if (!isEmpty(result.getString("guild"))) {
Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
@ -160,6 +180,8 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
sql.updateData("skill_reallocation_points",data.getSkillReallocationPoints());
sql.updateData("attribute_points", data.getAttributePoints());
sql.updateData("attribute_realloc_points", data.getAttributeReallocationPoints());
sql.updateData("skill_tree_reallocation_points",data.getSkillTreeReallocationPoints());
sql.updateData("level", data.getLevel());
sql.updateData("experience", data.getExperience());
sql.updateData("class", data.getProfess().getId());
@ -172,6 +194,9 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
sql.updateJSONObject("skills", data.mapSkillLevels().entrySet());
sql.updateJSONObject("times_claimed", data.getItemClaims().entrySet());
sql.updateJSONObject("skill_tree_points",data.getSkillTreePoints().entrySet());
sql.updateJSONObject("skill_tree_levels",data.getNodeLevelsEntrySet());
sql.updateData("attributes", data.getAttributes().toJsonString());
sql.updateData("professions", data.getCollectionSkills().toJsonString());

View File

@ -29,7 +29,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
/**
* The lore corresponding to each level
*/
private final List<String> lore = new ArrayList<>();
private final Map<Integer,List<String>> lores = new HashMap<>();
private final ExperienceTable experienceTable;
@ -53,7 +53,15 @@ 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);
lore.addAll(config.getStringList("lore"));
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);
@ -202,6 +210,7 @@ public class SkillTreeNode implements Unlockable, ExperienceObject {
public List<String> getLore(PlayerData playerData) {
Placeholders holders = getPlaceholders(playerData);
List<String> parsedLore = new ArrayList<>();
List<String> lore= lores.get(playerData.getNodeLevel(this));
lore.forEach(string -> parsedLore.add(
MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string))));
return parsedLore;

View File

@ -4,6 +4,7 @@ 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;

View File

@ -29,6 +29,7 @@ public class CustomSkillTree extends SkillTree {
ConfigurationSection section = config.getConfigurationSection("nodes."+node.getId() + ".children.soft");
if (section != null) {
for (String child : section.getKeys(false)) {
Validate.isTrue(isNode(child),"The node "+child+ "defined in children.soft of"+node.getId()+"doesn't exist.");
node.addChild(getNode(child));
getNode(child).addParent(node, section.getInt(child), ParentType.SOFT);
}
@ -36,23 +37,26 @@ public class CustomSkillTree extends SkillTree {
section = config.getConfigurationSection("nodes."+node.getId() + ".children.strong");
if (section != null) {
for (String child : section.getKeys(false)) {
Validate.isTrue(isNode(child),"The node "+child+ "defined in children.strong of"+node.getId()+"doesn't exist.");
node.addChild(getNode(child));
getNode(child).addParent(node, section.getInt(child), ParentType.STRONG);
}
}
Bukkit.broadcastMessage(node.getSoftParents().size()+" strong: "+node.getStrongParents().size());
}
}
private void setupRoots() {
//We find the roots of the tree which don't have any parents
for (SkillTreeNode node : nodes.values()) {
if (node.getSoftParents().size() == 0 && node.getStrongParents().size() == 0) {
if (node.getSoftParents().size()+node.getStrongParents().size() == 0) {
//We mark the node as a root also
roots.add(node);
node.setIsRoot();
}
}
Bukkit.broadcastMessage("" + roots.size());
}
}

View File

@ -69,7 +69,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
nodes.put(node.getId(), node);
} catch (Exception e) {
MMOCore.plugin.getLogger().log(Level.SEVERE, "Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage());
MMOCore.log( "Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage());
}
}
try {
@ -83,7 +83,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
}
}
} catch (Exception e) {
Bukkit.getLogger().log(Level.WARNING, "Couldn't load paths for skill tree: " + id);
MMOCore.log(Level.WARNING, "Couldn't load paths for skill tree: " + id);
}
@ -182,6 +182,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) {
Bukkit.broadcastMessage(getId()+(this instanceof CustomSkillTree)+" "+roots.size());
for (SkillTreeNode root : roots)
root.getTree().setupNodeStateFrom(root, playerData);
}
@ -291,6 +292,10 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
public SkillTreeNode getNode(String name) {
return Objects.requireNonNull(nodes.get(name), "Could not find node in tree '" + id + "' with name '" + name + "'");
}
public boolean isNode(String name) {
return nodes.containsKey(name);
}
@Override
public boolean equals(Object o) {

View File

@ -1,7 +1,3 @@
# GUI display name
name: Your Character
# GUI display name
name: '&eCurrent Skill Tree: &6{skill-tree-name}'
@ -14,7 +10,14 @@ items:
name: '{skill-tree-node}'
function: skill-tree
slots: [9,18,27]
lore: 'Description: {skill-tree-description}'
lore:
- ''
- '&aDescription:'
- '{tree-lore}'
- ''
- '--------------------'
- '&e◆Current {name} &epoints: &6{skill-tree-points}'
- '&e◆Current Global points: &6{global-points}'
next-tree-list-page:
function: 'next-tree-list-page'
@ -48,6 +51,8 @@ items:
- '&7Current State: &6{current-state}'
- '&7Current Level: &6{current-level}'
- '&7Max Level: &6{max-level}'
- '&7Max Children: &6{max-children}'
- '&7Size: &6{size}'
- '--------------------'
- '&7⧆ &6Requirements: '
- '&fStrong Parents: '
@ -56,7 +61,7 @@ items:
- '&fSoft Parents: '
- '{soft-parents}'
- '--------------------'
- '{custom-lore}'
- '{node-lore}'
- '--------------------'
- '&eCurrent {skill-tree} &epoints: &6{skill-tree-points}'
- '&eCurrent global points: &6{global-points}'

View File

@ -0,0 +1,179 @@
id: autocombat
name: AutoCombat
type: automatic
item: GOLDEN_AXE
lore:
- '&6This autoskill tree is used for combat abilities!'
nodes:
strength:
name: 'Combat strength'
children:
strong:
force: 2
agility: 1
wisdom: 3
experience-table: class_exp_table
max-level: 3
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
wisdom:
name: 'Wisdom'
size: 1
max-children: 2
max-level: 2
experience-table: class_exp_table
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
agility:
name: 'Agility'
size: 1
max-children: 2
max-level: 2
experience-table: class_exp_table
children:
strong:
agility2: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
agility2:
name: 'Agility2'
size: 1
max-children: 2
max-level: 2
experience-table: class_exp_table
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
force:
name: 'Force'
size: 1
max-children: 1
max-level: 2
experience-table: class_exp_table
children:
strong:
weaponry: 1
archery: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
weaponry:
name: 'Weaponry'
max-level: 2
experience-table: class_exp_table
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery:
name: 'Archery'
experience-table: class_exp_table
max-level: 2
size: 1
children:
strong:
archery2: 2
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery2:
name: 'Archery2'
experience-table: class_exp_table
max-level: 2
size: 1
children:
strong:
archery3: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery3:
name: 'Archery3'
experience-table: class_exp_table
max-level: 2
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
icons:
unlocked:
1:
item: 'GREEN_DYE'
locked:
1:
item: "BROWN_DYE"
unlockable:
1:
item: "BLUE_DYE"
fully-locked:
1:
item: "BLACK_DYE"
path:
item: "WHITE_DYE"

View File

@ -0,0 +1,141 @@
id: 'combat'
name: '&4Combat'
lore:
- '&6This skill tree is used for combat abilities!'
type: 'linked'
item: 'DIAMOND_AXE'
nodes:
strength:
name: 'Combat strength'
coordinates:
x: 0
y: 0
max-level: 2
is-root: true
size: 1
experience-table: class_exp_table
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
force:
name: 'Force'
size: 1
max-children: 1
experience-table: class_exp_table
coordinates:
x: 1
y: 0
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
weaponry:
name: 'Weaponry'
coordinates:
x: 2
y: 0
experience-table: class_exp_table
max-level: 2
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery:
name: 'Archery'
coordinates:
x: 1
y: 1
experience-table: class_exp_table
max-level: 2
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery2:
name: 'Archery2'
coordinates:
x: 1
y: 2
experience-table: class_exp_table
max-level: 2
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery3:
name: 'Archery3'
coordinates:
x: 1
y: 3
max-level: 2
size: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1 :
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
paths:
path1:
x: 2
y: 2
path2:
x: 2
y: 3
icons:
unlocked:
1:
item: 'GREEN_DYE'
locked:
1:
item: "BROWN_DYE"
unlockable:
1:
item: "BLUE_DYE"
fully-locked:
1:
item: "BLACK_DYE"
path:
item: "WHITE_DYE"

View File

@ -0,0 +1,170 @@
id: customcombat
name: CustomCombat
type: custom
item: GOLDEN_AXE
lore:
- '&6This autoskill tree is used for combat abilities!'
nodes:
strength:
name: 'Combat strength'
children:
strong:
force: 2
agility: 1
wisdom: 3
experience-table: class_exp_table
max-level: 3
size: 1
coordinates:
x: 0
y: 0
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
wisdom:
name: 'Wisdom'
size: 1
max-children: 2
max-level: 2
coordinates:
x: -1
y: 0
experience-table: class_exp_table
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
agility:
name: 'Agility'
size: 1
max-children: 2
max-level: 2
experience-table: class_exp_table
coordinates:
x: 1
y: 0
children:
strong:
agility2: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
agility2:
name: 'Agility2'
size: 1
max-children: 2
max-level: 2
experience-table: class_exp_table
coordinates:
x: 1
y: -1
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
force:
name: 'Force'
size: 1
max-children: 1
max-level: 2
children:
strong:
weaponry: 1
archery: 1
experience-table: class_exp_table
coordinates:
x: 0
y: 1
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
weaponry:
name: 'Weaponry'
max-level: 2
size: 1
coordinates:
x: 1
y: 1
experience-table: class_exp_table
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
archery:
name: 'Archery'
max-level: 2
size: 1
experience-table: class_exp_table
coordinates:
x: 0
y: -1
lores:
0:
- "&eThis lore will be shown when level 0"
1:
- "&eThis lore will be shown when level 1"
2:
- "&eThis lore will be shown when level 2"
3:
- "&eThis lore will be shown when level 3"
icons:
unlocked:
1:
item: 'YELLOW_DYE'
model-data: 1
2:
item: 'ORANGE_DYE'
model-data: 0
locked:
1:
item: "BROWN_DYE"
unlockable:
1:
item: "BLUE_DYE"
fully-locked:
1:
item: "BLACK_DYE"
path:
item: "WHITE_DYE"