Add @cursor token for ground-target spells/items

@cursor places a ground-target spell or on-use item at the cursor via
ClassicAPI's engine-level placement instead of the [mouseuse] reticle-
click simulation (so no auto-attack side effect).

- ParseMsg flags @cursor as conditionals.atCursor rather than setting a
  bogus "cursor" unit target, so it doesn't affect help/harm/exists/range
  checks or pass an invalid token to CastSpellByName.
- DoWithConditionals routes atCursor casts through C_Spell.CastAtCursor
  (spellID resolved from the spell index / GetSpellIdForName) and item
  uses through C_Item.UseAtCursor. Both fall back to a normal cast/use
  for non-ground actions.

New syntax, so existing macros are unaffected; MacroErrorChecker already
accepts @cursor.
This commit is contained in:
Brues
2026-06-21 02:34:12 -05:00
parent a220dbd003
commit b9895471f0
+28 -2
View File
@@ -2041,7 +2041,15 @@ function CleveRoids.ParseMsg(msg)
local _, _, target = string.find(conditionBlock, "(@[^%s,]+)")
if target then
conditionBlock = CleveRoids.Trim(string.gsub(conditionBlock, target, ""))
conditionals.target = string.sub(target, 2)
local tok = string.sub(target, 2)
-- @cursor is a ground-target directive, not a unit. Flag it so the cast
-- routes through ClassicAPI's CastAtCursor / UseAtCursor, and leave the
-- target at its default (CastAtCursor places at the cursor regardless).
if string.lower(tok) == "cursor" then
conditionals.atCursor = true
else
conditionals.target = tok
end
end
if conditionBlock and conditionals.action then
@@ -2655,7 +2663,25 @@ function CleveRoids.DoWithConditionals(msg, hook, fixEmptyTargetFunc, targetBefo
castMsg = msg .. "(" .. rank .. ")"
end
end
if action == CastSpellByName then
if conditionals.atCursor then
-- @cursor: place a ground-target spell/item at the cursor via
-- ClassicAPI (no AoE-reticle click). Both functions fall back to a
-- normal cast/use for non-ground actions.
if action == CastSpellByName then
local sp = CleveRoids.GetSpell(msg)
local spellId = sp and sp.id
if not spellId and GetSpellIdForName then
spellId = GetSpellIdForName(castMsg)
end
if spellId then
C_Spell.CastAtCursor(spellId)
else
CastSpellByName(castMsg)
end
else
C_Item.UseAtCursor(msg)
end
elseif action == CastSpellByName then
-- ! prefix anti-toggle: prevent CastSpellByName from toggling off active spells.
-- For Attack/AutoShot/Shoot, use the non-toggling AttackTarget() API.
-- For self-buffs/shapeshifts, skip if already active on the player.