From 7703aab8e0cad19ec111be095cb11ffa29fabfb3 Mon Sep 17 00:00:00 2001 From: JasperLorelai Date: Mon, 21 Sep 2026 21:28:44 +0200 Subject: [PATCH 1/3] fix: Player requirement during caster var mod --- .../magicspells/listeners/VariableListener.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/nisovin/magicspells/listeners/VariableListener.java b/core/src/main/java/com/nisovin/magicspells/listeners/VariableListener.java index 4197647e4..6d8a8a8cc 100644 --- a/core/src/main/java/com/nisovin/magicspells/listeners/VariableListener.java +++ b/core/src/main/java/com/nisovin/magicspells/listeners/VariableListener.java @@ -80,8 +80,10 @@ public void variableModsCasted(SpellCastedEvent event) { public void variableModsTarget(SpellTargetEvent event) { Multimap varMods = event.getSpell().getVariableModsTarget(); if (varMods == null || varMods.isEmpty()) return; - if (!(event.getCaster() instanceof Player caster)) return; - Player target = event.getTarget() instanceof Player ? (Player) event.getTarget() : null; + + Player caster = event.getCaster() instanceof Player player ? player : null; + Player target = event.getTarget() instanceof Player player ? player : null; + for (Map.Entry entry : varMods.entries()) { VariableMod mod = entry.getValue(); if (mod == null) continue; @@ -90,7 +92,10 @@ public void variableModsTarget(SpellTargetEvent event) { String variableName = entry.getKey(); String[] splits = variableName.split(":"); if (splits.length > 1) { - if (splits[0].equalsIgnoreCase("caster")) playerToMod = caster; + if (splits[0].equalsIgnoreCase("caster")) { + if (caster == null) continue; + playerToMod = caster; + } variableName = splits[1]; } // Target was expected, but they were not a player. From 7a634b560e0b3c4fe2c4ddbda4392e08565e2ee0 Mon Sep 17 00:00:00 2001 From: JasperLorelai Date: Tue, 22 Sep 2026 04:05:10 +0200 Subject: [PATCH 2/3] feat: Add "meta_held_item_slot" --- .../util/managers/VariableManager.java | 1 + .../variables/meta/HeldItemSlotVariable.java | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 core/src/main/java/com/nisovin/magicspells/variables/meta/HeldItemSlotVariable.java diff --git a/core/src/main/java/com/nisovin/magicspells/util/managers/VariableManager.java b/core/src/main/java/com/nisovin/magicspells/util/managers/VariableManager.java index c001732f1..18f42f14f 100644 --- a/core/src/main/java/com/nisovin/magicspells/util/managers/VariableManager.java +++ b/core/src/main/java/com/nisovin/magicspells/util/managers/VariableManager.java @@ -134,6 +134,7 @@ private void initialize() { addMetaVariableType("max_health", new MaxHealthVariable()); addMetaVariableType("current_health", new CurrentHealthVariable()); addMetaVariableType("health_scale", new HealthScaleVariable()); + addMetaVariableType("held_item_slot", new HeldItemSlotVariable()); addMetaVariableType("compass_target_x", new CompassTargetXVariable()); addMetaVariableType("compass_target_y", new CompassTargetYVariable()); addMetaVariableType("compass_target_z", new CompassTargetZVariable()); diff --git a/core/src/main/java/com/nisovin/magicspells/variables/meta/HeldItemSlotVariable.java b/core/src/main/java/com/nisovin/magicspells/variables/meta/HeldItemSlotVariable.java new file mode 100644 index 000000000..afcfe5a35 --- /dev/null +++ b/core/src/main/java/com/nisovin/magicspells/variables/meta/HeldItemSlotVariable.java @@ -0,0 +1,26 @@ +package com.nisovin.magicspells.variables.meta; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import com.nisovin.magicspells.variables.variabletypes.MetaVariable; + +public class HeldItemSlotVariable extends MetaVariable { + + @Override + public double getValue(String player) { + Player p = Bukkit.getPlayerExact(player); + return p != null ? p.getInventory().getHeldItemSlot() : 0; + } + + @Override + public void set(String player, double amount) { + Player p = Bukkit.getPlayerExact(player); + if (p == null) return; + + try { + p.getInventory().setHeldItemSlot((int) amount); + } catch (IllegalArgumentException _) {} + } + +} From 99c571fe93b1fb4f4b4a93c702bbf70af475e20c Mon Sep 17 00:00:00 2001 From: JasperLorelai Date: Tue, 22 Sep 2026 04:23:23 +0200 Subject: [PATCH 3/3] feat: Direct velocity option --- .../spells/instant/VelocitySpell.java | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/nisovin/magicspells/spells/instant/VelocitySpell.java b/core/src/main/java/com/nisovin/magicspells/spells/instant/VelocitySpell.java index e9b702d65..dd4208898 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/instant/VelocitySpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/instant/VelocitySpell.java @@ -32,6 +32,8 @@ public class VelocitySpell extends InstantSpell implements TargetedEntitySpell, private final ConfigData speed; + private final ConfigData velocity; + private final ConfigData cancelDamage; private final ConfigData powerAffectsSpeed; private final ConfigData addVelocityInstead; @@ -41,6 +43,8 @@ public VelocitySpell(MagicConfig config, String spellName) { speed = getConfigDataDouble("speed", 40); + velocity = getConfigDataVector("velocity", null); + cancelDamage = getConfigDataBoolean("cancel-damage", true); powerAffectsSpeed = getConfigDataBoolean("power-affects-speed", true); addVelocityInstead = getConfigDataBoolean("add-velocity-instead", false); @@ -60,33 +64,31 @@ public CastResult cast(SpellData data) { @Override public CastResult castAtEntity(SpellData data) { - double speed = this.speed.get(data) / 10; - if (powerAffectsSpeed.get(data)) speed *= data.power(); - - Vector velocity = data.target().getLocation().getDirection().normalize().multiply(speed); - - if (addVelocityInstead.get(data)) data.target().setVelocity(data.target().getVelocity().add(velocity)); - else data.target().setVelocity(velocity); - - velocityMonitor.add(new VelocityData(this, data, cancelDamage.get(data))); - playSpellEffects(data); - - return new CastResult(PostCastAction.HANDLE_NORMALLY, data); + return applyVelocity(data, data.target().getLocation().getDirection().normalize()); } @Override public CastResult castAtEntityFromLocation(SpellData data) { - double speed = this.speed.get(data) / 10; - if (powerAffectsSpeed.get(data)) speed *= data.power(); + return applyVelocity(data, data.location().getDirection().normalize()); + } + + private CastResult applyVelocity(SpellData data, Vector direction) { + Vector velocity = this.velocity.get(data); + + if (velocity == null) { + double speed = this.speed.get(data) / 10; + if (powerAffectsSpeed.get(data)) speed *= data.power(); - Vector velocity = data.location().getDirection().normalize().multiply(speed); + velocity = direction.multiply(speed); + } + + if (addVelocityInstead.get(data)) velocity = data.target().getVelocity().add(velocity); - if (addVelocityInstead.get(data)) data.target().setVelocity(data.target().getVelocity().add(velocity)); - else data.target().setVelocity(velocity); + data.target().setVelocity(velocity); velocityMonitor.add(new VelocityData(this, data, cancelDamage.get(data))); - playSpellEffects(data); + playSpellEffects(data); return new CastResult(PostCastAction.HANDLE_NORMALLY, data); }