input() and other new b42 macro functions

Doc requests, organization, and submissions

Moderators: dorpond, trevor, Azhrei

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

Post by PyroMancer2k »

Hay K.fan I read the change log and it said you were the one who wrote the code for the input() function. That's really cool and I was wondering if you could add some functionality to it.

1)For PROPS could you add an option to allow for check boxes? This way instead of having Text boxes listed could you have a display of check boxes. Like in the case of 4e you want to setup a input that has a player check what skills they have trained. Then it would of course save the prop list like normal making them equal to either 1 or 0. Right now the only way to do this is to write 17 lines for check boxes take them into 17 different variables. Then put them each into a StrProp which is a lot of extra work.

2)This one could is a bit more difficult then the check box but do able I imagine. That is again a new option for PROPS this time each prop is a LIST. In that is uses a list in each StrProp to make a drop down selection list. This way you can assign collection of props while limiting what the player can input into their selection. I know it's already possible to do list inside of StrProps as I wrote the following code as a quick test.

Code: Select all

[H: TheStrProp = "MyList=Gray, Black, Blue, Yellow ; YourList=Red, Orange, Brown, Tan"]
[getStrProp(TheStrProp, "MyList")]<BR>
[listGet(getStrProp(TheStrProp, "MyList"), Index)]<BR>
So the example would be something like say.

Code: Select all

[input("PlayerPicks | " + TheStrProp + " | Choose a color from each list | PROPS | TYPE=LIST")]
It would then set PlayerPicks = "MyList=***** ; YourList=*****" Where which ever color the player picked being the value in the ****. Since normal list can do either Number or String maybe have two types LISTNUM and LISTSTR as the option?


Anyhow what do you think of these ideas?

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

Post by knizia.fan »

PyroMancer2k wrote:Hay K.fan I read the change log and it said you were the one who wrote the code for the input() function. That's really cool and I was wondering if you could add some functionality to it.

1)For PROPS could you add an option to allow for check boxes? This way instead of having Text boxes listed could you have a display of check boxes. Like in the case of 4e you want to setup a input that has a player check what skills they have trained. Then it would of course save the prop list like normal making them equal to either 1 or 0. Right now the only way to do this is to write 17 lines for check boxes take them into 17 different variables. Then put them each into a StrProp which is a lot of extra work.

2)This one could is a bit more difficult then the check box but do able I imagine. That is again a new option for PROPS this time each prop is a LIST. In that is uses a list in each StrProp to make a drop down selection list. This way you can assign collection of props while limiting what the player can input into their selection. I know it's already possible to do list inside of StrProps as I wrote the following code as a quick test.

Code: Select all

[H: TheStrProp = "MyList=Gray, Black, Blue, Yellow ; YourList=Red, Orange, Brown, Tan"]
[getStrProp(TheStrProp, "MyList")]<BR>
[listGet(getStrProp(TheStrProp, "MyList"), Index)]<BR>
So the example would be something like say.

Code: Select all

[input("PlayerPicks | " + TheStrProp + " | Choose a color from each list | PROPS | TYPE=LIST")]
It would then set PlayerPicks = "MyList=***** ; YourList=*****" Where which ever color the player picked being the value in the ****. Since normal list can do either Number or String maybe have two types LISTNUM and LISTSTR as the option?


Anyhow what do you think of these ideas?
I intended the PROPS type to be a quick-and-dirty way to edit a property string, but a few people have been asking for functionality like this. The first problem that comes to mind is that for this to be useful, there has to be a way to specify a default value for each item. For the current system that only uses TEXT controls, the value in the StrProp is the default value. But for things like LIST and RADIO, I'd have to add yet another option to set a list of default values. And, I'm sure people will also want the ability to set all the other options for whatever inputType they use, so the PROPS type would become a monster catch-all that has to include everything.

For the moment, when I get some time I'm going to work on a system to make it easier to construct your 17 checkboxes. My plan is to let you specify multiple variables in a single string. So, you could type

Code: Select all

[input("AtkBonus ## Name | Bob,Mary,Andy | Pick a name | LIST ## Blah")]
That would be equivalent to

Code: Select all

[input("AtkBonus", "Name | Bob,Mary,Andy | Pick a name | LIST", "Blah")]
You could then use the list functions to construct such a multi-variable string, and set all the fancy options you want. It would only take a few lines of code to do the things people are asking for, thanks to the list functions.

Note that you might have to do extra work anyway even with what you proposed above, in order to construct the property string that contains all the settings. So hopefully the technique I'm suggesting will be no more work than that, and give you all the features of the individual inputType settings, and avoid the need for a lot of redundant options to the input() function.

I'll think about this some more and see what else I can do to make it more useful for you guys.

Craig
Great Wyrm
Posts: 2107
Joined: Sun Jun 22, 2008 7:53 pm
Location: Melbourne, Australia

Post by Craig »

knizia.fan wrote: I intended the PROPS type to be a quick-and-dirty way to edit a property string, but a few people have been asking for functionality like this. The first problem that comes to mind is that for this to be useful, there has to be a way to specify a default value for each item. For the current system that only uses TEXT controls, the value in the StrProp is the default value. But for things like LIST and RADIO, I'd have to add yet another option to set a list of default values. And, I'm sure people will also want the ability to set all the other options for whatever inputType they use, so the PROPS type would become a monster catch-all that has to include everything.
As food for thought how about allowing 2 property string arguments to input, the first containing the variables to edit and default values and the second options for each of the properties, something like

Code: Select all

[h: inProps = "Name=Long Sword; Damage=1d8; MaxDamage=8; Wielded=1;"]
[h: inPropsOpt = "Name=TEXT,WIDTH=16; Damage=TEXT,WIDTH=8; MaxDamage=TEXT,WIDTH=4, Wielded=CHECK | OPTIONS"]
[h: fail = input("outProps|" + inProps + "|PROPS", inPropsOpt)]
This has the nice advantage of keeping the data and presentation separate so we can grab data from a token pass it to input() get the result back and shove it back in the token without having to fuss with altering the properties string to include formating options.

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

Post by PyroMancer2k »

knizia.fan wrote:
I intended the PROPS type to be a quick-and-dirty way to edit a property string, but a few people have been asking for functionality like this. The first problem that comes to mind is that for this to be useful, there has to be a way to specify a default value for each item. For the current system that only uses TEXT controls, the value in the StrProp is the default value. But for things like LIST and RADIO, I'd have to add yet another option to set a list of default values. And, I'm sure people will also want the ability to set all the other options for whatever inputType they use, so the PROPS type would become a monster catch-all that has to include everything.
Well that I think could be done with something list this maybe.

Code: Select all

[H: TheStrProp = "MyList=Gray, Black, Blue, Yellow ; YourList=Red, Orange, Brown, Tan"; VehicleList=Truck, Car, Jeep, Bike"] 
[input("PlayerPicks | " + TheStrProp + " | Choose a color from each list | PROPS | TYPE=LIST SELECT=1,0,3")] 
That way looking the list it should start with Black, Red, Bike in those slots. If there are more Props then numbers in select list then they get default value. I don't know how much doing list in there would mess with the syntax.
knizia.fan wrote: For the moment, when I get some time I'm going to work on a system to make it easier to construct your 17 checkboxes. My plan is to let you specify multiple variables in a single string. So, you could type

Code: Select all

[input("AtkBonus ## Name | Bob,Mary,Andy | Pick a name | LIST ## Blah")]
That would be equivalent to

Code: Select all

[input("AtkBonus", "Name | Bob,Mary,Andy | Pick a name | LIST", "Blah")]
You could then use the list functions to construct such a multi-variable string, and set all the fancy options you want. It would only take a few lines of code to do the things people are asking for, thanks to the list functions.
The multiple variables sounds like a cool feature. Though if you want to store all the values in a single StrProp your still stuck having to use setStrProp() function 17 times which is the main problem. Truth be told while that would cut down greatly on how much you have to type for the input command it's the having the transfer 17 variables into a single string that is the most annoying ;).

The way I look at it though if you do it with the PROPS then the user can turn on the SETVARS=TRUE option which is already there and it will also set those variables to that. Thus allowing them to do the multiple variables as well. That's assuming I am understand the correct usage of SETVARS=TRUE.

As for the check box I was thinking something like this maybe.

Code: Select all

[input("TrainedSkills | Acrobatics= 1; Bluff=0; Nature=1; | Choose Skills you are Trained in. | PROPS | TYPE=CHECK")]
It would then display Check boxes instead of Text and given their values either checked or unchecked to start.
knizia.fan wrote:
Note that you might have to do extra work anyway even with what you proposed above, in order to construct the property string that contains all the settings. So hopefully the technique I'm suggesting will be no more work than that, and give you all the features of the individual inputType settings, and avoid the need for a lot of redundant options to the input() function.

I'll think about this some more and see what else I can do to make it more useful for you guys.
Thanks, I look forward to see what you come up with.

PS: Please don't change the syntax to much though so we don't have to rewrite our macros. ;)

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

Post by Mithrus »

Some good ideas on enhancing input, so I'll add my 2 bits. I think the current decision to have 1 parameter = 1 variable for input() should stay that way, regardless of new functionality. PROPS is a special case, but I think it can handle supporting the other formats without causing major headaches for you. Borrowing a lot from Craig's idea:

a typical parameter to input() follows this format: "varname | value | prompt | type | options"

when type = PROPS:
value contains the default values as normal (and is typically the contents of varname)
options will include 3 more options
* Option: FORMAT=varformat
* Option: FORMATSEP=; (the separater used in varformat)
* Option: FORMATLISTSEP=, (the separater used for each element in varformat)

varformat is a StrProp containing formatting for each element. For example:
"Var1=TEXT,WIDTH=nnn ; Var2=LIST,VALUE=STRING,TEXT=TRUE,ICON=FALSE,ICONSIZE=nnn,VALUES=x,y,z ; Var3=CHECK ; Var4=RADIO,ORIENT=H,VALUE=STRING,VALUES=x,y,z ; Var5=LABEL,TEXT=TRUE,ICON=FALSE,ICONSIZE=nnn"

This way, you could store varformat and use it in multiple input() calls as needed.

IMO, I'd prefer it if the LIST and RADIO types didn't break the mold of the other types, and had value contain the default value like the other types, and use an option VALUES=item1,item2,etc to provide the possible choices. The SELECT=nnn option would then not be needed. The only restriction would be that VALUES always be the last parameter.

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

Post by PyroMancer2k »

K.fan it's broke!! I just loaded b44 from the main site and several macros I made no longer work. :P

I even have your condition manager code completely unmodified. So I figure it must be something that changed with the StrProp, List, or input() functions. Could you let us know what changes were made?

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

Post by knizia.fan »

PyroMancer2k wrote:K.fan it's broke!! I just loaded b44 from the main site and several macros I made no longer work. :P

I even have your condition manager code completely unmodified. So I figure it must be something that changed with the StrProp, List, or input() functions. Could you let us know what changes were made?
Actually none of my changes made it into b44. I think your problem is that the [c(n): ] feature now starts roll.count at 0 instead of 1. As expected, this will break all sorts of macros. You'll have to modify most of your looping code -- typically you'll need to replace (roll.count-1) with just roll.count now.

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

Post by PyroMancer2k »

knizia.fan wrote:Actually none of my changes made it into b44. I think your problem is that the [c(n): ] feature now starts roll.count at 0 instead of 1. As expected, this will break all sorts of macros. You'll have to modify most of your looping code -- typically you'll need to replace (roll.count-1) with just roll.count now.
Yea the change log is finally up and I figured that was the problem when i saw that. I don't use the (roll.count-1) in most of my loops I just use roll.count so i'll have to chagne it to (roll.count+1) ;).

User avatar
palmer
Great Wyrm
Posts: 1367
Joined: Sat Sep 06, 2008 7:54 pm

Post by palmer »

eval("MeleePower" + roll.count)

Previously returned "MeleePower1, MeleePower2, MeleePower3" and it was good.

Now returns "MeleePower0, MeleePower1, MeleePower2" - not so good.

HOWEVER

eval("MeleePower" + roll.count+1) - obvious solution.

Except this returns "MeleePower01, MeleePower11, MeleePower21"

Rather unhelpful.

Any solutions?

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

Post by knizia.fan »

palmer wrote:eval("MeleePower" + roll.count)

Previously returned "MeleePower1, MeleePower2, MeleePower3" and it was good.

Now returns "MeleePower0, MeleePower1, MeleePower2" - not so good.

HOWEVER

eval("MeleePower" + roll.count+1) - obvious solution.

Except this returns "MeleePower01, MeleePower11, MeleePower21"

Rather unhelpful.

Any solutions?
When you use the + operator, MapTool has to decide whether you want:
1. Numerical addition
2. String joining

Since you have a string involved in your addition, MapTool must use string joining, which means that each item gets appended to the end of the string.

To fix this, you need to use + with numbers only, so that MapTool can use numerical addition. Thus:

Code: Select all

eval("MeleePower" + (roll.count+1) ) 

h3lrav3n
Kobold
Posts: 12
Joined: Thu Sep 28, 2006 1:03 am

Re: the attack macro & critical threats

Post by h3lrav3n »

PyroMancer2k wrote:
h3lrav3n wrote:The attack macro prints "a critical hit!" when the die roll is a natural 20. I was wondering if there was a way to get the attack macro to work with a threat range (For example: a longsword's threat range of 19-20) without a complete rewrite; possibly to be used in conjunction with the weapon edit macro.
Actually it would be very easy to do. First off you would need to add another property to the weapon. For our Example we will use ThreatRange as that property. Then in the case of a longsword it's 19-20 so set "ThreatRange=19;"

Next make a small edit to the code.

Code: Select all

{if(AtkRoll>=ThreatRange+AttackBonus+if(CA,2,0)+MiscAtk, ", a critical hit!", "")} 
And done. Since weapon edit code gets the property list from the weapons themselves adding properties doesn't change that macro at all. Just have to make sure you set all the ThreatRange properties for your weapons now ;). You'll have to manually add it but once you do it'll always appear in the edit list.
palmer wrote: PyroMancer pretty much has it. I use something of an alternative.
You still need to add a weapon prop for the crit range. Just make it a single number that represents the lower end of the range. Crit 18-20 is just written as 18.

Code: Select all

<Print>
I attack [Target] with my [ItemName].
Attack: [h:AttackRoll = 1d20] [AttackRoll + AttackBonus + if(CA, 2, 0) - ConcPenalty] vs AC. {if(AttackRoll>=CritRange, "Natural " + AttackRoll + ". Critical hit!", "")}
Damage: {if(AttackRoll>=CritRange, CritTotal, DamageTotal))} [Keyword] damage.
The key points here are
A: Make AttackRoll a separate variable
B: if(AttackRoll>=CritRange)

The only real functional difference is that my version will announce "Natural 20!" so all may gaze upon your e-dice rolling skills in awe.
But having that show was helpful during my debugging :)
Thanks guys! It works like a charm :)

h3lrav3n
Kobold
Posts: 12
Joined: Thu Sep 28, 2006 1:03 am

Post by h3lrav3n »

PyroMancer2k wrote:
knizia.fan wrote:Actually none of my changes made it into b44. I think your problem is that the [c(n): ] feature now starts roll.count at 0 instead of 1. As expected, this will break all sorts of macros. You'll have to modify most of your looping code -- typically you'll need to replace (roll.count-1) with just roll.count now.
Yea the change log is finally up and I figured that was the problem when i saw that. I don't use the (roll.count-1) in most of my loops I just use roll.count so i'll have to chagne it to (roll.count+1) ;).
I made the following changes to knizia.fan's attack macro and added the ThreatRange weapon property and it works fine:

<!-- Build the list of weapon names. --> [h: WpnList = ""] [h, c(9,""): WpnList = WpnList + getStrProp(eval("Weapon" + (roll.count+1)), "Name") + ","] <!-- Get the index of the previously selected weapon, if any. --> [h: WpnNum = getStrProp(Private, "DefaultWpn")] [h: WpnNum = if(WpnNum == "", 1, WpnNum)] <!-- Prompt the user for attack options. --> [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] <!-- Save the default weapon for next time. --> [h: Private = setStrProp(Private, "DefaultWpn", WpnNum)] <!-- Set variables from the weapon's property string. -- In this case, the variables are Name, AttackBonus, -- Damage, MaxDamage, Crit, and Keyword. --> [h: varsFromStrProp(eval("Weapon" + WpnNum))] <!-- Print out the results. --><hr> I attack my enemy with {Name}. <br><b>Attack roll:</b> [AtkRoll = 1d20 + AttackBonus + if(CA, 2, 0) + MiscAtk] {if(AtkRoll>=ThreatRange+AttackBonus+if(CA,2,0)+MiscAtk, ", a critical threat!", "")} {if(AtkRoll== 1+AttackBonus+if(CA,2,0)+MiscAtk, ", a critical miss!", "")} <br><b>Damage roll:</b> [eval(Damage) + MiscDmg] {Keyword} damage.<hr>

I also attempted to adjust the edit weapons macro:

<!-- Build the list of weapon names. --> [h: WpnList = ""] [h, c(9,""): WpnList = WpnList + getStrProp(eval("Weapon" + (roll.count+1)), "Name") + ","] <!-- Ask the user to select one of the weapons. --> [h: fail = input("WpnNum | " + WpnList + " | Select weapon to edit | LIST")] [h: abort(fail)] <!-- Obtain the property string for the selected weapon. --> [h: WpnNum = WpnNum + 1] [h: WpnName = "Weapon" + WpnNum] [h: WpnProps = eval(WpnName)] <!-- Error checking -- make sure the property string has been set up already. --> [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)] <!-- Print the new values to the chat window for verification. --> New properties for weapon #{WpnNum}: <table border=0> [h: NumProps = countStrProp(eval(WpnName))] [h,p,c(NumProps,""): "<tr><td style='padding:0px 5px'><b>" + indexKeyStrProp(WpnProps,roll.count-1) + "</b></td><td>" + eval(indexKeyStrProp(WpnProps,roll.count-1)) + "</td></tr>" ] </table>

It seems to work, however I get the following prompt in the chat window:

Could not execute the command: Invalid option: p

Where did I go wrong? Thanks in advance.

h3lrav3n
Kobold
Posts: 12
Joined: Thu Sep 28, 2006 1:03 am

Post by h3lrav3n »

Sorry... my last post above is in regards to b45.

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

Post by PyroMancer2k »

h3lrav3n wrote:Sorry... my last post above is in regards to b45.
P was renamed to R in b45. So in this section

Code: Select all

[h,p,c(NumProps,""): 
It should be

Code: Select all

[h,r,c(NumProps,""): 

User avatar
harchunk
Giant
Posts: 116
Joined: Sat Mar 22, 2008 7:12 pm

Post by harchunk »

knizia.fan wrote:
PyroMancer2k wrote:I was even considering taking it a step further in having it hold all the skills since like in 4.0 they take up 17 variables already assuming you put all their bonuses and such in a single variable. It's going to be a bit tricky on how to do it though.
Here's a quick attempt at a set of unified skill check macros for 4E D&D. It assumes a Skills property defined as:

Code: Select all

Skills: Acrobatics=0 ; Arcana=0 ; Athletics=0 ; Bluff=0 ; Diplomacy=0 ; Dungeoneering=0 ; Endurance=0 ; Heal=0 ; History=0 ; Insight=0 ; Intimidate=0 ; Nature=0 ; Perception=0 ; Religion=0 ; Stealth=0 ; Streetwise=0 ; Thievery=0 ;
(The macros also use a Private property for persistent settings, as usual.)

First, the "Set Skills" macro, which lets you adjust the bonuses for your character. This is where you enter training, feat, and other permanent bonuses.

Code: Select all

<SET>

[h: success = input(
  "foo | Don't add bonuses from abilities or level here. | Note | LABEL",
  "Skills | " + Skills + " | Set skill bonuses | PROPS"
)]
[h: abort(success)]
The macro displays the following dialog box:
Image


Then we have the "Skill Check" macro. It auto-adds the level bonus, ability bonus, and armor check penalty as appropriate.

Code: Select all

<SKILL>

<This>

<Some>
  [h: SkillNames = "Acrobatics, Arcana, Athletics, Bluff, Diplomacy, Dungeoneering, Endurance, Heal, History, Insight, Intimidate, Nature, Perception, Religion, Stealth, Streetwise, Thievery"]
  [h: SkillAbils = "Dex, Int, Str, Cha, Cha, Wis, Con, Wis, Int, Wis, Cha, Wis, Wis, Int, Dex, Cha, Dex"]
  [h: ArmorCheckAbils = "Str, Con, Dex"]
  [h: NumSkills = listCount(SkillNames)]

<Compute>
  [h: SkillBonuses = Skills]
  [h,c(NumSkills,""): SkillBonuses = setStrProp(
    SkillBonuses, 
    listGet(SkillNames, roll.count-1), 
    getStrProp(Skills, listGet(SkillNames, roll.count-1)) 
      + LevelBonus
      + eval(listGet(SkillAbils,roll.count-1)+"Bonus") 
      + if(listFind(ArmorCheckAbils, listGet(SkillAbils,roll.count-1)) != -1, ArmorCheckPenalty, 0)
  )]

<Construct>
  [h: SkillStr = SkillNames]
  [h,c(NumSkills,""): SkillStr = listReplace(
    SkillStr, 
    roll.count-1, 
    listGet(SkillNames, roll.count-1) 
      + " (" 
      + if(getStrProp(SkillBonuses, listGet(SkillNames,roll.count-1)) < 0, "", "+")
      + getStrProp(SkillBonuses, listGet(SkillNames,roll.count-1))
      + ")"
  )]

<Display>
  [h: success = input(
    "SkillNum | " + SkillStr + " | Select a skill | LIST | SELECT=" + getStrProp(Private, "LastSkill", 0),
    "TempBonus | 0 | Temporary bonus"
  )]
  [h: abort(success)]

<Make>
<!-- doesn't work in b43, will in b44  [h: SkillBonus = indexValueStrProp(SkillBonuses, SkillNum)] -->
  [h: SkillBonus = getStrProp(SkillBonuses, listGet(SkillNames, SkillNum))]
  <b>{listGet(SkillNames, SkillNum)} check:</b> [1d20 + SkillBonus + TempBonus]
  
<Save>
  [h: Private = setStrProp(Private, "LastSkill", SkillNum)]
You get the following dialog, which includes the net skill check bonus in the list for your verification. It remembers the last skill you used.
Image


I tried to use this macro and the first part isnt operating correctly this is what i get "Could not execute the command: Index: 0, Size: 0"

Post Reply

Return to “Documentation Requests/Discussion”