diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerEnterCastingModeEvent.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerEnterCastingModeEvent.java new file mode 100644 index 00000000..bc40bd99 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerEnterCastingModeEvent.java @@ -0,0 +1,36 @@ +package net.Indyuce.mmocore.api.event; + +import net.Indyuce.mmocore.api.player.PlayerData; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class PlayerEnterCastingModeEvent extends PlayerDataEvent implements Cancellable { + private static final HandlerList handlerList = new HandlerList(); + private boolean cancelled = false; + + public PlayerEnterCastingModeEvent(@NotNull Player who) { + super(PlayerData.get(who.getUniqueId())); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + + public static HandlerList getHandlerList(){ + return handlerList; + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExitCastingModeEvent.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExitCastingModeEvent.java new file mode 100644 index 00000000..6f859a32 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/event/PlayerExitCastingModeEvent.java @@ -0,0 +1,38 @@ +package net.Indyuce.mmocore.api.event; + + +import net.Indyuce.mmocore.api.player.PlayerData; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class PlayerExitCastingModeEvent extends PlayerDataEvent implements Cancellable { + private static final HandlerList handlerList = new HandlerList(); + private boolean cancelled = false; + + public PlayerExitCastingModeEvent(@NotNull Player who) { + super(PlayerData.get(who.getUniqueId())); + } + + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 6e87d2ab..677dac71 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -35,7 +35,7 @@ public class DefaultMMOLoader extends MMOLoader { if (config.getKey().equals("levelup_skill")) return new LevelUpSkillTrigger(config); - if (config.getKey().equals("skill_buff")) + if (config.getKey().equals("skill_buff")||config.getKey().equals("skill_modifier")) return new SkillModifierTrigger(config); if (config.getKey().equals("message")) diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index 642da37d..b4742478 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -9,9 +9,7 @@ import io.lumine.mythic.lib.player.cooldown.CooldownMap; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.SoundEvent; -import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent; -import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; -import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.event.*; import net.Indyuce.mmocore.api.event.unlocking.ItemLockedEvent; import net.Indyuce.mmocore.api.event.unlocking.ItemUnlockedEvent; import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; @@ -48,7 +46,7 @@ import net.Indyuce.mmocore.skill.binding.BoundSkillInfo; import net.Indyuce.mmocore.skill.binding.SkillSlot; import net.Indyuce.mmocore.skill.cast.SkillCastingInstance; import net.Indyuce.mmocore.skill.cast.SkillCastingMode; -import net.Indyuce.mmocore.skilltree.NodeStatus; +import net.Indyuce.mmocore.skilltree.SkillTreeStatus; import net.Indyuce.mmocore.skilltree.SkillTreeNode; import net.Indyuce.mmocore.skilltree.tree.SkillTree; import net.Indyuce.mmocore.waypoint.Waypoint; @@ -112,7 +110,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD /** * Cached for easier access. Current status of each skill tree node. */ - private final Map nodeStates = new HashMap<>(); + private final Map nodeStates = new HashMap<>(); private final Map nodeLevels = new HashMap<>(); private final Map skillTreePoints = new HashMap<>(); @@ -190,7 +188,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD // Stat triggers setup for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) for (SkillTreeNode node : skillTree.getNodes()) - node.getExperienceTable().claimStatTriggers(this, node); + node.getExperienceTable().claimRemovableTrigger(this, node); } public int getPointSpent(SkillTree skillTree) { @@ -264,9 +262,9 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD } public boolean canIncrementNodeLevel(SkillTreeNode node) { - NodeStatus nodeStatus = nodeStates.get(node); + SkillTreeStatus skillTreeStatus = nodeStates.get(node); //Check the State of the node - if (nodeStatus != NodeStatus.UNLOCKED && nodeStatus != NodeStatus.UNLOCKABLE) return false; + if (skillTreeStatus != SkillTreeStatus.UNLOCKED && skillTreeStatus != SkillTreeStatus.UNLOCKABLE) return false; return node.hasPermissionRequirement(this) && getNodeLevel(node) < node.getMaxLevel() && (skillTreePoints.getOrDefault(node.getTree().getId(), 0) + skillTreePoints.getOrDefault("global", 0) >= node.getSkillTreePointsConsumed()); } @@ -280,7 +278,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD // Claims the nodes experience table. node.getExperienceTable().claim(this, getNodeLevel(node), node); - if (nodeStates.get(node) == NodeStatus.UNLOCKABLE) setNodeState(node, NodeStatus.UNLOCKED); + 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())); @@ -303,11 +301,11 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD skillTreePoints.put(treeId, skillTreePoints.get(treeId) - withdraw); } - public void setNodeState(SkillTreeNode node, NodeStatus nodeStatus) { - nodeStates.put(node, nodeStatus); + public void setNodeState(SkillTreeNode node, SkillTreeStatus skillTreeStatus) { + nodeStates.put(node, skillTreeStatus); } - public NodeStatus getNodeStatus(SkillTreeNode node) { + public SkillTreeStatus getNodeStatus(SkillTreeNode node) { return nodeStates.get(node); } @@ -334,7 +332,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD skillTree.setupNodeStates(this); } - public Map getNodeStates() { + public Map getNodeStates() { return new HashMap<>(nodeStates); } @@ -1006,9 +1004,21 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD return skillCasting != null; } - public void setSkillCasting(@NotNull SkillCastingInstance skillCasting) { + /** + * @return true if the PlayerEnterCastingModeEvent successfully put the player into casting mode, otherwise if the event is cancelled, returns false. + * @apiNote Changed to a boolean to reflect the cancellation state of the event being fired + */ + public boolean setSkillCasting(@NotNull SkillCastingInstance skillCasting) { Validate.isTrue(!isCasting(), "Player already in casting mode"); + PlayerEnterCastingModeEvent event = new PlayerEnterCastingModeEvent(getPlayer()); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()){ + skillCasting.close(); + return false; + } this.skillCasting = skillCasting; + return true; } /** @@ -1024,11 +1034,33 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD return Objects.requireNonNull(skillCasting, "Player not in casting mode"); } - public void leaveSkillCasting() { + /** + * API Method to leave casting mode and fire the PlayerExitCastingModeEvent + * @return true if the skill casting mode was left, or false if the event was cancelled, keeping the player in casting mode. + */ + public boolean leaveSkillCasting(){ + return this.leaveSkillCasting(false); + } + + /** + * @param skipEvent Skip Firing the PlayerExitCastingModeEvent + * @return true if the PlayerExitCastingModeEvent is not cancelled, or if the event is skipped. + * + */ + public boolean leaveSkillCasting(boolean skipEvent) { Validate.isTrue(isCasting(), "Player not in casting mode"); + if (!skipEvent) { + PlayerExitCastingModeEvent event = new PlayerExitCastingModeEvent(getPlayer()); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + } skillCasting.close(); this.skillCasting = null; setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE, 0); // Reset action bar + return true; } public void displayActionBar(String message) { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java index b3376f54..4d973de9 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java @@ -345,8 +345,8 @@ public class SavedClassInformation implements ClassDataContainer { // 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); - profess.getExperienceTable().claimStatTriggers(player, profess); + node.getExperienceTable().claimRemovableTrigger(player, node); + profess.getExperienceTable().claimRemovableTrigger(player, profess); // Unload current class information player.unloadClassInfo(profess); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java index 1bf46c04..ae983ae4 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java @@ -103,14 +103,11 @@ public class PlayerStats { */ final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap(); - if (!MMOCore.plugin.configManager.passiveSkillNeedBound) { - skillMap.removeModifiers("MMOCorePassiveSkill"); - data.getProfess().getSkills() - .stream() - .filter((classSkill) -> classSkill.getSkill().getTrigger().isPassive() && data.hasUnlocked(classSkill) && data.hasUnlockedLevel(classSkill)) - .forEach(classSkill -> skillMap.addModifier(classSkill.toPassive(data))); - - } + skillMap.removeModifiers("MMOCorePassiveSkillNotBound"); + data.getProfess().getSkills() + .stream() + .filter((classSkill) -> !classSkill.needsBound()&&classSkill.getSkill().getTrigger().isPassive() && data.hasUnlocked(classSkill) && data.hasUnlockedLevel(classSkill)) + .forEach(classSkill -> skillMap.addModifier(classSkill.toPassive(data))); // This updates the player's class SCRIPTS skillMap.removeModifiers("MMOCoreClassScript"); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java index fca38336..817ff2cc 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java @@ -52,7 +52,7 @@ public class SkillModifierTrigger extends Trigger implements Removable { } /** - * Used by skill slots to apply a skillBuff + * Used by skill slots to apply a skill modifier. * to a dynamically chosen skill handler. */ public void apply(PlayerData playerData, SkillHandler skill) { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java index 1a3b3b44..d442c0c4 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java @@ -103,10 +103,10 @@ public class PlayerProfessions { for (Profession profession : MMOCore.plugin.professionManager.getAll()) { if (profession.hasExperienceTable()) - profession.getExperienceTable().claimStatTriggers(playerData, profession); + profession.getExperienceTable().claimRemovableTrigger(playerData, profession); } if (playerData.getProfess().hasExperienceTable()) - playerData.getProfess().getExperienceTable().claimStatTriggers(playerData, playerData.getProfess()); + playerData.getProfess().getExperienceTable().claimRemovableTrigger(playerData, playerData.getProfess()); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java index 5955c390..1abf446f 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java @@ -96,7 +96,7 @@ public class ExperienceItem { * @param professionLevel The profession level the player just reached * @param timesCollected Amount of times the exp item has already been claimed by the player * @return If the item should be claimed right now taking into - * account the randomness factor from the 'chance' parameter + * account the randomness factor from the 'chance' parameter */ public boolean roll(int professionLevel, int timesCollected) { @@ -136,8 +136,8 @@ public class ExperienceItem { * * @param playerData */ - public void applyStatTriggers(PlayerData playerData) { + public void applyRemovableTrigger(PlayerData playerData) { for (Trigger trigger : triggers) - if (trigger instanceof StatTrigger statTrigger) statTrigger.apply(playerData); + if (trigger instanceof Removable) trigger.apply(playerData); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java index ebcbcd91..690c2ba6 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java @@ -80,16 +80,16 @@ public class ExperienceTable { /** - * Called when a player joins and all the statTriggers are all triggered back + * Called when a player joins and all the removable triggers get claimed back. * * @param data PlayerData * @param object Either profession, skillTreeNode or class leveling up */ - public void claimStatTriggers(PlayerData data, ExperienceObject object) { + public void claimRemovableTrigger(PlayerData data, ExperienceObject object) { for (ExperienceItem item : items) { int timesClaimed = data.getClaims(object, this, item); for (int i = 0; i < timesClaimed; i++) - item.applyStatTriggers(data); + item.applyRemovableTrigger(data); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java index 639e60b5..3454bb3c 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/SkillTreeViewer.java @@ -1,7 +1,9 @@ package net.Indyuce.mmocore.gui.skilltree; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.UtilityMethods; import net.Indyuce.mmocore.MMOCore; +import java.util.logging.Level; import net.Indyuce.mmocore.api.SoundEvent; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; @@ -15,7 +17,6 @@ import net.Indyuce.mmocore.gui.skilltree.display.*; import net.Indyuce.mmocore.skilltree.*; import net.Indyuce.mmocore.skilltree.tree.SkillTree; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -32,6 +33,7 @@ import java.util.*; public class SkillTreeViewer extends EditableInventory { protected final Map icons = new HashMap<>(); + protected final Map statusNames = new HashMap<>(); public SkillTreeViewer() { super("skill-tree"); @@ -40,20 +42,24 @@ public class SkillTreeViewer extends EditableInventory { @Override public void reload(FileConfiguration config) { super.reload(config); + if (config.contains("status-names")) + for (SkillTreeStatus skillTreeStatus : SkillTreeStatus.values()) + statusNames.put(skillTreeStatus, config.getString("status-names." + UtilityMethods.ymlName(skillTreeStatus.name()), skillTreeStatus.name())); + //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()))) { - MMOCore.log("Missing path type: " + MMOCoreUtils.ymlName(pathType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name())); + MMOCore.log(Level.WARNING, "An error occurred while loading skill tree GUI: Missing path type: " + MMOCoreUtils.ymlName(pathType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name())); continue; } icons.put(new PathDisplayInfo(pathType, status), new Icon(config.getConfigurationSection("display.paths." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(pathType.name())))); } //Loads all the nodeDisplayInfo - for (NodeStatus status : NodeStatus.values()) + for (SkillTreeStatus status : SkillTreeStatus.values()) 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())); + MMOCore.log(Level.WARNING, "An error occurred while loading skill tree GUI: Missing node type: " + MMOCoreUtils.ymlName(nodeType.name()) + " for status: " + MMOCoreUtils.ymlName(status.name())); continue; } icons.put(new NodeDisplayInfo(nodeType, status), new Icon(config.getConfigurationSection("display.nodes." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(nodeType.name())))); @@ -219,10 +225,10 @@ public class SkillTreeViewer extends EditableInventory { if (inv.getSkillTree().isNode(coordinates)) { SkillTreeNode node = inv.getSkillTree().getNode(coordinates); List lore = new ArrayList<>(); - + Placeholders holders = getPlaceholders(inv, n); getLore().forEach(str -> { if (str.contains("{node-lore}")) { - lore.addAll(node.getLore(inv.getPlayerData())); + node.getLore(inv.getPlayerData()).forEach(s -> lore.add(holders.apply(inv.getPlayer(), s))); } else if (str.contains("{strong-parents}")) { lore.addAll(getParentsLore(inv, node, node.getParents(ParentType.STRONG))); } else if (str.contains("{soft-parents}")) { @@ -230,7 +236,7 @@ public class SkillTreeViewer extends EditableInventory { } 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)); + lore.add(holders.apply(inv.getPlayer(), str)); }); meta.setLore(lore); meta.setDisplayName(node.getName()); @@ -272,7 +278,8 @@ public class SkillTreeViewer extends EditableInventory { 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().getNodeStatus(node)); + SkillTreeStatus status = inv.getPlayerData().getNodeStatus(node); + holders.register("current-state", statusNames.getOrDefault(status, status.name())); holders.register("max-level", node.getMaxLevel()); holders.register("max-children", node.getMaxChildren()); holders.register("size", node.getSize()); @@ -347,18 +354,18 @@ public class SkillTreeViewer extends EditableInventory { if (skillTree.isNode(coordinates)) { SkillTreeNode node = skillTree.getNode(coordinates); - NodeStatus nodeStatus = playerData.getNodeStatus(node); + SkillTreeStatus skillTreeStatus = playerData.getNodeStatus(node); //If the node has its own display, it will be shown. - if (node.hasIcon(nodeStatus)) - return node.getIcon(nodeStatus); + if (node.hasIcon(skillTreeStatus)) + return node.getIcon(skillTreeStatus); NodeType nodeType = NodeType.getNodeType(hasUpPathOrNode, hasRightPathOrNode, hasDownPathOrNode, hasLeftPathOrNode); - DisplayInfo displayInfo = new NodeDisplayInfo(nodeType, nodeStatus); + DisplayInfo displayInfo = new NodeDisplayInfo(nodeType, skillTreeStatus); //Takes the display defined in the skill tree config if it exists. if (skillTree.hasIcon(displayInfo)) return skillTree.getIcon(displayInfo); Icon icon = icons.get(displayInfo); - Validate.notNull(icon, "The node " + node.getFullId() + " has no icon for the type " + nodeType + " and the status " + nodeStatus); + Validate.notNull(icon, "The node " + node.getFullId() + " has no icon for the type " + nodeType + " and the status " + skillTreeStatus); return icon; } else { PathType pathType = PathType.getPathType(hasUpPathOrNode, hasRightPathOrNode, hasDownPathOrNode, hasLeftPathOrNode); @@ -486,7 +493,7 @@ public class SkillTreeViewer extends EditableInventory { MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill-node", "skill-node", node.getName(), "level", "" + playerData.getNodeLevel(node)).send(player); MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_UP).playTo(getPlayer()); open(); - } else if (playerData.getNodeStatus(node) == NodeStatus.LOCKED || playerData.getNodeStatus(node) == NodeStatus.FULLY_LOCKED) { + } else if (playerData.getNodeStatus(node) == SkillTreeStatus.LOCKED || playerData.getNodeStatus(node) == SkillTreeStatus.FULLY_LOCKED) { MMOCore.plugin.configManager.getSimpleMessage("locked-node").send(player); MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer()); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java index f6398d1f..60b131d9 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/skilltree/display/NodeDisplayInfo.java @@ -1,25 +1,25 @@ package net.Indyuce.mmocore.gui.skilltree.display; -import net.Indyuce.mmocore.skilltree.NodeStatus; +import net.Indyuce.mmocore.skilltree.SkillTreeStatus; import java.util.Objects; public class NodeDisplayInfo implements DisplayInfo{ - private NodeStatus nodeStatus; + private SkillTreeStatus skillTreeStatus; private NodeType nodeType; - public NodeDisplayInfo(NodeType nodeType,NodeStatus nodeStatus) { - this.nodeStatus = nodeStatus; + public NodeDisplayInfo(NodeType nodeType, SkillTreeStatus skillTreeStatus) { + this.skillTreeStatus = skillTreeStatus; this.nodeType = nodeType; } - public NodeStatus getNodeState() { - return nodeStatus; + public SkillTreeStatus getNodeState() { + return skillTreeStatus; } - public NodeStatus getNodeStatus() { - return nodeStatus; + public SkillTreeStatus getNodeStatus() { + return skillTreeStatus; } public NodeType getNodeType() { @@ -31,18 +31,18 @@ public class NodeDisplayInfo implements DisplayInfo{ if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NodeDisplayInfo that = (NodeDisplayInfo) o; - return nodeStatus == that.nodeStatus && nodeType == that.nodeType; + return skillTreeStatus == that.skillTreeStatus && nodeType == that.nodeType; } @Override public int hashCode() { - return Objects.hash(nodeStatus, nodeType); + return Objects.hash(skillTreeStatus, nodeType); } @Override public String toString() { return "NodeDisplayInfo{" + - "nodeStatus=" + nodeStatus + + "nodeStatus=" + skillTreeStatus + ", nodeType=" + nodeType + '}'; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java index d0f13c88..a170adea 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java @@ -17,7 +17,7 @@ public class KingdomsXGuildModule implements GuildModule { @Override public AbstractGuild getGuild(PlayerData playerData) { - KingdomPlayer kPlayer = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(playerData.getUniqueId()); + KingdomPlayer kPlayer = KingdomPlayer.getKingdomPlayer(playerData.getPlayer()); if (kPlayer == null) return null; @@ -28,7 +28,7 @@ public class KingdomsXGuildModule implements GuildModule { @Override public Relationship getRelationship(Player player, Player target) { - final KingdomPlayer player1 = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(player.getUniqueId()); + final KingdomPlayer player1 = KingdomPlayer.getKingdomPlayer(player); if (player1 == null) return Relationship.GUILD_NEUTRAL; @@ -36,7 +36,7 @@ public class KingdomsXGuildModule implements GuildModule { if (kingdom1 == null) return Relationship.GUILD_NEUTRAL; - final KingdomPlayer player2 = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(target.getUniqueId()); + final KingdomPlayer player2 = KingdomPlayer.getKingdomPlayer(target.getPlayer()); if (player2 == null) return Relationship.GUILD_NEUTRAL; diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java index 3cc25cbd..50161246 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java @@ -11,55 +11,63 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; public class FishingDropItem implements Weighted { - private final RandomAmount experience, tugs; - private final DropItem dropItem; + private final RandomAmount experience, tugs, vanillaExp; + private final DropItem dropItem; - public FishingDropItem(MMOLineConfig config) { - config.validateKeys("tugs", "experience"); + public FishingDropItem(MMOLineConfig config) { + config.validateKeys("tugs", "experience"); - tugs = new RandomAmount(config.getString("tugs")); - experience = new RandomAmount(config.getString("experience")); + tugs = new RandomAmount(config.getString("tugs")); + experience = new RandomAmount(config.getString("experience")); + vanillaExp = config.contains("vanilla-exp") ? new RandomAmount(config.getString("vanilla-experience")) : new RandomAmount(0, 0); + dropItem = MMOCore.plugin.loadManager.loadDropItem(config); + } - dropItem = MMOCore.plugin.loadManager.loadDropItem(config); - } + /** + * An item cannot have a negative weight. Since drop items have 0 weight + * by default, MMOCore takes 1 as minimum value if the item weight is + * negative or equal to 0 + */ + @Override + public double getWeight() { + return dropItem.getWeight() <= 0 ? 1 : dropItem.getWeight(); + } - /** - * An item cannot have a negative weight. Since drop items have 0 weight - * by default, MMOCore takes 1 as minimum value if the item weight is - * negative or equal to 0 - */ - @Override - public double getWeight() { - return dropItem.getWeight() <= 0 ? 1 : dropItem.getWeight(); - } + public DropItem getItem() { + return dropItem; + } - public DropItem getItem() { - return dropItem; - } + public RandomAmount getExperience() { + return experience; + } - public RandomAmount getExperience() { - return experience; - } + public RandomAmount getVanillaExp() { + return vanillaExp; + } - public RandomAmount getTugs() { - return tugs; - } + public RandomAmount getTugs() { + return tugs; + } - public int rollExperience() { - return experience.calculateInt(); - } + public int rollExperience() { + return experience.calculateInt(); + } - public int rollTugs() { - return tugs.calculateInt(); - } + public int rollVanillaExp() { + return vanillaExp.calculateInt(); + } - public DropItem getDropItem() { - return dropItem; - } + public int rollTugs() { + return tugs.calculateInt(); + } - @Nullable - public ItemStack collect(LootBuilder builder) { - dropItem.collect(builder); - return builder.getLoot().stream().findAny().orElse(null); - } + public DropItem getDropItem() { + return dropItem; + } + + @Nullable + public ItemStack collect(LootBuilder builder) { + dropItem.collect(builder); + return builder.getLoot().stream().findAny().orElse(null); + } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java index 73ea8273..203a10c6 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java @@ -20,7 +20,7 @@ import java.util.*; public class ClassSkill implements CooldownObject, Unlockable { private final RegisteredSkill skill; private final int unlockLevel, maxSkillLevel; - private final boolean unlockedByDefault; + private final boolean unlockedByDefault, needsBound; private final Map parameters = new HashMap<>(); /** @@ -37,10 +37,15 @@ public class ClassSkill implements CooldownObject, Unlockable { } public ClassSkill(RegisteredSkill skill, int unlockLevel, int maxSkillLevel, boolean unlockedByDefault) { + this(skill, unlockLevel, maxSkillLevel, unlockedByDefault, MMOCore.plugin.configManager.passiveSkillNeedBound); + } + + public ClassSkill(RegisteredSkill skill, int unlockLevel, int maxSkillLevel, boolean unlockedByDefault, boolean needsBound) { this.skill = skill; this.unlockLevel = unlockLevel; this.maxSkillLevel = maxSkillLevel; this.unlockedByDefault = unlockedByDefault; + this.needsBound = needsBound; for (String param : skill.getHandler().getParameters()) this.parameters.put(param, skill.getParameterInfo(param)); } @@ -50,6 +55,7 @@ public class ClassSkill implements CooldownObject, Unlockable { unlockLevel = config.getInt("level"); maxSkillLevel = config.getInt("max-level"); unlockedByDefault = config.getBoolean("unlocked-by-default", true); + needsBound = config.getBoolean("needs-bound", MMOCore.plugin.configManager.passiveSkillNeedBound); for (String param : skill.getHandler().getParameters()) { LinearValue defaultValue = skill.getParameterInfo(param); this.parameters.put(param, config.isConfigurationSection(param) ? readLinearValue(defaultValue, config.getConfigurationSection(param)) : defaultValue); @@ -78,6 +84,10 @@ public class ClassSkill implements CooldownObject, Unlockable { return unlockedByDefault; } + public boolean needsBound() { + return needsBound; + } + @Override public String getUnlockNamespacedKey() { return "skill:" + skill.getHandler().getId().toLowerCase(); @@ -90,18 +100,17 @@ public class ClassSkill implements CooldownObject, Unlockable { playerData.unbindSkill(slot); }); //Update the stats to remove the passive skill if it is locked - if (!MMOCore.plugin.configManager.passiveSkillNeedBound && getSkill().getTrigger().isPassive()) + if (!needsBound && getSkill().getTrigger().isPassive()) playerData.getStats().updateStats(); } @Override public void whenUnlocked(PlayerData playerData) { - if (!MMOCore.plugin.configManager.passiveSkillNeedBound && getSkill().getTrigger().isPassive()) + if (!needsBound && getSkill().getTrigger().isPassive()) playerData.getStats().updateStats(); } - /** * Skill modifiers are now called parameters. */ @@ -109,6 +118,7 @@ public class ClassSkill implements CooldownObject, Unlockable { public void addModifier(String modifier, LinearValue linear) { addParameter(modifier, linear); } + /** * This method can only override default parameters and * will throw an error when trying to define non existing modifiers @@ -165,7 +175,8 @@ public class ClassSkill implements CooldownObject, Unlockable { */ public PassiveSkill toPassive(PlayerData caster) { Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active"); - return new PassiveSkill("MMOCorePassiveSkill", toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER); + //MMOCorePassiveSkillNotBound to identify passive skills that don't need to be bound + return new PassiveSkill("MMOCorePassiveSkill" + (!needsBound ? "NotBound" : ""), toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER); } @Override diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java index a06b0d14..4d27d56b 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/BoundSkillInfo.java @@ -29,11 +29,11 @@ public class BoundSkillInfo implements Closable { this.playerData = playerData; // Apply skill buffs associated to the slot - for (SkillModifierTrigger skillBuffTrigger : skillSlot.getSkillBuffTriggers()) - if (skillBuffTrigger.getTargetSkills().contains(classSkill.getSkill().getHandler())) - skillBuffTrigger.apply(playerData, classSkill.getSkill().getHandler()); + for (SkillModifierTrigger skillModifierTrigger : skillSlot.getSkillModifierTriggers()) + if (skillModifierTrigger.getTargetSkills().contains(classSkill.getSkill().getHandler())) + skillModifierTrigger.apply(playerData, classSkill.getSkill().getHandler()); - if (classSkill.getSkill().getTrigger().isPassive()) { + if (classSkill.getSkill().getTrigger().isPassive()&& classSkill.needsBound()) { registered = classSkill.toPassive(playerData); registered.register(playerData.getMMOPlayerData()); } else registered = null; @@ -64,9 +64,9 @@ public class BoundSkillInfo implements Closable { open = false; // Unregister skill if passive - if (isPassive()) registered.unregister(playerData.getMMOPlayerData()); + if (isPassive()&& classSkill.needsBound()) registered.unregister(playerData.getMMOPlayerData()); // Remove skill buffs associated to the slot - skillSlot.getSkillBuffTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(playerData, classSkill.getSkill().getHandler())); + skillSlot.getSkillModifierTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(playerData, classSkill.getSkill().getHandler())); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/SkillSlot.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/SkillSlot.java index 08f58c90..0bfb11c1 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/SkillSlot.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/binding/SkillSlot.java @@ -22,10 +22,10 @@ public class SkillSlot implements Unlockable { private final boolean isUnlockedByDefault; private final boolean canManuallyBind; - private final List skillBuffTriggers = new ArrayList<>(); + private final List skillModifierTriggers = new ArrayList<>(); private final Material item; - public SkillSlot(int slot, int modelData, String formula, String name, List lore, boolean isUnlockedByDefault, boolean canManuallyBind, List skillBuffTriggers) { + public SkillSlot(int slot, int modelData, String formula, String name, List lore, boolean isUnlockedByDefault, boolean canManuallyBind, List skillModifierTriggers) { this.slot = slot; this.modelData = modelData; this.formula = formula; @@ -34,7 +34,7 @@ public class SkillSlot implements Unlockable { this.item = null; this.canManuallyBind = canManuallyBind; this.isUnlockedByDefault = isUnlockedByDefault; - this.skillBuffTriggers.addAll(skillBuffTriggers); + this.skillModifierTriggers.addAll(skillModifierTriggers); } public SkillSlot(ConfigurationSection section) { @@ -49,7 +49,7 @@ public class SkillSlot implements Unlockable { if (section.contains("skill-buffs")) for (String skillBuff : section.getStringList("skill-buffs")) if (skillBuff.startsWith("skill_buff")) - skillBuffTriggers.add((SkillModifierTrigger) MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(skillBuff))); + skillModifierTriggers.add((SkillModifierTrigger) MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(skillBuff))); } public int getSlot() { @@ -81,8 +81,8 @@ public class SkillSlot implements Unlockable { return isUnlockedByDefault; } - public List getSkillBuffTriggers() { - return skillBuffTriggers; + public List getSkillModifierTriggers() { + return skillModifierTriggers; } public boolean canManuallyBind() { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java index 9fe2c397..e05758e4 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java @@ -12,6 +12,7 @@ import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.skill.cast.*; +import org.bukkit.GameMode; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -70,6 +71,8 @@ public class KeyCombos implements SkillCastingListener { public void whenPressingKey(PlayerKeyPressEvent event) { PlayerData playerData = event.getData(); Player player = playerData.getPlayer(); + if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast) + return; // Start combo when there is an initializer key if (!event.getData().isCasting() && initializerKey != null) { @@ -79,8 +82,9 @@ public class KeyCombos implements SkillCastingListener { if (event.getPressed().shouldCancelEvent()) event.setCancelled(true); // Start combo - playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)); - if (beginComboSound != null) beginComboSound.playTo(player); + if (playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)) && beginComboSound != null) + beginComboSound.playTo(player); + } return; } @@ -95,8 +99,8 @@ public class KeyCombos implements SkillCastingListener { final @NotNull ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap); if (comboMap.isComboStart(event.getPressed())) { casting = new CustomSkillCastingInstance(playerData); - playerData.setSkillCasting(casting); - if (beginComboSound != null) beginComboSound.playTo(player); + if (playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)) && beginComboSound != null) + beginComboSound.playTo(player); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java index ca459b64..6f338ff1 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java @@ -56,8 +56,9 @@ public class SkillBar implements SkillCastingListener { // Enter spell casting final PlayerData playerData = event.getData(); if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills().isEmpty()) { - playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)); - MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player); + if (playerData.setSkillCasting(new CustomSkillCastingInstance(playerData))) { + MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player); + } } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java index 92acb49e..48c55fef 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java @@ -4,6 +4,7 @@ import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.player.PlayerMetadata; import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; +import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.SoundObject; import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent; import net.Indyuce.mmocore.api.player.PlayerData; @@ -11,6 +12,7 @@ import net.Indyuce.mmocore.skill.cast.PlayerKey; import net.Indyuce.mmocore.skill.cast.SkillCastingInstance; import net.Indyuce.mmocore.skill.cast.SkillCastingListener; import net.Indyuce.mmocore.skill.cast.SkillCastingMode; +import org.bukkit.GameMode; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -56,7 +58,8 @@ public class SkillScroller implements SkillCastingListener { public void whenPressingKey(PlayerKeyPressEvent event) { PlayerData playerData = event.getData(); Player player = playerData.getPlayer(); - + if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast) + return; if (event.getPressed() == enterKey) { // Leave casting mode @@ -77,7 +80,10 @@ public class SkillScroller implements SkillCastingListener { if (event.getPressed().shouldCancelEvent()) event.setCancelled(true); // Enter casting mode - playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)); + if (!playerData.setSkillCasting(new CustomSkillCastingInstance(playerData))) { + return; + } + if (enterSound != null) enterSound.playTo(player); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeNode.java index 5b604491..84065c41 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeNode.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeNode.java @@ -9,12 +9,10 @@ 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.Bukkit; import org.bukkit.Location; import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; @@ -30,7 +28,7 @@ public class SkillTreeNode implements ExperienceObject { private String permissionRequired; - private final Map icons = new HashMap<>(); + private final Map icons = new HashMap<>(); private IntegerCoordinates coordinates; /** @@ -68,7 +66,7 @@ public class SkillTreeNode implements ExperienceObject { this.id = config.getName(); this.tree = tree; if (config.isConfigurationSection("display")) { - for (NodeStatus status : NodeStatus.values()) { + for (SkillTreeStatus status : SkillTreeStatus.values()) { 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."); @@ -105,11 +103,11 @@ public class SkillTreeNode implements ExperienceObject { return tree; } - public boolean hasIcon(NodeStatus status) { + public boolean hasIcon(SkillTreeStatus status) { return icons.containsKey(status); } - public Icon getIcon(NodeStatus status) { + public Icon getIcon(SkillTreeStatus status) { return icons.get(status); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java index ef5438fa..0522670d 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreePath.java @@ -7,13 +7,13 @@ import net.Indyuce.mmocore.skilltree.tree.SkillTree; public record SkillTreePath(SkillTree tree, IntegerCoordinates coordinates, SkillTreeNode from, SkillTreeNode to) { public PathStatus getStatus(PlayerData playerData) { - NodeStatus fromStatus = playerData.getNodeStatus(from); - NodeStatus toStatus = playerData.getNodeStatus(to); - if (fromStatus == NodeStatus.UNLOCKED && toStatus == NodeStatus.UNLOCKED) + SkillTreeStatus fromStatus = playerData.getNodeStatus(from); + SkillTreeStatus toStatus = playerData.getNodeStatus(to); + if (fromStatus == SkillTreeStatus.UNLOCKED && toStatus == SkillTreeStatus.UNLOCKED) return PathStatus.UNLOCKED; - if ((fromStatus == NodeStatus.UNLOCKABLE && toStatus == NodeStatus.LOCKED) || (fromStatus == NodeStatus.LOCKED && toStatus == NodeStatus.UNLOCKABLE)) + if ((fromStatus == SkillTreeStatus.UNLOCKABLE && toStatus == SkillTreeStatus.LOCKED) || (fromStatus == SkillTreeStatus.LOCKED && toStatus == SkillTreeStatus.UNLOCKABLE)) return PathStatus.UNLOCKABLE; - if (fromStatus == NodeStatus.FULLY_LOCKED || toStatus == NodeStatus.FULLY_LOCKED) + if (fromStatus == SkillTreeStatus.FULLY_LOCKED || toStatus == SkillTreeStatus.FULLY_LOCKED) return PathStatus.FULLY_LOCKED; return PathStatus.LOCKED; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/NodeStatus.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeStatus.java similarity index 94% rename from MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/NodeStatus.java rename to MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeStatus.java index c2f979cd..582dbda0 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/NodeStatus.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/SkillTreeStatus.java @@ -1,6 +1,6 @@ package net.Indyuce.mmocore.skilltree; -public enum NodeStatus { +public enum SkillTreeStatus { /** * The player does not have access to this skill tree node just yet. diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java index 8adeb0bf..1759ca61 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skilltree/tree/SkillTree.java @@ -12,7 +12,6 @@ import net.Indyuce.mmocore.skilltree.*; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -103,7 +102,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje } //Loads all the nodeDisplayInfo - for (NodeStatus status : NodeStatus.values()) + for (SkillTreeStatus status : SkillTreeStatus.values()) for (NodeType nodeType : NodeType.values()) { ConfigurationSection section = config.getConfigurationSection("display.nodes." + MMOCoreUtils.ymlName(status.name()) + "." + MMOCoreUtils.ymlName(nodeType.name())); if (section != null) @@ -173,9 +172,9 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje */ private void setupNodeStateFrom(SkillTreeNode node, PlayerData playerData) { if (playerData.getNodeLevel(node) > 0) { - playerData.setNodeState(node, NodeStatus.UNLOCKED); + playerData.setNodeState(node, SkillTreeStatus.UNLOCKED); } else if (playerData.getNodeLevel(node) == 0 && node.isRoot()) { - playerData.setNodeState(node, NodeStatus.UNLOCKABLE); + playerData.setNodeState(node, SkillTreeStatus.UNLOCKABLE); } else { Set strongParents = node.getParents(ParentType.STRONG); Set softParents = node.getParents(ParentType.SOFT); @@ -199,7 +198,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje numberChildren++; //We must check if the parent is Fully Locked or not and if it can unlock a new node(with its max children constraint) - if (numberChildren >= strongParent.getMaxChildren() || playerData.getNodeStatus(strongParent) == NodeStatus.FULLY_LOCKED) + if (numberChildren >= strongParent.getMaxChildren() || playerData.getNodeStatus(strongParent) == SkillTreeStatus.FULLY_LOCKED) isFullyLockedFromStrongParent = true; } @@ -213,7 +212,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje for (SkillTreeNode child : softParent.getChildren()) if (playerData.getNodeLevel(child) > 0) numberChildren++; - if (numberChildren < softParent.getMaxChildren() && playerData.getNodeStatus(softParent) != NodeStatus.FULLY_LOCKED) + if (numberChildren < softParent.getMaxChildren() && playerData.getNodeStatus(softParent) != SkillTreeStatus.FULLY_LOCKED) isFullyLockedFromSoftParent = false; } for (SkillTreeNode incompatibleParent : incompatibleParents) { @@ -226,11 +225,11 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje boolean isFullyLocked = isFullyLockedFromSoftParent || isFullyLockedFromStrongParent || isFullyLockedFromIncompatibleParent; boolean isUnlockable = isUnlockableFromSoftParent && isUnlockableFromStrongParent; if (isFullyLocked) - playerData.setNodeState(node, NodeStatus.FULLY_LOCKED); + playerData.setNodeState(node, SkillTreeStatus.FULLY_LOCKED); else if (isUnlockable) - playerData.setNodeState(node, NodeStatus.UNLOCKABLE); + playerData.setNodeState(node, SkillTreeStatus.UNLOCKABLE); else - playerData.setNodeState(node, NodeStatus.LOCKED); + playerData.setNodeState(node, SkillTreeStatus.LOCKED); } //We recursively call the algorithm for all the children of the current node for (SkillTreeNode child : node.getChildren()) diff --git a/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java b/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java index 4dadc341..47e78d5b 100644 --- a/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java +++ b/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java @@ -61,7 +61,7 @@ public class FishingListener implements Listener { private final Player player; private final FishHook hook; - private final int fishStrength, experienceDropped; + private final int fishStrength, experienceDropped, vanillaExpDropped; private int currentPulls; @@ -82,7 +82,7 @@ public class FishingListener implements Listener { this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat("FISHING_STRENGTH") / 100)); this.experienceDropped = caught.rollExperience(); - + this.vanillaExpDropped = caught.rollVanillaExp(); fishing.add(player.getUniqueId()); runTaskTimer(MMOCore.plugin, 0, 2); Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); @@ -195,7 +195,7 @@ public class FishingListener implements Listener { player.getWorld().playSound(player.getLocation(), VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 0); for (int j = 0; j < 8; j++) location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, 0, 4 * (RANDOM.nextDouble() - .5), RANDOM.nextDouble() + 1, 4 * (RANDOM.nextDouble() - .5), .08); - + player.giveExp(vanillaExpDropped); if (MMOCore.plugin.fishingManager.hasLinkedProfession()) playerData.getCollectionSkills().giveExperience(MMOCore.plugin.fishingManager.getLinkedProfession(), experienceDropped, EXPSource.FISHING, location, true); } diff --git a/MMOCore-Dist/src/main/resources/config.yml b/MMOCore-Dist/src/main/resources/config.yml index 6e73e3ab..490ed8b3 100644 --- a/MMOCore-Dist/src/main/resources/config.yml +++ b/MMOCore-Dist/src/main/resources/config.yml @@ -222,8 +222,11 @@ death-exp-loss: # Maximum number of skill slots. This means that you cannot unlock more than X skill slots. max-skill-slots: 8 + # When set to true, passive skills must be bound in order to take effect. # When set to false, unlocked skills will take effect right away. +# This is only the default behavior for skills but can be overridden by specifying true/false to +# the needs-bound field in the class skills section. passive-skill-need-bound: true # Set this to true to allow players in diff --git a/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml b/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml index ba5ef85e..e7ae88a5 100644 --- a/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml +++ b/MMOCore-Dist/src/main/resources/default/gui/skill-tree.yml @@ -77,7 +77,9 @@ items: function: 'skill-tree-node' 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 + #The lore that will be displayed after the lore of the node. + #The {node-lore} placeholder will be replaced by the lore specified in the skill tree node config. + #All the placeholders you see here can also be used in the node lore. lore: - '&7Current State: &6{current-state}' - '&7Current Level: &6{current-level}' @@ -99,6 +101,15 @@ items: - '&e◆Points spent for {skill-tree}&e:&6 {point-spent}' - '&e◆Current {skill-tree} &epoints: &6{skill-tree-points}' - '&e◆Current &6global&e points: &6{global-points}' + +#This is the name that will be displayed for each status. +status-names: + unlocked: 'Unlocked' + unlockable: 'Unlockable' + locked: 'Locked' + fully-locked: 'Fully Locked' + + display: paths: unlocked: