Help with a broken loop

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
User avatar
TheIneffableCheese
Cave Troll
Posts: 64
Joined: Sun Mar 22, 2015 3:57 pm

Help with a broken loop

Post by TheIneffableCheese »

I'm having a problem with a loop in a macro. This is my first time using a Lib:Token set up.

I'm building a module to add tokens to the initiative panel. I am using code from Toy Robot's toolbar macros as the basis.

Essentially, there is a campaign macro that builds a dialog to take in initiative rolls. It then sends the list of tokens and the corresponding initiative values to a macro on Lib:Initiative which is supposed to parse out the values, add the tokens to the initiative panel, and sort the tokens.

The first macro seems to work just fine. The second macro - the one that is actually adding the tokens to the initiative panel - has a FOREACH loop to go through each of the selected tokens. It seems to start out fine, but it seems to break if there are tokens with a space in the name. It crashes out of the loop and the rest of the macro stops. I'd appreciate another set of eyes running over this.

Here is the code for the dialog set up:
Spoiler

Code: Select all

[h: tableText = ""]
[h: addList = getSelectedNames("%%")]

[h, FOREACH(creature, addList, "","%%" ): tableText= tableText 
 + strformat("<tr><td align=right>%s</td><td><input type=text size=5 name='%s' value='%s'></td></tr>", 
creature, 
creature, 
"1d20+"+getProperty("Initiative", creature) 
)]

[DIALOG("Add to Initiative", "input=1; height=300; width=250; temporary=1"):{
<html>
<body>
<form method=get action='[r: macroLinkText("Roll Initiative@Lib:Initiative", "None", encode(addList)+"," )]'>
<center>
    <table>
        <tr><td colspan=2><center><b>Enter initiative scores or dice notation.</b></center></td></tr>
        [r: tableText]
    </table>
    <br>
    <input type=submit value=Add>
</center>
</form>
</body>
</html>
}]
And here is the code that adds the tokens to the initiative panel:
Spoiler

Code: Select all

[h: tokenNamesList = decode( listGet(macro.args, 0) )]
[h: initArgs = listGet(macro.args, 1)]

[h, foreach(Token, tokenNamesList,"","%%"), CODE:
{
	[h: switchToken(Token)]
	[h: InitMod = getProperty("Initiative")*0.01]
	[h: UncannyDodge = getProperty("UncannyDodge")]
	[h: InitRoll =  ( eval(  string(   getStrProp(initArgs, Token)  )  )  )]
	[h, if(UncannyDodge != 1): setState("FlatFooted",1)]
	[h: addToInitiative()]
	[h: setInitiative(InitRoll+InitMod)]
	[h: deselectTokens()]
}]

[h: "/** The macro breaks somewhere around here. The rest of the macro is halted"]

[h: setInitiativeRound(1)]
[h: sortInitiative()]
[h: setCurrentInitiative(0)]

[h: activeCreature = getInitiativeToken()]
[h: setState("Active",1,activeCreature)]
[h: setState("FlatFooted",0,activeCreature)]
[h: goto(activeCreature)]

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Help with a broken loop

Post by wolph42 »

a debug trick:

remove the for loop and replace it with [Token = "a token name with a space in it"] select that token and run the macro.
Also during debugging it might help to remove the h: in the end you only need one "h," for the entire foreach loop. This too might help with debugging.
This way you know exactly WHERE the macro stops and you get a more accurate error report.

User avatar
TheIneffableCheese
Cave Troll
Posts: 64
Joined: Sun Mar 22, 2015 3:57 pm

Re: Help with a broken loop

Post by TheIneffableCheese »

Thanks for the tip Wolph - I followed your advice and the broken line seems to be the fourth line of the loop:

Code: Select all

[InitRoll =  ( eval(  string(   getStrProp(initArgs, Token)  )  )  )]
Unfortunately, the evaluation is something I lifted from TR's toolbar, and I don't really know how to approach it differently. Similarly, I can't avoid using spaces in my token names since Maptool iterates copies with a space and a number.

Thanks again for your help.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Help with a broken loop

Post by wolph42 »

Get hè inner part out so
Tmp = string(...etc...)
And then broadcast it so
Broadcast(tmp)
And then eval(tmp)
So you know exactly what you're evaluating. Let me know what it is.

User avatar
TheIneffableCheese
Cave Troll
Posts: 64
Joined: Sun Mar 22, 2015 3:57 pm

Re: Help with a broken loop

Post by TheIneffableCheese »

So I did a whole lot of tinkering, and it appears the problem is the "getStrProp" - I dug into it on the wiki, and the wiki specifically says the key can't have a space in it.

I'm not entirely sure why it only breaks if there is a key value with a space as the last item in the list, but there you go. I went through the functions and couldn't find anything that would easily replace the getStrProp function. Maybe there is some way to remove the spaces somehow? Or possibly use token IDs instead of token names?

Just for reference, here are examples of the variables that come through on the Lib macro

The raw macro.args variable:

Code: Select all

Elf%25%25Mage%25%25Hero+1%25%25Mystic%25%25Troll+1%25%25Troll+2%25%25Troll+3%25%25Troll+A,Elf=1d20+20 ; Mage=1d20+2 ; Hero 1=1d20+-1 ; Mystic=1d20+5 ; Troll 1=1d20+3 ; Troll 2=1d20+3 ; Troll 3=1d20+3 ; Troll A=1d20+3
tokenNamesList variable value from the macro.args above:

Code: Select all

Elf%%Mage%%Hero 1%%Mystic%%Troll 1%%Troll 2%%Troll 3%%Troll A
initArgs variable value from the macro.args above:

Code: Select all

Elf=1d20+20 ; Mage=1d20+2 ; Hero 1=1d20+-1 ; Mystic=1d20+5 ; Troll 1=1d20+3 ; Troll 2=1d20+3 ; Troll 3=1d20+3 ; Troll A=1d20+3

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Help with a broken loop

Post by wolph42 »

indeed either use the tokenId's or encode the names or use tokenName = replace(tokenName, " ", "_") if you use getSelectedTokens i think you can use replace on the entire string at once as the only spaces in there would be the ones in the names. When you need to retrieve them you can simply reverse it with tokenName = replace(tokenName, "_", " ")

User avatar
TheIneffableCheese
Cave Troll
Posts: 64
Joined: Sun Mar 22, 2015 3:57 pm

Re: Help with a broken loop

Post by TheIneffableCheese »

So in the end I decided to take the path of least resistance. I built a simple macro that loops through the token names and uses the replace function to change " " for "_". It adds one more step to token setup, but since I'm already using a setup routine, a few clicks more after populating a map is not that big of a deal.

Thanks very much for your help, Wolph - I can foresee a lot of use coming from the broadcast() trick you gave me. I've already used it to troubleshoot another minor problem I was having.


User avatar
TheIneffableCheese
Cave Troll
Posts: 64
Joined: Sun Mar 22, 2015 3:57 pm

Re: Help with a broken loop

Post by TheIneffableCheese »

Just a follow up - I tried to use this last night with my group for the first time, and it was broken. I had to work around it the entire night much to my chagrin.

This morning I looked into it some more and I think I found the problem. Some of my character names had hyphens and that seems to be what hung the loop. Once I cleared that out of the token names, it seems to work fine.

Looks like the getStrProp function also dislikes hyphens - as long as my token names just have letters, numbers, and underscores it seems to work fine.

Just thought I'd add this for posterity if anyone else is trying to solve a similar problem.


Post Reply

Return to “Macros”