From 88d02f140f975346ccd1c95474b45afaad6e0c2d Mon Sep 17 00:00:00 2001 From: Jules Date: Sun, 22 Oct 2023 00:03:35 +0200 Subject: [PATCH] Skill casting timeout, fixed casting particles --- .../skill/cast/SkillCastingHandler.java | 32 +++++++++++ .../skill/cast/SkillCastingInstance.java | 36 +++++++++---- .../skill/cast/SkillCastingListener.java | 18 ------- .../mmocore/skill/cast/SkillCastingMode.java | 12 ++--- .../skill/cast/listener/KeyCombos.java | 54 +++++++++---------- .../mmocore/skill/cast/listener/SkillBar.java | 19 ++++--- .../cast/listener/SkillCastingDisabled.java | 8 ++- .../skill/cast/listener/SkillScroller.java | 18 ++++--- 8 files changed, 114 insertions(+), 83 deletions(-) create mode 100644 MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java delete mode 100644 MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingListener.java diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java new file mode 100644 index 00000000..b16d999b --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingHandler.java @@ -0,0 +1,32 @@ +package net.Indyuce.mmocore.skill.cast; + +import net.Indyuce.mmocore.api.player.PlayerData; +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; + +public abstract class SkillCastingHandler implements Listener { + private final int timeoutDelay; + private final boolean timesOut; + + public SkillCastingHandler(@NotNull ConfigurationSection config) { + timesOut = config.contains("time-out"); + timeoutDelay = config.getInt("time-out"); + Validate.isTrue(!timesOut || timeoutDelay > 0, "Timeout must be strictly positive or disabled"); + } + + public boolean doesTimeOut() { + return timesOut; + } + + public int getTimeoutDelay() { + return timeoutDelay; + } + + @NotNull + public abstract SkillCastingMode getCastingMode(); + + @NotNull + public abstract SkillCastingInstance newInstance(@NotNull PlayerData player); +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingInstance.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingInstance.java index efe640ce..1ad65a9d 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingInstance.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingInstance.java @@ -7,17 +7,21 @@ import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; public abstract class SkillCastingInstance extends BukkitRunnable implements Listener { private final PlayerData caster; + private final SkillCastingHandler handler; + private final int runnablePeriod = 10; // Hard coded private boolean open = true; - private int j; + private int j, sinceLastActivity; - public SkillCastingInstance(PlayerData caster, int runnablePeriod) { + public SkillCastingInstance(@NotNull SkillCastingHandler handler, @NotNull PlayerData caster) { + this.handler = handler; this.caster = caster; - runTaskTimer(MMOCore.plugin, 0, runnablePeriod); + runTaskTimer(MMOCore.plugin, 0, 1); Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); } @@ -26,7 +30,7 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis } public void close() { - Validate.isTrue(open, "Skill casting already ended"); + Validate.isTrue(open, "Skill casting already closed"); open = false; @@ -37,6 +41,12 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis cancel(); } + public void refreshTimeOut() { + sinceLastActivity = 0; + } + + private static final int PARTICLES_PER_TICK = 2; + @Override public void run() { if (!caster.isOnline() || caster.getPlayer().isDead()) { @@ -44,16 +54,20 @@ public abstract class SkillCastingInstance extends BukkitRunnable implements Lis return; } + // Check for timeout + if (handler.doesTimeOut() && sinceLastActivity++ > handler.getTimeoutDelay()) { + caster.leaveSkillCasting(true); + return; + } + // Apply casting particles - if (caster.getProfess().getCastParticle() != null) - for (int k = 0; k < 2; k++) { - double a = (double) j++ / 5; - caster.getProfess().getCastParticle() - .display(caster.getPlayer().getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a))); - } + if (caster.getProfess().getCastParticle() != null) for (int k = 0; k < PARTICLES_PER_TICK; k++) { + final double a = (double) (PARTICLES_PER_TICK * j + k) / 4; + caster.getProfess().getCastParticle().display(caster.getPlayer().getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a))); + } // Apply casting mode-specific effects - onTick(); + if (j++ % runnablePeriod == 0) onTick(); } public abstract void onTick(); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingListener.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingListener.java deleted file mode 100644 index 69d5f0e0..00000000 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingListener.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.Indyuce.mmocore.skill.cast; - - -import net.Indyuce.mmocore.api.player.PlayerData; -import org.bukkit.event.Listener; -import org.jetbrains.annotations.NotNull; - -/** - * @apiNote Purely for API - */ -public interface SkillCastingListener extends Listener { - - @NotNull - public SkillCastingMode getCastingMode(); - - @NotNull - public SkillCastingInstance newInstance(@NotNull PlayerData player); -} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java index c9418fe4..e52adf26 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java @@ -1,8 +1,8 @@ package net.Indyuce.mmocore.skill.cast; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.skill.cast.listener.SkillBar; import net.Indyuce.mmocore.skill.cast.listener.KeyCombos; +import net.Indyuce.mmocore.skill.cast.listener.SkillBar; import net.Indyuce.mmocore.skill.cast.listener.SkillCastingDisabled; import net.Indyuce.mmocore.skill.cast.listener.SkillScroller; import org.apache.commons.lang.Validate; @@ -42,7 +42,7 @@ public enum SkillCastingMode { /** * Entirely disables skill casting. */ - NONE(config -> new SkillCastingDisabled()); + NONE(config -> new SkillCastingDisabled(config)); /** * Not implemented yet. @@ -63,11 +63,11 @@ public enum SkillCastingMode { ; - private final Function listenerLoader; + private final Function listenerLoader; - private static SkillCastingListener current; + private static SkillCastingHandler current; - SkillCastingMode(Function listenerLoader) { + SkillCastingMode(Function listenerLoader) { this.listenerLoader = listenerLoader; } @@ -81,7 +81,7 @@ public enum SkillCastingMode { } @NotNull - public static SkillCastingListener getCurrent() { + public static SkillCastingHandler getCurrent() { return Objects.requireNonNull(current, "Skill casting mode hasn't been initialized yet"); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java index 27890325..8d09ed30 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java @@ -21,8 +21,7 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.*; -public class KeyCombos implements SkillCastingListener { - +public class KeyCombos extends SkillCastingHandler { private final ComboMap comboMap; /** @@ -43,7 +42,9 @@ public class KeyCombos implements SkillCastingListener { @Nullable private final SoundObject beginComboSound, comboClickSound, failComboSound; - public KeyCombos(ConfigurationSection config) { + public KeyCombos(@NotNull ConfigurationSection config) { + super(config); + comboMap = new ComboMap(config.getConfigurationSection("combos")); actionBarOptions = config.contains("action-bar") ? new ActionBarOptions(config.getConfigurationSection("action-bar")) : null; @@ -108,6 +109,7 @@ public class KeyCombos implements SkillCastingListener { if (casting == null) return; // Adding pressed key + casting.refreshTimeOut(); casting.current.registerKey(event.getPressed()); casting.onTick(); if (comboClickSound != null) comboClickSound.playTo(player); @@ -135,30 +137,6 @@ public class KeyCombos implements SkillCastingListener { } } - private static final Set IGNORED_WHEN_CASTING = new HashSet<>(); - - static { - IGNORED_WHEN_CASTING.add(TriggerType.RIGHT_CLICK); - IGNORED_WHEN_CASTING.add(TriggerType.LEFT_CLICK); - IGNORED_WHEN_CASTING.add(TriggerType.SHIFT_RIGHT_CLICK); - IGNORED_WHEN_CASTING.add(TriggerType.SHIFT_LEFT_CLICK); - IGNORED_WHEN_CASTING.add(TriggerType.SNEAK); - } - - /** - * This makes sure NO skills are cast when in casting mode so that - * item abilities from MMOItems don't interfere with that. - *

- * Any trigger type that has a PlayerKey associated to it will - * be ignored if the player is currently in casting mode. - */ - @EventHandler - public void ignoreOtherSkills(PlayerCastSkillEvent event) { - TriggerType triggerType = event.getCast().getTrigger(); - if (IGNORED_WHEN_CASTING.contains(triggerType) && PlayerData.get(event.getData()).isCasting()) - 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) @@ -168,7 +146,7 @@ public class KeyCombos implements SkillCastingListener { private final ComboMap combos; CustomSkillCastingInstance(PlayerData caster) { - super(caster, 10); + super(KeyCombos.this, caster); combos = Objects.requireNonNullElse(caster.getProfess().getComboMap(), comboMap); } @@ -180,6 +158,26 @@ public class KeyCombos implements SkillCastingListener { getCaster().getPlayer().sendTitle(" ", actionBarOptions.format(this), 0, 20, 0); else getCaster().displayActionBar(actionBarOptions.format(this)); } + + private static final List IGNORED_WHEN_CASTING = Arrays.asList( + TriggerType.RIGHT_CLICK, + TriggerType.LEFT_CLICK, + TriggerType.SHIFT_RIGHT_CLICK, + TriggerType.SHIFT_LEFT_CLICK, + TriggerType.SNEAK); + + /** + * This makes sure NO skills are cast when in casting mode so that + * item abilities from MMOItems don't interfere with that. + *

+ * Any trigger type that has a PlayerKey associated to it will + * be ignored if the player is currently in casting mode. + */ + @EventHandler + public void ignoreOtherSkills(PlayerCastSkillEvent event) { + if (!event.getPlayer().equals(getCaster().getPlayer())) return; + if (IGNORED_WHEN_CASTING.contains(event.getCast().getTrigger())) event.setCancelled(true); + } } private class ActionBarOptions { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java index 08bb6608..62988477 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java @@ -9,25 +9,23 @@ 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.cast.PlayerKey; -import net.Indyuce.mmocore.skill.cast.SkillCastingInstance; -import net.Indyuce.mmocore.skill.cast.SkillCastingListener; -import net.Indyuce.mmocore.skill.cast.SkillCastingMode; +import net.Indyuce.mmocore.skill.cast.*; import org.bukkit.GameMode; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; import java.util.Objects; -public class SkillBar implements SkillCastingListener { +public class SkillBar extends SkillCastingHandler { private final PlayerKey mainKey; private final boolean disableSneak; - public SkillBar(ConfigurationSection config) { + public SkillBar(@NotNull ConfigurationSection config) { + super(config); + mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key"))); disableSneak = config.getBoolean("disable-sneak"); } @@ -70,7 +68,7 @@ public class SkillBar implements SkillCastingListener { private int j; CustomSkillCastingInstance(PlayerData playerData) { - super(playerData, 1); + super(SkillBar.this, playerData); } @EventHandler @@ -89,7 +87,8 @@ public class SkillBar implements SkillCastingListener { if (event.getPreviousSlot() == event.getNewSlot()) return; event.setCancelled(true); - int slot = event.getNewSlot() + 1 + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0); + refreshTimeOut(); + final int slot = event.getNewSlot() + 1 + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0); /* * The event is called again soon after the first since when @@ -153,7 +152,7 @@ public class SkillBar implements SkillCastingListener { @Override public void onTick() { - if (j++ % 20 == 0) getCaster().displayActionBar(getFormat(getCaster())); + if (j++ % 2 == 0) getCaster().displayActionBar(getFormat(getCaster())); } } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillCastingDisabled.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillCastingDisabled.java index 6457f58b..d88fe44e 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillCastingDisabled.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillCastingDisabled.java @@ -1,12 +1,16 @@ package net.Indyuce.mmocore.skill.cast.listener; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; import net.Indyuce.mmocore.skill.cast.SkillCastingInstance; -import net.Indyuce.mmocore.skill.cast.SkillCastingListener; import net.Indyuce.mmocore.skill.cast.SkillCastingMode; +import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; -public class SkillCastingDisabled implements SkillCastingListener { +public class SkillCastingDisabled extends SkillCastingHandler { + public SkillCastingDisabled(@NotNull ConfigurationSection config) { + super(config); + } @Override public SkillCastingInstance newInstance(@NotNull PlayerData player) { diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java index 34f59ee5..684cd356 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java @@ -9,8 +9,8 @@ import net.Indyuce.mmocore.api.SoundObject; import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.skill.cast.PlayerKey; +import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; import net.Indyuce.mmocore.skill.cast.SkillCastingInstance; -import net.Indyuce.mmocore.skill.cast.SkillCastingListener; import net.Indyuce.mmocore.skill.cast.SkillCastingMode; import org.bukkit.GameMode; import org.bukkit.configuration.ConfigurationSection; @@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.Objects; -public class SkillScroller implements SkillCastingListener { +public class SkillScroller extends SkillCastingHandler { /** * Key players need to press to start casting @@ -32,7 +32,8 @@ public class SkillScroller implements SkillCastingListener { @Nullable private final SoundObject enterSound, changeSound, leaveSound; - public SkillScroller(ConfigurationSection config) { + public SkillScroller(@NotNull ConfigurationSection config) { + super(config); // Load sounds enterSound = config.contains("sound.enter") ? new SoundObject(config.getConfigurationSection("sound.enter")) : null; @@ -110,14 +111,15 @@ public class SkillScroller implements SkillCastingListener { event.setCancelled(true); - int previous = event.getPreviousSlot(), current = event.getNewSlot(); - int dist1 = 9 + current - previous, dist2 = current - previous, dist3 = current - previous - 9; - 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 previous = event.getPreviousSlot(), current = event.getNewSlot(); + 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 - CustomSkillCastingInstance casting = (CustomSkillCastingInstance) playerData.getSkillCasting(); + final CustomSkillCastingInstance casting = (CustomSkillCastingInstance) playerData.getSkillCasting(); casting.index = mod(casting.index + change, playerData.getBoundSkills().size()); casting.onTick(); + casting.refreshTimeOut(); if (changeSound != null) changeSound.playTo(event.getPlayer()); } @@ -135,7 +137,7 @@ public class SkillScroller implements SkillCastingListener { private int index = 0; CustomSkillCastingInstance(PlayerData caster) { - super(caster, 10); + super(SkillScroller.this, caster); } @Override