diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java index 2578bf27..e643fb00 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java @@ -25,7 +25,10 @@ import net.Indyuce.mmocore.player.playerclass.ClassTriggerType; import net.Indyuce.mmocore.player.stats.StatInfo; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; +import net.Indyuce.mmocore.skill.cast.KeyCombo; +import net.Indyuce.mmocore.skill.cast.PlayerKey; import net.md_5.bungee.api.ChatColor; +import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; @@ -54,6 +57,12 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { private final Map skills = new LinkedHashMap<>(); private final List subclasses = new ArrayList<>(); + @Nullable + //If the class redefines its own key combos. + private final HashMap combos= new HashMap<>(); + private int longestCombo; + + @Deprecated private final Map classTriggers = new HashMap<>(); @@ -110,6 +119,26 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { } this.expTable = expTable; + + ConfigurationSection section=config.getConfigurationSection("combos"); + if(section!=null) { + // Load different combos + for (String key : section.getKeys(false)) + try { + int spellSlot = Integer.valueOf(key); + Validate.isTrue(spellSlot >= 0, "Spell slot must be at least 0"); + Validate.isTrue(!combos.values().contains(spellSlot), "There is already a key combo with the same skill slot"); + KeyCombo combo = new KeyCombo(); + for (String str : section.getStringList(key)) + combo.registerKey(PlayerKey.valueOf(UtilityMethods.enumName(str))); + + combos.put(combo, spellSlot); + longestCombo = Math.max(longestCombo, combo.countKeys()); + } catch (RuntimeException exception) { + MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load key combo '" + key + "': " + exception.getMessage()); + } + + } if (config.contains("triggers")) for (String key : config.getConfigurationSection("triggers").getKeys(false)) { try { @@ -323,6 +352,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return eventTriggers.keySet(); } + @Deprecated public boolean hasEventTriggers(String name) { return eventTriggers.containsKey(name); @@ -384,6 +414,15 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return stats.keySet(); } + @Nullable + public HashMap getCombos() { + return combos; + } + + public int getLongestCombo() { + return longestCombo; + } + @NotNull private LinearValue getStatInfo(String stat) { LinearValue found = stats.get(stat); diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index e1ab9e6c..2c4fb192 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -376,15 +376,13 @@ public class SkillList extends EditableInventory { if (item.getFunction().equals("slot")) { int index = slotSlots.indexOf(context.getSlot()); - - // unbind if there is a current spell. +KEy // unbind if there is a current spell. if (context.getClickType() == ClickType.RIGHT) { if (!playerData.hasSkillBound(index)) { MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); return; } - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); playerData.unbindSkill(index); open(); @@ -400,6 +398,7 @@ public class SkillList extends EditableInventory { return; } + if (!playerData.hasSkillUnlocked(selected)) { MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); diff --git a/src/main/java/net/Indyuce/mmocore/listener/event/PlayerPressKeyListener.java b/src/main/java/net/Indyuce/mmocore/listener/event/PlayerPressKeyListener.java index 92afba3b..ef23bbe4 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/event/PlayerPressKeyListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/event/PlayerPressKeyListener.java @@ -13,6 +13,7 @@ import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerSwapHandItemsEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.inventory.EquipmentSlot; /** * This registers all the KeyPress events. All events are registered @@ -32,7 +33,7 @@ public class PlayerPressKeyListener implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void registerClickKey(PlayerInteractEvent event) { - if (event.useItemInHand() != Event.Result.DENY && event.getAction().name().contains("CLICK")) { + if (event.useItemInHand() != Event.Result.DENY && event.getAction().name().contains("CLICK")&&event.getHand().equals(EquipmentSlot.HAND)) { boolean rightClick = event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK; PlayerKeyPressEvent called = new PlayerKeyPressEvent(PlayerData.get(event.getPlayer()), rightClick ? PlayerKey.RIGHT_CLICK : PlayerKey.LEFT_CLICK, event); Bukkit.getPluginManager().callEvent(called); diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java index f59d888d..5c6ef186 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java +++ b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java @@ -15,6 +15,7 @@ import net.Indyuce.mmocore.skill.cast.KeyCombo; import net.Indyuce.mmocore.skill.cast.PlayerKey; import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -49,13 +50,6 @@ public class KeyCombos implements Listener { @Nullable private final SoundObject beginComboSound, comboClickSound, failComboSound; - /** - * Essentially the inverse of the {@link #combos} map. This maps - * the skill slot to the corresponding key combo. There's no problem - * because the maps are 100% bijective - */ - private static final Map PUBLIC_COMBOS = new HashMap<>(); - public KeyCombos(ConfigurationSection config) { int longestCombo = 0; @@ -72,8 +66,6 @@ public class KeyCombos implements Listener { combos.put(combo, spellSlot); longestCombo = Math.max(longestCombo, combo.countKeys()); - - PUBLIC_COMBOS.put(spellSlot, combo); } catch (RuntimeException exception) { MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load key combo '" + key + "': " + exception.getMessage()); } @@ -112,6 +104,7 @@ public class KeyCombos implements Listener { } + // Adding pressed key CustomSkillCastingHandler casting = (CustomSkillCastingHandler) playerData.getSkillCasting(); casting.current.registerKey(event.getPressed()); @@ -123,8 +116,8 @@ public class KeyCombos implements Listener { event.setCancelled(true); // Hash current combo and check - if (combos.containsKey(casting.current)) { - int spellSlot = combos.get(casting.current) - 1; + if (casting.classCombos.containsKey(casting.current)) { + int spellSlot = casting.classCombos.get(casting.current) - 1; playerData.leaveCastingMode(); // Cast spell @@ -136,7 +129,7 @@ public class KeyCombos implements Listener { } // Check if current combo is too large - if (casting.current.countKeys() >= longestCombo) { + if (casting.current.countKeys() >= casting.classLongestCombo) { playerData.leaveCastingMode(); if (failComboSound != null) failComboSound.playTo(player); @@ -167,20 +160,36 @@ public class KeyCombos implements Listener { event.setCancelled(true); } + + /** + * Loads the player current combos & the combos applicable to the player (combos defined in its class or the default combos of the config.yml) + */ private class CustomSkillCastingHandler extends SkillCastingHandler { private final KeyCombo current = new KeyCombo(); + //Combos used: default combos from the config or the combos defined in the player class. + private final Map classCombos; + private int classLongestCombo; CustomSkillCastingHandler(PlayerData caster) { super(caster, 10); + if (!caster.getProfess().getCombos().isEmpty()) { + classCombos=caster.getProfess().getCombos(); + classLongestCombo=caster.getProfess().getLongestCombo(); + } else { + classCombos = combos; + classLongestCombo=longestCombo; + } } @Override public void onTick() { if (actionBarOptions != null) - getCaster().displayActionBar(actionBarOptions.format(current)); + getCaster().displayActionBar(actionBarOptions.format(this)); } + } + private class ActionBarOptions { private final String separator, noKey; @@ -198,18 +207,19 @@ public class KeyCombos implements Listener { keyNames.put(key, Objects.requireNonNull(config.getString("key-name." + key.name()), "Could not find translation for key " + key.name())); } - public String format(KeyCombo currentCombo) { + public String format(CustomSkillCastingHandler casting) { // Join all keys with separator - String builder = currentCombo.countKeys() == 0 ? noKey : keyNames.get(currentCombo.getAt(0)); + String builder = casting.current.countKeys() == 0 ? noKey : keyNames.get(casting.current.getAt(0)); int j = 1; - for (; j < currentCombo.countKeys(); j++) - builder += separator + keyNames.get(currentCombo.getAt(j)); + for (; j < casting.current.countKeys(); j++) + builder += separator + keyNames.get(casting.current.getAt(j)); // All remaining - for (; j < longestCombo; j++) + for (; j < casting.classLongestCombo; j++) builder += separator + noKey; + return MythicLib.plugin.parseColors(builder); } }