Fixed /skills not working when a class has too many slots configured

This commit is contained in:
Jules 2024-04-23 22:54:49 -07:00
parent 176657e3fd
commit 3248ffe541
8 changed files with 65 additions and 30 deletions

View File

@ -1220,7 +1220,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
*/ */
public void bindSkill(int slot, @NotNull ClassSkill skill) { public void bindSkill(int slot, @NotNull ClassSkill skill) {
Validate.notNull(skill, "Skill cannot be null"); Validate.notNull(skill, "Skill cannot be null");
if (slot < 0) return; if (slot <= 0) return;
// Unbinds the previous skill (important for passive skills) // Unbinds the previous skill (important for passive skills)
unbindSkill(slot); unbindSkill(slot);

View File

@ -32,6 +32,7 @@ import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.binding.SkillSlot; import net.Indyuce.mmocore.skill.binding.SkillSlot;
import net.Indyuce.mmocore.skill.cast.ComboMap; import net.Indyuce.mmocore.skill.cast.ComboMap;
import net.Indyuce.mmocore.skilltree.tree.SkillTree; import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.Indyuce.mmocore.util.ConfigUtils;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -66,7 +67,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
@Nullable @Nullable
private final CastingParticle castParticle; private final CastingParticle castParticle;
private final Map<Integer, SkillSlot> skillSlots = new HashMap<>(); private final List<SkillSlot> skillSlots = new ArrayList<>();
private final List<SkillTree> skillTrees = new ArrayList<>(); private final List<SkillTree> skillTrees = new ArrayList<>();
private final List<PassiveSkill> classScripts = new LinkedList(); private final List<PassiveSkill> classScripts = new LinkedList();
private final Map<String, LinearValue> stats = new HashMap<>(); private final Map<String, LinearValue> stats = new HashMap<>();
@ -174,15 +175,13 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
} }
// Skill slots // Skill slots
for (int i = 1; i < MMOCore.plugin.configManager.maxSkillSlots + 1; i++) if (config.isConfigurationSection("skill-slots"))
try { ConfigUtils.iterateConfigSectionList(
if (config.contains("skill-slots." + i)) config.getConfigurationSection("skill-slots"),
skillSlots.put(i, new SkillSlot(config.getConfigurationSection("skill-slots." + i))); skillSlots,
else SkillSlot::new,
skillSlots.put(i, new SkillSlot(i, 0, "true", "&eSkill Slot " + MMOCoreUtils.intToRoman(i), new ArrayList<>(), false, true, new ArrayList<>())); index -> new SkillSlot(index, 0, "true", "&eUnconfigured Skill Slot " + MMOCoreUtils.intToRoman(index), new ArrayList<>(), false, true, new ArrayList<>()),
} catch (RuntimeException exception) { (key, exception) -> MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load skill slot '" + key + "' from class '" + getId() + "': " + exception.getMessage()));
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load skill slot '" + String.valueOf(i) + "' from class '" + getId() + "': " + exception.getMessage());
}
// Class skills // Class skills
for (RegisteredSkill registered : MMOCore.plugin.skillManager.getAll()) { for (RegisteredSkill registered : MMOCore.plugin.skillManager.getAll()) {
@ -365,9 +364,9 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
/** /**
* @return A list of passive skills which correspond to class * @return A list of passive skills which correspond to class
* scripts wrapped in a format recognized by MythicLib. * scripts wrapped in a format recognized by MythicLib.
* Class scripts are handled just like * Class scripts are handled just like
* passive skills * passive skills
*/ */
@NotNull @NotNull
public List<PassiveSkill> getScripts() { public List<PassiveSkill> getScripts() {
@ -426,19 +425,21 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
} }
public boolean hasSlot(int slot) { public boolean hasSlot(int slot) {
return skillSlots.containsKey(slot); return 1 <= slot && slot <= skillSlots.size();
} }
public List<SkillTree> getSkillTrees() { public List<SkillTree> getSkillTrees() {
return skillTrees; return skillTrees;
} }
@Nullable
public SkillSlot getSkillSlot(int slot) { public SkillSlot getSkillSlot(int slot) {
return skillSlots.get(slot); return hasSlot(slot) ? skillSlots.get(slot - 1) : null;
} }
public Collection<SkillSlot> getSlots() { @NotNull
return skillSlots.values(); public List<SkillSlot> getSlots() {
return skillSlots;
} }
@NotNull @NotNull

View File

@ -19,7 +19,7 @@ public class UnlockSlotTrigger extends Trigger implements Removable {
}catch(NumberFormatException e){ }catch(NumberFormatException e){
throw new IllegalArgumentException("The slot should be a number"); throw new IllegalArgumentException("The slot should be a number");
} }
Validate.isTrue(slot > 0 && slot <= MMOCore.plugin.configManager.maxSkillSlots, "The slot should be between 1 and " + MMOCore.plugin.configManager.maxSkillSlots); Validate.isTrue(slot > 0, "Slot number must be positive");
} }
@Override @Override

View File

@ -53,10 +53,6 @@ public class SlotCommandTreeNode extends CommandTreeNode {
sender.sendMessage(ChatColor.RED + "The slot can't be negative."); sender.sendMessage(ChatColor.RED + "The slot can't be negative.");
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
if (slot > MMOCore.plugin.configManager.maxSkillSlots) {
sender.sendMessage(ChatColor.RED + "The slot can't be higher than " + MMOCore.plugin.configManager.maxSkillSlots + ".");
return CommandResult.FAILURE;
}
SkillSlot skillSlot = playerData.getProfess().getSkillSlot(slot); SkillSlot skillSlot = playerData.getProfess().getSkillSlot(slot);
if(skillSlot.isUnlockedByDefault()){ if(skillSlot.isUnlockedByDefault()){
sender.sendMessage(ChatColor.RED + "You can't lock a skill that is unlocked by default."); sender.sendMessage(ChatColor.RED + "You can't lock a skill that is unlocked by default.");

View File

@ -213,8 +213,8 @@ public class SkillList extends EditableInventory {
@Override @Override
public ItemStack display(SkillViewerInventory inv, int n) { public ItemStack display(SkillViewerInventory inv, int n) {
final @NotNull SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1); final @Nullable SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1);
if (!inv.getPlayerData().hasUnlocked(skillSlot)) if (skillSlot == null || !inv.getPlayerData().hasUnlocked(skillSlot))
return new ItemStack(Material.AIR); return new ItemStack(Material.AIR);
final @Nullable ClassSkill boundSkill = inv.getPlayerData().getBoundSkill(n + 1); final @Nullable ClassSkill boundSkill = inv.getPlayerData().getBoundSkill(n + 1);

View File

@ -34,7 +34,7 @@ public class ConfigManager {
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown; public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown, public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown,
pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown; pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown;
public int maxPartyLevelDifference, maxPartyPlayers, maxSkillSlots, minCombatLevel, maxCombatLevelDifference, skillTreeScrollStepX, skillTreeScrollStepY; public int maxPartyLevelDifference, maxPartyPlayers, minCombatLevel, maxCombatLevelDifference, skillTreeScrollStepX, skillTreeScrollStepY;
public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>(); public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>();
private final FileConfiguration messages; private final FileConfiguration messages;
@ -160,7 +160,6 @@ public class ConfigManager {
canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast"); canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast");
cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp"); cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp");
saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info"); saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info");
maxSkillSlots = MMOCore.plugin.getConfig().getInt("max-skill-slots");
overrideVanillaExp = MMOCore.plugin.getConfig().getBoolean("override-vanilla-exp"); overrideVanillaExp = MMOCore.plugin.getConfig().getBoolean("override-vanilla-exp");
} }

View File

@ -0,0 +1,42 @@
package net.Indyuce.mmocore.util;
import net.Indyuce.mmocore.MMOCore;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.logging.Level;
public class ConfigUtils {
public static <T> void iterateConfigSectionList(@NotNull ConfigurationSection config,
@NotNull List<T> list,
@NotNull Function<ConfigurationSection, T> subconfigHandler,
@NotNull Function<Integer, T> fill,
@NotNull BiConsumer<String, RuntimeException> errorHandler) {
int expectedOrdinal = 1;
for (String key : config.getKeys(false))
try {
final int index = Integer.parseInt(key);
final ConfigurationSection subconfig = config.getConfigurationSection(key);
Validate.notNull(subconfig, "Not a configuration section");
MMOCore.plugin.getLogger().log(Level.INFO, "Received " + index);
// Replace
if (index < expectedOrdinal) list.set(index, subconfigHandler.apply(subconfig));
else {
while (expectedOrdinal < index)
list.add(fill.apply(expectedOrdinal++));
list.add(subconfigHandler.apply(subconfig));
expectedOrdinal++;
}
} catch (RuntimeException exception) {
errorHandler.accept(key, exception);
}
}
}

View File

@ -229,9 +229,6 @@ death-exp-loss:
# Percentage of current EXP you lose when dying. # Percentage of current EXP you lose when dying.
percent: 30 percent: 30
# 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 true, passive skills must be bound in order to take effect.
# When set to false, unlocked skills will take effect right away. # 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 # This is only the default behavior for skills but can be overridden by specifying true/false to