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 bb807241..246ca357 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 @@ -23,6 +23,9 @@ public class DefaultMMOLoader extends MMOLoader { if (config.getKey().equals("stat")) return new StatTrigger(config); + if(config.getKey().equals("unlock_slot")) + return new UnlockSlotTrigger(config); + if (config.getKey().equals("unlock_skill")) return new UnlockSkillTrigger(config); 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 9ac77dc3..3fbe0b3a 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 @@ -21,6 +21,7 @@ import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; import net.Indyuce.mmocore.api.player.profess.Subclass; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.skillbinding.BoundSkillInfo; +import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot; import net.Indyuce.mmocore.api.player.social.FriendRequest; import net.Indyuce.mmocore.api.player.stats.PlayerStats; import net.Indyuce.mmocore.api.quest.PlayerQuests; @@ -122,7 +123,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * -Skills * -Skill Books */ - private final Set<String> unlockedItems= new HashSet<>(); + private final Set<String> unlockedItems = new HashSet<>(); /** * Saves the amount of times the player has claimed some * exp item in exp tables, for both exp tables used @@ -376,7 +377,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc } - /** * @return If the item is unlocked by the player * This is used for skills that can be locked & unlocked. @@ -384,13 +384,16 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * Looks at the real value and thus remove the plugin identifier */ public boolean hasUnlocked(Unlockable unlockable) { - String unlockableKey = unlockable.getUnlockNamespacedKey().substring(unlockable.getUnlockNamespacedKey().indexOf(":")); - return unlockedItems - .stream() - .filter(key -> key.substring(key.indexOf(":")).equals(unlockableKey)) - .collect(Collectors.toList()).size() != 0; + return hasUnlocked(unlockable.getUnlockNamespacedKey()); + } + public boolean hasUnlocked(String unlockNamespacedKey) { + return unlockedItems + .stream() + .filter(key -> key.equals(unlockNamespacedKey)) + .collect(Collectors.toList()).size() != 0; + } /** * Unlocks an item for the player. This is mainly used to unlock skills. @@ -799,9 +802,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc final double r = Math.sin((double) t / warpTime * Math.PI); for (double j = 0; j < Math.PI * 2; j += Math.PI / 4) getPlayer().getLocation().getWorld().spawnParticle(Particle.REDSTONE, getPlayer().getLocation().add( - Math.cos((double) 5 * t / warpTime + j) * r, - (double) 2 * t / warpTime, - Math.sin((double) 5 * t / warpTime + j) * r), + Math.cos((double) 5 * t / warpTime + j) * r, + (double) 2 * t / warpTime, + Math.sin((double) 5 * t / warpTime + j) * r), 1, new Particle.DustOptions(Color.PURPLE, 1.25f)); } }.runTaskTimer(MMOCore.plugin, 0, 1); @@ -830,7 +833,8 @@ 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, @NotNull EXPSource source, @Nullable Location hologramLocation, boolean splitExp) { + public void giveExperience(double value, @NotNull EXPSource source, @Nullable Location hologramLocation, + boolean splitExp) { if (value <= 0) { experience = Math.max(0, experience + value); return; @@ -1172,7 +1176,14 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc profess.getSkills() .stream() .filter(ClassSkill::isUnlockedByDefault) - .forEach(skill ->unlock(skill.getSkill())); + .forEach(skill -> unlock(skill.getSkill())); + + //Loads the classUnlockedSlots + profess.getSlots() + .stream() + .filter(SkillSlot::isUnlockedByDefault) + .forEach(this::unlock); + } public boolean hasSkillBound(int slot) { @@ -1204,7 +1215,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc if (slot >= 0) { //We apply the skill buffs associated with the slot to the skill. profess.getSkillSlot(slot).getSkillBuffTriggers().forEach(skillBuffTrigger -> - skillBuffTrigger.apply(this,skill.getSkill().getHandler().getId())); + skillBuffTrigger.apply(this, skill.getSkill().getHandler().getId())); if (skill.getSkill().getTrigger().isPassive()) { @@ -1220,7 +1231,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc public void unbindSkill(int slot) { //We remove the skill buffs associated with the slot from the skill that is . profess.getSkillSlot(slot).getSkillBuffTriggers().forEach(skillBuffTrigger -> - skillBuffTrigger.remove(this,boundSkills.get(slot).getClassSkill().getSkill().getHandler().getId())); + skillBuffTrigger.remove(this, boundSkills.get(slot).getClassSkill().getSkill().getHandler().getId())); BoundSkillInfo boundSkillInfo = boundSkills.remove(slot); boundSkillInfo.unbind(); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java index 0fb0070b..8e0d2688 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java @@ -15,6 +15,7 @@ import io.lumine.mythic.lib.skill.Skill; import io.lumine.mythic.lib.skill.handler.MythicLibSkillHandler; import io.lumine.mythic.lib.skill.trigger.TriggerType; import io.lumine.mythic.lib.version.VersionMaterial; +import jdk.jshell.execution.Util; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.event.EventTrigger; @@ -39,6 +40,7 @@ import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; +import org.bukkit.Utility; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.inventory.ItemStack; @@ -105,9 +107,11 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { throw new IllegalArgumentException("Could not apply playerhead texture: " + exception.getMessage()); } Validate.isTrue(config.isConfigurationSection("skill-slots"), "You must define the skills-slots for class " + id); - for (String key : config.getConfigurationSection("skill-slots").getKeys(false)) { - SkillSlot skillSlot = new SkillSlot(config.getConfigurationSection("skill-slots." + key)); - skillSlots.put(skillSlot.getSlot(), skillSlot); + for (int i = 1; i < MMOCore.plugin.configManager.maxSlots + 1; i++) { + if (config.contains("skill-slots." + i)) + skillSlots.put(i, new SkillSlot(config.getConfigurationSection("skill-slots." + i))); + else + skillSlots.put(i, new SkillSlot(i, 0, "true", "&eSkill Slot " + MMOCoreUtils.intToRoman(i), new ArrayList<>(), false, new ArrayList<>())); } for (String string : config.getStringList("display.lore")) description.add(ChatColor.GRAY + MythicLib.plugin.parseColors(string)); @@ -185,7 +189,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { if (config.contains("skills." + key)) skills.put(key, new ClassSkill(registered, config.getConfigurationSection("skills." + key))); else - skills.put(key, new ClassSkill(registered, 1, 1,false)); + skills.put(key, new ClassSkill(registered, 1, 1, false)); } castParticle = config.contains("cast-particle") ? new CastingParticle(config.getConfigurationSection("cast-particle")) : null; @@ -428,6 +432,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return skillSlots.get(slot); } + public Collection<SkillSlot> getSlots() { + return skillSlots.values(); + } + public ClassSkill getSkill(RegisteredSkill skill) { return getSkill(skill.getHandler().getId()); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java index 91e58797..dd9f7ecc 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java @@ -2,31 +2,36 @@ package net.Indyuce.mmocore.api.player.profess.skillbinding; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.Unlockable; import net.Indyuce.mmocore.api.quest.trigger.SkillBuffTrigger; import net.Indyuce.mmocore.skill.ClassSkill; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; + import java.util.ArrayList; import java.util.List; -public class SkillSlot { +public class SkillSlot implements Unlockable { private final int slot, modelData; private final String formula; private final String name; private final List<String> lore; + private final boolean isUnlockedByDefault; + private final List<SkillBuffTrigger> skillBuffTriggers; private Material item; - public SkillSlot(int slot, int modelData, String formula, String name, List<String> lore, List<SkillBuffTrigger> skillBuffTriggers, Material item) { + public SkillSlot(int slot, int modelData, String formula, String name, List<String> lore, boolean isUnlockedByDefault, List<SkillBuffTrigger> skillBuffTriggers) { this.slot = slot; this.modelData = modelData; this.formula = formula; this.name = name; this.lore = lore; + this.isUnlockedByDefault = isUnlockedByDefault; this.skillBuffTriggers = skillBuffTriggers; - this.item = item; } public SkillSlot(ConfigurationSection section) { @@ -37,10 +42,11 @@ public class SkillSlot { if (section.contains("item")) this.item = Material.valueOf(section.getString("item")); this.modelData = section.getInt("model-data", 0); - skillBuffTriggers= new ArrayList<>(); - if(section.contains("skill-buffs")) - for(String skillBuff:section.getStringList("skill-buffs")) - if(skillBuff.startsWith("skill_buff")){ + isUnlockedByDefault = section.getBoolean("unlocked-by-default", true); + skillBuffTriggers = new ArrayList<>(); + if (section.contains("skill-buffs")) + for (String skillBuff : section.getStringList("skill-buffs")) + if (skillBuff.startsWith("skill_buff")) { skillBuffTriggers.add((SkillBuffTrigger) MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(skillBuff))); } } @@ -69,6 +75,10 @@ public class SkillSlot { return modelData; } + public boolean isUnlockedByDefault() { + return isUnlockedByDefault; + } + public List<SkillBuffTrigger> getSkillBuffTriggers() { return skillBuffTriggers; } @@ -76,4 +86,24 @@ public class SkillSlot { public boolean canPlaceSkill(ClassSkill classSkill) { return classSkill.getSkill().matchesFormula(formula); } + + @Override + public String getUnlockNamespacedKey() { + return "slot:"+slot; + } + + /** + * If we lock a slot that had a skill bound + * to it we first unbind the attached skill. + */ + @Override + public void whenLocked(PlayerData playerData) { + if(playerData.hasSkillBound(slot)) + playerData.unbindSkill(slot); + } + + @Override + public void whenUnlocked(PlayerData playerData) { + + } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/UnlockSlotTrigger.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/UnlockSlotTrigger.java new file mode 100644 index 00000000..9c87c042 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/UnlockSlotTrigger.java @@ -0,0 +1,37 @@ +package net.Indyuce.mmocore.api.quest.trigger; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot; +import net.Indyuce.mmocore.api.quest.trigger.api.Removable; +import net.Indyuce.mmocore.skill.RegisteredSkill; +import org.apache.commons.lang.Validate; + +import java.util.Objects; + + +public class UnlockSlotTrigger extends Trigger implements Removable { + private final int slot; + + public UnlockSlotTrigger(MMOLineConfig config) { + super(config); + config.validateKeys("slot"); + slot = Integer.parseInt("slot"); + Validate.isTrue(slot > 0 && slot <= MMOCore.plugin.configManager.maxSlots, "The slot should be between 1 and " + MMOCore.plugin.configManager.maxSlots); + } + + @Override + public void apply(PlayerData player) { + SkillSlot skillSlot = player.getProfess().getSkillSlot(slot); + if (!player.hasUnlocked(skillSlot)) + player.unlock(skillSlot); + } + + @Override + public void remove(PlayerData player) { + SkillSlot skillSlot = player.getProfess().getSkillSlot(slot); + if (player.hasUnlocked(skillSlot)) + player.lock(skillSlot); + } +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SlotCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SlotCommandTreeNode.java new file mode 100644 index 00000000..38c2c852 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SlotCommandTreeNode.java @@ -0,0 +1,79 @@ +package net.Indyuce.mmocore.command.rpg.admin; + +import io.lumine.mythic.lib.command.api.CommandTreeNode; +import io.lumine.mythic.lib.command.api.Parameter; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot; +import net.Indyuce.mmocore.command.api.CommandVerbose; +import net.Indyuce.mmocore.skill.ClassSkill; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +public class SlotCommandTreeNode extends CommandTreeNode { + public SlotCommandTreeNode(CommandTreeNode parent) { + super(parent, "skill"); + addChild(new LockSlotCommandTreeNode(this, "lock", true)); + addChild(new LockSlotCommandTreeNode(this, "unlock", false)); + } + + public class LockSlotCommandTreeNode extends CommandTreeNode { + private final boolean lock; + + public LockSlotCommandTreeNode(CommandTreeNode parent, String id, boolean lock) { + super(parent, id); + this.lock = lock; + addParameter(Parameter.PLAYER); + addParameter(Parameter.AMOUNT); + } + + @Override + public CommandResult execute(CommandSender sender, String[] args) { + if (args.length < 5) + return CommandResult.THROW_USAGE; + Player player = Bukkit.getPlayer(args[3]); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + "."); + return CommandResult.FAILURE; + } + PlayerData playerData = PlayerData.get(player); + int slot; + try { + slot = Integer.parseInt(args[4]); + } catch (NumberFormatException e) { + sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number."); + return CommandResult.FAILURE; + } + if (slot <= 0) { + sender.sendMessage(ChatColor.RED + "The slot can't be negative."); + return CommandResult.FAILURE; + } + SkillSlot skillSlot=playerData.getProfess().getSkillSlot(slot); + if (lock) { + if (!playerData.hasUnlocked(skillSlot)) { + CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill slot " + skillSlot.getName() + " is already locked" + " for " + player.getName()); + return CommandResult.SUCCESS; + } + playerData.lock(skillSlot); + + } else { + if (playerData.hasUnlocked(skillSlot)) { + CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill slot " + skillSlot.getName() + " is already unlocked" + " for " + player.getName()); + return CommandResult.SUCCESS; + } + playerData.unlock(skillSlot); + } + CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill slot " + skillSlot.getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName())); + return CommandResult.SUCCESS; + } + } + + + @Override + public CommandResult execute(CommandSender sender, String[] args) { + return CommandResult.THROW_USAGE; + } +} 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 575ad2f4..b5cbb113 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 @@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.SoundEvent; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot; import net.Indyuce.mmocore.api.util.MMOCoreUtils; @@ -15,9 +16,7 @@ import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; -import net.Indyuce.mmocore.api.SoundEvent; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; @@ -66,49 +65,7 @@ public class SkillList extends EditableInventory { } if (function.equals("slot")) - return new SlotItem(config) { - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - if (!inv.getPlayerData().getProfess().hasSlot(n + 1)) { - return new ItemStack(Material.AIR); - } - SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1); - ItemStack item = super.display(inv, n); - if (!inv.getPlayerData().hasSkillBound(n + 1)) { - //If there is an item filled in the slot config it shows it, else shows the default item. - Material material = skillSlot.hasItem() ? skillSlot.getItem() : super.emptyMaterial; - int customModelData = skillSlot.hasItem() ? skillSlot.getModelData() : super.emptyCMD; - item.setType(material); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), skillSlot.getName())); - List<String> lore = skillSlot.getLore() - .stream() - .map(str -> MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), str)) - .collect(Collectors.toList()); - meta.setLore(lore); - if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) { - meta.setCustomModelData(customModelData); - } - item.setItemMeta(meta); - - } - - return item; - } - - /** - * This should only be called when there is a skill bound. - */ - @Override - public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - Placeholders holders = super.getPlaceholders(inv, n); - String none = MythicLib.plugin.parseColors(config.getString("no-skill")); - RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n + 1) ? inv.getPlayerData().getBoundSkill(n + 1).getSkill() : null; - holders.register("skill", skill == null ? none : skill.getName()); - return holders; - } - - }; + return new SlotItem(config); if (function.equals("previous")) return new SimplePlaceholderItem<SkillViewerInventory>(config) { @@ -200,6 +157,39 @@ public class SkillList extends EditableInventory { emptyCMD = config.getInt("empty-custom-model-data", getModelData()); } + + @Override + public ItemStack display(SkillViewerInventory inv, int n) { + if (!inv.getPlayerData().hasUnlocked("slot:" + n)) { + return new ItemStack(Material.AIR); + } + SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1); + ItemStack item = super.display(inv, n); + if (!inv.getPlayerData().hasSkillBound(n + 1)) { + //If there is an item filled in the slot config it shows it, else shows the default item. + Material material = skillSlot.hasItem() ? skillSlot.getItem() : emptyMaterial; + int customModelData = skillSlot.hasItem() ? skillSlot.getModelData() : emptyCMD; + item.setType(material); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), skillSlot.getName())); + List<String> lore = skillSlot.getLore() + .stream() + .map(str -> MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), str)) + .collect(Collectors.toList()); + meta.setLore(lore); + if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) { + meta.setCustomModelData(customModelData); + } + item.setItemMeta(meta); + + } + + return item; + } + + /** + * This should only be called when there is a skill bound. + */ @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { RegisteredSkill selected = inv.selected.getSkill(); @@ -209,10 +199,12 @@ public class SkillList extends EditableInventory { holders.register("index", "" + (n + 1)); holders.register("slot", MMOCoreUtils.intToRoman(n + 1)); holders.register("selected", selected == null ? none : selected.getName()); - + RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n + 1) ? inv.getPlayerData().getBoundSkill(n + 1).getSkill() : null; + holders.register("skill", skill == null ? none : skill.getName()); return holders; } + @Override public boolean hasDifferentDisplay() { return true; @@ -317,7 +309,9 @@ public class SkillList extends EditableInventory { private final List<Integer> skillSlots; private final List<Integer> slotSlots; - //The skill the player Selected + /** + * The skill the player Selected + */ private ClassSkill selected; private int page = 0; @@ -329,6 +323,7 @@ public class SkillList extends EditableInventory { .sorted(Comparator.comparingInt(ClassSkill::getUnlockLevel)) .collect(Collectors.toList()); skillSlots = getEditable().getByFunction("skill").getSlots(); + Validate.notNull(getEditable().getByFunction("slot"), "Your skill GUI config file is out-of-date, please regenerate it."); slotSlots = getEditable().getByFunction("slot").getSlots(); selected = skills.get(page * skillSlots.size()); 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 26e3911c..d4d93cd8 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 @@ -34,7 +34,7 @@ public class ConfigManager { public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown; public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown, pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown; - public int maxPartyLevelDifference, maxBoundActiveSkills, maxBoundPassiveSkills, minCombatLevel, maxCombatLevelDifference; + public int maxPartyLevelDifference, maxSlots, minCombatLevel, maxCombatLevelDifference; public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>(); private final FileConfiguration messages; @@ -157,8 +157,7 @@ public class ConfigManager { canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast"); cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp"); saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info"); - maxBoundActiveSkills = MMOCore.plugin.getConfig().getInt("max-bound-active-skills", 6); - maxBoundPassiveSkills = MMOCore.plugin.getConfig().getInt("max-bound-passive-skills", 3); + maxSlots = MMOCore.plugin.getConfig().getInt("max-slots"); overrideVanillaExp = MMOCore.plugin.getConfig().getBoolean("override-vanilla-exp"); } diff --git a/MMOCore-Dist/src/main/resources/config.yml b/MMOCore-Dist/src/main/resources/config.yml index a796b374..d59b2c26 100644 --- a/MMOCore-Dist/src/main/resources/config.yml +++ b/MMOCore-Dist/src/main/resources/config.yml @@ -197,16 +197,14 @@ death-exp-loss: # Percentage of current EXP you lose when dying. percent: 30 -#Default max bound active and passive skills. -#These value can be modified for each class in the class yml. -max-bound-active-skills: 6 +#Maximum number of slot. This means that you can't unlock a slot greater than max-slots. (The slot count starts at 1 & end at max-slots). +max-slots: 10 #If you want players to bound their passive skills. #If false, all the passive skills unlocked will be active #Also set max-bound-passive-skills to 0 if seting passive-skill-need-bound to false. passive-skill-need-bound: true -max-bound-passive-skills: 3 # Fun extra RPG feature that switches the player's hotbar with # the 9 lower row items of his inventory. This allows the player