input() and other new b42 macro functions

Doc requests, organization, and submissions

Moderators: dorpond, trevor, Azhrei

User avatar
RedDog
Dragon
Posts: 393
Joined: Sat Jan 05, 2008 10:02 pm
Location: Clearwater, FL

Post by RedDog »

In reading your reply, I can certainly see some of the obstacles that would go into supporting wrapping text. I was just wondering if there was some functionality that I was not seeing. Don't get me wrong, this is some really nice stuff as it is. It will definitely be a great help for the streamlining certain functions.

knizia.fan
Giant
Posts: 197
Joined: Wed Jul 30, 2008 3:43 pm

Post by knizia.fan »

I'm not objecting to your idea, just pointing out that I'd need a better concept of the final goal so that I could more correctly understand what would be needed. If you want to work more on this I'd be happy to at least think about what it would take. I haven't used tables at all, so it's possible they'd be a big help.

nwelte1
Giant
Posts: 151
Joined: Mon Nov 19, 2007 10:52 pm

Post by nwelte1 »

I was reading over the sample macros provided by k.fan and had a few dumb questions. My questions are the result of coming late into the macro game and have no programming experience. So, please pardon me if my questions have obvious answers.

With regard to this part of attack macro code:


[h: fail = input(
"WpnNum | " + WpnList + " | Select weapon to use | LIST | SELECT=" + (WpnNum-1),
"CA | 0 | Combat Advantage | CHECK",
"MiscAtk | 0 | Misc. attack bonus",
"MiscDmg | 0 | Misc. damage bonus"
)]
[h: abort(fail)]
[h: WpnNum = WpnNum + 1]]

What are the + around “+ Wpnlist +” for?
“Select=” is doing what?
What is the “(WpnNum-1)” for? From what I can tell it does not appear to be an argument for the imput function.
Why make WpnNum = WpnNum+1? If I understand the macro right, previously we made WpnNum equal the weapon selection made through the dialog box. If +1 is added to WpnNum does that not change all subsequent references?

Perhaps, I am tired and simply need to look at this tomorrow.

User avatar
PyroMancer2k
Dragon
Posts: 925
Joined: Thu Sep 11, 2008 2:04 pm

Post by PyroMancer2k »

I copied the Weapon# and private into the token properties even gave them the default values you had listed. Then I copied your Attack and Edit lines of code. When I try to run them it doesn't work those I get a prompt to Enter Value for: Weapon1 which I do. But then in chat window it displays the error message "Could not execute the command: Illegal type for argument 1 to getStrProp(), expected java.lang.String but got java.math.BigDecimal"

The State one works though it doesn't display the same green looking box that your pics show. Also it was kinda a pain renaming all those states. I had them in already but weren't named what you called them :P. Is there a way to check the list of states without manually typing them all out like that?

knizia.fan
Giant
Posts: 197
Joined: Wed Jul 30, 2008 3:43 pm

Post by knizia.fan »

nwelte1 wrote:I was reading over the sample macros provided by k.fan and had a few dumb questions. My questions are the result of coming late into the macro game and have no programming experience. So, please pardon me if my questions have obvious answers.
No problem, feel free to ask questions.
nwelte1 wrote:With regard to this part of attack macro code:


[h: fail = input(
"WpnNum | " + WpnList + " | Select weapon to use | LIST | SELECT=" + (WpnNum-1),
"CA | 0 | Combat Advantage | CHECK",
"MiscAtk | 0 | Misc. attack bonus",
"MiscDmg | 0 | Misc. damage bonus"
)]
[h: abort(fail)]
[h: WpnNum = WpnNum + 1]]

What are the + around “+ Wpnlist +” for?
Words inside square brackets [ ] are normally interpreted by maptool as either a variable name or a function name. By putting text inside quotation marks " ", we tell MapTool that this is just raw text which should be left as-is. Programmers use the term "string" to refer to text inside quote marks like that.

For example, if you are impersonating a token, try typing [HP] in the chat window. That will print out a number which is your token's hit points (assuming you've set the HP token property already). But if you type ["HP"], you'll just see the letters HP, since MapTool prints out the string without trying to interpret it.

So, if we look at the first line of text inside the input() function, let's underline the text in the strings:

"WpnNum | " + WpnList + " | Select weapon to use | LIST | SELECT=" + (WpnNum-1)

The + symbols are being used to join those two strings to a couple of calculated quantities, to form one big string. Let's say that the WpnList variable contains the text "Sword, Dagger, Axe" and the WpnNum variable contains the number 2. Then the final string we build will be:

"WpnNum | Sword, Dagger, Axe | Select weapon to use | LIST | SELECT=1"

This final string is now constructed in the way that the input() function wants.
nwelte1 wrote:“Select=” is doing what?
If you look at the first post in this thread, you'll see that the LIST inputType has an option called SELECT which can be set to a number. This number controls which item in the list is initially selected when the dialog is shown. In our example, SELECT=1 causes the second item to be selected (remember that we start counting at 0).
nwelte1 wrote:What is the “(WpnNum-1)” for? From what I can tell it does not appear to be an argument for the imput function.
Hopefully this is clear from what I said above. The (WpnNum-1) is a calculated value which is attached to the end of the big string we construct. It is part of the first argument to the input() function. The input() function uses the normal programmer's method where the first item in a list is given the number zero. However our properties are numbered beginning from 1, since non-programmers like to start counting from the number 1. (How silly.) So, when we want to select Weapon2, we send the number (2-1)=1 to the function.
nwelte1 wrote:Why make WpnNum = WpnNum+1? If I understand the macro right, previously we made WpnNum equal the weapon selection made through the dialog box. If +1 is added to WpnNum does that not change all subsequent references?
If the user selects the first item in the list (i.e. Weapon1), the input() function will assign the number 0 to the WpnNum variable. When we save the number, the macro chooses to save the number 1 instead of 0, to match the numbering of the property names.

Programmers like to start counting from the number 0 because it makes many calculations more straightforward, but it can cause a little confusion in cases like this. The code is a bit complicated here because I decided to save the number in the non-programmer style (starting at 1), which means I have to subtract 1 at the beginning, and then add 1 afterwards.

knizia.fan
Giant
Posts: 197
Joined: Wed Jul 30, 2008 3:43 pm

Post by knizia.fan »

PyroMancer2k wrote:I copied the Weapon# and private into the token properties even gave them the default values you had listed. Then I copied your Attack and Edit lines of code. When I try to run them it doesn't work those I get a prompt to Enter Value for: Weapon1 which I do. But then in chat window it displays the error message "Could not execute the command: Illegal type for argument 1 to getStrProp(), expected java.lang.String but got java.math.BigDecimal"
If you're getting a prompt asking for a value for Weapon1, that means something went wrong when you created the token properties. Please check the following things.
  1. Impersonate the token, then type [Weapon1] in the chat window. Do you get the big string printed out, or do you get prompted to enter a value for Weapon1? If you get prompted, something's wrong with the token property.
  2. When you entered the value for Weapon1, did you do it as a default for the token property (in the Campaign Settings dialog box), or did you enter the text into the token's Edit Token dialog box? If you set it as a default, I think there's a quirk in the way default properties work: you must open and close the Edit Token dialog box before the default token property value will stick.
You'll know things are working right if you can impersonate the token and type [Weapon1], [Weapon2], etc. and get the big string printed out. The Attack macro should work for you then. If not, post here and someone will try to help.
PyroMancer2k wrote:The State one works though it doesn't display the same green looking box that your pics show. Also it was kinda a pain renaming all those states. I had them in already but weren't named what you called them :P. Is there a way to check the list of states without manually typing them all out like that?
I'm not sure what you mean by green looking box. Do you mean the green grass background around the dialog box? That's just the default map you get when starting MapTool. Or, if you mean that the borders of the dialog box have a green tinge, that's because I'm running Windows Vista, which has translucent borders around all windows. But the interior of the dialog box should match the picture no matter what operating system you use: you should have two checkboxes and five dropdown lists.

I don't think there's a way to get MapTool to spit out a list of all the defined states. However, one trick you could have used (too late now :)) is to load my sample campagin, click Edit > Campaign Properties > Export to save the states and token properties to a file, and then Import those settings into your own campaign. (You'll have to re-enter your token property list and any other customized campaign settings.)

knizia.fan
Giant
Posts: 197
Joined: Wed Jul 30, 2008 3:43 pm

Post by knizia.fan »

Build 43 has one additional feature. The getStrProp(props, key) function normally returns an empty string if the key is not found. You can now provide an optional third argument: getStrProp(props, key, defaultValue). Now, if the key is not found, the defaultValue is returned.

This lets you turn the following lines of code

Code: Select all

[h: WeaponNumber = getStrProp(props, "WeaponNumber")]
[h: WeaponNumber = if(WeaponNumber=="", 1, WeaponNumber)]
into just one line:

Code: Select all

[h: WeaponNumber = getStrProp(props, "WeaponNumber", 1)]
Some of my example macros can now be cleaned up a bit, if you want. I'll update the main post with this new feature.

User avatar
PyroMancer2k
Dragon
Posts: 925
Joined: Thu Sep 11, 2008 2:04 pm

Post by PyroMancer2k »

I figured out the weapon list bug. It has to do with b42 and b43 now it seems. The tokens don't update their values when you change them. And even though they had default values once I manually got it to change the weapon code worked fine?!? Go figure. Though I'm having the same problems I had in b42 with macros not accepting changes the first time around either.

Anyhow since it seems we are going for the fewest possible Variables I took your weapon edit code and modified it so that it only uses 2 Variables. The Description one which is default on tokens :) And WeaponC.

I'll admit it was a good exercise in learning the new code. Here it is if you know how to streamline it more that would be nice ;).

This Macro Sets Up Description Variable for use.

Code: Select all

[H:Description=setStrProp(Description, "DefaultWpn", "1")]
[H:c(9,""): Description=setStrProp(Description, eval('"Name" + roll.count'), "Unarmed")]
[H:c(9,""): Description=setStrProp(Description, eval('"AttackBonus" + roll.count'), 0)]
[H:c(9,""): Description=setStrProp(Description, eval('"Damage" + roll.count'), "1d4")]
[H:c(9,""): Description=setStrProp(Description, eval('"MaxDamage" + roll.count'), 4)]
[H:c(9,""): Description=setStrProp(Description, eval('"Crit" + roll.count'), "1d6")]
[H:c(9,""): Description=setStrProp(Description, eval('"Keyword" + roll.count'), "")]
This is modified K.fan code to store weapon in 1 Variable. WeaponC Variable is more of a temp holder.

Code: Select all

<Build>
  [h: WpnList = ""]
  [h, c(9,""): WpnList = WpnList + getStrProp(Description, eval('"Name" + roll.count')) + ","]

<Ask>
  [H: fail = input("WpnNum | " + WpnList + " | Select weapon to edit | LIST")]
  [H:abort(fail)]
 
<Obtain>
  [H: WpnNum = WpnNum + 1]
  [H: WpnName = "WeaponC"]
  [H: WpnProps = "Name" + WpnNum + "=" + getStrProp(Description, eval('"Name" + WpnNum')) + "; AttackBonus" + WpnNum + "=" + getStrProp(Description, eval('"AttackBonus" + WpnNum')) +"; Damage" + WpnNum + "=" + getStrProp(Description, eval('"Damage" + WpnNum')) +"; MaxDamage" + WpnNum + "=" + getStrProp(Description, eval('"MaxDamage" + WpnNum')) +"; Crit" + WpnNum + "=" + getStrProp(Description, eval('"Crit" + WpnNum')) +"; Keyword" + WpnNum + "=" + getStrProp(Description, eval('"Keyword" + WpnNum')) +";"]

<Error>
  [H: NumProps = countStrProp(eval(WpnName))]
  [H: abort(NumProps)]
 
<!-- Put up a dialog with all the properties in the property string.
  -- Note that the new property string is automatically assigned back to the
  -- token property that holds the weapon's property string. -->
  [H: fail = input("blah | " + WpnNum + " | Weapon number | LABEL",
      WpnName + " | " + WpnProps + " | Weapon properties | PROPS | setvars=true")]
  [H: abort(fail)]<br>

[H:Description=setStrProp(Description, eval('"Name" + WpnNum'), getStrProp(WeaponC, eval('"Name" + WpnNum')))]
[H:Description=setStrProp(Description, eval('"AttackBonus" + WpnNum'), getStrProp(WeaponC, eval('"AttackBonus" + WpnNum')))]
[H:Description=setStrProp(Description, eval('"Damage" + WpnNum'), getStrProp(WeaponC, eval('"Damage" + WpnNum')))]
[H:Description=setStrProp(Description, eval('"MaxDamage" + WpnNum'), getStrProp(WeaponC, eval('"MaxDamage" + WpnNum')))]
[H:Description=setStrProp(Description, eval('"Crit" + WpnNum'), getStrProp(WeaponC, eval('"Crit" + WpnNum')))]
[H:Description=setStrProp(Description, eval('"Keyword" + WpnNum'), getStrProp(WeaponC, eval('"Keyword" + WpnNum')))]


<Print>
New properties for weapon #{WpnNum}:
<table>
[h: NumProps = countStrProp(eval(WpnName))]
[h,p,c(NumProps,""):
    "<tr><td><b>"
    + indexKeyStrProp(WpnProps,roll.count-1)
    + "</b></td><td>"
    + eval(indexKeyStrProp(WpnProps,roll.count-1))
    + "</td></tr>" ]
</table>

How come the <!-- --> sections seem to close off when I post them?

Lindharin
Dragon
Posts: 668
Joined: Sat Apr 21, 2007 4:51 pm

Post by Lindharin »

K.fan, this is awesome! I just had the time to read through it, and I'm thrilled with all the new functionality, and you did a great job with the documentation. Congrats!

Any reason you didn't start with Weapon0 instead of Weapon1? That would avoid the whole WpnNum-1, WpnNum+1 situation and remove confusion from non-coders, as well as giving one more weapon slot.

Personally, I'm going to make Weapon0 be Unarmed. Then my "default" weapon will still be number 1 (your favorite sword, axe or whatever) but weapon 0 is there when you just want to smack someone... :lol:

Tacomannerism
Kobold
Posts: 23
Joined: Mon Sep 15, 2008 9:45 am

Post by Tacomannerism »

knizia.fan wrote:
Tacomannerism wrote:

Code: Select all

Exception occurred during event dispatching:
java.lang.ClassCastException: net.rptools.maptool.util.PersistenceUtil$PersistedCampaign cannot be cast to net.rptools.maptool.model.CampaignProperties
	at net.rptools.maptool.util.PersistenceUtil.loadCampaignProperties(PersistenceUtil.java:354)
	at net.rptools.maptool.client.ui.campaignproperties.CampaignPropertiesDialog$6$1.run(CampaignPropertiesDialog.java:534)
Interesting that it only happens on Linux. I created this file over 3 weeks ago when I submitted the first version of the patch. The state code has been revised since then to add new features and bar states. Based on your stack trace, I'm guessing that there's an incompatibility in the file format.

I've recreated the settings file using the shipping b42 here. Please give that file a try and let me know what you see.
I tried out the re-created settings file and no exceptions were raised, so that seemed to correct the file format.

User avatar
PyroMancer2k
Dragon
Posts: 925
Joined: Thu Sep 11, 2008 2:04 pm

Post by PyroMancer2k »

Lindharin wrote:K.fan, this is awesome! I just had the time to read through it, and I'm thrilled with all the new functionality, and you did a great job with the documentation. Congrats!

Any reason you didn't start with Weapon0 instead of Weapon1? That would avoid the whole WpnNum-1, WpnNum+1 situation and remove confusion from non-coders, as well as giving one more weapon slot.

Personally, I'm going to make Weapon0 be Unarmed. Then my "default" weapon will still be number 1 (your favorite sword, axe or whatever) but weapon 0 is there when you just want to smack someone... :lol:
Actually I don't think that it is possible to avoid that. The selection box no doubt seem to be like an array it always starts at 0. While having a Weapon0 would fix that problem it wouldn't fix the [c():] use which always starts at 1.

So from what I can tell your stuck between two functions where one always starts at 0 and goes to Count - 1. While the other starts at 1 and goes to Count.

Lindharin
Dragon
Posts: 668
Joined: Sat Apr 21, 2007 4:51 pm

Post by Lindharin »

PyroMancer2k wrote:While having a Weapon0 would fix that problem it wouldn't fix the [c():] use which always starts at 1.
Good catch! I just posted in this thread a request for a new option in [] that works just like c() but starts with 0 instead of 1. This would integrate the macro looping mechanism with the 0-based lists and string properties from b43, and it wouldn't change the existing c() option so existing macros won't break.

Mithrus
Cave Troll
Posts: 30
Joined: Fri Sep 12, 2008 11:52 pm

Post by Mithrus »

Thanks so much for new functionality! Lists and hashes/assoc arrays are SO useful, and especially the input() function.

That being said, I think there is a bug in varsFromStrProp(). I was expecting it to overwrite any previous variable with what was in the hash, but it doesn't seem to do that. Macros in general are seeming VERY buggy atm, so it could just be something else, but trying to use the following code and nothing happens:

(this is the starting value)
AttrCur="Intelligence=1 ; Strength=1 ; Presence=2 ; Wits=4 ; Dexterity=4 ; Manipulation=2 ; Resolve=2 ; Stamina=3 ; Composure=2 ; "

(I do some stuff that calculates Str/Dex/Sta/Man)

Before: [Strength] [Dexterity] [Stamina] [Manipulation]

[h: AttrCur=setStrProp(eval("AttrCur"), "Strength", Str)]
[h: AttrCur=setStrProp(eval("AttrCur"), "Dexterity", Dex)]
[h: AttrCur=setStrProp(eval("AttrCur"), "Stamina", Sta)]
[h: AttrCur=setStrProp(eval("AttrCur"), "Manipulation", Man)]

[AttrCur]
[h: varsFromStrProp(AttrCur)]

After: [Strength] [Dexterity] [Stamina] [Manipulation]

AttrCur shows the updated values, but the "After" values are the same as the "Before". Any ideas? I'll post the whole macro if needed.

User avatar
Sir Flak
Dragon
Posts: 344
Joined: Thu Sep 28, 2006 4:20 pm
Location: Oklahoma, US

Post by Sir Flak »

I'm having trouble getting the input function to work

Code: Select all

[input(“MiscAttMod”,”MiscDamMod”,”MiscSavMod”)]
doesn't work for me. It puts out:

Code: Select all

Could not execute the command: line 1:7: unexpected char: 0x93
Anything wrong that you can see?

EDIT: I wrote the Macro in wordpad. I think it uses different quotes character in word pad than in rptools. When i typed it directly in rptools it worked.

Code: Select all

[input("MiscAttMod","MiscDamMod","MiscSavMod")]
Wierd guess maybe i should use note pad??
Last edited by Sir Flak on Tue Sep 16, 2008 3:02 pm, edited 1 time in total.

User avatar
BigO
Dragon
Posts: 558
Joined: Mon Jul 28, 2008 12:23 pm
Location: Oshkosh, WI
Contact:

Post by BigO »

Sir Flak wrote:I'm having trouble getting the input function to work

Code: Select all

[input(“MiscAttMod”,”MiscDamMod”,”MiscSavMod”)]
doesn't work for me. It puts out:

Code: Select all

Could not execute the command: line 1:7: unexpected char: 0x93
Anything wrong that you can see?
You have the wrong kind of quotes there. You need to use " not “ and ”.
--O

I am a small and fragile flower.
http://maptool.rocks.andyousuck.com

Post Reply

Return to “Documentation Requests/Discussion”