View Single Post
Fenris447
Senior Member
 
Join Date: Sep 2017
Posts: 600

Old April 15th, 2020, 06:25 AM
And in case someone finds this post in the future, here's how it works. The usrCandid1 field allows you to generate a list for the player, based on criteria you provide. This criteria is based on tags, and thus is called a "tag expression." In the case of 'ra5CUAEASIChg', the player can pick between the attributes of DEX or INT. To do this, it uses this tag expression:

Code:
component.BaseAttr & (IsAttr.aDEX | IsAttr.aINT)
Let's tackle the first part: component.BaseAttr. This is kinda hard to describe (I'm still not an expert) but most "things" in Hero Lab have a component, sort of their core functionality. If you use the debug menus to look at the tags on a weapon, a hero, a spell, whatever, you'll probably find a component tag. For attributes, the component tag is BaseAttr. So the first part of this tag expression says "include everything that has the BaseAttr component tag." This whittles the list down to just those attributes, cutting out spells, armor, race, whatever.

Next is the ampersand '&'. This is additive, meaning that for something to show up on the list, it has to meet both the first criterion and the following one(s).

Then the parentheses begin. If you remember your algebra classes, you know that this encloses operations inside the parentheses, so anything outside them treats what is inside as one thing. In this example, it means that whatever output comes from inside the parenthesis, it's added to the first criteria by that ampersand.

Now we get two attributes. Dexterity and Intelligence both natively have IsAttr tags with their own values of aDEX and aINT respectively. The '|' here is what's important. That means 'or'. So inside the parentheses, this is saying "it can either have the aDEX IsAttr tag OR the aINT IsAttr tag." This is why having this inside parentheses is important. Without the parentheses, it would read like this:

Code:
component.BaseAttr & IsAttr.aDEX | IsAttr.aINT
Which would mean "either its a basic attribute and is dex, or it's int". That leaves the door open for anything besides a base attribute, that has that INT tag to come into this list for the player. And we don't want that. So we put the "or" inside the parentheses, to make sure the "or" is only between these two options. Both will show up, so long as both also meet the base attribute criteria outside the parentheses, since it's applied to anything inside the parentheses.

In the example from OP, we removed the INT portion, which means we don't need an "or", and we don't need parentheses since there's only two criteria and both must be met. So OP should have this:

Code:
component.BaseAttr & IsAttr.aDEX
See the problem? It's now going to only show you DEX as your choice. That's the opposite of what he wanted. He want's everything except for DEX. You might be inclined to do this, then:

Code:
component.BaseAttr & (IsAttr.aSTR | IsAttr.aCON | IsAttr.aINT | IsAttr.aWIS | IsAttr.aCHA)
Technically, this is correct! You're saying you want a base attribute, and saying it can be STR, CON, INT, WIS, or CHA. You're technically excluding DEX so it will give you what you want.

But it's a pain. Instead, you can use another operator: '!' The exclamation mark means 'not' (cue Borat Not Jokes youtube video). So instead of listing everything that isn't DEX, you just do this:

Code:
component.BaseAttr & !IsAttr.aDEX
That says "give me all base attributes that aren't DEX". Unless you've homebrew added some extra attribute types, you'll get a list of the five you want.


So we're good right? Well...no, not really. All we've done is generate a list. Hero Lab is intelligent enough to know that when you select Strength on the list, you want the Strength attribute. But it doesn't have instructions from us on what to do with that selection.

That's where the eval script comes in. Eval scripts are instructions we give to a Thing, in this case an ability, to perform operations. In this case, we're going to have a script look at what attribute was selected in that usrCandid1 field, take it, and apply the +1 ability score we want.

Code:
  ~ If we're disabled, do nothing
      doneif (tagis[Helper.Disable] <> 0)

      if (field[usrChosen1].ischosen <> 0) then
        field[usrChosen1].chosen.field[aStartMod].value += 1
        perform field[usrChosen1].chosen.assign[Custom.AttrUp]
        endif
The first part is boilerplate instructions that are always good to include in your eval scripts. It basically says that if something has added the Helper.Disable tag to this ability, the eval script is done and shouldn't run any more. An example of this is the Class Feature Variants. One variant feature replaces an existing class feature. So I programmed the variant feature to add the Helper.Disable tag to the original feature. Because that original feature has this in it's script, it knows not to do anything since it's been disabled.

Next we're checking to see if the player has actually picked something. When they do, Hero Lab automatically changes the value of "ischosen" to 1, which satisfies the "if then" statement looking for that.

Hero Lab then takes the attribute you've chosen and finds the value of the field within that attribute called aStartMod. This is basically the starting amount of that field. '+=' is a neat shortcut built into Hero Lab's script. It basically says "the thing is now equal to what it already was plus what ever number is here". So '+= 1' means "add 1 to whatever was already there."

I'm a little hazy on what the second part here does, and why both it and the previous line are necessary. But often in Hero Lab, you gotta roll with what works. And this works.

Found an issue with or have a suggestion for the 5e Community Pack? Please post it here at our GitHub.

Feel free to stop by the Lone Wolf Development Subreddit, for discussion of any and all LWD products and community efforts!
Fenris447 is offline   #3 Reply With Quote