Fixed permanent skills not triggering when locked/unlocked

This commit is contained in:
Jules 2024-05-09 18:01:36 -07:00
parent 952b543b45
commit 3df5676304
13 changed files with 128 additions and 77 deletions

View File

@ -207,8 +207,6 @@ public class MMOCore extends MMOPlugin {
if (Bukkit.getPluginManager().getPlugin("MMOMana") != null) {
getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "MMOCore is not meant to be used with MMOItems ManaAndStamina");
getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "Please read the installation guide!");
Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] MMOCore is not meant to be used with MMOItems ManaAndStamina");
Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] Please read the installation guide!");
return;
}

View File

@ -393,11 +393,11 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
*/
public boolean unlock(Unlockable unlockable) {
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot unlock an item unlocked by default");
unlockable.whenUnlocked(this);
final boolean wasLocked = unlockedItems.add(unlockable.getUnlockNamespacedKey());
// Call the event synchronously
if (wasLocked)
if (wasLocked) {
unlockable.whenUnlocked(this);
Bukkit.getScheduler().runTask(MythicLib.plugin, () -> Bukkit.getPluginManager().callEvent(new ItemUnlockedEvent(this, unlockable.getUnlockNamespacedKey())));
}
return wasLocked;
}
@ -409,11 +409,11 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
*/
public boolean lock(Unlockable unlockable) {
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot lock an item unlocked by default");
unlockable.whenLocked(this);
boolean wasUnlocked = unlockedItems.remove(unlockable.getUnlockNamespacedKey());
if (wasUnlocked)
//Calls the event synchronously
if (wasUnlocked) {
unlockable.whenLocked(this);
Bukkit.getScheduler().runTask(MythicLib.plugin, () -> Bukkit.getPluginManager().callEvent(new ItemLockedEvent(this, unlockable.getUnlockNamespacedKey())));
}
return wasUnlocked;
}
@ -1224,19 +1224,37 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
Validate.notNull(skill, "Skill cannot be null");
if (slot <= 0) return;
// Friendly error in case server owner makes a skill permanent while players have already bound it
if (skill.isPermanent()) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Attempted to bind permanent skill " + skill.getSkill().getName() + " to player " + getUniqueId());
return;
}
// Unbinds the previous skill (important for passive skills)
unbindSkill(slot);
final SkillSlot skillSlot = getProfess().getSkillSlot(slot);
boundSkills.put(slot, new BoundSkillInfo(skillSlot, skill, this));
}
public void unbindSkill(int slot) {
@Nullable
public BoundSkillInfo unbindSkill(int slot) {
final @Nullable BoundSkillInfo boundSkillInfo = boundSkills.remove(slot);
if (boundSkillInfo != null) boundSkillInfo.close();
return boundSkillInfo;
}
public List<ClassSkill> getBoundSkills() {
return boundSkills.values().stream().map(BoundSkillInfo::getClassSkill).collect(Collectors.toList());
@NotNull
public Map<Integer, BoundSkillInfo> getBoundSkills() {
return boundSkills;
}
/**
* @return If the player has at least one active skill bound
*/
public boolean hasActiveSkillBound() {
for (BoundSkillInfo bound : boundSkills.values())
if (!bound.isPassive()) return true;
return false;
}
@NotNull

View File

@ -103,10 +103,9 @@ public class PlayerStats {
// Updates the player's unbindable CLASS passive skills
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
skillMap.removeModifiers("MMOCorePassiveSkillNotBound");
skillMap.removeModifiers("MMOCorePermanentSkill");
for (ClassSkill skill : data.getProfess().getSkills())
if (!skill.needsBound()
&& skill.getSkill().getTrigger().isPassive()
if (skill.isPermanent()
&& skill.getSkill().getTrigger() != TriggerType.LOGIN
&& data.hasUnlocked(skill)
&& data.hasUnlockedLevel(skill))

View File

@ -23,14 +23,12 @@ public class UnlockSkillTrigger extends Trigger implements Removable {
@Override
public void apply(PlayerData playerData) {
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null)
playerData.unlock(found);
if (found != null) playerData.unlock(found);
}
@Override
public void remove(PlayerData playerData) {
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null)
playerData.lock(found);
if (found != null) playerData.lock(found);
}
}

View File

@ -13,26 +13,23 @@ public class UnlockSlotTrigger extends Trigger implements Removable {
public UnlockSlotTrigger(MMOLineConfig config) {
super(config);
config.validateKeys("slot");
try {
slot = Integer.parseInt(config.getString("slot"));
}catch(NumberFormatException e){
throw new IllegalArgumentException("The slot should be a number");
} catch (NumberFormatException exception) {
throw new IllegalArgumentException("Slot should be a number");
}
Validate.isTrue(slot > 0, "Slot number must be positive");
}
@Override
public void apply(PlayerData player) {
final SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
if (!player.hasUnlocked(skillSlot))
player.unlock(skillSlot);
player.unlock(player.getProfess().getSkillSlot(slot));
}
@Override
public void remove(PlayerData player) {
final SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
if (player.hasUnlocked(skillSlot))
player.lock(skillSlot);
player.lock(player.getProfess().getSkillSlot(slot));
}
}

View File

@ -77,7 +77,7 @@ public class SkillCommandTreeNode extends CommandTreeNode {
}
int value = change.apply(playerData.getSkillLevel(skill), amount);
playerData.setSkillLevel(skill, value);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + player.getName() + ChatColor.YELLOW
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + player.getName() + ChatColor.YELLOW
+ " is now level " + ChatColor.GOLD + value + ChatColor.YELLOW + " for " + skill.getName() + ".");
return CommandResult.SUCCESS;
}
@ -100,31 +100,31 @@ public class SkillCommandTreeNode extends CommandTreeNode {
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] + ".");
sender.sendMessage(ChatColor.RED + "Could not find player called " + args[3] + ".");
return CommandResult.FAILURE;
}
PlayerData playerData = PlayerData.get(player);
ClassSkill skill = playerData.getProfess().getSkill(args[4]);
if (skill == null) {
sender.sendMessage(ChatColor.RED + "The player's class doesn't have a skill called " + args[4] + ".");
sender.sendMessage(ChatColor.RED + "Class doesn't have a skill called " + args[4] + ".");
return CommandResult.FAILURE;
}
if (lock) {
if (!playerData.hasUnlocked(skill)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill " + skill.getSkill().getName() + " is already locked" + " for " + player.getName());
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "Skill " + skill.getSkill().getName() + " already locked for " + player.getName());
return CommandResult.SUCCESS;
}
playerData.lock(skill);
} else {
if (playerData.hasUnlocked(skill)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill " + skill.getSkill().getName() + " is already unlocked" + " for " + player.getName());
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "Skill " + skill.getSkill().getName() + " already unlocked for " + player.getName());
return CommandResult.SUCCESS;
}
playerData.unlock(skill);
}
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill " + skill.getSkill().getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName()));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + "Skill " + ChatColor.GOLD + skill.getSkill().getName() + ChatColor.YELLOW + " now " + (lock ? "locked" : "unlocked") + " for " + ChatColor.GOLD + player.getName());
return CommandResult.SUCCESS;
}
}

View File

@ -4,6 +4,7 @@ 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.skill.binding.BoundSkillInfo;
import net.Indyuce.mmocore.skill.binding.SkillSlot;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import net.Indyuce.mmocore.skill.ClassSkill;
@ -54,7 +55,7 @@ public class SlotCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
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.");
return CommandResult.FAILURE;
}
@ -72,7 +73,7 @@ public class SlotCommandTreeNode extends CommandTreeNode {
}
playerData.unlock(skillSlot);
}
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill slot " + skillSlot.getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName()));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + "The skill slot " + skillSlot.getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName()));
return CommandResult.SUCCESS;
}
}
@ -113,7 +114,7 @@ public class SlotCommandTreeNode extends CommandTreeNode {
}
playerData.bindSkill(slot, skill);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill " + skill.getSkill().getHandler().getId() + " is now bound to the slot " + slot);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + "Skill " + ChatColor.GOLD + skill.getSkill().getHandler().getId() + ChatColor.YELLOW + " now bound to slot " + ChatColor.GOLD + slot);
return CommandResult.SUCCESS;
}
}
@ -143,11 +144,10 @@ public class SlotCommandTreeNode extends CommandTreeNode {
sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
return CommandResult.FAILURE;
}
String skill = playerData.hasSkillBound(slot) ? playerData.getBoundSkill(slot).getSkill().getHandler().getId() : "none";
if (playerData.hasSkillBound(slot))
playerData.unbindSkill(slot);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill " + skill + " has been unbounded from the slot " + slot);
final BoundSkillInfo found = playerData.unbindSkill(slot);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + (found != null ?
"Skill " + ChatColor.GOLD + found.getClassSkill().getSkill().getName() + ChatColor.YELLOW + " was taken off the slot " + ChatColor.GOLD + slot :
"Could not find skill at slot " + ChatColor.GOLD + slot));
return CommandResult.SUCCESS;
}
}

View File

@ -19,7 +19,7 @@ import java.util.*;
public class ClassSkill implements CooldownObject, Unlockable {
private final RegisteredSkill skill;
private final int unlockLevel, maxSkillLevel;
private final boolean unlockedByDefault, needsBinding, upgradable;
private final boolean unlockedByDefault, permanent, upgradable;
private final Map<String, LinearValue> parameters = new HashMap<>();
public ClassSkill(RegisteredSkill skill, int unlockLevel, int maxSkillLevel) {
@ -48,7 +48,7 @@ public class ClassSkill implements CooldownObject, Unlockable {
this.unlockLevel = unlockLevel;
this.maxSkillLevel = maxSkillLevel;
this.unlockedByDefault = unlockedByDefault;
this.needsBinding = needsBinding;
this.permanent = !needsBinding && skill.getTrigger().isPassive();
this.upgradable = upgradable;
for (String param : skill.getHandler().getParameters())
this.parameters.put(param, skill.getParameterInfo(param));
@ -59,7 +59,7 @@ public class ClassSkill implements CooldownObject, Unlockable {
unlockLevel = config.getInt("level");
maxSkillLevel = config.getInt("max-level");
unlockedByDefault = config.getBoolean("unlocked-by-default", true);
needsBinding = config.getBoolean("needs-bound", MMOCore.plugin.configManager.passiveSkillsNeedBinding);
permanent = !config.getBoolean("needs-bound", MMOCore.plugin.configManager.passiveSkillsNeedBinding) && skill.getTrigger().isPassive();
upgradable = config.getBoolean("upgradable", true);
for (String param : skill.getHandler().getParameters()) {
LinearValue defaultValue = skill.getParameterInfo(param);
@ -93,8 +93,18 @@ public class ClassSkill implements CooldownObject, Unlockable {
return unlockedByDefault;
}
@Deprecated
public boolean needsBound() {
return needsBinding;
return !isPermanent();
}
/**
* @return Permanent skills are passive skills which do
* not have to be bound in order to apply their effects.
* Permanent skills can only be passive skills.
*/
public boolean isPermanent() {
return permanent;
}
@Override
@ -104,20 +114,22 @@ public class ClassSkill implements CooldownObject, Unlockable {
@Override
public void whenLocked(PlayerData playerData) {
playerData.mapBoundSkills().forEach((slot, skill) -> {
if (skill.equalsIgnoreCase(getUnlockNamespacedKey().split(":")[1]))
// Unbind the skill if necessary
new HashMap<>(playerData.getBoundSkills()).forEach((slot, bound) -> {
if (this.equals(bound.getClassSkill()))
playerData.unbindSkill(slot);
});
// Update the stats to remove the passive skill if it is locked
if (!needsBinding && getSkill().getTrigger().isPassive())
playerData.getStats().updateStats();
// Update stats to flush permanent skill
if (isPermanent()) playerData.getStats().updateStats();
}
@Override
public void whenUnlocked(PlayerData playerData) {
if (!needsBinding && getSkill().getTrigger().isPassive())
playerData.getStats().updateStats();
// Update stats to register permanent skill
if (isPermanent()) playerData.getStats().updateStats();
}
@ -138,7 +150,6 @@ public class ClassSkill implements CooldownObject, Unlockable {
parameters.put(parameter, linear);
}
/**
* Skill modifiers are now called parameters.
*/
@ -190,10 +201,10 @@ public class ClassSkill implements CooldownObject, Unlockable {
* is called. It needs to be saved somewhere when trying to
* unregister the passive skill from the skill map later on.
*/
@NotNull
public PassiveSkill toPassive(PlayerData caster) {
Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active");
//MMOCorePassiveSkillNotBound to identify passive skills that don't need to be bound
return new PassiveSkill("MMOCorePassiveSkill" + (!needsBinding ? "NotBound" : ""), toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER);
return new PassiveSkill("MMOCore" + (permanent ? "Permanent" : "Passive") + "Skill", toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER);
}
@Override

View File

@ -33,7 +33,7 @@ public class BoundSkillInfo implements Closeable {
if (skillModifierTrigger.getTargetSkills().contains(classSkill.getSkill().getHandler()))
skillModifierTrigger.apply(playerData, classSkill.getSkill().getHandler());
if (classSkill.getSkill().getTrigger().isPassive() && classSkill.needsBound()) {
if (classSkill.getSkill().getTrigger().isPassive() && !classSkill.isPermanent()) {
registered = classSkill.toPassive(playerData);
registered.register(playerData.getMMOPlayerData());
} else registered = null;
@ -64,7 +64,7 @@ public class BoundSkillInfo implements Closeable {
open = false;
// Unregister skill if passive
if (isPassive()&& classSkill.needsBound()) registered.unregister(playerData.getMMOPlayerData());
if (registered != null) registered.unregister(playerData.getMMOPlayerData());
// Remove skill buffs associated to the slot
skillSlot.getSkillModifierTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(playerData, classSkill.getSkill().getHandler()));

View File

@ -1,7 +1,9 @@
package net.Indyuce.mmocore.skill.cast;
import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.binding.BoundSkillInfo;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
@ -9,11 +11,20 @@ import org.bukkit.event.Listener;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
public abstract class SkillCastingInstance extends BukkitRunnable implements Listener {
private final PlayerData caster;
private final SkillCastingHandler handler;
private final int runnablePeriod = 10; // Hard coded
private static final int RUNNABLE_PERIOD = 10;
/**
* This variable temporarily stores the active skills that the player
* can try to cast.
*/
private List<BoundSkillInfo> activeSkills;
private boolean open = true;
private int j, sinceLastActivity;
@ -45,11 +56,18 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis
sinceLastActivity = 0;
}
@NotNull
public List<BoundSkillInfo> getActiveSkills() {
if (activeSkills == null)
activeSkills = caster.getBoundSkills().values().stream().filter(bound -> !bound.isPassive()).collect(Collectors.toList());
return activeSkills;
}
private static final int PARTICLES_PER_TICK = 2;
@Override
public void run() {
if (!caster.isOnline() || caster.getPlayer().isDead() || caster.getBoundSkills().isEmpty()) {
if (UtilityMethods.isInvalidated(caster.getMMOPlayerData()) || !caster.hasActiveSkillBound()) {
caster.leaveSkillCasting(true);
return;
}
@ -67,7 +85,10 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis
}
// Apply casting mode-specific effects
if (j++ % runnablePeriod == 0) onTick();
if (j++ % RUNNABLE_PERIOD == 0) {
activeSkills = null;
onTick();
}
}
public abstract void onTick();

View File

@ -74,7 +74,7 @@ public class KeyCombos extends SkillCastingHandler {
if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast) return;
// Don't start combos if no skills are bound
if (playerData.getBoundSkills().isEmpty()) return;
if (!playerData.hasActiveSkillBound()) return;
// Start combo when there is an initializer key
if (!event.getData().isCasting() && initializerKey != null) {

View File

@ -10,6 +10,7 @@ import net.Indyuce.mmocore.api.SoundEvent;
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.binding.BoundSkillInfo;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
@ -57,7 +58,10 @@ public class SkillBar extends SkillCastingHandler {
// 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())
if (player.getGameMode() != GameMode.SPECTATOR
&& (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE)
&& !playerData.isCasting()
&& playerData.hasActiveSkillBound())
if (playerData.setSkillCasting())
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
}
@ -92,16 +96,17 @@ public class SkillBar extends SkillCastingHandler {
event.setCancelled(true);
refreshTimeOut();
final int slot = event.getNewSlot() + 1 + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
final int activeSlot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
/*
* The event is called again soon after the first since when
* cancelling the first one, the player held item slot must go back
* to the previous one.
*/
if (slot >= 1 && getCaster().hasSkillBound(slot)) {
if (activeSlot < getActiveSkills().size()) {
final ClassSkill classSkill = getActiveSkills().get(activeSlot).getClassSkill();
final PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null));
classSkill.toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null));
}
}
@ -121,18 +126,22 @@ public class SkillBar extends SkillCastingHandler {
}
}
@NotNull
private String getFormat(PlayerData data) {
final StringBuilder str = new StringBuilder();
if (!data.isOnline()) return str.toString();
for (int slot : data.mapBoundSkills().keySet()) {
final ClassSkill skill = data.getBoundSkill(slot);
if (skill.getSkill().getTrigger().isPassive()) continue;
str.append(str.isEmpty() ? "" : 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}",
String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0)))
.replace("{skill}", data.getBoundSkill(slot).getSkill().getName()));
int slot = 1;
for (BoundSkillInfo active : getActiveSkills()) {
final ClassSkill skill = active.getClassSkill();
str.append(str.isEmpty() ? "" : 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}", String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0)))
.replace("{skill}", skill.getSkill().getName()));
slot++;
}
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());
}

View File

@ -83,7 +83,7 @@ public class SkillScroller extends SkillCastingHandler {
}
// Check if there are skills bound
if (playerData.getBoundSkills().isEmpty()) return;
if (!playerData.hasActiveSkillBound()) return;
// Cancel event if necessary
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
@ -120,7 +120,7 @@ public class SkillScroller extends SkillCastingHandler {
}
public ClassSkill getSelected() {
return getCaster().getBoundSkill(index + 1);
return getActiveSkills().get(index).getClassSkill();
}
@EventHandler
@ -128,7 +128,7 @@ public class SkillScroller extends SkillCastingHandler {
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
PlayerData playerData = PlayerData.get(event.getPlayer());
if (playerData.getBoundSkills().isEmpty()) {
if (!playerData.hasActiveSkillBound()) {
playerData.leaveSkillCasting(true);
return;
}
@ -139,9 +139,9 @@ public class SkillScroller extends SkillCastingHandler {
final int dist1 = 9 + current - previous, dist2 = current - previous, dist3 = current - previous - 9;
final int change = Math.abs(dist1) < Math.abs(dist2) ? (Math.abs(dist1) < Math.abs(dist3) ? dist1 : dist3) : (Math.abs(dist3) < Math.abs(dist2) ? dist3 : dist2);
// Scroll trough items
// Scroll through items
final CustomSkillCastingInstance casting = (CustomSkillCastingInstance) playerData.getSkillCasting();
casting.index = mod(casting.index + change, playerData.getBoundSkills().size());
casting.index = mod(casting.index + change, getActiveSkills().size());
casting.onTick();
casting.refreshTimeOut();