• 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

Strange Pre-requisite

Lawful_g

Well-known member
I am making a pre requisite script for a Custom Ability, the knowledge ranks required goes up by 2 each time one of several other custom abilities is taken. A Maximum of 3 of these abilities can be taken.

I made the 3 pre-reqs below, trying to use that ? trick you showed me mgehl.

Message: Knowledge (dungeoneering) 8 ranks required

@valid = 1

var prereqs as number
prereqs = hero.childcount[cPaADW?]

if (prereqs = 0) then
if (#skillranks[kKnowDun] < 8) then
@valid = 0
endif
endif

Message: Knowledge (dungeoneering) 10 ranks required
@valid = 1

var prereqs as number
prereqs = hero.childcount[cPaADW?]

if (prereqs = 1) then
if (#skillranks[kKnowDun] < 10) then
@valid = 0
endif
endif

Message: Knowledge (dungeoneering) 12 ranks required
@valid = 1

var prereqs as number
prereqs = hero.childcount[cPaADW?]

if (prereqs = 2) then
if (#skillranks[kKnowDun] < 12) then
@valid = 0
endif
endif


I get an error "Non-existent thing cPaADW referenced by script", so I changed things a little, switching the definition of prereqs to:
prereqs = hero.tagcount[SpcReplace.cPaADW?]

But for some reason, there only appears to be the lowest requirement show, even if several of the other custom abilities have been taken.

Any recommendations?
 
The XXX? format only works for tags, not when searching for a pick with childcount. So, you can't have a ? in childcount.
 
Last edited:
Try creating a character for whom this ability would be valid. Now, in the develop menu, floating info windows, select "show hero tags". Count the number of SpcReplace tags there. Now add a copy or two of the special, and count.

The answer's 0. There's nothing in the program that forwards the SpcReplace tags from the special to the hero. Therefore, hero.tagcount[SpcReplace.cPaADW?] will always be 0, which is why you're only ever seeing the first prereq.

What it sounds like you have is a grouping of custom abilities. Because you want to restrict the hero to having a maximum of 3, I'm guessing that they're not the only custom abilities this class can take. So, what you want to do is to create a tag that identifies your grouping. That's what the User tag group that's at the bottom of most everything in the editor is for. Create a tag like "DungeonSpc" (Dungeoneering Special) (give it a better name, of course) in the User group, and add it to all these specials.

After that, you can go searching for all the custom specials on the hero that have that tag, and add one to a count each time you find one:

Code:
var speccount as number
foreach pick in hero where "component.BaseCustSp & User.DungeonSpc"
  speccount += 1
  nexteach

BTW, if these specials are the only custom abilities this class can take, and your limit of three was enforced by the custom ability requirements of the class, this becomes easier. You don't need to create the User tag group, since you know that only the specials defined for this class are the things you want to look for.

Code:
var speccount as number
foreach pick in hero where "component.BaseCustSp & SpecSource.cHelpRog"
  speccount += 1
  nexteach

Note that the script I wrote there is looking for Rogue (cHelpRog) specials - replace that with the ID of the class these are for.

Now, think about what it is you want to test - for the first of these abilities that's added to the hero, there needs to be 8 ranks of dungeoneering, the second requires 10, and the third 12. Express that mathematically:
dungeoneering ranks >= (4 + special count) * 2

or:

Code:
if (#skillranks[kKnowDun] >= (4 + speccount) * 2) then
@valid = 1
endif

(Oh, and look at your code - you used less than (<) - did you mean to use less than or equal to (<=)?)

The next question; is this prereq on the things that are being counted? (Does everything with User.DungeonSpc have this prereq?)

If so, what happens if your character has 8 ranks of Dungeoneering, and takes the first copy? Once added to the hero, the hero has prereqs = 1, so 10 ranks of dungeoneering are required, and the special becomes invalid once it's added.

So, your script needs to know whether it's operating on a thing (which is the case if the special is still in the list of available specials) or on a pick (which is the case once it's been added to the hero).

Rob and Colen anticipated this - the special variable @ispick is equal to 1 if the script is running on a pick, and equal to 0 if the script is running on a thing. (BTW, @ispick is only available in validation scripts.)

Revising the previous equation:
dungeoneering ranks >= (4 + special count) * 2

we now have:
dungeoneering tanks >= (4 + special count - @ispick) * 2

That way, when you've added 0 copies, you'll need (4+0-0)*2 = 8 ranks. Once you've added 1 copy, the special count will go up to 1. The custom abilities that are still in the list, waiting to be picked, will have @ispick = 0, so they'll need (4+1-0) * 2 = 10 ranks. The copy that you've selected will have @ispick = 1, so it will need (4+1-1) * 2, or 8 ranks.

Putting it all together, for the ease of copying:

Code:
var speccount as number
foreach pick in hero where "component.BaseCustSp & User.DungeonSpc"
  speccount += 1
  nexteach
 
if (#skillranks[kKnowDun] >= (4 + speccount - @ispick) * 2) then
@valid = 1
endif

Your limit of three will be a second prereq (unless these are the only specials this class can take, and you're using the class to enforce how many specials it gets:

Code:
var speccount as number
foreach pick in hero where "component.BaseCustSp & User.DungeonSpc"
  speccount += 1
  nexteach
 
if (speccount - @ispick <= 3) then
@valid = 1
endif
 
Last edited:
Custom messages:

prereqs in HeroLab can generate messages inside the script. What you're trying to do is a perfect example of when to so this.

@message is a special variable that's available to prereqs. When you begin a prereq script, it has been set as whatever you entered into the message field. Note that even if you intend to replace the whole thing, you do need to enter something as the message for a prereq. This way, if you don't change @message during the script, it begins equal to whatever was entered into the message field, and ends equal to whatever was entered into the message field - and is then shown to the user when the prereq isn't met.

So, after checking the number of ranks of dungeoneering against the number of specials, let's generate a message about that:

Code:
var dungeonreq as number
dungeonreq = (4 + speccount - @ispick) * 2
@message = "Knowledge (Dungeoneering) " & dungeonreq & " ranks required."

As long as you have to create a variable that stores the number of ranks that are required, let's use it earlier on:

Code:
var speccount as number
foreach pick in hero where "component.BaseCustSp & User.DungeonSpc"
  speccount += 1
  nexteach
 
var dungeonreq as number
dungeonreq = (4 + speccount - @ispick) * 2
 
if (#skillranks[kKnowDun] >= dungeonreq) then
@valid = 1
endif
 
@message = Knowledge (Dungeoneering) " & dungeonreq & " ranks required."
 
Last edited:
Back
Top