forked from Upstream/mmocore
Fixed permanent skills not triggering when locked/unlocked
This commit is contained in:
parent
952b543b45
commit
3df5676304
@ -207,8 +207,6 @@ public class MMOCore extends MMOPlugin {
|
|||||||
if (Bukkit.getPluginManager().getPlugin("MMOMana") != null) {
|
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 + "MMOCore is not meant to be used with MMOItems ManaAndStamina");
|
||||||
getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "Please read the installation guide!");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,11 +393,11 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
*/
|
*/
|
||||||
public boolean unlock(Unlockable unlockable) {
|
public boolean unlock(Unlockable unlockable) {
|
||||||
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot unlock an item unlocked by default");
|
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot unlock an item unlocked by default");
|
||||||
unlockable.whenUnlocked(this);
|
|
||||||
final boolean wasLocked = unlockedItems.add(unlockable.getUnlockNamespacedKey());
|
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())));
|
Bukkit.getScheduler().runTask(MythicLib.plugin, () -> Bukkit.getPluginManager().callEvent(new ItemUnlockedEvent(this, unlockable.getUnlockNamespacedKey())));
|
||||||
|
}
|
||||||
return wasLocked;
|
return wasLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,11 +409,11 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
*/
|
*/
|
||||||
public boolean lock(Unlockable unlockable) {
|
public boolean lock(Unlockable unlockable) {
|
||||||
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot lock an item unlocked by default");
|
Validate.isTrue(!unlockable.isUnlockedByDefault(), "Cannot lock an item unlocked by default");
|
||||||
unlockable.whenLocked(this);
|
|
||||||
boolean wasUnlocked = unlockedItems.remove(unlockable.getUnlockNamespacedKey());
|
boolean wasUnlocked = unlockedItems.remove(unlockable.getUnlockNamespacedKey());
|
||||||
if (wasUnlocked)
|
if (wasUnlocked) {
|
||||||
//Calls the event synchronously
|
unlockable.whenLocked(this);
|
||||||
Bukkit.getScheduler().runTask(MythicLib.plugin, () -> Bukkit.getPluginManager().callEvent(new ItemLockedEvent(this, unlockable.getUnlockNamespacedKey())));
|
Bukkit.getScheduler().runTask(MythicLib.plugin, () -> Bukkit.getPluginManager().callEvent(new ItemLockedEvent(this, unlockable.getUnlockNamespacedKey())));
|
||||||
|
}
|
||||||
return wasUnlocked;
|
return wasUnlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1224,19 +1224,37 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
Validate.notNull(skill, "Skill cannot be null");
|
Validate.notNull(skill, "Skill cannot be null");
|
||||||
if (slot <= 0) return;
|
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)
|
// Unbinds the previous skill (important for passive skills)
|
||||||
unbindSkill(slot);
|
unbindSkill(slot);
|
||||||
final SkillSlot skillSlot = getProfess().getSkillSlot(slot);
|
final SkillSlot skillSlot = getProfess().getSkillSlot(slot);
|
||||||
boundSkills.put(slot, new BoundSkillInfo(skillSlot, skill, this));
|
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);
|
final @Nullable BoundSkillInfo boundSkillInfo = boundSkills.remove(slot);
|
||||||
if (boundSkillInfo != null) boundSkillInfo.close();
|
if (boundSkillInfo != null) boundSkillInfo.close();
|
||||||
|
return boundSkillInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ClassSkill> getBoundSkills() {
|
@NotNull
|
||||||
return boundSkills.values().stream().map(BoundSkillInfo::getClassSkill).collect(Collectors.toList());
|
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
|
@NotNull
|
||||||
|
@ -103,10 +103,9 @@ public class PlayerStats {
|
|||||||
|
|
||||||
// Updates the player's unbindable CLASS passive skills
|
// Updates the player's unbindable CLASS passive skills
|
||||||
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
|
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
|
||||||
skillMap.removeModifiers("MMOCorePassiveSkillNotBound");
|
skillMap.removeModifiers("MMOCorePermanentSkill");
|
||||||
for (ClassSkill skill : data.getProfess().getSkills())
|
for (ClassSkill skill : data.getProfess().getSkills())
|
||||||
if (!skill.needsBound()
|
if (skill.isPermanent()
|
||||||
&& skill.getSkill().getTrigger().isPassive()
|
|
||||||
&& skill.getSkill().getTrigger() != TriggerType.LOGIN
|
&& skill.getSkill().getTrigger() != TriggerType.LOGIN
|
||||||
&& data.hasUnlocked(skill)
|
&& data.hasUnlocked(skill)
|
||||||
&& data.hasUnlockedLevel(skill))
|
&& data.hasUnlockedLevel(skill))
|
||||||
|
@ -23,14 +23,12 @@ public class UnlockSkillTrigger extends Trigger implements Removable {
|
|||||||
@Override
|
@Override
|
||||||
public void apply(PlayerData playerData) {
|
public void apply(PlayerData playerData) {
|
||||||
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
|
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
|
||||||
if (found != null)
|
if (found != null) playerData.unlock(found);
|
||||||
playerData.unlock(found);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(PlayerData playerData) {
|
public void remove(PlayerData playerData) {
|
||||||
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
|
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
|
||||||
if (found != null)
|
if (found != null) playerData.lock(found);
|
||||||
playerData.lock(found);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,26 +13,23 @@ public class UnlockSlotTrigger extends Trigger implements Removable {
|
|||||||
|
|
||||||
public UnlockSlotTrigger(MMOLineConfig config) {
|
public UnlockSlotTrigger(MMOLineConfig config) {
|
||||||
super(config);
|
super(config);
|
||||||
|
|
||||||
config.validateKeys("slot");
|
config.validateKeys("slot");
|
||||||
try {
|
try {
|
||||||
slot = Integer.parseInt(config.getString("slot"));
|
slot = Integer.parseInt(config.getString("slot"));
|
||||||
}catch(NumberFormatException e){
|
} catch (NumberFormatException exception) {
|
||||||
throw new IllegalArgumentException("The slot should be a number");
|
throw new IllegalArgumentException("Slot should be a number");
|
||||||
}
|
}
|
||||||
Validate.isTrue(slot > 0, "Slot number must be positive");
|
Validate.isTrue(slot > 0, "Slot number must be positive");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(PlayerData player) {
|
public void apply(PlayerData player) {
|
||||||
final SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
|
player.unlock(player.getProfess().getSkillSlot(slot));
|
||||||
if (!player.hasUnlocked(skillSlot))
|
|
||||||
player.unlock(skillSlot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(PlayerData player) {
|
public void remove(PlayerData player) {
|
||||||
final SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
|
player.lock(player.getProfess().getSkillSlot(slot));
|
||||||
if (player.hasUnlocked(skillSlot))
|
|
||||||
player.lock(skillSlot);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class SkillCommandTreeNode extends CommandTreeNode {
|
|||||||
}
|
}
|
||||||
int value = change.apply(playerData.getSkillLevel(skill), amount);
|
int value = change.apply(playerData.getSkillLevel(skill), amount);
|
||||||
playerData.setSkillLevel(skill, value);
|
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() + ".");
|
+ " is now level " + ChatColor.GOLD + value + ChatColor.YELLOW + " for " + skill.getName() + ".");
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
@ -100,31 +100,31 @@ public class SkillCommandTreeNode extends CommandTreeNode {
|
|||||||
return CommandResult.THROW_USAGE;
|
return CommandResult.THROW_USAGE;
|
||||||
Player player = Bukkit.getPlayer(args[3]);
|
Player player = Bukkit.getPlayer(args[3]);
|
||||||
if (player == null) {
|
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;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
PlayerData playerData = PlayerData.get(player);
|
PlayerData playerData = PlayerData.get(player);
|
||||||
|
|
||||||
ClassSkill skill = playerData.getProfess().getSkill(args[4]);
|
ClassSkill skill = playerData.getProfess().getSkill(args[4]);
|
||||||
if (skill == null) {
|
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;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
if (lock) {
|
if (lock) {
|
||||||
if (!playerData.hasUnlocked(skill)) {
|
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;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
playerData.lock(skill);
|
playerData.lock(skill);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (playerData.hasUnlocked(skill)) {
|
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;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
playerData.unlock(skill);
|
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;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.command.api.CommandTreeNode;
|
|||||||
import io.lumine.mythic.lib.command.api.Parameter;
|
import io.lumine.mythic.lib.command.api.Parameter;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
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.skill.binding.SkillSlot;
|
||||||
import net.Indyuce.mmocore.command.api.CommandVerbose;
|
import net.Indyuce.mmocore.command.api.CommandVerbose;
|
||||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||||
@ -54,7 +55,7 @@ public class SlotCommandTreeNode extends CommandTreeNode {
|
|||||||
return CommandResult.FAILURE;
|
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.");
|
||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
@ -72,7 +73,7 @@ public class SlotCommandTreeNode extends CommandTreeNode {
|
|||||||
}
|
}
|
||||||
playerData.unlock(skillSlot);
|
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;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,7 +114,7 @@ public class SlotCommandTreeNode extends CommandTreeNode {
|
|||||||
}
|
}
|
||||||
playerData.bindSkill(slot, skill);
|
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;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,11 +144,10 @@ public class SlotCommandTreeNode extends CommandTreeNode {
|
|||||||
sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
|
sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
|
||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
String skill = playerData.hasSkillBound(slot) ? playerData.getBoundSkill(slot).getSkill().getHandler().getId() : "none";
|
final BoundSkillInfo found = playerData.unbindSkill(slot);
|
||||||
if (playerData.hasSkillBound(slot))
|
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + (found != null ?
|
||||||
playerData.unbindSkill(slot);
|
"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));
|
||||||
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill " + skill + " has been unbounded from the slot " + slot);
|
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import java.util.*;
|
|||||||
public class ClassSkill implements CooldownObject, Unlockable {
|
public class ClassSkill implements CooldownObject, Unlockable {
|
||||||
private final RegisteredSkill skill;
|
private final RegisteredSkill skill;
|
||||||
private final int unlockLevel, maxSkillLevel;
|
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<>();
|
private final Map<String, LinearValue> parameters = new HashMap<>();
|
||||||
|
|
||||||
public ClassSkill(RegisteredSkill skill, int unlockLevel, int maxSkillLevel) {
|
public ClassSkill(RegisteredSkill skill, int unlockLevel, int maxSkillLevel) {
|
||||||
@ -48,7 +48,7 @@ public class ClassSkill implements CooldownObject, Unlockable {
|
|||||||
this.unlockLevel = unlockLevel;
|
this.unlockLevel = unlockLevel;
|
||||||
this.maxSkillLevel = maxSkillLevel;
|
this.maxSkillLevel = maxSkillLevel;
|
||||||
this.unlockedByDefault = unlockedByDefault;
|
this.unlockedByDefault = unlockedByDefault;
|
||||||
this.needsBinding = needsBinding;
|
this.permanent = !needsBinding && skill.getTrigger().isPassive();
|
||||||
this.upgradable = upgradable;
|
this.upgradable = upgradable;
|
||||||
for (String param : skill.getHandler().getParameters())
|
for (String param : skill.getHandler().getParameters())
|
||||||
this.parameters.put(param, skill.getParameterInfo(param));
|
this.parameters.put(param, skill.getParameterInfo(param));
|
||||||
@ -59,7 +59,7 @@ public class ClassSkill implements CooldownObject, Unlockable {
|
|||||||
unlockLevel = config.getInt("level");
|
unlockLevel = config.getInt("level");
|
||||||
maxSkillLevel = config.getInt("max-level");
|
maxSkillLevel = config.getInt("max-level");
|
||||||
unlockedByDefault = config.getBoolean("unlocked-by-default", true);
|
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);
|
upgradable = config.getBoolean("upgradable", true);
|
||||||
for (String param : skill.getHandler().getParameters()) {
|
for (String param : skill.getHandler().getParameters()) {
|
||||||
LinearValue defaultValue = skill.getParameterInfo(param);
|
LinearValue defaultValue = skill.getParameterInfo(param);
|
||||||
@ -93,8 +93,18 @@ public class ClassSkill implements CooldownObject, Unlockable {
|
|||||||
return unlockedByDefault;
|
return unlockedByDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public boolean needsBound() {
|
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
|
@Override
|
||||||
@ -104,20 +114,22 @@ public class ClassSkill implements CooldownObject, Unlockable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void whenLocked(PlayerData playerData) {
|
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);
|
playerData.unbindSkill(slot);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the stats to remove the passive skill if it is locked
|
// Update stats to flush permanent skill
|
||||||
if (!needsBinding && getSkill().getTrigger().isPassive())
|
if (isPermanent()) playerData.getStats().updateStats();
|
||||||
playerData.getStats().updateStats();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void whenUnlocked(PlayerData playerData) {
|
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);
|
parameters.put(parameter, linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skill modifiers are now called parameters.
|
* 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
|
* is called. It needs to be saved somewhere when trying to
|
||||||
* unregister the passive skill from the skill map later on.
|
* unregister the passive skill from the skill map later on.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
public PassiveSkill toPassive(PlayerData caster) {
|
public PassiveSkill toPassive(PlayerData caster) {
|
||||||
Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active");
|
Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active");
|
||||||
//MMOCorePassiveSkillNotBound to identify passive skills that don't need to be bound
|
return new PassiveSkill("MMOCore" + (permanent ? "Permanent" : "Passive") + "Skill", toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER);
|
||||||
return new PassiveSkill("MMOCorePassiveSkill" + (!needsBinding ? "NotBound" : ""), toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,7 +33,7 @@ public class BoundSkillInfo implements Closeable {
|
|||||||
if (skillModifierTrigger.getTargetSkills().contains(classSkill.getSkill().getHandler()))
|
if (skillModifierTrigger.getTargetSkills().contains(classSkill.getSkill().getHandler()))
|
||||||
skillModifierTrigger.apply(playerData, 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 = classSkill.toPassive(playerData);
|
||||||
registered.register(playerData.getMMOPlayerData());
|
registered.register(playerData.getMMOPlayerData());
|
||||||
} else registered = null;
|
} else registered = null;
|
||||||
@ -64,7 +64,7 @@ public class BoundSkillInfo implements Closeable {
|
|||||||
open = false;
|
open = false;
|
||||||
|
|
||||||
// Unregister skill if passive
|
// 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
|
// Remove skill buffs associated to the slot
|
||||||
skillSlot.getSkillModifierTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(playerData, classSkill.getSkill().getHandler()));
|
skillSlot.getSkillModifierTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(playerData, classSkill.getSkill().getHandler()));
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package net.Indyuce.mmocore.skill.cast;
|
package net.Indyuce.mmocore.skill.cast;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.UtilityMethods;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.skill.binding.BoundSkillInfo;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
@ -9,11 +11,20 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class SkillCastingInstance extends BukkitRunnable implements Listener {
|
public abstract class SkillCastingInstance extends BukkitRunnable implements Listener {
|
||||||
private final PlayerData caster;
|
private final PlayerData caster;
|
||||||
private final SkillCastingHandler handler;
|
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 boolean open = true;
|
||||||
private int j, sinceLastActivity;
|
private int j, sinceLastActivity;
|
||||||
|
|
||||||
@ -45,11 +56,18 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis
|
|||||||
sinceLastActivity = 0;
|
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;
|
private static final int PARTICLES_PER_TICK = 2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!caster.isOnline() || caster.getPlayer().isDead() || caster.getBoundSkills().isEmpty()) {
|
if (UtilityMethods.isInvalidated(caster.getMMOPlayerData()) || !caster.hasActiveSkillBound()) {
|
||||||
caster.leaveSkillCasting(true);
|
caster.leaveSkillCasting(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -67,7 +85,10 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply casting mode-specific effects
|
// Apply casting mode-specific effects
|
||||||
if (j++ % runnablePeriod == 0) onTick();
|
if (j++ % RUNNABLE_PERIOD == 0) {
|
||||||
|
activeSkills = null;
|
||||||
|
onTick();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onTick();
|
public abstract void onTick();
|
||||||
|
@ -74,7 +74,7 @@ public class KeyCombos extends SkillCastingHandler {
|
|||||||
if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast) return;
|
if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast) return;
|
||||||
|
|
||||||
// Don't start combos if no skills are bound
|
// 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
|
// Start combo when there is an initializer key
|
||||||
if (!event.getData().isCasting() && initializerKey != null) {
|
if (!event.getData().isCasting() && initializerKey != null) {
|
||||||
|
@ -10,6 +10,7 @@ import net.Indyuce.mmocore.api.SoundEvent;
|
|||||||
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
|
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
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.PlayerKey;
|
||||||
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
||||||
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
||||||
@ -57,7 +58,10 @@ public class SkillBar extends SkillCastingHandler {
|
|||||||
|
|
||||||
// Enter spell casting
|
// Enter spell casting
|
||||||
final PlayerData playerData = event.getData();
|
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())
|
if (playerData.setSkillCasting())
|
||||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
|
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
|
||||||
}
|
}
|
||||||
@ -92,16 +96,17 @@ public class SkillBar extends SkillCastingHandler {
|
|||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
refreshTimeOut();
|
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
|
* The event is called again soon after the first since when
|
||||||
* cancelling the first one, the player held item slot must go back
|
* cancelling the first one, the player held item slot must go back
|
||||||
* to the previous one.
|
* 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);
|
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) {
|
private String getFormat(PlayerData data) {
|
||||||
final StringBuilder str = new StringBuilder();
|
final StringBuilder str = new StringBuilder();
|
||||||
if (!data.isOnline()) return str.toString();
|
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}",
|
int slot = 1;
|
||||||
String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
|
for (BoundSkillInfo active : getActiveSkills()) {
|
||||||
data, skill) ? noStamina : ready)).replace("{index}",
|
final ClassSkill skill = active.getClassSkill();
|
||||||
String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0)))
|
|
||||||
.replace("{skill}", data.getBoundSkill(slot).getSkill().getName()));
|
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());
|
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ public class SkillScroller extends SkillCastingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if there are skills bound
|
// Check if there are skills bound
|
||||||
if (playerData.getBoundSkills().isEmpty()) return;
|
if (!playerData.hasActiveSkillBound()) return;
|
||||||
|
|
||||||
// Cancel event if necessary
|
// Cancel event if necessary
|
||||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||||
@ -120,7 +120,7 @@ public class SkillScroller extends SkillCastingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ClassSkill getSelected() {
|
public ClassSkill getSelected() {
|
||||||
return getCaster().getBoundSkill(index + 1);
|
return getActiveSkills().get(index).getClassSkill();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -128,7 +128,7 @@ public class SkillScroller extends SkillCastingHandler {
|
|||||||
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
|
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
|
||||||
|
|
||||||
PlayerData playerData = PlayerData.get(event.getPlayer());
|
PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||||
if (playerData.getBoundSkills().isEmpty()) {
|
if (!playerData.hasActiveSkillBound()) {
|
||||||
playerData.leaveSkillCasting(true);
|
playerData.leaveSkillCasting(true);
|
||||||
return;
|
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 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);
|
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();
|
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.onTick();
|
||||||
casting.refreshTimeOut();
|
casting.refreshTimeOut();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user