• 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

Restrict Classes available for a race

athelu

Well-known member
Hello,

I would like to be able to prevent certain races in my game from being able to take certain classes. my search-fu did not reveal anybody else looking to accomplish this. Any help?
 
You have two ways of doing this:

a) You overwrite the existing classes or Race using Replace Thing ID and setup Pre-Req scripts that gives an error/warning message. This has the advantage of looking really nice in the selection process and getting the warning message to your players as they are picking races/classes. The really bad part is by using Replace Thing ID will cause issues with any class/race outside of CORE (cause of copyright). You will also run into issues down the road because any "fixes" to the replaced classes/races by LW will not longer be available to you and your players.

b) Create a new Mechanic and bootstrap new Simple Things to the Mechanic. Have each Simple Thing represent a single "Race" and then setup Pre-Req so that if Race X is taken with Class Y to give a warning message. Note the issue is that the message will ONLY appear "After" a player has taken both the class/race combo. The good side of this is you won't have to worry about copyright races/classes. WAY easier to maintain and setup and future fixes to classes/races will still happen for you and your players.

And assuming NOTHING above makes any sense to you I would recommend reading the Glossary of Terms for the Editor. Then check out FAQ#2 for all the places to learn about the editor including YouTube videos. :)
 
Thanks for the help. I am aware of these tools in the editor, but as of yet have not needed to use them.

Taking a look at one of the examples I found, I have the following:

if (hero.tagis[israce.rdwarf] = 1)

This however gives me an error saying "group israce not defined"
 
Last edited:
if (hero.tagis[race.dwarf] <> 0)
The basic syntax is correct but HL cares about capitalization. So its "Race.rDwarf". "rDwarf" is the unique id of the Dwarf Thing.

Macros are your friend here and you can do:
Code:
if (#hasrace[rDwarf] = 0) then

this should evaluate the current portfolio to see if the race is set to dwarf (I think).
What I am unsure of, is if I have built the field/content correctly. When I use the "findthing" button, and locate the race, it gives me something different (rDwarf). so, should I be using rDwarf? or is that a different way to reference the object?

I am wondering where I may find the canonical naming for these. Or better yet, even a list of the actual fields on the character. I have done a bit by picking out examples that already live in the system to lean some naming syntax for my custom items, but when it comes to some of the core items for the game system I am not sure where to find them.
All this is covered in the videos or FAQ#9. Basically turning on and using debug tools.

Outside of that and returning to the question at hand. You suggested that I create a simpleThing ( I think this is the Simple tab). There are a number of options - and I see you suggested using Pre-Reqs to perform this. I assume there is a reason this is preffered, and not the eval scripts, or Eval Rule?
Figured its easier to setup if each Race is its own Simple Thing. I say Pre-Req as they are easy to use instead of Eval Rules. You don't need the added power of Eval Rules. And we are doing pre-req logic so Eval Scripts won't help you.

This is allot of the basic information you would get from the videos. :)


Should I create a Pre-req for each class combination for the race, or would it be ok to just use a single if statement to test all of the possible offending classes?
On each Simple Thing I would do one Pre-Req per Class/Race combo.

In example lets assume Elfs can't be Inquisitor's
Code:
#hasrace[rElf] + hero.tagis[Classes.Inquisito] <> 2

Then you can add multiple Pre-Req like the above to take into account each situation.

To explain the above code some:
#hasrace[rElf] - This is a macro that tests for the presence or absence of the Race.rElf tag on the hero (ie character). The macro returns a Boolean of true (1) or false (0).

+ - We want to add the results of our two "functions" together to see if they are "both" true (ie 2).

hero.tagis[Classes.Inquisito] - Test for the presence or absence of the Classes.Inquisito tag on the hero. This function returns a Boolean of true (1) or false (0).

<> 2 - A Pre-Req is always setup to display the "error" on a condition that is not valid. If we are NOT 2 then we will not display what is in the "message" section of the pre-req.
 
Thanks, this helps a lot. I have started digging through the videos and have started using the debug tools which has gotten me a bit further.

Interestingly enough though I get "unspecified error parsing script" when trying what you put in the code block.

You mentioned this is a macro, which is great. The documentation also said macros could be found on the Menu, but this does not appear to be the case anymore. Is there someplace where all the Macros are listed?

Also - is there preference in using fields vs tags? I see in my testing that many of these overlap and I could go to either a tag or field for the information.
 
Interestingly enough though I get "unspecified error parsing script" when trying what you put in the code block.
Hmmm. I am not any where near HL so its possible I told you the wrong section to put the script into. I can double check once I am home. Some times I mix up the names... :o :o

You mentioned this is a macro, which is great. The documentation also said macros could be found on the Menu, but this does not appear to be the case anymore. Is there someplace where all the Macros are listed?
Yeah I think the list was removed. I use a google sheet that AndrewD2 put together HERE. He does a good job of keeping it updated.

Also - is there preference in using fields vs tags? I see in my testing that many of these overlap and I could go to either a tag or field for the information.
That is sort of a complex question. Tags are very powerful and should be used more than a field on average. But many times the value you need is easier to use a field. It sort of depends on WHERE you are running.

In example if I know I am writing a script on a Class Ability that is bootstrapped to a class I can simply access the field[xAllLvl].value to get the classes level. This is preferred because then the Class Ability is more generic and could be bootstrapped to a several different classes. In addition its less CPU to count the Classes.? tag on the hero.

Sorry don't have a really good answer to this one.... :(
 
Code:
#hasrace[rElf] + hero.tagis[Classes.Inquisito] <> 2
Yeah my bad! The above type of Pre-Req script goes on a "Expr-Reqs" section not the "Pre-Reqs" section. Expr-Reqs are the short simple way of doing error checking. You put in the basic script above and a "Message" and away you go.

For Pre-Reqs you would write the above like:
Code:
validif (#hasrace[rElf] + hero.tagis[Classes.Inquisito] <> 2)

Or like this:
Code:
~ Default to valid
@valid = 1

~ If we are an Elf and Inquisitor we are invalid
If (#hasrace[rElf] + hero.tagis[Classes.Inquisito] = 2) then
  @valid = 0
endif

Basically a Pre-Req gives you more power and flexibility in doing error checking as you can write full script logic with If/Then/Elseif logic.
 
ew. kinda stinks that things are handled differently in the various tools. Can I use the validif with then statements as well? or do I just drop to a if then?
 
ew. kinda stinks that things are handled differently in the various tools.

Can I use the validif with then/else statements as well? or do I just drop to a if statement instead?

And the message box is triggered when the state is determined to NOT be valid, correct? So any statement I create that does not meet the test results displays the message box. Just want to make sure I am understanding this correctly.

So here, 1=true, 0=false.

Code:
~ Default to valid
@valid = 1

~ If we are an Elf and Inquisitor we are invalid
If (#hasrace[rElf] + hero.tagis[Classes.Inquisito] = 2) then
  @valid = 0
endif

and the @ lets us declare a variable on the fly, that we can update, correct? Is this variable persistent for the time the characters is open? Or only during the time the check is performed? are these global variables that could be updated by other scripts/checks? Just trying to understand if I should be clearing them out or not.
 
@valid is a special variable predefined in Hero Lab. There is also @ispick which is 1 if the item is on the character and 0 if it hasn't been selected yet.
 
ew. kinda stinks that things are handled differently in the various tools.
This is a feature not bad thing. Each TYPE of script has different uses. Expr-Reqs are great because they are very small and simple to use. You don't have to know about @value or if/then/else logic. Just put in your condition and HL does the rest.

Can I use the validif with then/else statements as well? or do I just drop to a if statement instead?
validif and doneif are complete "IF" statements that return true/false. You can't use else or elseif logic with them. Hence why I gave both examples. These are constructs of the language that make doing code easier.

The above example shows that using the validif() is way easier to write as it's less lines of code. But if I "really" need more advanced logic checking (ie else) I can use a normal if statement with the @valid.

But nothing is "forcing" you to use one over the other. If you want to write everything using an elseif you can.

And the message box is triggered when the state is determined to NOT be valid, correct? So any statement I create that does not meet the test results displays the message box. Just want to make sure I am understanding this correctly.
Correct.

and the @ lets us declare a variable on the fly, that we can update, correct? Is this variable persistent for the time the characters is open? Or only during the time the check is performed? are these global variables that could be updated by other scripts/checks? Just trying to understand if I should be clearing them out or not.
@ variables are predefined HL variables as AndrewD2 said. If you want to make your "own" variable up you can do this:
Code:
var NewVar as string
var NewVar2 as number
They will init to blank/zeros. This is a scripting language so no clean up of memory is required by the end user. HL will do that for you. But the more variables you create the more CPU usage is used. Also you should always be using Tags for 99% of special testing not string compare.

Most Picks (Simple Things being an exception) you have access to the abValue fields. You should use those to store values. The reason is that a field on a Pick can be modified by other Scripts. Which is very useful.

For example lets say I wanted to make Power attack give an additional +1 bonus on damage. I could do this:
Code:
hero.childfound[fPowAtt].field[abValue2].value += 1

Or the above using a macro:
Code:
#value2[fPowAtt] += 1
 
Great, thanks for the help guys. this gets me along quite a bit actually.

I have it working, but notice that the exception is easy to miss. I guess this is just how HL handles these types of things. I was expecting a modal message box or something similar.

As to timing - since this is when a character is picking a level I noticed that there were 3 different timings around that : Pre-level, Levels, Post-Levels. Based upon what you said in a previous post I am assuming this check should happened Post-levels. My search-fu suggested this should maybe be happening in the 15000 range. (still trying to figure out timing).
 
I have it working, but notice that the exception is easy to miss. I guess this is just how HL handles these types of things. I was expecting a modal message box or something similar.
There is the "notify" function that will pop up a window. But that window will POP up every time anything changes on the character. But it would get your players attention.

You would have to make this into an Eval-Rule I think to make notify happen.

As to timing - since this is when a character is picking a level I noticed that there were 3 different timings around that : Pre-level, Levels, Post-Levels. Based upon what you said in a previous post I am assuming this check should happened Post-levels. My search-fu suggested this should maybe be happening in the 15000 range. (still trying to figure out timing).
Any Pre-Req checking should happen REALLY late like in the Validation timing actually. Unless you have some "specific" reason not too.

This is also why I like Expr-Reqs as they don't even ask for a timing they just always run at validation.

Most timing you are finding on the boards is about "Eval-Script" timing which is very important when they run.
 
So I think I have this working , and figured I would put my configuration in here in case anybody else is looking to do the same:

Created new Simple Thing:
UniqueID: stathdwarf
Name: Dwarven Class Restrictions

(from my time creating add-ons for other games, I always prefix my objects with a unique identifier - in this case 'ath' - so I know what is my stuff).

Within stathdwarf I created a Expr-Reqs (iserror, Highlight panel):
Message: Dwarves may not take the Class: Magus
Expression:
Code:
#hasrace[rathdwarf] + hero.tagis[Classes.Magus] <> 2
~This generates a warning message that is visible to the
~user via the notification box and status bar.

Within stathdwarf I created Pre-Reqs (IsError, highlight panel):
Message: (left blank)
Expression:
Code:
~ Default to valid
@valid = 1

~ If we are an Dwarf and Magus we are invalid
If (#hasrace[rathdwarf] + hero.tagis[Classes.Magus] = 2) then
 notify "Dwarves may not take the Class: Magus"
~This generates a pop-up window that the user must acknowledge

endif


Created a new Mechanic:
UniqueID: mathclassr
Name: Class Restrictions

As a bootstrap I added: stathDwarf
I also set the Source to my customization file.

I created a number of restrictions (10 classes actually) for dwarves and tested them and things work just how I would like.

Props to the guys on the forum who helped get me here.
 
(from my time creating add-ons for other games, I always prefix my objects with a unique identifier - in this case 'ath' - so I know what is my stuff).
Yep great plan. So much so that the editor supports this as a feature. You go to the Tools menu to use a user identity. It only uses 2 characters but that way say "at" or "ah" would get auto added to the Unique ID for you. :)

In HL the first letter or two is often used to identity the type of Thing. In example "f" is for Feat and "tr" for Traits. etc...

Awesome job! Glad this worked out for you. :)
 
Back
Top