Thread Tools Display Modes
12-05-05, 01:03 PM   #1
Thoinan
A Defias Bandit
Join Date: Dec 2005
Posts: 2
Multi use macro

Trying to create a macro for any spell, whereas the script checks first if the spell is castable on the target, and if so, casts and prints a message. The whole idea is to stop <no target> spam. I'm new to scripting in WoW so bear with me:

/script CastSpellByName("spell"); ct = SpellCanTargetUnit("target") if (ct == 1) then SendChatMessage('your say message', 'Say') else SpellStopTargeting(); end

Just to break down what I'm trying to do:
1. Check if spell is castable on target and assign value ct.
2. If ct is true ( I'm assuming this is like good old binary whereas 1=true, 0=false) then execute the chat message.
3. If the spell is not castable, cancels targetting.

Am I approaching this correctly or is there a cleaner way to do this? Also getting an error

[string "CastSpellByName("spell"); ct = SpellCanTargetUnit("target") if (ct == 1) then SendChatMessage('your say message', 'Say') else SpellStopTargeting(); end ":1: `then' expected nearī`;'
  Reply With Quote
12-05-05, 04:07 PM   #2
TigerHeart
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 132
Try this

/script CastSpellByName("spell"); ct = SpellCanTargetUnit("target"); if (ct == 1) then SendChatMessage('your say message', 'Say'); else SpellStopTargeting(); end;
  Reply With Quote
12-05-05, 04:26 PM   #3
Gello
A Molten Giant
AddOn Author - Click to view addons
Join Date: Jan 2005
Posts: 521
That error is odd. Your syntax is fine. Are you sure there's no line breaks? When you begin a /script everything involved in the script must be one continuous line. You can use multiple /script's but they need to be self-contained. (ie, you can't do /script if (ct==1) then (newline) /script dostuff end) Copy-pasting can often add line breaks when it wraps. I'd double check there are none. Your syntax is correct.

That said, in that macro ct will never equal 1.

When you CastSpellByName() it begins casting and then if the beneficial spell can't land on the current target then you will be in spell targeting mode and SpellCanTargetUnit("target") will return nil. (otherwise it would've cast the spell and you would not be in targeting mode and SpellCanTargetUnit() will return nil)

For detrimental spells, you never get into targeting mode and SpellCanTargetUnit() will always return nil. (Generally, WoW functions with a yes/no result often return 1 for true and nil for false. IsActionInRange is a notable exception that uses 1 or 0 for yes/no.)

You asked if there was a cleaner way to do it so here's the same macro:

/script CastSpellByName("spell") if SpellCanTargetUnit("target") then SendChatMessage('your say message', 'Say') else SpellStopTargeting() end

In lua if you have this:

if Something then
-- do stuff
end

Something is true if it's anything except nil or false. Even an empty string or 0 is "true", which can be confusing when coming from another language.

Since I assume this macro is for detrimental spells (nukes, debuffs, etc), you will probably want to check if you can cast it before casting:

/script if UnitCreatureType("target")=="Humanoid" or UnitCreatureType("target")=="Beast" then CastSpellByName("Polymorph") end

Another tip on shortcuts: You can substitute functions and strings used by assigning them to a variable:

/script local t="target" local u=UnitCreatureType if u(t)=="Humanoid" or u(t)=="Beast" then CastSpellByName("Polymorph") end

the local tag makes it so the variable only exists for that macro and doesn't persist in the game. (Which you sometimes want to do if the macro depends on setting a variable in a previous press). You can string many variables and their values together by clumping them with commas:

/script local t,u="target",UnitCreatureType if u(t)=="Humanoid" or u(t)=="Beast" then CastSpellByName("Polymorph") end

If the macro is intended for beneficial spells, unfortunately that's a lot more complicated. Macros run instantly and you can't tell it to react to something that happens in the future. In this case when you eventually target something you can't tell it what to do then. Well, you can but that involves function hooks and stuff and is generally far beyond the scope of a macro.
  Reply With Quote
12-06-05, 04:18 PM   #4
Thoinan
A Defias Bandit
Join Date: Dec 2005
Posts: 2
Thanks for clearing up the variable bit.

Getting no error with mine anymore, so thats good. But with both things, the spell casts but there's no message output in /say.

Currently testing it with Repentance, a humanoid only ranged stun.

/script CastSpellByName("Repentance"); ct = SpellCanTargetUnit("target"); if (ct == 1) then SendChatMessage('Repentance on %t', 'Say'); else SpellStopTargeting(); end;

And the improved one from Gello:

/script CastSpellByName("Repentance") if SpellCanTargetUnit("target") then SendChatMessage('Repentance on %t', 'Say') else SpellStopTargeting() end
  Reply With Quote
12-06-05, 04:32 PM   #5
Gello
A Molten Giant
AddOn Author - Click to view addons
Join Date: Jan 2005
Posts: 521
SpellCanTargetUnit("target") will never be true immediately after a CastSpell/ByName.

SpellCanTargetUnit is only used while in spell targeting mode (cast a beneficial spell without a target or self cast), and never used for "target" since you can't get into spell targeting mode if your target can accept the spell.

Determintal spells (stuff you cast on hostiles, including Repentance) never, ever go into spell targeting mode. If the target is invalid then it says so and that's it.

For detrimental spells, since there is never a targeting mode and all the SpellCanTargetUnit, SpellTargetUnit, etc functions never apply, to do stuff differently depending on if the spell can cast, you'll want to make the check manually by a series of checks before casting.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Multi use macro

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off