mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2025-01-20 09:11:26 +01:00
Implemented feature associated to ticket #824 by adding incompatible-parents field in skill tree node config.
This commit is contained in:
parent
a125320dd0
commit
8e504e1a10
@ -12,10 +12,7 @@ import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
import net.Indyuce.mmocore.gui.skilltree.display.*;
|
||||
import net.Indyuce.mmocore.skilltree.IntegerCoordinates;
|
||||
import net.Indyuce.mmocore.skilltree.NodeStatus;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreePath;
|
||||
import net.Indyuce.mmocore.skilltree.*;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
@ -43,8 +40,8 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
super.reload(config);
|
||||
//Loads all the pathDisplayInfo
|
||||
for (PathStatus status : PathStatus.values())
|
||||
for (PathType pathType :PathType.values()){
|
||||
if(!config.contains("display.paths." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(pathType.name()))){
|
||||
for (PathType pathType : PathType.values()) {
|
||||
if (!config.contains("display.paths." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(pathType.name()))) {
|
||||
MMOCore.log("Missing path type: " + MMOCoreUtils.ymlName(pathType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name()));
|
||||
continue;
|
||||
}
|
||||
@ -52,8 +49,8 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
}
|
||||
//Loads all the nodeDisplayInfo
|
||||
for (NodeStatus status : NodeStatus.values())
|
||||
for (NodeType nodeType :NodeType.values()){
|
||||
if(!config.contains("display.nodes." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(nodeType.name()))){
|
||||
for (NodeType nodeType : NodeType.values()) {
|
||||
if (!config.contains("display.nodes." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(nodeType.name()))) {
|
||||
MMOCore.log("Missing node type: " + MMOCoreUtils.ymlName(nodeType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name()));
|
||||
continue;
|
||||
}
|
||||
@ -225,9 +222,11 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
if (str.contains("{node-lore}")) {
|
||||
lore.addAll(node.getLore(inv.getPlayerData()));
|
||||
} else if (str.contains("{strong-parents}")) {
|
||||
lore.addAll(getParentsLore(inv, node, node.getStrongParents()));
|
||||
lore.addAll(getParentsLore(inv, node, node.getParents(ParentType.STRONG)));
|
||||
} else if (str.contains("{soft-parents}")) {
|
||||
lore.addAll(getParentsLore(inv, node, node.getSoftParents()));
|
||||
lore.addAll(getParentsLore(inv, node, node.getParents(ParentType.SOFT)));
|
||||
} else if (str.contains("{incompatible-parents}")) {
|
||||
lore.addAll(getParentsLore(inv, node, node.getParents(ParentType.INCOMPATIBLE)));
|
||||
} else
|
||||
lore.add(getPlaceholders(inv, n).apply(inv.getPlayer(), str));
|
||||
});
|
||||
@ -345,9 +344,9 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
|
||||
if (skillTree.isNode(coordinates)) {
|
||||
SkillTreeNode node = skillTree.getNode(coordinates);
|
||||
NodeStatus nodeStatus =playerData.getNodeStatus(node);
|
||||
NodeStatus nodeStatus = playerData.getNodeStatus(node);
|
||||
//If the node has its own display, it will be shown.
|
||||
if(node.hasIcon(nodeStatus))
|
||||
if (node.hasIcon(nodeStatus))
|
||||
return node.getIcon(nodeStatus);
|
||||
|
||||
NodeType nodeType = NodeType.getNodeType(hasUpPath, hasRightPath, hasDownPath, hasLeftPath);
|
||||
@ -479,7 +478,7 @@ public class SkillTreeViewer extends EditableInventory {
|
||||
} else if (playerData.getNodeLevel(node) >= node.getMaxLevel()) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("skill-node-max-level-hit").send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
|
||||
}else if(!node.hasPermissionRequirement(playerData)){
|
||||
} else if (!node.hasPermissionRequirement(playerData)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("missing-skill-node-permission").send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmocore.manager;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.skilltree.ParentType;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import net.Indyuce.mmocore.manager.registry.MMOCoreRegister;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
@ -35,7 +36,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.getParents(ParentType.SOFT).size() == 0).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Collection<SkillTreeNode> getAllNodes() {
|
||||
|
@ -3,5 +3,8 @@ package net.Indyuce.mmocore.skilltree;
|
||||
public enum ParentType {
|
||||
SOFT,
|
||||
|
||||
STRONG
|
||||
STRONG,
|
||||
|
||||
INCOMPATIBLE;
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ 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.skilltree.SkillTreeViewer;
|
||||
import net.Indyuce.mmocore.gui.skilltree.display.Icon;
|
||||
import net.Indyuce.mmocore.skilltree.tree.ParentInformation;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
@ -18,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// We must use generics to get the type of the corresponding tree
|
||||
public class SkillTreeNode implements ExperienceObject {
|
||||
@ -52,8 +55,7 @@ public class SkillTreeNode implements ExperienceObject {
|
||||
* You only need to have the requirement for one of your softParents
|
||||
* but you need to fulfill the requirements of all of your strong parents.
|
||||
**/
|
||||
private final Map<SkillTreeNode, Integer> softParents = new HashMap<>();
|
||||
private final Map<SkillTreeNode, Integer> strongParents = new HashMap<>();
|
||||
private final Map<ParentInformation, Integer> parents = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Prefix used in node key
|
||||
@ -66,12 +68,12 @@ public class SkillTreeNode implements ExperienceObject {
|
||||
this.tree = tree;
|
||||
if (config.isConfigurationSection("display")) {
|
||||
for (NodeStatus status : NodeStatus.values()) {
|
||||
String ymlStatus=MMOCoreUtils.ymlName(status.name());
|
||||
String ymlStatus = MMOCoreUtils.ymlName(status.name());
|
||||
if (!config.isConfigurationSection("display." + ymlStatus)) {
|
||||
MMOCore.log("Could not find node display for status " + ymlStatus + " for node " + id + " in tree " + tree.getId() + ". Using default display.");
|
||||
continue;
|
||||
}
|
||||
icons.put(status, new Icon(config.getConfigurationSection("display." +MMOCoreUtils.ymlName(status.name()))));
|
||||
icons.put(status, new Icon(config.getConfigurationSection("display." + MMOCoreUtils.ymlName(status.name()))));
|
||||
}
|
||||
}
|
||||
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
|
||||
@ -120,10 +122,7 @@ public class SkillTreeNode implements ExperienceObject {
|
||||
|
||||
// Used when postLoaded
|
||||
public void addParent(SkillTreeNode parent, int requiredLevel, ParentType parentType) {
|
||||
if (parentType == ParentType.SOFT)
|
||||
softParents.put(parent, requiredLevel);
|
||||
else
|
||||
strongParents.put(parent, requiredLevel);
|
||||
parents.put(new ParentInformation(parent, parentType), requiredLevel);
|
||||
}
|
||||
|
||||
public void addChild(SkillTreeNode child) {
|
||||
@ -138,12 +137,23 @@ public class SkillTreeNode implements ExperienceObject {
|
||||
this.coordinates = coordinates;
|
||||
}
|
||||
|
||||
|
||||
public int getParentNeededLevel(SkillTreeNode parent) {
|
||||
return softParents.containsKey(parent) ? softParents.get(parent) : strongParents.containsKey(parent) ? strongParents.get(parent) : 0;
|
||||
for (Map.Entry<ParentInformation, Integer> entry : parents.entrySet())
|
||||
if (entry.getKey().node().equals(parent))
|
||||
return entry.getValue();
|
||||
throw new RuntimeException("Could not find parent " + parent.getId() + " for node " + id);
|
||||
}
|
||||
|
||||
public int getParentNeededLevel(SkillTreeNode parent, ParentType parentType) {
|
||||
return parents.get(new ParentInformation(parent, parentType));
|
||||
}
|
||||
|
||||
public boolean hasParent(SkillTreeNode parent) {
|
||||
return softParents.containsKey(parent) || strongParents.containsKey(parent);
|
||||
for (Map.Entry<ParentInformation, Integer> entry : parents.entrySet())
|
||||
if (entry.getKey().node() == parent)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getMaxLevel() {
|
||||
@ -154,18 +164,19 @@ public class SkillTreeNode implements ExperienceObject {
|
||||
return maxChildren;
|
||||
}
|
||||
|
||||
public boolean hasPermissionRequirement(PlayerData playerData){
|
||||
public boolean hasPermissionRequirement(PlayerData playerData) {
|
||||
return permissionRequired == null || playerData.getPlayer().hasPermission(permissionRequired);
|
||||
}
|
||||
|
||||
public Set<SkillTreeNode> getSoftParents() {
|
||||
return softParents.keySet();
|
||||
public Set<SkillTreeNode> getParents() {
|
||||
return parents.keySet().stream().map(ParentInformation::node).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<SkillTreeNode> getStrongParents() {
|
||||
return strongParents.keySet();
|
||||
public Set<SkillTreeNode> getParents(ParentType parentType) {
|
||||
return parents.entrySet().stream().filter(entry -> entry.getKey().type() == parentType).map((entry) -> entry.getKey().node()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
public List<SkillTreeNode> getChildren() {
|
||||
return children;
|
||||
}
|
||||
@ -256,7 +267,8 @@ public class SkillTreeNode implements ExperienceObject {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, @NotNull EXPSource source) {
|
||||
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation,
|
||||
@NotNull EXPSource source) {
|
||||
throw new RuntimeException("Attributes don't have experience");
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.Indyuce.mmocore.skilltree.tree;
|
||||
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import net.Indyuce.mmocore.skilltree.ParentType;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -18,20 +19,14 @@ public class CustomSkillTree extends SkillTree {
|
||||
|
||||
// Setup the children and parents for each node.
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
|
||||
ConfigurationSection section = config.getConfigurationSection("nodes." + node.getId() + ".parents.soft");
|
||||
for (String key : config.getConfigurationSection("nodes." + node.getId() + "parents").getKeys(false)) {
|
||||
ConfigurationSection section = config.getConfigurationSection("nodes." + node.getId() + ".parents." + key);
|
||||
if (section != null) {
|
||||
for (String parent : section.getKeys(false)) {
|
||||
node.addParent(getNode(parent), section.getInt(parent), ParentType.SOFT);
|
||||
node.addParent(getNode(parent), section.getInt(parent), ParentType.valueOf(UtilityMethods.enumName(key)));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
setupRoots();
|
||||
@ -41,7 +36,7 @@ public class CustomSkillTree extends SkillTree {
|
||||
|
||||
// Find the tree roots which don't have any parents
|
||||
for (SkillTreeNode node : nodes.values()) {
|
||||
if (node.getSoftParents().size() + node.getStrongParents().size() == 0) {
|
||||
if (node.getParents().size() == 0) {
|
||||
// We mark the node as a root also
|
||||
roots.add(node);
|
||||
node.setIsRoot();
|
||||
|
@ -0,0 +1,7 @@
|
||||
package net.Indyuce.mmocore.skilltree.tree;
|
||||
|
||||
import net.Indyuce.mmocore.skilltree.ParentType;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
|
||||
public record ParentInformation(SkillTreeNode node, ParentType type) {
|
||||
}
|
@ -6,10 +6,7 @@ import io.lumine.mythic.lib.api.util.PostLoadObject;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.registry.RegisteredObject;
|
||||
import net.Indyuce.mmocore.skilltree.IntegerCoordinates;
|
||||
import net.Indyuce.mmocore.skilltree.NodeStatus;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreePath;
|
||||
import net.Indyuce.mmocore.skilltree.*;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -54,7 +51,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
|
||||
protected final Map<String, SkillTreeNode> nodes = new HashMap<>();
|
||||
protected final int maxPointSpent;
|
||||
//Caches the height of the skill tree
|
||||
protected int minX, minY, maxX, maxY;
|
||||
protected final List<SkillTreeNode> roots = new ArrayList<>();
|
||||
|
||||
public SkillTree(ConfigurationSection config) {
|
||||
@ -108,43 +104,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
|
||||
|
||||
@Override
|
||||
protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection);
|
||||
/*
|
||||
|
||||
public Icon getIcon(SkillTreeNode node) {
|
||||
SkillTree skillTree = node.getTree();
|
||||
|
||||
DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize());
|
||||
|
||||
return skillTree.getIcon(displayInfo);
|
||||
}
|
||||
|
||||
public Icon getIcon(SkillTree skillTree, IntegerCoordinates coordinates) {
|
||||
|
||||
if (skillTree.isNode(coordinates)) {
|
||||
SkillTreeNode node = skillTree.getNode(coordinates);
|
||||
DisplayInfo displayInfo = new DisplayInfo(nodeStates.get(node), node.getSize());
|
||||
return skillTree.getIcon(displayInfo);
|
||||
}
|
||||
if (skillTree.isPath(coordinates)) return skillTree.getIcon(DisplayInfo.pathInfo);
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
public int getMaxX() {
|
||||
return maxX;
|
||||
}
|
||||
|
||||
public int getMinX() {
|
||||
return minX;
|
||||
}
|
||||
|
||||
public int getMinY() {
|
||||
return minY;
|
||||
}
|
||||
|
||||
public int getMaxY() {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
public List<String> getLore() {
|
||||
return lore;
|
||||
@ -207,13 +166,18 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
|
||||
} else if (playerData.getNodeLevel(node) == 0 && node.isRoot()) {
|
||||
playerData.setNodeState(node, NodeStatus.UNLOCKABLE);
|
||||
} else {
|
||||
boolean isUnlockableFromStrongParent = node.getStrongParents().size() == 0 ? true : true;
|
||||
boolean isUnlockableFromSoftParent = node.getSoftParents().size() == 0 ? true : false;
|
||||
boolean isFullyLockedFromStrongParent = node.getStrongParents().size() == 0 ? false : false;
|
||||
boolean isFullyLockedFromSoftParent = node.getSoftParents().size() == 0 ? false : true;
|
||||
Set<SkillTreeNode> strongParents = node.getParents(ParentType.STRONG);
|
||||
Set<SkillTreeNode> softParents = node.getParents(ParentType.SOFT);
|
||||
Set<SkillTreeNode> incompatibleParents = node.getParents(ParentType.INCOMPATIBLE);
|
||||
|
||||
for (SkillTreeNode strongParent : node.getStrongParents()) {
|
||||
if (playerData.getNodeLevel(strongParent) < node.getParentNeededLevel(strongParent)) {
|
||||
boolean isUnlockableFromStrongParent = true;
|
||||
boolean isUnlockableFromSoftParent = softParents.size() == 0;
|
||||
boolean isFullyLockedFromStrongParent = false;
|
||||
boolean isFullyLockedFromSoftParent = softParents.size() != 0;
|
||||
boolean isFullyLockedFromIncompatibleParent = false;
|
||||
|
||||
for (SkillTreeNode strongParent : strongParents) {
|
||||
if (playerData.getNodeLevel(strongParent) < node.getParentNeededLevel(strongParent, ParentType.STRONG)) {
|
||||
isUnlockableFromStrongParent = false;
|
||||
}
|
||||
//We count the number of children the parent
|
||||
@ -228,11 +192,11 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
|
||||
}
|
||||
|
||||
|
||||
for (SkillTreeNode softParent : node.getSoftParents()) {
|
||||
if (playerData.getNodeLevel(softParent) >= node.getParentNeededLevel(softParent)) {
|
||||
for (SkillTreeNode softParent : node.getParents(ParentType.SOFT)) {
|
||||
if (playerData.getNodeLevel(softParent) >= node.getParentNeededLevel(softParent, ParentType.SOFT)) {
|
||||
isUnlockableFromSoftParent = true;
|
||||
}
|
||||
//We count the number of children the parent
|
||||
//We count the number of children the parent has
|
||||
int numberChildren = 0;
|
||||
for (SkillTreeNode child : softParent.getChildren())
|
||||
if (playerData.getNodeLevel(child) > 0)
|
||||
@ -240,8 +204,14 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
|
||||
if (numberChildren < softParent.getMaxChildren() && playerData.getNodeStatus(softParent) != NodeStatus.FULLY_LOCKED)
|
||||
isFullyLockedFromSoftParent = false;
|
||||
}
|
||||
for (SkillTreeNode incompatibleParent : node.getParents(ParentType.INCOMPATIBLE)) {
|
||||
if (playerData.getNodeLevel(incompatibleParent) > 0) {
|
||||
isFullyLockedFromIncompatibleParent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isFullyLocked = isFullyLockedFromSoftParent || isFullyLockedFromStrongParent;
|
||||
boolean isFullyLocked = isFullyLockedFromSoftParent || isFullyLockedFromStrongParent || isFullyLockedFromIncompatibleParent;
|
||||
boolean isUnlockable = isUnlockableFromSoftParent && isUnlockableFromStrongParent;
|
||||
if (isFullyLocked)
|
||||
playerData.setNodeState(node, NodeStatus.FULLY_LOCKED);
|
||||
|
Loading…
Reference in New Issue
Block a user