forked from Upstream/mmocore
Skill Tree.
This commit is contained in:
parent
fbba7ff034
commit
467d9263c4
@ -211,19 +211,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
|||||||
return nodeLevelsString.entrySet();
|
return nodeLevelsString.entrySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeModifiersFrom(SkillTree skillTree) {
|
|
||||||
for (SkillTreeNode node : skillTree.getNodes()) {
|
|
||||||
for (int i = 0; i < node.getMaxLevel(); i++) {
|
|
||||||
List<PlayerModifier> modifiers = node.getModifiers(i);
|
|
||||||
if (modifiers != null) {
|
|
||||||
for (PlayerModifier modifier : modifiers) {
|
|
||||||
modifier.unregister(getMMOPlayerData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canIncrementNodeLevel(SkillTreeNode node) {
|
public boolean canIncrementNodeLevel(SkillTreeNode node) {
|
||||||
NodeState nodeState = nodeStates.get(node);
|
NodeState nodeState = nodeStates.get(node);
|
||||||
//Check the State of the node
|
//Check the State of the node
|
||||||
@ -238,21 +225,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
|||||||
*/
|
*/
|
||||||
public <T extends SkillTree> void incrementNodeLevel(SkillTreeNode node) {
|
public <T extends SkillTree> void incrementNodeLevel(SkillTreeNode node) {
|
||||||
setNodeLevel(node, getNodeLevel(node) + 1);
|
setNodeLevel(node, getNodeLevel(node) + 1);
|
||||||
//Triggers the triggers of the node
|
//Claims the nodes experience table.
|
||||||
List<Trigger> triggers = node.getTriggers(getNodeLevel(node));
|
node.getExperienceTable().claim(this,getNodeLevel(node),node);
|
||||||
if (triggers != null) {
|
|
||||||
for (Trigger trigger : triggers) {
|
|
||||||
trigger.apply(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Applies player modifiers
|
|
||||||
List<PlayerModifier> modifiers = node.getModifiers(getNodeLevel(node));
|
|
||||||
if (modifiers != null)
|
|
||||||
for (PlayerModifier modifier : modifiers) {
|
|
||||||
modifier.register(getMMOPlayerData());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeStates.get(node) == NodeState.UNLOCKABLE)
|
if (nodeStates.get(node) == NodeState.UNLOCKABLE)
|
||||||
setNodeState(node, NodeState.UNLOCKED);
|
setNodeState(node, NodeState.UNLOCKED);
|
||||||
|
@ -28,6 +28,7 @@ public class AdminCommandTreeNode extends CommandTreeNode {
|
|||||||
addChild(new PointsCommandTreeNode("attr-realloc", this, PlayerData::setAttributeReallocationPoints, PlayerData::giveAttributeReallocationPoints, PlayerData::getAttributeReallocationPoints));
|
addChild(new PointsCommandTreeNode("attr-realloc", this, PlayerData::setAttributeReallocationPoints, PlayerData::giveAttributeReallocationPoints, PlayerData::getAttributeReallocationPoints));
|
||||||
addChild(new PointsCommandTreeNode("skill-realloc", this, PlayerData::setSkillReallocationPoints, PlayerData::giveSkillReallocationPoints, PlayerData::getSkillReallocationPoints));
|
addChild(new PointsCommandTreeNode("skill-realloc", this, PlayerData::setSkillReallocationPoints, PlayerData::giveSkillReallocationPoints, PlayerData::getSkillReallocationPoints));
|
||||||
addChild(new PointsCommandTreeNode("skill-tree-realloc", this, PlayerData::setSkillTreeReallocationPoints, PlayerData::giveSkillTreeReallocationPoints, PlayerData::getSkillTreeReallocationPoints));
|
addChild(new PointsCommandTreeNode("skill-tree-realloc", this, PlayerData::setSkillTreeReallocationPoints, PlayerData::giveSkillTreeReallocationPoints, PlayerData::getSkillTreeReallocationPoints));
|
||||||
|
addChild(new SkillTreePointsCommandTreeNode(this,(playerData, integer, s) -> playerData.setSkillTreePoints(s,integer),(playerData, integer, s) -> playerData.giveSkillTreePoints(s,integer),((playerData, s) -> playerData.getSkillTreePoint(s))));
|
||||||
for (PlayerResource res : PlayerResource.values())
|
for (PlayerResource res : PlayerResource.values())
|
||||||
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
|
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import net.Indyuce.mmocore.experience.PlayerProfessions;
|
|||||||
import net.Indyuce.mmocore.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.command.CommandVerbose;
|
import net.Indyuce.mmocore.command.CommandVerbose;
|
||||||
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
|
||||||
|
import net.Indyuce.mmocore.util.TriConsumer;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -88,10 +89,6 @@ public class ExperienceCommandTreeNode extends CommandTreeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface TriConsumer<A, B, C> {
|
|
||||||
void accept(A a, B b, C c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute(CommandSender sender, String[] args) {
|
public CommandResult execute(CommandSender sender, String[] args) {
|
||||||
|
@ -8,6 +8,7 @@ import net.Indyuce.mmocore.experience.EXPSource;
|
|||||||
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
import net.Indyuce.mmocore.experience.Profession;
|
import net.Indyuce.mmocore.experience.Profession;
|
||||||
import net.Indyuce.mmocore.command.CommandVerbose;
|
import net.Indyuce.mmocore.command.CommandVerbose;
|
||||||
|
import net.Indyuce.mmocore.util.TriConsumer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -85,10 +86,6 @@ public class LevelCommandTreeNode extends CommandTreeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface TriConsumer<A, B, C> {
|
|
||||||
void accept(A a, B b, C c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute(CommandSender sender, String[] args) {
|
public CommandResult execute(CommandSender sender, String[] args) {
|
||||||
|
@ -2,10 +2,10 @@ package net.Indyuce.mmocore.command.rpg.admin;
|
|||||||
|
|
||||||
import io.lumine.mythic.lib.command.api.CommandTreeNode;
|
import io.lumine.mythic.lib.command.api.CommandTreeNode;
|
||||||
import io.lumine.mythic.lib.command.api.Parameter;
|
import io.lumine.mythic.lib.command.api.Parameter;
|
||||||
import io.lumine.mythic.utils.functions.TriConsumer;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.command.CommandVerbose;
|
import net.Indyuce.mmocore.command.CommandVerbose;
|
||||||
|
import net.Indyuce.mmocore.util.TriConsumer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
@ -15,6 +15,7 @@ import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
|||||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||||
import net.Indyuce.mmocore.tree.IntegerCoordinates;
|
import net.Indyuce.mmocore.tree.IntegerCoordinates;
|
||||||
import net.Indyuce.mmocore.tree.SkillTreeNode;
|
import net.Indyuce.mmocore.tree.SkillTreeNode;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
@ -26,6 +27,7 @@ import org.bukkit.persistence.PersistentDataContainer;
|
|||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SkillTreeViewer extends EditableInventory {
|
public class SkillTreeViewer extends EditableInventory {
|
||||||
@ -159,19 +161,25 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ItemStack display(SkillTreeInventory inv, int n) {
|
public ItemStack display(SkillTreeInventory inv, int n) {
|
||||||
int slot = getSlots().get(n);
|
IntegerCoordinates coordinates = inv.getCoordinates(n);
|
||||||
int deltaX = (slot - inv.getMinSlot()) % 9;
|
|
||||||
int deltaY = (slot - inv.getMinSlot()) / 9;
|
|
||||||
IntegerCoordinates coordinates = new IntegerCoordinates(inv.getX() + deltaX, inv.getY() + deltaY);
|
|
||||||
if (inv.getSkillTree().isNode(coordinates) || inv.getSkillTree().isPath(coordinates)) {
|
if (inv.getSkillTree().isNode(coordinates) || inv.getSkillTree().isPath(coordinates)) {
|
||||||
Icon icon = inv.getPlayerData().getIcon(inv.getSkillTree(), coordinates);
|
Icon icon = inv.getPlayerData().getIcon(inv.getSkillTree(), coordinates);
|
||||||
ItemStack item = super.display(inv, n, icon.getMaterial(), icon.getCustomModelData());
|
ItemStack item = super.display(inv, n, icon.getMaterial(), icon.getCustomModelData());
|
||||||
ItemMeta meta = item.getItemMeta();
|
ItemMeta meta = item.getItemMeta();
|
||||||
if (inv.getSkillTree().isNode(coordinates)) {
|
if (inv.getSkillTree().isNode(coordinates)) {
|
||||||
SkillTreeNode node = inv.getSkillTree().getNode(coordinates);
|
SkillTreeNode node = inv.getSkillTree().getNode(coordinates);
|
||||||
List<String> lore = new ArrayList<>(node.getLore(inv.getPlayerData()));
|
List<String> lore = new ArrayList<>();
|
||||||
lore.add("");
|
|
||||||
getLore().forEach(str -> lore.add(MythicLib.plugin.parseColors(getPlaceholders(inv, n).apply(inv.getPlayer(), str))));
|
getLore().forEach(str -> {
|
||||||
|
if (str.contains("{node-lore}")) {
|
||||||
|
lore.addAll(node.getLore(inv.getPlayerData()));
|
||||||
|
} else if (str.contains("{strong-parents}")) {
|
||||||
|
lore.addAll(getParentsLore(inv, node, node.getStrongParents()));
|
||||||
|
} else if (str.contains("{soft-parents}")) {
|
||||||
|
lore.addAll(getParentsLore(inv, node, node.getSoftParents()));
|
||||||
|
} else
|
||||||
|
lore.add(getPlaceholders(inv, n).apply(inv.getPlayer(), str));
|
||||||
|
});
|
||||||
meta.setLore(lore);
|
meta.setLore(lore);
|
||||||
meta.setDisplayName(node.getName());
|
meta.setDisplayName(node.getName());
|
||||||
}
|
}
|
||||||
@ -191,10 +199,32 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft&Strong children lore for the node
|
||||||
|
*/
|
||||||
|
public List<String> getParentsLore(SkillTreeInventory inv, SkillTreeNode node, Collection<SkillTreeNode> parents) {
|
||||||
|
List<String> lore = new ArrayList<>();
|
||||||
|
for (SkillTreeNode parent : parents) {
|
||||||
|
int level = inv.getPlayerData().getNodeLevel(parent);
|
||||||
|
ChatColor color = level >= node.getParentNeededLevel(parent) ? ChatColor.GREEN : ChatColor.RED;
|
||||||
|
lore.add(ChatColor.GRAY + "◆" + parent.getName() + ": " + color + node.getParentNeededLevel(parent));
|
||||||
|
}
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Placeholders getPlaceholders(SkillTreeInventory inv, int n) {
|
public Placeholders getPlaceholders(SkillTreeInventory inv, int n) {
|
||||||
Placeholders holders = new Placeholders();
|
Placeholders holders = new Placeholders();
|
||||||
holders.register("skill-tree", inv.getSkillTree().getName());
|
holders.register("skill-tree", inv.getSkillTree().getName());
|
||||||
|
if (inv.getSkillTree().isNode(inv.getCoordinates(n))) {
|
||||||
|
SkillTreeNode node = inv.getNode(n);
|
||||||
|
holders.register("current-level", inv.getPlayerData().getNodeLevel(node));
|
||||||
|
holders.register("current-state", inv.getPlayerData().getNodeState(node));
|
||||||
|
holders.register("max-level", node.getMaxLevel());
|
||||||
|
holders.register("max-children", node.getMaxChildren());
|
||||||
|
holders.register("size", node.getSize());
|
||||||
|
}
|
||||||
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
|
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
|
||||||
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
|
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
|
||||||
return holders;
|
return holders;
|
||||||
@ -210,6 +240,7 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
private int treeListPage;
|
private int treeListPage;
|
||||||
private final int maxTreeListPage;
|
private final int maxTreeListPage;
|
||||||
private final SkillTree skillTree;
|
private final SkillTree skillTree;
|
||||||
|
private final List<Integer> slots;
|
||||||
|
|
||||||
public SkillTreeInventory(PlayerData playerData, EditableInventory editable) {
|
public SkillTreeInventory(PlayerData playerData, EditableInventory editable) {
|
||||||
super(playerData, editable);
|
super(playerData, editable);
|
||||||
@ -217,7 +248,7 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
skillTree = playerData.getOpenedSkillTree();
|
skillTree = playerData.getOpenedSkillTree();
|
||||||
maxTreeListPage = (MMOCore.plugin.skillTreeManager.getAll().size() - 1) / editable.getByFunction("skill-tree").getSlots().size();
|
maxTreeListPage = (MMOCore.plugin.skillTreeManager.getAll().size() - 1) / editable.getByFunction("skill-tree").getSlots().size();
|
||||||
//We get the width and height of the GUI(corresponding to the slots given)
|
//We get the width and height of the GUI(corresponding to the slots given)
|
||||||
List<Integer> slots = editable.getByFunction("skill-tree-node").getSlots();
|
slots = editable.getByFunction("skill-tree-node").getSlots();
|
||||||
minSlot = 64;
|
minSlot = 64;
|
||||||
maxSlot = 0;
|
maxSlot = 0;
|
||||||
for (int slot : slots) {
|
for (int slot : slots) {
|
||||||
@ -254,6 +285,19 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
return getEditable().getName().replace("{skill-tree-name}", skillTree.getName()).replace("{skill-tree-id}", skillTree.getId());
|
return getEditable().getName().replace("{skill-tree-name}", skillTree.getName()).replace("{skill-tree-id}", skillTree.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IntegerCoordinates getCoordinates(int n) {
|
||||||
|
int slot = slots.get(n);
|
||||||
|
int deltaX = (slot - getMinSlot()) % 9;
|
||||||
|
int deltaY = (slot - getMinSlot()) / 9;
|
||||||
|
IntegerCoordinates coordinates = new IntegerCoordinates(getX() + deltaX, getY() + deltaY);
|
||||||
|
return coordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkillTreeNode getNode(int n) {
|
||||||
|
return getSkillTree().getNode(getCoordinates(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public SkillTree getSkillTree() {
|
public SkillTree getSkillTree() {
|
||||||
return skillTree;
|
return skillTree;
|
||||||
}
|
}
|
||||||
@ -292,8 +336,6 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
//We remove all the nodeStates progress
|
//We remove all the nodeStates progress
|
||||||
playerData.giveSkillTreePoints(skillTree.getId(), reallocated);
|
playerData.giveSkillTreePoints(skillTree.getId(), reallocated);
|
||||||
playerData.giveSkillTreeReallocationPoints(-1);
|
playerData.giveSkillTreeReallocationPoints(-1);
|
||||||
//We unregister all the modifiers or the player
|
|
||||||
playerData.removeModifiersFrom(skillTree);
|
|
||||||
for (SkillTreeNode node : skillTree.getNodes()) {
|
for (SkillTreeNode node : skillTree.getNodes()) {
|
||||||
playerData.setNodeLevel(node, 0);
|
playerData.setNodeLevel(node, 0);
|
||||||
playerData.setNodeState(node, NodeState.LOCKED);
|
playerData.setNodeState(node, NodeState.LOCKED);
|
||||||
@ -323,16 +365,14 @@ public class SkillTreeViewer extends EditableInventory {
|
|||||||
|
|
||||||
if (event.getClickType() == ClickType.RIGHT) {
|
if (event.getClickType() == ClickType.RIGHT) {
|
||||||
int offset = event.getSlot();
|
int offset = event.getSlot();
|
||||||
int xOffset=offset%9-middleSlot%9;
|
int xOffset = offset % 9 - middleSlot % 9;
|
||||||
int yOffset=offset/9-middleSlot/9;
|
int yOffset = offset / 9 - middleSlot / 9;
|
||||||
x += xOffset;
|
x += xOffset;
|
||||||
y += yOffset-1;
|
y += yOffset - 1;
|
||||||
open();
|
open();
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (event.getClickType() == ClickType.LEFT) {
|
||||||
|
|
||||||
else if (event.getClickType() == ClickType.LEFT) {
|
|
||||||
PersistentDataContainer container = event.getItemStack().getItemMeta().getPersistentDataContainer();
|
PersistentDataContainer container = event.getItemStack().getItemMeta().getPersistentDataContainer();
|
||||||
int x = container.get(new NamespacedKey(MMOCore.plugin, "coordinates.x"), PersistentDataType.INTEGER);
|
int x = container.get(new NamespacedKey(MMOCore.plugin, "coordinates.x"), PersistentDataType.INTEGER);
|
||||||
int y = container.get(new NamespacedKey(MMOCore.plugin, "coordinates.y"), PersistentDataType.INTEGER);
|
int y = container.get(new NamespacedKey(MMOCore.plugin, "coordinates.y"), PersistentDataType.INTEGER);
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
package net.Indyuce.mmocore.tree;
|
package net.Indyuce.mmocore.tree;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import io.lumine.mythic.lib.UtilityMethods;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
|
||||||
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
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.gui.api.item.Placeholders;
|
||||||
import net.Indyuce.mmocore.player.Unlockable;
|
import net.Indyuce.mmocore.player.Unlockable;
|
||||||
import net.Indyuce.mmocore.tree.skilltree.AutomaticSkillTree;
|
import net.Indyuce.mmocore.tree.skilltree.AutomaticSkillTree;
|
||||||
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
|
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
//We must use generics to get the type of the corresponding tree
|
//We must use generics to get the type of the corresponding tree
|
||||||
public class SkillTreeNode implements Unlockable {
|
public class SkillTreeNode implements Unlockable, ExperienceObject {
|
||||||
private final SkillTree tree;
|
private final SkillTree tree;
|
||||||
private final String name, id;
|
private final String name, id;
|
||||||
private IntegerCoordinates coordinates;
|
private IntegerCoordinates coordinates;
|
||||||
@ -29,11 +29,9 @@ public class SkillTreeNode implements Unlockable {
|
|||||||
/**
|
/**
|
||||||
* The lore corresponding to each level
|
* The lore corresponding to each level
|
||||||
*/
|
*/
|
||||||
private final HashMap<NodeContext, List<String>> lores = new HashMap<>();
|
private final List<String> lore = new ArrayList<>();
|
||||||
|
|
||||||
//TODO modifiers depending on level with drop tables
|
private final ExperienceTable experienceTable;
|
||||||
private final HashMap<Integer, List<PlayerModifier>> modifiers = new HashMap<>();
|
|
||||||
private final HashMap<Integer, List<Trigger>> triggers = new HashMap<>();
|
|
||||||
|
|
||||||
//The max level the skill tree node can have and the max amount of children it can have.
|
//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 int maxLevel, maxChildren, size;
|
||||||
@ -55,56 +53,10 @@ public class SkillTreeNode implements Unlockable {
|
|||||||
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
|
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
|
||||||
size = Objects.requireNonNull(config.getInt("size"));
|
size = Objects.requireNonNull(config.getInt("size"));
|
||||||
isRoot = config.getBoolean("is-root", false);
|
isRoot = config.getBoolean("is-root", false);
|
||||||
|
lore.addAll(config.getStringList("lore"));
|
||||||
//We initialize the value of the lore for each skill tree node.
|
String expTableId = config.getString("experience-table");
|
||||||
for (String state : Objects.requireNonNull(config.getConfigurationSection("lores")).getKeys(false)) {
|
Validate.notNull(expTableId, "You must specify an exp table for " + getFullId() + ".");
|
||||||
NodeState nodeState = NodeState.valueOf(UtilityMethods.enumName(state));
|
this.experienceTable = MMOCore.plugin.experience.getTableOrThrow(expTableId);
|
||||||
if (nodeState == NodeState.UNLOCKED) {
|
|
||||||
//TODO: Message could'nt load ... instead of exce/*99+*-*99**9+-ption
|
|
||||||
ConfigurationSection section = config.getConfigurationSection("lores." + state);
|
|
||||||
for (String level : section.getKeys(false))
|
|
||||||
lores.put(new NodeContext(nodeState, Integer.parseInt(level)), section.getStringList(level));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
lores.put(new NodeContext(nodeState, 0), config.getStringList("lores." + state));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//We load the triggers
|
|
||||||
if (config.contains("triggers")) {
|
|
||||||
try {
|
|
||||||
ConfigurationSection section = config.getConfigurationSection("triggers");
|
|
||||||
for (String levelFormat : section.getKeys(false)) {
|
|
||||||
final int level = Integer.parseInt(levelFormat);
|
|
||||||
final List<Trigger> triggers = new ArrayList<>();
|
|
||||||
for (String str : section.getStringList(levelFormat))
|
|
||||||
triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(str)));
|
|
||||||
this.triggers.put(level, triggers);
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't load triggers for skill node " + tree.getId() + "." + id + " : Problem with the Number Format.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//We load the player Modifiers
|
|
||||||
if (config.contains("modifiers")) {
|
|
||||||
try {
|
|
||||||
ConfigurationSection section = config.getConfigurationSection("modifiers");
|
|
||||||
for (String level : section.getKeys(false)) {
|
|
||||||
int value = Integer.parseInt(level);
|
|
||||||
for (String str : section.getStringList(level)) {
|
|
||||||
PlayerModifier modifier = MythicLib.plugin.getModifiers().loadPlayerModifier(new MMOLineConfig(str));
|
|
||||||
if (!modifiers.containsKey(value)) {
|
|
||||||
modifiers.put(value, new ArrayList<>());
|
|
||||||
}
|
|
||||||
modifiers.get(value).add(modifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't load modifiers for the skill node " + tree.getId() + "." + id + " :Problem with the Number Format.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
maxLevel = config.contains("max-level") ? config.getInt("max-level") : 1;
|
maxLevel = config.contains("max-level") ? config.getInt("max-level") : 1;
|
||||||
@ -116,15 +68,6 @@ public class SkillTreeNode implements Unlockable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (config.contains("modifiers")) {
|
|
||||||
for (String key : config.getConfigurationSection("modifiers").getKeys(false)) {
|
|
||||||
PlayerModifier mod = MythicLib.plugin.getModifiers().loadPlayerModifier(new ConfigSectionObject(config.getConfigurationSection(key)));
|
|
||||||
modifiers.put(1, mod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public SkillTree getTree() {
|
public SkillTree getTree() {
|
||||||
return tree;
|
return tree;
|
||||||
@ -205,12 +148,26 @@ public class SkillTreeNode implements Unlockable {
|
|||||||
return coordinates;
|
return coordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PlayerModifier> getModifiers(int level) {
|
@Override
|
||||||
return modifiers.get(level);
|
public String getKey() {
|
||||||
|
return "skill_tree_node:" + getFullId().replace("-", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Trigger> getTriggers(int level) {
|
@Nullable
|
||||||
return triggers.get(level);
|
@Override
|
||||||
|
public ExpCurve getExpCurve() {
|
||||||
|
throw new RuntimeException("Attributes don't have experience");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public ExperienceTable getExperienceTable() {
|
||||||
|
return Objects.requireNonNull(experienceTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasExperienceTable() {
|
||||||
|
return experienceTable != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -239,60 +196,13 @@ public class SkillTreeNode implements Unlockable {
|
|||||||
holders.register("level", playerData.getNodeLevel(this));
|
holders.register("level", playerData.getNodeLevel(this));
|
||||||
holders.register("max-level", getMaxLevel());
|
holders.register("max-level", getMaxLevel());
|
||||||
holders.register("max-children", getMaxChildren());
|
holders.register("max-children", getMaxChildren());
|
||||||
|
|
||||||
//List of all the children of the node
|
|
||||||
String str = "";
|
|
||||||
for (SkillTreeNode node : getChildren())
|
|
||||||
str += node.getName() + ",";
|
|
||||||
//We remove the last comma
|
|
||||||
if (str.length() != 0)
|
|
||||||
str = str.substring(0, str.length() - 1);
|
|
||||||
holders.register("children", str);
|
|
||||||
|
|
||||||
//list of parents with the level needed for each of them
|
|
||||||
str = "";
|
|
||||||
for (SkillTreeNode node : getSoftParents())
|
|
||||||
str += node.getName() + " " + MMOCoreUtils.toRomanNumerals(getParentNeededLevel(node)) + ",";
|
|
||||||
//We remove the last comma
|
|
||||||
if (str.length() != 0)
|
|
||||||
str = str.substring(0, str.length() - 1);
|
|
||||||
holders.register("soft-parents-level", str);
|
|
||||||
|
|
||||||
//list of parents
|
|
||||||
str = "";
|
|
||||||
for (SkillTreeNode node : getSoftParents())
|
|
||||||
str += node.getName() + ",";
|
|
||||||
//We remove the last comma
|
|
||||||
if (str.length() != 0)
|
|
||||||
str = str.substring(0, str.length() - 1);
|
|
||||||
holders.register("soft-parents", str);
|
|
||||||
|
|
||||||
//list of parents with the level needed for each of them
|
|
||||||
str = "";
|
|
||||||
for (SkillTreeNode node : getStrongParents())
|
|
||||||
str += node.getName() + " " + MMOCoreUtils.toRomanNumerals(getParentNeededLevel(node)) + ",";
|
|
||||||
//We remove the last comma
|
|
||||||
if (str.length() != 0)
|
|
||||||
str = str.substring(0, str.length() - 1);
|
|
||||||
holders.register("strong-parents-level", str);
|
|
||||||
|
|
||||||
//list of parents
|
|
||||||
str = "";
|
|
||||||
for (SkillTreeNode node : getStrongParents())
|
|
||||||
str += node.getName() + ",";
|
|
||||||
//We remove the last comma
|
|
||||||
if (str.length() != 0)
|
|
||||||
str = str.substring(0, str.length() - 1);
|
|
||||||
holders.register("strong-parents", str);
|
|
||||||
|
|
||||||
return holders;
|
return holders;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getLore(PlayerData playerData) {
|
public List<String> getLore(PlayerData playerData) {
|
||||||
Placeholders holders = getPlaceholders(playerData);
|
Placeholders holders = getPlaceholders(playerData);
|
||||||
List<String> parsedLore = new ArrayList<>();
|
List<String> parsedLore = new ArrayList<>();
|
||||||
NodeContext context = new NodeContext(playerData.getNodeState(this), playerData.getNodeLevel(this));
|
lore.forEach(string -> parsedLore.add(
|
||||||
lores.get(context).forEach(string -> parsedLore.add(
|
|
||||||
MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string))));
|
MythicLib.plugin.parseColors(holders.apply(playerData.getPlayer(), string))));
|
||||||
return parsedLore;
|
return parsedLore;
|
||||||
|
|
||||||
@ -320,6 +230,16 @@ public class SkillTreeNode implements Unlockable {
|
|||||||
return MMOCore.plugin.skillTreeManager.get(treeId).getNode(coords);
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldHandle(PlayerData playerData) {
|
||||||
|
throw new RuntimeException("Attributes don't have experience");
|
||||||
|
}
|
||||||
|
|
||||||
public class NodeContext {
|
public class NodeContext {
|
||||||
private final NodeState nodeState;
|
private final NodeState nodeState;
|
||||||
private final int nodeLevel;
|
private final int nodeLevel;
|
||||||
|
@ -96,15 +96,15 @@ public class AutomaticSkillTree extends SkillTree {
|
|||||||
SkillTreeNode child = node.getChildren().get(i);
|
SkillTreeNode child = node.getChildren().get(i);
|
||||||
|
|
||||||
if (childrenSize % 2 == 1 && i == 0) {
|
if (childrenSize % 2 == 1 && i == 0) {
|
||||||
child.setCoordinates(new IntegerCoordinates(x, y - 2));
|
child.setCoordinates(new IntegerCoordinates(x, y - 1));
|
||||||
leftOffset += 2 + nodeBranches.get(child).getLeftBranches();
|
leftOffset += 2 + nodeBranches.get(child).getLeftBranches();
|
||||||
rightOffset += 2 + nodeBranches.get(child).getRightBranches();
|
rightOffset += 2 + nodeBranches.get(child).getRightBranches();
|
||||||
} else if (i % 2 == 0) {
|
} else if (i % 2 == 0) {
|
||||||
child.setCoordinates(new IntegerCoordinates(x - leftOffset - 2 - nodeBranches.get(child).getWidth(), y - 2));
|
child.setCoordinates(new IntegerCoordinates(x - leftOffset - 2 - nodeBranches.get(child).getWidth(), y - 1));
|
||||||
for (SkillTreeNode skillTree : nodeBranches.keySet())
|
for (SkillTreeNode skillTree : nodeBranches.keySet())
|
||||||
leftOffset += 2 + nodeBranches.get(child).getWidth();
|
leftOffset += 2 + nodeBranches.get(child).getWidth();
|
||||||
} else {
|
} else {
|
||||||
child.setCoordinates(new IntegerCoordinates(x + rightOffset + 2 + nodeBranches.get(child).getWidth(), y - 2));
|
child.setCoordinates(new IntegerCoordinates(x + rightOffset + 2 + nodeBranches.get(child).getWidth(), y - 1));
|
||||||
rightOffset += 2 + nodeBranches.get(child).getWidth();
|
rightOffset += 2 + nodeBranches.get(child).getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,9 +149,9 @@ public class AutomaticSkillTree extends SkillTree {
|
|||||||
leftBranches += nodeBranches.get(child).getLeftBranches();
|
leftBranches += nodeBranches.get(child).getLeftBranches();
|
||||||
rightBranches += nodeBranches.get(child).getRightBranches();
|
rightBranches += nodeBranches.get(child).getRightBranches();
|
||||||
} else if (i % 2 == 0) {
|
} else if (i % 2 == 0) {
|
||||||
leftBranches += nodeBranches.get(child).getWidth() + 2;
|
leftBranches += nodeBranches.get(child).getWidth();
|
||||||
} else {
|
} else {
|
||||||
rightBranches += nodeBranches.get(child).getWidth() + 2;
|
rightBranches += nodeBranches.get(child).getWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,13 @@ import net.Indyuce.mmocore.MMOCore;
|
|||||||
import net.Indyuce.mmocore.tree.ParentType;
|
import net.Indyuce.mmocore.tree.ParentType;
|
||||||
import net.Indyuce.mmocore.tree.SkillTreeNode;
|
import net.Indyuce.mmocore.tree.SkillTreeNode;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class CustomSkillTree extends SkillTree{
|
public class CustomSkillTree extends SkillTree {
|
||||||
public CustomSkillTree(ConfigurationSection config) {
|
public CustomSkillTree(ConfigurationSection config) {
|
||||||
super(config);
|
super(config);
|
||||||
|
|
||||||
@ -17,7 +18,6 @@ public class CustomSkillTree extends SkillTree{
|
|||||||
super.coordinatesSetup();
|
super.coordinatesSetup();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -25,31 +25,33 @@ public class CustomSkillTree extends SkillTree{
|
|||||||
|
|
||||||
//We setup the children and parents for each node.
|
//We setup the children and parents for each node.
|
||||||
for (SkillTreeNode node : nodes.values()) {
|
for (SkillTreeNode node : nodes.values()) {
|
||||||
ConfigurationSection section = config.getConfigurationSection(node.getId() + ".children.soft");
|
|
||||||
if(section!=null) {
|
ConfigurationSection section = config.getConfigurationSection("nodes."+node.getId() + ".children.soft");
|
||||||
|
if (section != null) {
|
||||||
for (String child : section.getKeys(false)) {
|
for (String child : section.getKeys(false)) {
|
||||||
node.addChild(getNode(child));
|
node.addChild(getNode(child));
|
||||||
getNode(child).addParent(node, section.getInt(child), ParentType.SOFT);
|
getNode(child).addParent(node, section.getInt(child), ParentType.SOFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
section = config.getConfigurationSection(node.getId() + ".children.strong");
|
section = config.getConfigurationSection("nodes."+node.getId() + ".children.strong");
|
||||||
if(section!=null) {
|
if (section != null) {
|
||||||
for (String child : section.getKeys(false)) {
|
for (String child : section.getKeys(false)) {
|
||||||
node.addChild(getNode(child));
|
node.addChild(getNode(child));
|
||||||
getNode(child).addParent(node, section.getInt(child), ParentType.STRONG);
|
getNode(child).addParent(node, section.getInt(child), ParentType.STRONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Bukkit.broadcastMessage(node.getSoftParents().size()+" strong: "+node.getStrongParents().size());
|
||||||
|
|
||||||
}
|
}
|
||||||
//We find the roots of the tree which don't have any parents
|
//We find the roots of the tree which don't have any parents
|
||||||
for (SkillTreeNode node : nodes.values()) {
|
for (SkillTreeNode node : nodes.values()) {
|
||||||
if (node.getSoftParents().size() == 0 && node.getStrongParents().size() == 0) {
|
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
|
//We mark the node as a root also
|
||||||
roots.add(node);
|
roots.add(node);
|
||||||
node.setIsRoot();
|
node.setIsRoot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MMOCore.plugin.getLogger().log(Level.SEVERE,roots.size()+" ROOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOoooT");
|
Bukkit.broadcastMessage("" + roots.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package net.Indyuce.mmocore.util;
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface TriConsumer<A, B, C> {
|
||||||
|
void accept(A a, B b, C c);
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
# GUI display name
|
||||||
|
name: Your Character
|
||||||
|
|
||||||
|
|
||||||
# GUI display name
|
# GUI display name
|
||||||
name: '&eCurrent Skill Tree: &6{skill-tree-name}'
|
name: '&eCurrent Skill Tree: &6{skill-tree-name}'
|
||||||
|
|
||||||
@ -9,25 +13,51 @@ items:
|
|||||||
skill-tree:
|
skill-tree:
|
||||||
name: '{skill-tree-node}'
|
name: '{skill-tree-node}'
|
||||||
function: skill-tree
|
function: skill-tree
|
||||||
slots: [9,18,27,36]
|
slots: [9,18,27]
|
||||||
lore: 'Description: {skill-tree-description}'
|
lore: 'Description: {skill-tree-description}'
|
||||||
|
|
||||||
next-tree-list-page:
|
next-tree-list-page:
|
||||||
function: 'next-tree-list-page'
|
function: 'next-tree-list-page'
|
||||||
item: ARROW
|
item: ARROW
|
||||||
slots: [ 45 ]
|
slots: [ 36 ]
|
||||||
|
|
||||||
previous-tree-list-page:
|
previous-tree-list-page:
|
||||||
function: 'previous-tree-list-page'
|
function: 'previous-tree-list-page'
|
||||||
item: 'ARROW'
|
item: 'ARROW'
|
||||||
slots: [ 0 ]
|
slots: [ 0 ]
|
||||||
|
|
||||||
|
reallocation:
|
||||||
|
function: reallocation
|
||||||
|
item: CAULDRON
|
||||||
|
slots: [45]
|
||||||
|
name: '&aReallocate Skill Tree Points'
|
||||||
|
lore:
|
||||||
|
- ''
|
||||||
|
- 'You have spent a total of &6{total}&7 skill tree points.'
|
||||||
|
- '&7Right click to reallocate them.'
|
||||||
|
- ''
|
||||||
|
- '&eCosts 1 attribute reallocation point.'
|
||||||
|
- '&e◆ Skill Tree Reallocation Points: &6{realloc-points}'
|
||||||
|
|
||||||
skill-tree-node:
|
skill-tree-node:
|
||||||
|
|
||||||
function: '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: [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]
|
||||||
#The lore that will be displayed after the lore of the node
|
#The lore that will be displayed after the lore of the node
|
||||||
lore:
|
lore:
|
||||||
|
- '&7Current State: &6{current-state}'
|
||||||
|
- '&7Current Level: &6{current-level}'
|
||||||
|
- '&7Max Level: &6{max-level}'
|
||||||
|
- '--------------------'
|
||||||
|
- '&7⧆ &6Requirements: '
|
||||||
|
- '&fStrong Parents: '
|
||||||
|
- '{strong-parents}'
|
||||||
|
- ''
|
||||||
|
- '&fSoft Parents: '
|
||||||
|
- '{soft-parents}'
|
||||||
|
- '--------------------'
|
||||||
|
- '{custom-lore}'
|
||||||
|
- '--------------------'
|
||||||
- '&eCurrent {skill-tree} &epoints: &6{skill-tree-points}'
|
- '&eCurrent {skill-tree} &epoints: &6{skill-tree-points}'
|
||||||
- '&eCurrent global points: &6{global-points}'
|
- '&eCurrent global points: &6{global-points}'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user