diff --git a/MMOCore-API/pom.xml b/MMOCore-API/pom.xml index 19d53be3..3deab351 100644 --- a/MMOCore-API/pom.xml +++ b/MMOCore-API/pom.xml @@ -192,7 +192,7 @@ net.citizensnpcs Citizens - 2.0.25 + 2.0.30 provided diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/MMOCore.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/MMOCore.java index 1366ece4..495a0c98 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -277,8 +277,8 @@ public class MMOCore extends JavaPlugin { commandMap.register("mmocore", new PartyCommand(config.getConfigurationSection("party"))); if (config.contains("guild")) commandMap.register("mmocore", new GuildCommand(config.getConfigurationSection("guild"))); - if (config.contains("skill-tree")) - commandMap.register("mmocore", new SkillTreeCommand(config.getConfigurationSection("skill-tree"))); + if (config.contains("skill-trees")) + commandMap.register("mmocore", new SkillTreeCommand(config.getConfigurationSection("skill-trees"))); if (hasEconomy() && economy.isValid()) { if (config.contains("withdraw")) commandMap.register("mmocore", new WithdrawCommand(config.getConfigurationSection("withdraw"))); 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 858b058a..63894e16 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 @@ -6,8 +6,6 @@ import io.lumine.mythic.lib.api.stat.StatInstance; import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.player.cooldown.CooldownMap; import io.lumine.mythic.lib.player.skill.PassiveSkill; -import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; -import net.Indyuce.mmocore.party.provided.Party; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.SoundEvent; @@ -34,8 +32,9 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable; import net.Indyuce.mmocore.guild.provided.Guild; import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect; import net.Indyuce.mmocore.party.AbstractParty; +import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; +import net.Indyuce.mmocore.party.provided.Party; import net.Indyuce.mmocore.player.Unlockable; -import net.Indyuce.mmocore.player.stats.StatInfo; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; @@ -72,6 +71,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc */ private final MMOPlayerData mmoData; + /** * Can be null, the {@link #getProfess()} method will return the * player class, or the default one if this field is null. @@ -119,8 +119,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc private final Map tableItemClaims = new HashMap<>(); // NON-FINAL player data stuff made public to facilitate field change - public boolean noCooldown; - private boolean statLoaded; + public boolean noCooldown, statsLoaded; public CombatRunnable combat; /** @@ -136,14 +135,13 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc questData = new PlayerQuests(this); playerStats = new PlayerStats(this); - //Used to see if the triggers need to be applied - boolean statLoaded = false; + // Used to see if the triggers need to be applied for (StatInstance instance : mmoData.getStatMap().getInstances()) for (StatModifier modifier : instance.getModifiers()) - if (modifier.getKey().startsWith("trigger")) - statLoaded = true; - this.statLoaded = statLoaded; - + if (modifier.getKey().startsWith("trigger")) { + statsLoaded = true; + break; + } } /** @@ -173,34 +171,28 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc j++; } - for (SkillTree skillTree : profess.getSkillTrees()) { - for (SkillTreeNode node : skillTree.getNodes()) { + for (SkillTree skillTree : getProfess().getSkillTrees()) + for (SkillTreeNode node : skillTree.getNodes()) if (!nodeLevels.containsKey(node)) nodeLevels.put(node, 0); - } - } setupSkillTree(); } public void setupSkillTree() { - //Node states setup - for (SkillTree skillTree : profess.getSkillTrees()) + // Node states setup + for (SkillTree skillTree : getProfess().getSkillTrees()) skillTree.setupNodeState(this); - - if (!statLoaded) - //Stat triggers setup - for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) { - for (SkillTreeNode node : skillTree.getNodes()) { + // Stat triggers setup + if (!statsLoaded) { + for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) + for (SkillTreeNode node : skillTree.getNodes()) node.getExperienceTable().claimStatTriggers(this, node); - } - } - statLoaded = true; - + statsLoaded = true; + } } - public int getPointSpent(SkillTree skillTree) { return pointSpent.getOrDefault(skillTree, 0); } @@ -211,7 +203,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc public void clearPointsSpent() { pointSpent.clear(); - } public void setSkillTreePoints(String treeId, int points) { @@ -233,27 +224,23 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc return new HashMap(skillTreePoints); } - - public void clearSkillTreePoints() { skillTreePoints.clear(); } - public boolean containsSkillPointTreeId(String treeId) { return skillTreePoints.containsKey(treeId); } public Set> getNodeLevelsEntrySet() { HashMap nodeLevelsString = new HashMap<>(); - for (SkillTreeNode node : nodeLevels.keySet()) { + for (SkillTreeNode node : nodeLevels.keySet()) nodeLevelsString.put(node.getFullId(), nodeLevels.get(node)); - } return nodeLevelsString.entrySet(); } - public boolean isStatLoaded() { - return statLoaded; + public boolean areStatsLoaded() { + return statsLoaded; } public Map getNodeLevels() { @@ -377,7 +364,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc tableItemClaims.clear(); } - @Override public void close() { @@ -796,8 +782,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * If it's null, no hologram will be displayed * @param splitExp Should the exp be split among party members */ - public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation, - boolean splitExp) { + public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation, boolean splitExp) { if (value <= 0) return; @@ -999,7 +984,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc return Objects.requireNonNull(skillCasting, "Player not in casting mode"); } - public void leaveCastingMode() { + public void leaveSkillCasting() { Validate.isTrue(isCasting(), "Player not in casting mode"); skillCasting.close(); this.skillCasting = null; @@ -1115,36 +1100,56 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc return slot >= boundSkills.size() ? null : boundSkills.get(slot); } - public void setBoundPassiveSkill(int slot, PassiveSkill skill) { + /** + * Registers a passive skill in the list. This method guarantees interface + * between ML passive skills and the MMOCore list. + * + * @param slot Slot to which you're binding the skill. + * Use -1 to force-register the skill + * @param skill Skill being bound + */ + public void bindPassiveSkill(int slot, @NotNull PassiveSkill skill) { Validate.notNull(skill, "Skill cannot be null"); - if (boundPassiveSkills.size() < getProfess().getMaxBoundActiveSkills()) - boundPassiveSkills.add(skill); - else - boundPassiveSkills.set(slot, skill); - boundPassiveSkills.get(slot).register(getMMOPlayerData()); + final int maxBound = getProfess().getMaxBoundActiveSkills(); + if (slot > 0 && boundPassiveSkills.size() >= maxBound) { + final @NotNull PassiveSkill current = boundPassiveSkills.set(slot, skill); + if (current != null) + current.unregister(mmoData); + skill.register(mmoData); + return; + } + + boundPassiveSkills.add(skill); + skill.register(mmoData); } public boolean hasPassiveSkillBound(int slot) { return slot < boundPassiveSkills.size(); } + @Nullable public PassiveSkill getBoundPassiveSkill(int slot) { return slot >= boundPassiveSkills.size() ? null : boundPassiveSkills.get(slot); } - public void addPassiveBoundSkill(PassiveSkill skill) { - boundPassiveSkills.add(skill); - skill.register(getMMOPlayerData()); + @Deprecated + public void setBoundSkill(int slot, ClassSkill skill) { + bindActiveSkill(slot, skill); } - public void setBoundSkill(int slot, ClassSkill skill) { - + /** + * Binds a skill to the player. + * + * @param slot Slot to which you're binding the skill. + * Use -1 to force-register the skill + * @param skill Skill being bound + */ + public void bindActiveSkill(int slot, ClassSkill skill) { Validate.notNull(skill, "Skill cannot be null"); - if (boundSkills.size() < getProfess().getMaxBoundActiveSkills()) - boundSkills.add(skill); - else + if (slot > 0 && boundSkills.size() >= getProfess().getMaxBoundActiveSkills()) boundSkills.set(slot, skill); - + else + boundSkills.add(skill); } public void unbindSkill(int slot) { @@ -1155,7 +1160,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc PassiveSkill skill = boundPassiveSkills.get(slot); skill.unregister(getMMOPlayerData()); boundPassiveSkills.remove(slot); - } public List getBoundSkills() { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/SkillTreeCommand.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/SkillTreeCommand.java index 2fd40c25..9fca6e5e 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/SkillTreeCommand.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/SkillTreeCommand.java @@ -25,7 +25,7 @@ public class SkillTreeCommand extends BukkitCommand { if (!(sender instanceof Player player)) return false; PlayerData data = PlayerData.get(player); - MMOCommandEvent event = new MMOCommandEvent(data, "skilltree"); + MMOCommandEvent event = new MMOCommandEvent(data, "skilltrees"); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) return true; 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 4b16578b..868da7e5 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 @@ -100,7 +100,7 @@ public class PlayerProfessions { for (Entry entry : obj.getAsJsonObject("timesClaimed").entrySet()) playerData.getItemClaims().put("profession." + entry.getKey(), entry.getValue().getAsInt()); - if (!playerData.isStatLoaded()) + if (!playerData.areStatsLoaded()) for (Profession profession : MMOCore.plugin.professionManager.getAll()) { if (profession.hasExperienceTable()) profession.getExperienceTable().claimStatTriggers(playerData, profession); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index 6766ef8a..2eefa626 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -358,16 +358,6 @@ public class SkillList extends EditableInventory { @Override public void whenClicked(InventoryClickContext context, InventoryItem item) { - /* - if (skillSlots.contains(event.getRawSlot()) - && event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + (event.getRawSlot() - 13)) % skills.size(); - open(); - return; - } - */ - if (item.getFunction().equals("skill")) { int index = skillSlots.size() * page + skillSlots.indexOf(context.getSlot()); player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); @@ -377,8 +367,6 @@ public class SkillList extends EditableInventory { } if (item.getFunction().equals("reallocation")) { - - int spent = getPlayerData().countSkillPointsWhenReallocate(); if (spent < 1) { @@ -455,7 +443,7 @@ public class SkillList extends EditableInventory { } player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.setBoundPassiveSkill(index, selected.toPassive(playerData)); + playerData.bindPassiveSkill(index, selected.toPassive(playerData)); open(); return; } @@ -497,7 +485,7 @@ public class SkillList extends EditableInventory { } player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.setBoundSkill(index, selected); + playerData.bindActiveSkill(index, selected); open(); return; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/api/InventoryClickContext.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/api/InventoryClickContext.java index 32ac3698..7f5fd539 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/api/InventoryClickContext.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/api/InventoryClickContext.java @@ -4,26 +4,31 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class InventoryClickContext { private final int slot; - private final ItemStack itemStack; + + @Nullable + private final ItemStack currentItem; + + @NotNull private final ClickType clickType; + @NotNull private final Cancellable event; - private Inventory inv; - public InventoryClickContext(int slot, ItemStack itemStack, ClickType clickType, Cancellable event) { - this.slot = slot; - this.itemStack = itemStack; - this.clickType = clickType; - this.event = event; + @Nullable + private final Inventory inv; + + public InventoryClickContext(int slot, ItemStack currentItem, ClickType clickType, Cancellable event) { + this(slot, currentItem, clickType, event, null); } - public InventoryClickContext(int slot, ItemStack itemStack, ClickType clickType, Cancellable event, Inventory inv) { + public InventoryClickContext(int slot, ItemStack currentItem, ClickType clickType, Cancellable event, Inventory inv) { this.slot = slot; - this.itemStack = itemStack; + this.currentItem = currentItem; this.clickType = clickType; this.event = event; this.inv = inv; @@ -48,13 +53,15 @@ public class InventoryClickContext { */ @Nullable public ItemStack getClickedItem() { - return itemStack; + return currentItem; } + @NotNull public Cancellable getEvent() { return event; } + @Nullable public Inventory getInventory() { return inv; } @@ -63,6 +70,7 @@ public class InventoryClickContext { return inv != null; } + @NotNull public ClickType getClickType() { return clickType; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java index 3dcb7c23..92bbfcbe 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java @@ -76,12 +76,12 @@ public class ConfigManager { loadDefaultFile("expcurves", "mining.txt"); } - if(!new File(MMOCore.plugin.getDataFolder()+"/skilltree").exists()) { - loadDefaultFile("skilltree","combat.yml"); - loadDefaultFile("skilltree","mage-arcane-mage.yml"); - loadDefaultFile("skilltree","rogue-marksman.yml"); - loadDefaultFile("skilltree","warrior-paladin.yml"); - loadDefaultFile("skilltree","general.yml"); + if(!new File(MMOCore.plugin.getDataFolder()+"/skill-trees").exists()) { + loadDefaultFile("skill-trees","combat.yml"); + loadDefaultFile("skill-trees","mage-arcane-mage.yml"); + loadDefaultFile("skill-trees","rogue-marksman.yml"); + loadDefaultFile("skill-trees","warrior-paladin.yml"); + loadDefaultFile("skill-trees","general.yml"); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/SkillTreeManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/SkillTreeManager.java index 9d25125e..be55981e 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/SkillTreeManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/SkillTreeManager.java @@ -57,7 +57,7 @@ public class SkillTreeManager extends MMOCoreRegister { public void initialize(boolean clearBefore) { if (clearBefore) registered.clear(); - File file = new File(MMOCore.plugin.getDataFolder() + "/skilltree"); + File file = new File(MMOCore.plugin.getDataFolder() + "/skill-trees"); if (!file.exists()) file.mkdirs(); load(file); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java index d6fb1777..0a7dd22f 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java @@ -121,7 +121,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager { if (data.getProfess().hasSkill(id)) { ClassSkill skill = data.getProfess().getSkill(id); if (skill.getSkill().getTrigger().isPassive()) - data.addPassiveBoundSkill(skill.toPassive(data)); + data.bindPassiveSkill(-1, skill.toPassive(data)); else data.getBoundSkills().add(skill); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java index 6be5aec7..c3b738eb 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java @@ -70,7 +70,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager { if (data.getProfess().hasSkill(id)) { ClassSkill skill = data.getProfess().getSkill(id); if (skill.getSkill().getTrigger().isPassive()) - data.addPassiveBoundSkill(skill.toPassive(data)); + data.bindPassiveSkill(-1, skill.toPassive(data)); else data.getBoundSkills().add(skill); 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 b9aeb4ff..f301c62a 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 @@ -5,14 +5,12 @@ import io.lumine.mythic.lib.player.cooldown.CooldownObject; import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.skill.PassiveSkill; import io.lumine.mythic.lib.script.condition.Condition; -import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.gui.api.item.Placeholders; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; import java.util.*; @@ -121,10 +119,9 @@ public class ClassSkill implements CooldownObject { /** - * Be careful, this method creates a new UUID each time it is called. Need to be remembered when trying to unregister passive skill - * from PassiveSkillMap. - * - * @return + * Be careful, this method creates a new UUID each time it + * is called. It needs to be saved somewhere when trying to + * unregister the passive skill from the skill map later on. */ public PassiveSkill toPassive(PlayerData caster) { Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active"); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/ComboMap.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/ComboMap.java index 94b18007..5ba63e6d 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/ComboMap.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/ComboMap.java @@ -33,7 +33,7 @@ public class ComboMap { Validate.isTrue(spellSlot >= 0, "Spell slot must be at least 0"); Validate.isTrue(!combos.values().contains(spellSlot), "There is already a key combo with the same skill slot"); KeyCombo combo = new KeyCombo(); - for (String str : config.getStringList("combos." + key)) + for (String str : config.getStringList(key)) combo.registerKey(PlayerKey.valueOf(UtilityMethods.enumName(str))); combos.put(combo, spellSlot); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java index d878b785..1be71afa 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java @@ -40,7 +40,7 @@ public abstract class SkillCastingHandler extends BukkitRunnable implements List @Override public void run() { if (!caster.isOnline() || caster.getPlayer().isDead()) - caster.leaveCastingMode(); + caster.leaveSkillCasting(); else { // Apply casting particles 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 3f56a98e..e8039bf7 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 @@ -19,6 +19,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.*; @@ -80,7 +81,7 @@ public class KeyCombos implements Listener { return; } - CustomSkillCastingHandler casting = null; + @Nullable CustomSkillCastingHandler casting = null; // Player is already casting if (event.getData().isCasting()) @@ -88,7 +89,7 @@ public class KeyCombos implements Listener { // Start combo when there is NO initializer key else { - final ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap); + final @NotNull ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap); if (comboMap.isComboStart(event.getPressed())) { casting = new CustomSkillCastingHandler(playerData); playerData.setSkillCasting(casting); @@ -113,7 +114,7 @@ public class KeyCombos implements Listener { // Hash current combo and check if (casting.combos.getCombos().containsKey(casting.current)) { final int spellSlot = casting.combos.getCombos().get(casting.current) - 1; - playerData.leaveCastingMode(); + playerData.leaveSkillCasting(); // Cast spell if (playerData.hasSkillBound(spellSlot)) { @@ -125,7 +126,7 @@ public class KeyCombos implements Listener { // Check if current combo is too large if (casting.current.countKeys() >= casting.combos.getLongest()) { - playerData.leaveCastingMode(); + playerData.leaveSkillCasting(); if (failComboSound != null) failComboSound.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 79d519b0..c0cd3bc8 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 @@ -5,12 +5,10 @@ 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.player.PlayerData; -import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent; import net.Indyuce.mmocore.api.SoundEvent; -import net.Indyuce.mmocore.loot.chest.particle.CastingParticle; +import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent; +import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.skill.ClassSkill; -import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.cast.PlayerKey; import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; import org.bukkit.GameMode; @@ -25,9 +23,11 @@ import java.util.Objects; public class SkillBar implements Listener { private final PlayerKey mainKey; + private final boolean disableSneak; public SkillBar(ConfigurationSection config) { mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key"))); + disableSneak = config.getBoolean("disable-sneak"); } @EventHandler @@ -62,10 +62,13 @@ public class SkillBar implements Listener { @EventHandler public void onSkillCast(PlayerItemHeldEvent event) { - Player player = event.getPlayer(); - if (!getCaster().isOnline()) return; if (!event.getPlayer().equals(getCaster().getPlayer())) return; + if (!getCaster().isOnline()) { + getCaster().leaveSkillCasting(); + return; + } + /* * When the event is cancelled, another playerItemHeldEvent is * called and previous and next slots are equal. the event must not @@ -73,8 +76,9 @@ public class SkillBar implements Listener { */ if (event.getPreviousSlot() == event.getNewSlot()) return; - //If the player is sneaking, we don't trigger the casting mode (used to avoid conflicts with other plugins using shift+F to open GUI. - if(player.isSneaking()) return; + // Extra option to improve support with other plugins + final Player player = event.getPlayer(); + if (disableSneak && player.isSneaking()) return; event.setCancelled(true); int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0); @@ -86,8 +90,8 @@ public class SkillBar implements Listener { */ if (slot >= 0 && getCaster().hasSkillBound(slot)) { PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); - int delay= getCaster().getBoundSkill(slot).getDelay(getCaster()); - getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null),delay); + int delay = getCaster().getBoundSkill(slot).getDelay(getCaster()); + getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null), delay); } } @@ -103,7 +107,7 @@ public class SkillBar implements Listener { MMOCore.plugin.configManager.getSimpleMessage("casting.no-longer").send(getCaster().getPlayer()); } }.runTask(MMOCore.plugin); - PlayerData.get(player).leaveCastingMode(); + getCaster().leaveSkillCasting(); } } @@ -115,7 +119,7 @@ public class SkillBar implements Listener { str.append((str.length() == 0) ? "" : split).append((onCooldown(data, skill) ? onCooldown.replace("{cooldown}", String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina( data, skill) ? noStamina : ready)).replace("{index}", - "" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0))) + "" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0))) .replace("{skill}", data.getBoundSkill(j).getSkill().getName())); } return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString()); 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 f2ee6781..651d0654 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 @@ -54,7 +54,7 @@ public class SkillScroller implements Listener { if (event.getPressed().shouldCancelEvent()) event.setCancelled(true); - playerData.leaveCastingMode(); + playerData.leaveSkillCasting(); if (leaveSound != null) leaveSound.playTo(player); return; @@ -94,7 +94,7 @@ public class SkillScroller implements Listener { return; if (playerData.getBoundSkills().isEmpty()) { - playerData.leaveCastingMode(); + playerData.leaveSkillCasting(); return; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java index 25a16be3..00298044 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java @@ -11,8 +11,8 @@ import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult; import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; import io.lumine.mythic.lib.util.EntityLocationType; import io.lumine.mythic.lib.util.ParabolicProjectile; -import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Particle; @@ -45,7 +45,7 @@ public class Ambers extends SkillHandler implements Listener @EventHandler public void spawnAmber(PlayerAttackEvent event) { - MMOPlayerData data = event.getData(); + MMOPlayerData data = event.getAttacker().getData(); if (!event.getAttack().getDamage().hasType(DamageType.SKILL)) return; @@ -53,7 +53,7 @@ public class Ambers extends SkillHandler implements Listener if (passive == null) return; - passive.getTriggeredSkill().cast(new TriggerMetadata(event.getAttack(), event.getEntity())); + passive.getTriggeredSkill().cast(new TriggerMetadata(event.getAttacker(), event.getAttack(), event.getEntity())); } public static class Amber extends BukkitRunnable { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java index eeb3b1e3..22cd0762 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/list/Sneaky_Picky.java @@ -37,7 +37,7 @@ public class Sneaky_Picky extends SkillHandler implements Lis @EventHandler public void a(PlayerAttackEvent event) { - MMOPlayerData data = event.getData(); + MMOPlayerData data = event.getAttacker().getData(); if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || PlayerData.get(data.getUniqueId()).isInCombat()) return; @@ -45,6 +45,6 @@ public class Sneaky_Picky extends SkillHandler implements Lis if (skill == null) return; - skill.getTriggeredSkill().cast(new TriggerMetadata(event.getAttack(), event.getEntity())); + skill.getTriggeredSkill().cast(new TriggerMetadata(event.getAttacker(), event.getAttack(), event.getEntity())); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/NodeState.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/NodeState.java index 0492e4ff..504acfdc 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/NodeState.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/NodeState.java @@ -1,6 +1,24 @@ package net.Indyuce.mmocore.tree; public enum NodeState { - LOCKED,UNLOCKED,UNLOCKABLE,FULLY_LOCKED; + /** + * The player does not have access to this skill tree node just yet. + */ + LOCKED, + /** + * The player has bought and unlocked the skill tree node. + */ + UNLOCKED, + + /** + * The player has access to but has not unlocked the node yet. + */ + UNLOCKABLE, + + /** + * The player had access to this node, but unlocked another + * node which now prevents him from unlocking this one. + */ + FULLY_LOCKED; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java index d344a557..35f670d8 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/tree/skilltree/SkillTree.java @@ -5,12 +5,12 @@ import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.util.PostLoadObject; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.tree.NodeState; -import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo; import net.Indyuce.mmocore.manager.registry.RegisteredObject; -import net.Indyuce.mmocore.tree.skilltree.display.Icon; import net.Indyuce.mmocore.tree.IntegerCoordinates; +import net.Indyuce.mmocore.tree.NodeState; import net.Indyuce.mmocore.tree.SkillTreeNode; +import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo; +import net.Indyuce.mmocore.tree.skilltree.display.Icon; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -32,7 +32,6 @@ import java.util.logging.Level; * - extra attribute pts * - particle or potion effects * - * @author jules * @author Ka0rX * @see {@link SkillTreeNode} */ @@ -61,7 +60,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje Objects.requireNonNull(config.getStringList("lore"), "Could not find skill tree lore").forEach(str -> lore.add(MythicLib.plugin.parseColors(str))); this.item = Material.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("item")))); Validate.isTrue(config.isConfigurationSection("nodes"), "Could not find any nodes in the tree"); - this.maxPointSpent =config.getInt("max-point-spent",Integer.MAX_VALUE); + this.maxPointSpent = config.getInt("max-point-spent", Integer.MAX_VALUE); for (String key : config.getConfigurationSection("nodes").getKeys(false)) { try { @@ -69,7 +68,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje nodes.put(node.getId(), node); } catch (Exception e) { - MMOCore.log( "Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage()); + MMOCore.log("Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage()); } } try { @@ -86,7 +85,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje MMOCore.log(Level.WARNING, "Couldn't load paths for skill tree: " + id); } - try { //Load the icons of the skill tree. for (String key : config.getConfigurationSection("icons").getKeys(false)) { @@ -102,7 +100,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje } } } catch (Exception e) { - MMOCore.log( "Couldn't load icons for the skill tree " + id); + MMOCore.log("Couldn't load icons for the skill tree " + id); e.printStackTrace(); } } @@ -118,7 +116,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje } } - @Override protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection); @@ -178,7 +175,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje roots.add(node); } - /** * Recursively go through the skill trees to update the the node states */ @@ -187,7 +183,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje setupNodeStateFrom(root, playerData); } - public List getRoots() { return roots; } @@ -292,6 +287,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje public SkillTreeNode getNode(String name) { return Objects.requireNonNull(nodes.get(name), "Could not find node in tree '" + id + "' with name '" + name + "'"); } + public boolean isNode(String name) { return nodes.containsKey(name); } diff --git a/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/PlayerListener.java b/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/PlayerListener.java index 01ada1c5..67e33c7b 100644 --- a/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/PlayerListener.java +++ b/MMOCore-Dist/src/main/java/net/Indyuce/mmocore/listener/PlayerListener.java @@ -1,6 +1,7 @@ package net.Indyuce.mmocore.listener; +import io.lumine.mythic.lib.api.event.PlayerAttackEvent; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.player.PlayerData; @@ -8,12 +9,9 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.gui.api.InventoryClickContext; import net.Indyuce.mmocore.gui.api.PluginInventory; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.inventory.InventoryClickEvent; @@ -39,9 +37,8 @@ public class PlayerListener implements Listener { */ @EventHandler public void b(InventoryClickEvent event) { - if (event.getInventory().getHolder() instanceof PluginInventory&&event.getCurrentItem()!=null) - ((PluginInventory) event.getInventory().getHolder()) - .whenClicked(new InventoryClickContext(event.getRawSlot(), event.getCurrentItem(), event.getClick(), event, event.getInventory())); + if (event.getInventory().getHolder() instanceof PluginInventory) + ((PluginInventory) event.getInventory().getHolder()).whenClicked(new InventoryClickContext(event.getRawSlot(), event.getCurrentItem(), event.getClick(), event, event.getInventory())); } /** @@ -57,17 +54,9 @@ public class PlayerListener implements Listener { * Updates the player's combat log data every time he hits an entity, or * gets hit by an entity or a projectile sent by another entity */ - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void d(EntityDamageByEntityEvent event) { - if (event.getEntity() instanceof Player && !event.getEntity().hasMetadata("NPC")) - PlayerData.get((Player) event.getEntity()).updateCombat(); - - if (event.getDamager() instanceof Player && !event.getDamager().hasMetadata("NPC")) - PlayerData.get((Player) event.getDamager()).updateCombat(); - - if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player) - if (!((Player) ((Projectile) event.getDamager()).getShooter()).hasMetadata("NPC")) - PlayerData.get((Player) ((Projectile) event.getDamager()).getShooter()).updateCombat(); + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void d(PlayerAttackEvent event) { + PlayerData.get(event.getAttacker().getPlayer()).updateCombat(); } @EventHandler 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 ff3aa47b..4dadc341 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 @@ -9,10 +9,7 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.loot.fishing.FishingDropItem; import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.FishHook; import org.bukkit.entity.Item; import org.bukkit.entity.Player; @@ -183,6 +180,9 @@ public class FishingListener implements Listener { if (called.isCancelled()) return; + // Increase player statistic + player.incrementStatistic(Statistic.FISH_CAUGHT); + // Calculate yeet velocity Item item = hook.getWorld().dropItemNaturally(hook.getLocation(), collect); MMOCoreUtils.displayIndicator(location.add(0, 1.25, 0), diff --git a/MMOCore-Dist/src/main/resources/default/commands.yml b/MMOCore-Dist/src/main/resources/default/commands.yml index 4533d9d4..618cd337 100644 --- a/MMOCore-Dist/src/main/resources/default/commands.yml +++ b/MMOCore-Dist/src/main/resources/default/commands.yml @@ -28,8 +28,8 @@ guild: withdraw: main: "withdraw" aliases: ["w"] -skill-tree: - main: "skilltree" +skill-trees: + main: "skilltrees" aliase: ["st"] deposit: main: "deposit" diff --git a/MMOCore-Dist/src/main/resources/default/professions/fishing.yml b/MMOCore-Dist/src/main/resources/default/professions/fishing.yml index ed2b9985..c5972134 100644 --- a/MMOCore-Dist/src/main/resources/default/professions/fishing.yml +++ b/MMOCore-Dist/src/main/resources/default/professions/fishing.yml @@ -22,7 +22,8 @@ exp-sources: {} on-fish: overriding-drop-table: conditions: - - 'biome{name=swamp}' + - 'region{name=swamp,second-region}' + - 'biome{name=beach}' # When drop table is read, one of these # items will be selected randomly. @@ -30,15 +31,16 @@ on-fish: # Tugs needed: 4 to 5 # Fishing EXP earned: 1 to 6 - - 'mmoitem{type=CONSUMABLE;id=SUSHI_ROLL;tugs=30-40;experience=1-6}' + - 'mmoitem{type=CONSUMABLE;id=SUSHI_ROLL;tugs=4-5;experience=1-6} 1 1-1 9' # Tugs needed: 10 to 20 # Fishing EXP earned: 20 to 30 - - 'mmoitem{type=GEM_STONE;id=SPITEFUL_OPAQUE_DIAMOND;tugs=10-15;experience=20-30}' + - 'mmoitem{type=GEM_STONE;id=SPITEFUL_OPAQUE_DIAMOND;tugs=10-15;experience=20-30} 1 1-1 1' # Default drop table which always apply. # When removing every drop table, the vanilla # fishing mecanism is back. default: items: - - 'vanilla{type=SALMON;tugs=4-5;experience=1-6}' + - 'vanilla{type=SALMON;tugs=4-5;experience=1-6} 1 2-5 1' + diff --git a/MMOCore-Dist/src/main/resources/default/skilltree/combat.yml b/MMOCore-Dist/src/main/resources/default/skill-trees/combat.yml similarity index 100% rename from MMOCore-Dist/src/main/resources/default/skilltree/combat.yml rename to MMOCore-Dist/src/main/resources/default/skill-trees/combat.yml diff --git a/MMOCore-Dist/src/main/resources/default/skilltree/general.yml b/MMOCore-Dist/src/main/resources/default/skill-trees/general.yml similarity index 100% rename from MMOCore-Dist/src/main/resources/default/skilltree/general.yml rename to MMOCore-Dist/src/main/resources/default/skill-trees/general.yml diff --git a/MMOCore-Dist/src/main/resources/default/skilltree/mage-arcane-mage.yml b/MMOCore-Dist/src/main/resources/default/skill-trees/mage-arcane-mage.yml similarity index 100% rename from MMOCore-Dist/src/main/resources/default/skilltree/mage-arcane-mage.yml rename to MMOCore-Dist/src/main/resources/default/skill-trees/mage-arcane-mage.yml diff --git a/MMOCore-Dist/src/main/resources/default/skilltree/rogue-marksman.yml b/MMOCore-Dist/src/main/resources/default/skill-trees/rogue-marksman.yml similarity index 100% rename from MMOCore-Dist/src/main/resources/default/skilltree/rogue-marksman.yml rename to MMOCore-Dist/src/main/resources/default/skill-trees/rogue-marksman.yml diff --git a/MMOCore-Dist/src/main/resources/default/skilltree/warrior-paladin.yml b/MMOCore-Dist/src/main/resources/default/skill-trees/warrior-paladin.yml similarity index 100% rename from MMOCore-Dist/src/main/resources/default/skilltree/warrior-paladin.yml rename to MMOCore-Dist/src/main/resources/default/skill-trees/warrior-paladin.yml