Fixed NPE when clicking certain skill tree nodes

This commit is contained in:
Jules 2024-06-03 22:48:11 -07:00
parent 5c2bd9b637
commit fb84e2f96e
4 changed files with 40 additions and 28 deletions

View File

@ -2,8 +2,6 @@ package net.Indyuce.mmocore.api.player;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.api.stat.StatInstance;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.data.SynchronizedDataHolder;
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
import io.lumine.mythic.lib.util.Closeable;
@ -22,7 +20,6 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.social.FriendRequest;
import net.Indyuce.mmocore.api.player.stats.PlayerStats;
import net.Indyuce.mmocore.api.quest.PlayerQuests;
import net.Indyuce.mmocore.api.quest.trigger.StatTrigger;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
@ -90,7 +87,11 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
private final List<UUID> friends = new ArrayList<>();
/**
* @deprecated Use {@link #hasUnlocked(Unlockable)} instead
* TODO Use {@link #hasUnlocked(Unlockable)} instead
* <p>
* Merge waypoints with unlocked items, and create a method
* plugin-scope to check if some item is class-specific and
* should be reset when switching class
*/
@Deprecated
private final Set<String> waypoints = new HashSet<>();
@ -281,11 +282,10 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
skillTreePoints.clear();
// Clear node claim count
final Iterator<String> ite = tableItemClaims.keySet().iterator();
while (ite.hasNext()) if (ite.next().startsWith(SkillTreeNode.KEY_PREFIX)) ite.remove();
tableItemClaims.keySet().removeIf(s -> s.startsWith(SkillTreeNode.KEY_PREFIX));
}
public boolean canIncrementNodeLevel(SkillTreeNode node) {
public boolean canIncrementNodeLevel(@NotNull SkillTreeNode node) {
SkillTreeStatus skillTreeStatus = nodeStates.get(node);
//Check the State of the node
if (skillTreeStatus != SkillTreeStatus.UNLOCKED && skillTreeStatus != SkillTreeStatus.UNLOCKABLE) return false;
@ -297,32 +297,37 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
* Consumes skill tree points from the tree first and then consumes the
* global skill-tree points ('all')
*/
public void incrementNodeLevel(SkillTreeNode node) {
setNodeLevel(node, getNodeLevel(node) + 1);
public void incrementNodeLevel(@NotNull SkillTreeNode node) {
nodeLevels.merge(node, 1, (level, ignored) -> level + 1);
// Claims the nodes experience table.
node.getExperienceTable().claim(this, getNodeLevel(node), node);
if (nodeStates.get(node) == SkillTreeStatus.UNLOCKABLE) setNodeState(node, SkillTreeStatus.UNLOCKED);
int pointToWithdraw = node.getSkillTreePointsConsumed();
if (skillTreePoints.get(node.getTree().getId()) > 0) {
int pointWithdrawn = Math.min(pointToWithdraw, skillTreePoints.get(node.getTree().getId()));
int cost = node.getSkillTreePointsConsumed();
final int skillTreeSpecificPoints = skillTreePoints.getOrDefault(node.getTree().getId(), 0);
if (skillTreeSpecificPoints > 0) {
int pointWithdrawn = Math.min(cost, skillTreeSpecificPoints);
withdrawSkillTreePoints(node.getTree().getId(), pointWithdrawn);
pointToWithdraw -= pointWithdrawn;
cost -= pointWithdrawn;
}
if (pointToWithdraw > 0) withdrawSkillTreePoints("global", pointToWithdraw);
// We unload the nodeStates map (for the skill tree) and reload it completely
for (SkillTreeNode node1 : node.getTree().getNodes())
nodeStates.remove(node1);
if (cost > 0) withdrawSkillTreePoints("global", cost);
// Unload the nodeStates map (for the skill tree) and reload it completely
for (SkillTreeNode node1 : node.getTree().getNodes()) nodeStates.remove(node1);
node.getTree().setupNodeStates(this);
}
@Deprecated
public int getSkillTreePoint(String treeId) {
return getSkillTreePoints(treeId);
}
public int getSkillTreePoints(@NotNull String treeId) {
return skillTreePoints.getOrDefault(treeId, 0);
}
public void withdrawSkillTreePoints(String treeId, int withdraw) {
skillTreePoints.put(treeId, skillTreePoints.get(treeId) - withdraw);
public void withdrawSkillTreePoints(@NotNull String treeId, int withdrawn) {
final int cost = Math.max(0, withdrawn);
skillTreePoints.computeIfPresent(treeId, (ignored, points) -> cost >= points ? null : points - cost);
}
public void setNodeState(SkillTreeNode node, SkillTreeStatus skillTreeStatus) {

View File

@ -29,7 +29,7 @@ public class AdminCommandTreeNode extends CommandTreeNode {
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-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))));
addChild(new SkillTreePointsCommandTreeNode(this, (playerData, integer, s) -> playerData.setSkillTreePoints(s, integer), (playerData, integer, s) -> playerData.giveSkillTreePoints(s, integer), PlayerData::getSkillTreePoints));
for (PlayerResource res : PlayerResource.values())
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
}

View File

@ -103,8 +103,8 @@ public class SkillTreeViewer extends EditableInventory {
@Override
public Placeholders getPlaceholders(SkillTreeInventory inv, int n) {
Placeholders holders = new Placeholders();
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoint(inv.getSkillTree().getId()));
holders.register("global-points", inv.getPlayerData().getSkillTreePoint("global"));
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoints(inv.getSkillTree().getId()));
holders.register("global-points", inv.getPlayerData().getSkillTreePoints("global"));
holders.register("realloc-points", inv.getPlayerData().getSkillTreeReallocationPoints());
int maxPointSpent = inv.getSkillTree().getMaxPointSpent();
holders.register("max-point-spent", maxPointSpent == Integer.MAX_VALUE ? "" : maxPointSpent);
@ -185,8 +185,8 @@ public class SkillTreeViewer extends EditableInventory {
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"));
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoints(inv.getSkillTree().getId()));
holders.register("global-points", inv.getPlayerData().getSkillTreePoints("global"));
return holders;
}
}
@ -316,8 +316,8 @@ public class SkillTreeViewer extends EditableInventory {
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"));
holders.register("skill-tree-points", inv.getPlayerData().getSkillTreePoints(inv.getSkillTree().getId()));
holders.register("global-points", inv.getPlayerData().getSkillTreePoints("global"));
return holders;
}
@ -484,7 +484,7 @@ public class SkillTreeViewer extends EditableInventory {
playerData.giveSkillTreeReallocationPoints(-1);
playerData.resetSkillTree(skillTree);
skillTree.setupNodeStates(playerData);
ConfigMessage.fromKey("reallocated-points", "points", "" + playerData.getSkillTreePoint(skillTree.getId()), "skill-tree", skillTree.getName()).send(player);
ConfigMessage.fromKey("reallocated-points", "points", "" + playerData.getSkillTreePoints(skillTree.getId()), "skill-tree", skillTree.getName()).send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.RESET_SKILL_TREE).playTo(player);
open();
return;

View File

@ -94,6 +94,13 @@ public class ExperienceManager implements MMOCoreManager {
return expTables.values();
}
// TODO when required, define class-specific unlockable items.
// TODO - Skill, skill slots are class-specific
// TODO - Waypoints are not
public boolean isClassSpecific(@NotNull String namespacedKey) {
return true;
}
@Override
public void initialize(boolean clearBefore) {
if (clearBefore) {