Lone Wolf Development Forums  

Go Back   Lone Wolf Development Forums > Hero Lab Forums > HL - Pathfinder Roleplaying Game

Notices

Reply
 
Thread Tools Display Modes
TCArknight
Senior Member
 
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321

Old October 6th, 2022, 12:49 PM
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

Working on -
  • (SWADE) WIP Savage Rifts
  • Savage Rifts (Deluxe): Update link in This post
  • Star Trek Adventures: Update link in This post
TCArknight is offline   #1 Reply With Quote
Mathias
Senior Member
Lone Wolf Staff
 
Join Date: May 2005
Posts: 13,207

Old October 6th, 2022, 01:02 PM
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.
Mathias is offline   #2 Reply With Quote
TCArknight
Senior Member
 
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321

Old October 6th, 2022, 02:12 PM
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 -
Quote:
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

Working on -
  • (SWADE) WIP Savage Rifts
  • Savage Rifts (Deluxe): Update link in This post
  • Star Trek Adventures: Update link in This post
TCArknight is offline   #3 Reply With Quote
Mathias
Senior Member
Lone Wolf Staff
 
Join Date: May 2005
Posts: 13,207

Old October 6th, 2022, 02:32 PM
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.
Mathias is offline   #4 Reply With Quote
TCArknight
Senior Member
 
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321

Old October 6th, 2022, 03:42 PM
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
	  
	  perform this.field[usrChosen1].setchosen[Ability,tagexpr,hero]
but I get this referencing field[usrChosen1] -
Quote:
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?

Working on -
  • (SWADE) WIP Savage Rifts
  • Savage Rifts (Deluxe): Update link in This post
  • Star Trek Adventures: Update link in This post
TCArknight is offline   #5 Reply With Quote
Mathias
Senior Member
Lone Wolf Staff
 
Join Date: May 2005
Posts: 13,207

Old October 7th, 2022, 09:21 AM
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.
Mathias is offline   #6 Reply With Quote
TCArknight
Senior Member
 
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321

Old October 7th, 2022, 11:59 AM
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”.
TCArknight is offline   #7 Reply With Quote
Mathias
Senior Member
Lone Wolf Staff
 
Join Date: May 2005
Posts: 13,207

Old October 7th, 2022, 12:25 PM
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 by Mathias; October 7th, 2022 at 12:31 PM.
Mathias is offline   #8 Reply With Quote
TCArknight
Senior Member
 
Join Date: Jan 2007
Location: NW Arkansas
Posts: 1,321

Old October 7th, 2022, 01:47 PM
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[
	  trustme
	  
	  ~ 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>

Working on -
  • (SWADE) WIP Savage Rifts
  • Savage Rifts (Deluxe): Update link in This post
  • Star Trek Adventures: Update link in This post
TCArknight is offline   #9 Reply With Quote
Mathias
Senior Member
Lone Wolf Staff
 
Join Date: May 2005
Posts: 13,207

Old October 7th, 2022, 01:57 PM
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.
Mathias is offline   #10 Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 04:17 AM.


Powered by vBulletin® - Copyright ©2000 - 2024, vBulletin Solutions, Inc.
wolflair.com copyright ©1998-2016 Lone Wolf Development, Inc. View our Privacy Policy here.