• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Target.? and usrChosen1?

TCArknight

Well-known member
Howdy!

I was wondering if might be able to share the specifics of the coding behind the use of the Target.? tag for setting the value of a user menu?

I'm finding that it would be useful to have that sort of functionality in a dataset I'm working on for a system other than PF.

Thanks!
TC
 
The pseudocode for this:


if (tagis[Target1.?] <> 0) then
~use a foreach to find a thing/pick with that Reference1 tag that isn't the pick running this script (whether to run a foreach thing or a foreach pick is handled by checking the tags about whether this drop-down is thing or pick based)
else
~handle the user's choice in the drop-down normally

endif


The Target1 tag group is created in tags.1st - you have to also formally define Reference1 in the same file, and it has to be earlier in the file (usually just the next item up, so they're easy to find together). Then, Reference1 is also an identity tag on anything that might need it, and when building the foreaches, you use replace(the string you built using tagids[],"Target1","Reference1",0) - this way, Reference1 only ever exists on the picks that are being referenced, and Target1 only exists on picks making references to those other picks.


Oh, and leaving out the "1" at the end of the tag group's Id was a mistake - we found that out when we needed to create Target2 and Reference2 so that a second drop-down could also receive the same mechanics.
 
Thank you Mathias!

Is it best to use setchosen[] to set the menu item or is there another better way to handle it? (would you have the details on the setchosen[] as far as the variables, requirements, etc.?

I have the code below for the script, and I get an issue with the eachpick -
Hero Lab was forced to stop compilation after the following errors were detected:

Syntax error in 'eval' script for Component 'Talent' (Eval Script '#4') on line 14
-> Reference to undeclared variable: 'eachpick'

Code:
~ done if this doesn't have a UserSelect component
	  doneif (tagis[component.UserSelect] = 0)
	  
	  ~ done if this doesn't have a Target1 component
	  doneif (tagis[Target1.?] = 0)
	  
	  ~ if we do have a Target1 tag, we need to set the usrChosen1 to the target
	  var myRef as string
	  myRef = tagids[Target1.?,","]
	  myRef = replace(myRef,"Target1","Reference1",0)
	  
	  foreach pick in hero from BaseScore where myRef
	    perform field[usrChosen1].setchosen[Ability,eachpick.thingid,hero]
	    nexteach
 
The Target1 mechanism we built does not use setchosen. The procedure just sets the focus to the item that's found, or if no Target1 tag is present, sets the focus to the user's choice in the drop-down. So then all the scripts looking at this drop-down just call the procedure, then verify that a focus was set, then continue, using whatever the focus was set to.

This way, if the Target1 tag is no longer assigned, the drop-down goes back to being user-controlled, with no memory of having been overridden.
 
Ah, thanks Mathias. :)

What I have is a Talent/Edge which, when gained from another ability requires a specific Attribute to be the selection.

To that end, I try:
Code:
~ if we do have a Target1 tag, we need to set the usrChosen1 to the target
	  var myRef as string
	  var tagexpr as string
	  
	  myRef = tagids[Target1.?,","]
	  myRef = replace(myRef,"Target1","Reference1",0)
	  
	  foreach pick in hero from BaseScore where myRef
	    tagexpr = "component.BaseScore & " & eachpick.idstring
	    nexteach
      notify tagexpr
	  
	  [B]perform this.field[usrChosen1].setchosen[Ability,tagexpr,hero][/B]
but I get this referencing field[usrChosen1] -
Hero Lab was forced to stop compilation after the following errors were detected:

Syntax error in 'eval' script for Component 'UserSelect' (Eval Script '#4') on line 17
-> Field not found
Am I missing something?
 
eachpick.idstring will give you an expression like "abMyAbility". setchosen is looking for a tag expression that uniquely identifies the pick it should set, like "Reference1.abMyAbility" or "thingid.abMyAbility". So you don't actually need a foreach there - just make use of the tag you already have.
 
So, I should just be able to use the Reference1.xxx as the tagexpr, correct?

Is that what causes the field not found error? I’ve got that script in the UserSelect component itself where the field usrChosen1 is, and I’m still getting “Field not found”.
 
I'm not sure if that's the entire reason for the field not found - there could be a second error I didn't see when looking at your code.

This should work:
myRef = tagids[Target1.?,"|"]
myRef = replace(myRef,"Target1","Reference1",0)
perform this.field[usrChosen1].setchosen[Ability,myRef,hero]

Oh, actually, you had an error in myRef - you had a ",", but you're building a tag expression, so you want "|" to mean "OR". The code you were writing would have failed at the foreach step if there was more than one Target1 tag, because it wouldn't have been a properly formatted tag expression.

Also, I'd add a safety check at the beginning - test that there is exactly 1 Target1 tag before building your variable and running setchosen, because if there's 0, then things will fail, and if there's 2, then it's mostly random which choice will be selected (although the choice is likely to be consistent for that character loaded at that time, but it could change if you build a new test character, or even if you save and load your test character). You can even add a notify if there's more than one - that's a combo of abilities you didn't expect to be able to happen, but the user made it happen anyway.

HL's error reporting can sometimes fail in ways that pretend the error is earlier than expected - I think what's happening here is that the real error is "the tag expression is not formed as a tag expression", but that's not specifically checked for, so it's just stored as "I found an error on this line", which gets traced back up the chain of transitions - setchosen, back to field, back to "this", and the field is where HL notices "this has been flagged as an error" and then it just defaults to the standard error report for errors about fields.
 
Last edited:
Thanks Mathias!

I found the issue. the setchosen[] process apparently requires a trusted script. This is my final script in case anyone else wants to do similar...

Code:
    <!-- If the ability needs a specific selection, set it based on the Target1.? tags -->
    <eval index="4" phase="Final" priority="1000"><![CDATA[
	  [COLOR="Red"]trustme[/COLOR]
	  
	  ~ done if this doesn't have a Target1 tag
	  doneif (tagcount[Target1.?] <> 1)
	  
	  ~ if we do have a single Target1 tag, we need to set the usrChosen1 to the target
	  var myRef as string
	  var tagexpr as string
	  
	  myRef = tagids[Target1.?,"|"]
          myRef = replace(myRef,"Target1","Reference1",0)
	  perform this.field[usrChosen1].setchosen[Ability,myRef,hero]
	  
      ]]></eval>
 
And in terms of code style, I would avoid this - I would set up the Target1/Reference1 mechanism as I described it, using either the Target1 or the user's choice to set a focus, and then doing everything else with that drop-down based on the focus. Trusted scripts are something I think should be avoided if there's a way around it, because you can overwrite what the user set, with no record of what they did originally set, in case your newly added thing was a mis-click.
 
Back
Top