You are not logged in.

Applications: [GameMaster: OPEN] | [Volunteer Testers: OPEN]


This forum will be permanently shut down on Friday 13.07.2018
Please copy or save all important information from old forum before they will be deactivated
We have moved to new board. https://forum.runesofmagic.gameforge.com/Come join us.

1

Friday, September 19th 2014, 1:41am

Anatomy of More Complex Macros

I have been trying to create some conditional macros lately and find that no matter how long I've perused these forums, I still don't understand what I'm doing. I would love it if someone could help me understand the purpose/proper syntax of the different parts of this code, including when/how/why to use "break" "end" "end end" and semicolons between different parts:

Source code

1
/run for i=1,100 do n,_,_,id=UnitBuff("player",i) if id==500675 then CancelPlayerBuff(i) break else CastSpellByName("Hide") end end


Source code

1
/run hide = false; for i=1,40 do if UnitBuff("player",i) == "Hide" then hide == "true"; CancelPlayerBuff(i); break end end if hide == false then CastSpellByName("Hide") end


I just am failing to understand what each section does or is supposed to do. By the way, neither of the above works to toggle hide off and on. I'm not really looking for a working version of the above, just a better understanding of what the code says/does. If I have missed a good post that handles this elsewhere, it wasn't for lack of reading and trying to find it.

2

Friday, September 19th 2014, 10:51am

I just am failing to understand what each section does or is supposed to do.
The problem is that to use it in /run macro, the lua code is glued into one line, making it hard to read.

The keywords in lua mark syntatic blocks, there is no need for semicolons.

So your first macro split into multiple line would look like this:

Source code

1
2
3
4
5
6
7
8
9
for i=1,100 do 
      n,_,_,id=UnitBuff("player",i) 
      if id==500675 then 
            CancelPlayerBuff(i) 
            break 
      else 
            CastSpellByName("Hide") 
      end 
end

As you can see the strange "end end" are in fact two separate ends: one finishing the block for "if" statement, one finishing the code of the "for" loop. In the same way "break else" have nothing to do with each other: break breaks the "for" loop, else belongs to the inner "if".

But it is tricky with semicolons. For example, take the section of the second macro:

Source code

1
then hide = true; CancelPlayerBuff(i); break end
(I've corrected the first part: 'hide == "true"' made no sense here imho). Now, here I believe you could skip the second semicolon; I'm not sure however about the first one: I thought that if you have two statements which are not keywords then the semicolon is actually obligatory, but I'm not sure. In any case, it does help reading. So the second macro after simply splitting to multiple lines would look like this:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
hide = false; 
for i=1,40 do 
      if UnitBuff("player",i) == "Hide" then 
            hide = true; -- this was corrected
            CancelPlayerBuff(i); 
            break 
      end 
end 

if hide == false then 
      CastSpellByName("Hide") 
end
where, I think the semicolon after the first "hide = false" and after CancelPlayerBuff(i) could be removed; I'm not sure about the one after "hide = true".
>>>> >>>> >>>>
>>>>
>>>> Please, bring back (bound if there is no other option) dias to AH! :thumbsup:
>>>> If you do this we will all love you forever. ;)
>>>>
>>>> >>>> >>>>

3

Friday, September 19th 2014, 10:55am

Im splitting the macro code up over multiple lines so its easier to understand what each part does ^^ If you want the macro to work, you'll need to remove the unnecessary whitespace and line breaks.

First macro:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
/run -- execute the following lua code
    for i=1,100 do -- iterate over all numbers from 1 to 100 in steps of 1
                   -- (so repeat the following block of commands for i=1, i=2, i=3, ..., i=100)
        n,_,_,id=UnitBuff("player",i) -- get the name (n) and the id of the i-th buff of the player (you)
        if id==500675 then -- if the id is equal to the one of a specific buff (stealth I guess)...
            CancelPlayerBuff(i) -- then remove the buff...
            break -- and stop iterating (break means you'll abort the for-loop
                  -- since we have found the stealth buff there's no need to look further
        else -- if id is not equal...
            CastSpellByName("Hide") -- try to cast hide
        end
    end


There is some weirdness going on in that macro: the variable n isn't used (anymore? i guess the check for the id qas originally a check for the buff name ^^), and it tries to cast hide each iteration of the loop!! CastSpellByName is not instant, it has a delay until the cast is executed, so even if the steatlh debuff was found and removed, hide would be cast regardless of that (unless the stealth buff was the first buff). Also, funnily, if CastSpellByName would be instant then it would remove the stealth buff you just got ^^

a slightly better version of the same macro would look like this:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
/run
    local wasHidden = false
    for i=1,100 do
        local _, _, _, id = UnitBuff("player", i)
        if id == 500675 then
            CancelPlayerBuff(i)
            wasHidden = true
            break
        end
    end
    if not wasHidden then
        CastSpellByName("Hide")
    end

or that for short:

Source code

1
/run local w=0 for i=1,100 do local _,_,_,d=UnitBuff("player",i) if d==500675 then CancelPlayerBuff(i) w=1 break end end if w==0 then CastSpellByName("Hide") end

The better version only tries to cast Hide if there is no stealth buff found and after the loop is done so there is no way to mess it up ^^

Second Macro:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
/run
    hide = false;
    for i=1,40 do
        if UnitBuff("player",i) == "Hide" then
            hide == "true"; -- error: should be hide = true
            CancelPlayerBuff(i);
            break
        end
    end
    if hide == false then
        CastSpellByName("Hide")
    end

This macro looks quite familiar, doesn't it? ^^ The main difference is that it's checking if the name matches instead of the id. But due to the line I commented the macro will throw an error, since it's trying to compare hide with "true" instead of assigning something to hide. Other than that, the stealth buff could be named differently than "Hide" (I'm playing on the german version, so I don't really know the exact english names ^^), which would make the macro fail to find the stealth buff and cast Hide anyways...

If something is not clear feel free to ask ^^

EDIT: Lol, Uure was faster ^^ I blame my registration process to the forum :P
To the semicolons: Lua treats them mostly like they aren't there, unless there would be some ambiguity whitout them like

Source code

1
2
func1(x)
(y and func2 or func3)(z)

This post has been edited 1 times, last edit by "hoffmale" (Sep 19th 2014, 11:08am)


4

Saturday, September 20th 2014, 12:18am

I really appreciate both of your responses. I am starting to understand the various parts of the macro better, now. As a bonus, I now have a working Hide toggle macro. Thank you!

This post has been edited 1 times, last edit by "Ozmondius" (Sep 20th 2014, 12:26am)