← PRC8
Heroes Of Profound Enlightenment 8:: Manual :: PrC Making :: Guide
- Introduction
- Prelude
- Tools of the Trade
- IRC Information
- Script Compiler
- CVS Information
- File Overview
- Getting Started
- PRC Rules and General Guidelines
- Classes.2da
- Other Required 2da's
- Feat.2da
- Spells.2da
- Creating Active Feats
- Creating Combat Feats
- Creating Passive Feats
- Creating Multi-Function Feats (Sub Radials)
Introduction
I have decicided to create a tutorial on how to make a Prestige Class and how to make it compatible with the Heroes Of Profound Enlightenment 8. I hope this allows new custom content builders to help make their content compatible with the PRC8. This will make it easier for them to use both their content and ours, and also make it easier on us if they would allow us to add their content to our pack.
Prelude
That being said, I would like to reiterate the information in the basic section with the following links. I cannot stress how useful these two links are when developing. The 2da coverage from the CCG is very useful when making feats and spells. The Lexicon has some good tutorials for those new to scripting. In addition, the Lexicon has a listing of all the functions in the engine with information on how to use them. This is very useful if you script outside of the toolset as many of us in the PRC do.
For information on 2DAs, harcoded limitations, etc. Check the NWN:EE Developer Wiki.
For questions concerning scripting check out the NWN Lexicon.
Tools of the Trade
The following is a list of utility programs that are quite handy for making PrC's.
| NotePad | A basic text editor... .2da and .nss files are both plain text files, making a plain text editor a definite must. |
| TextPad | Another text editor. Can be found here. This text editor can mass replace text in many files rather quickly. Excellent when making mass replaces. Syntax highlighting for NWN can be found on the internet. |
| NotePad++ | Another text editor. Can be found here. This does everything Notepad & TextPad do, but more & better. Has a configurable NWN:EE IDE plug-in you can find here |
| Aurora Toolset | Occasionally the toolset is useful. Especially, if you are making summonable critters or dialogues. |
| CCCH | The CODI Custom Content Helper. Has a .tlk editor as well as some pretty decent 2da editing capabilities. Some use it, some do not. Definitely worth mentioning though. It can be found here. |
| Axe Murderer's Killer TLK | My preferred TLK editor that isn't NotePad++. Good for merging. It can be found here. |
| NWN TLK Editor 1.0 | A very old TLK editor. It can be found here. |
| TlkEditEE | My prefered 2DA editor that isn't Excel. It's on Github. |
| NWN Explorer | A good tool to look through all the standard files of the game. Great for checking out the games icon when you want to modify them to create new ones. It can be found here. |
| Discord | We use this to communicate, grab it here |
Back to Top
IRC Information
- Download mIRC here.
- Go to "Tools" and select "Options"
- Open the "Connect" tree and select "Servers"
- Click the "Add" button
- Fill in Description and Group as "PRC"
- Fill in IRC Server as "irc.neverwinterconnections.com"
- Click the "Connect to Server" button
- Once connected type in "/join #terran"
Additionally, if you want to automatically join a channel on startup you can again go into Tools > Options > Connect > Options.
- Click the "Perform" button.
- Check the "Enable Perform on Connect" checkbox.
- In the "Perform Commands:" textbox fill in all commands you want to run.
- Type in "/join #terran" to connect to our channel.
Back to Top
Script Compiler
The PRC team has done some modifications to Torlack's compiler so that we can compile all of our scripts outside of the compiler. It was not something we orginally wanted to do, but it seems we hit some kind of hardcoded limit in the standard compiler and could no longer compile our work. We decided to release this compiler publicly for developers to use you can get a link to it in the downloads section of the website.
To make any script changes to the PRC you will need to:
- Extract the include files from prc_include.hak into a temporary "include" folder in the same directory as the compiler.
- Run the compiler on your scripts:
Usage:
nwnnsscomp [-cdegoqx] [-t#] [-v#] [[-i pathspec] ...] infile [outfile]
pathspec - semicolon separated list of directories to search for files.
infile - name of the input file.
outfile - name of the output file.
-c - Compile the script (default)
-d - Decompile the script (can't be used with -c)
-e - Enable non-Bioware extensions
-g - Don't produce ndb debug file
-i - Add Search Path
-o - Optimize the compiled source
-q - Silence most messages
-x - Extract script from NWN data files
-vx.xx - Set the version of the compiler
-t1 - Perform a compilation test with BIF scripts
-t2 - Perform a compilation test with the given module
-t3 - Optimization space saving report with the given module
-t4 - Perform a compilation test with the given file or files
-i is basically an include folder, though the system may look for your compile file in there as well if you are elsewhere
- Copy the modified .ncs files into a custom hak and make sure that hak is on the top of the list in the module properties.
Back to Top
CVS Information
Accessing the PRC Bug Report Tracker:
- PRC Bug Tracker
- You will not be able to add bugs to this, only PRC members can do so.
- Place CVS bug reports in the PRC Custom Content Help forum.
- See this thread for bug reporting guidelines.
- Because several of the important PRC files are .exes, they are known to work fully only on Windows. Sorry, Linux and Mac users.
- Download and install Tortoise CVS. Follow their install instructions completely.
- Right click on your desktop or other folder where you wish to download the PRC CVS. This will take roughly 750 megs, more if you download both the NWN1 and NWN2 repositories.
- Select CVS, and then Preferences on the opened menu.
- Under the Advanced tab, change the Network Compression to "6 - Good". Hit ok.
- Select CVS Checkout
- Place this line in the CVS Root: ":pserver:anonymous@cvs.nwnprc.berlios.de:/cvsroot/nwnprc"
- Place either "nwnprc" or "nwn2prc" in the module line.
- Select ok. It will begin to check out. This will take a long time. Simply wait until it is complete.
- Open the nwnprc or nwn2prc.
- Create a text file called config.make (.make is the file extension).
- Open this file, and type in these three lines for NWN1: Replace the NWN_DIR with where your NWN1 directory is locatedCode:NWN_DIR = C:\NWN PRC_VERSION = 31d PRC_INSTALLVERSION = 3.1d
- Open this file, and type in these three lines for NWN2: Replace the NWN_DIR with where your NWN1 directory is located (Yes, still NWN1, unfortunately).Code:NWN_DIR = C:\NWN PRC_VERSION = 31d PRC_INSTALLVERSION = 3.1d MY_DOCS = C:\Documents and Settings\Username\My Documents\Neverwinter Nights 2
Replace MY_DOCS with the location of your NWN2 directory in your My Documents folder. - Your installation should now be complete. To test this, double click make.bat. This is the file that will compile the entire PRC. It will only compile files that have been modified, or have had their includes modified, since the last compile.
- Upon a finished compile, the program will copy all PRC files into your NWN dir's hak, tlk, and erf folder. This will overwrite any existing files, including public release PRC files. Please be aware of this fact.
- This will have more errors than a standard release. Follow instructions below to report them.
- Compile all files and test them before submitting to the PRC.
- Enjoy. If you have any questions, comments, or concerns with this process or with adding content to the PRC, post them in the PRC Custom Content Help forum. Place all bug reports regarding CVS in this same forum. See this thread for bug reporting guidelines.
- All files and emails should have PRC CVS in the title.
- Compress the file and email to PRCDev@GMail.com.
- OR: Use YouSendIt.com
- OR: Another electronic submission format (RapidShare, providing a download link, etc).
| 2das | 2das go here |
| Craft2das | 2da files specifically for the crafting systems |
| DevNotes | Developer notes |
| epicspellscripts | Epic spell scripts |
| erf | Files that go into the erf |
| gfx | graphics - icons and the like |
| include | Includes go here |
| newspellbook | Newspellbook files |
| ocfixerf | Files that go into the ocfix erf |
| others | Item and creature blueprints, some vfx |
| psionics | Psionics files |
| race2das | 2das used by races |
| scripts | General code |
| spells | Spell code |
| tlk | TLK files |
| tools | Tools used by the PRC (can be very helpful for other projects) |
| users | Personal directories used by PRC members, mostly to store works in progress before merging with the rest of the code |
You will likely notice there are a few directories I did not mention above. Any directory containing "objs" in its name holds compiled data. This prevents PrC makers from having to compile every single script whenever they use the Make System. The tempcpl directory is an empty directory that temporarily stores data while compiling.
Back to Top
File Overview
There are many files in the PRC pack, so I will label those most important to PrC makers, and what they do. If you are using the .hak files they have the same name as the directories. For example, /2das is the same as prc_2das.hak.
| Folder / File | Description |
|---|---|
| /2das | directory |
| classes.2da | The 2da containing all classes. For more information check out the Custom Content Guide. |
| feat.2da | The 2da for feats... again check the CCG for more info. |
| spells.2da | The 2da for spells. |
| masterfeats.2da | This 2da is for feats like Favored Enemy or Weapon Focus, where it is a single feat, but you have to select a certain version of the feat. |
| skills.2da | The 2da for skills |
| cls_skill_****.2da | These files determine the class and cross-class skills for your PrC. They reference the value in skills.2da. |
| cls_pres_****.2da | These files list requirements for a prestige class. |
| cls_feat_****.2da | These files contain the feats and at which level a PrC gains them. |
| cls_bfeat_****.2da | This file contains bonus feat allocation for the PrC. Bonus feats are those such as fighter feats or rogue bonus feats. Also note that most classes gain bonus feats during epic levels. |
| /include | directory |
| prc_class_const.nss | All FEAT_* constants go in here. |
| prc_feat_const.nss | All CLASS_TYPE_* constants go here. |
| prc_racialtypes_const.nss | All RACIAL_TYPE_* constants go here. |
| prc_spell_const.nss | All SPELL_* constants go here. |
| prc_ipfeat_const.nss | All constants dealing with item properties go here. |
| prc_inc_function.nss | This file is not necessarily the most intuitively named. While it does contain a few functions used by several classes, its main use is the heart of the passive feat system. Passive feats are applied by calling a class specific script on multiple events, such as onequip, onload, and onlevel. When a line is added into the EvalPRCFeats function, it will execute the script on all the main events. This saves us from having to put the code in multiple places. If your passive feats are not working, be sure that you added the proper line of code here. It is an easy thing to forget, I know I have done it before. Another important function in this file is DeletePRCLocalInts. This file is used to delete local integers stored to make sure an ability is or is not updated. For instance, if you have an ability that can upgrade on level up, then you would want to delete the local int so that your code will re-add the bonus. Just make sure you use the SetCompositeBonus function described later in the guide. While those are the two primary functions, you might find some of the other functions useful. |
| inc_item_props.nss | Another very important file. Here you will find the aforementioned SetCompositeBonus function as well as numerous other functions that deal with creature skins and item properties. |
| prc_inc_util.nss | A new file created for utility functions. Those that could be useful for multiple classes or abilities. |
| prc_inc_clsfunc.nss | A file for all class functions that need to be included in multiple files. This prevents us from having many includes for various classes. |
| prc_alterations.nss | This one is important if you ever need to determine a creatures RACIAL_TYPE_* constant. This file houses the MyPRCGetRacialType function. |
| inc_combat.nss, inc_combat2.nss, prc_inc_combat.nss |
inc_combat and inc_combat2 are the original coding used to simulate combat for attacks such as the Arcane Trickster's Impromtu Sneak Attack ability. prc_inc_combat took the data in the previous files and added to it. New coders should use prc_inc_combat, though I thought I would mention all of them so coders do not get confused. |
| prc_inc_sneak.nss | This file contains numerous functions used to simulate sneak attacks and to add sneak attacks to prestige classes. In order to make new classes with sneak attack stack, we add a dummy feat to the player. The code that gives them the sneak attack feat(s) is placed in this file. |
| prc_inc_unarmed.nss | Determines the unarmed "creature weapon" damage of many of the monk PrC's. For those making a monk PrC that has fist damage upgrades, this is the file to look into. |
| prc_inc_spells.nss | Contains many useful functions for determining caster level, mostly. The goal is to consolidate all caster level functions into this file. In the future, all new PrC's that add to caster levels should be added to the GetArcanePRCLevels and GetDivinePRCLevels functions. Very little else should be necessary, except when new casting feats are created. |
| prcsp_engine.nss | Functions that determine spell resistance and if a player resists a spell. |
| prcsp_spell_adjs.nss | Functions that return spell penetration bonuses. |
| /scripts | directory |
| prc_prereq.nss | This script allows a PrC builder to add in custom scripts to determine if a player can take a PrC. Bioware's 2da system had a few limitations that prevented us from properly doing some class requirements. A good example would be the Tempest. Tempests need Ambidexterity and Two-Weapon Fighting or Ranger Dual wield. In addition, they need Weapon Focus(any melee weapon) or Weapon Finesse. The 2da files FEATOR required did not allow two or conditions, it ended up working if you had any of the feats. We needed to script in the check for Ranger Dual Wield or Ambidexterity and Two-Weapon Fighting. |
| prc_enforce_feat.nss | This script is used to circimvent some issues in the bioware engine and how feats are granted. There are several things that cannot be done with the 2da files such as race or gender specific feats. In adddition this file is also used to limit bonus feats and the levels they can be gained at. This was required for classes such as the Red Wizard as they are only supposed to take the Limited School feats at certain levels. |
| /race2das | directory |
| race_feat_****.2da | This 2da holds all the racial feats for the specific race. Note: This also contains feats for spells associated with a race. |
| racialtypes.2da | This file stores the base information about each race. Contains information that links it to the aforementioned race 2das. |
| /racescripts | directory |
| race_hb.nss | Any abiltiies that require a heartbeat to check go in here. Things like Light Blindness/Sensitivity. |
| race_skin.nss | All bonuses that are applies to the skin for a race. Damage Resistance, Natural Armor, etc. Most things a race would need are already implemented, just need to give a race the proper feat. |
| /spells | directory |
| x2_s3_onhitcast.nss | Script used for On Hit: Unique Powers. It should not be needed for most classes, but I figured it was worth mentioning. |
| /tlk | directory |
| prc_consortium.tlk | The only file in this directory. The tlk file holds the in game text for all the PrC's, feats, spells, etc. |
Back to Top
Getting Started
If you plan to make your PrC compatible with the PRC pack, then it is best to get the most current files from the PRC. To get those files, you will likely need to contact Stratovarius. The reason this is important is because you will want to make sure you are using open .tlk, and .2da slots. If you are not, then either another PRC member or yourself will need to move a lot of data around to add your PrC.
Free 2da entries can be seen in the 2das in cvs. Free tlk entries can be found using the tlksearch utility in the tools directory. See the header block in the source code (tlksearch.c) for information on how to use the tool. The first thing I usually do is make a text file. I store a main text file for each PrC I make. In this file I keep all the important things I will need. The class desription, bab, class skill list, abilities, ability descriptions, etc. Having all of this in a text file is very convenient since you can copy / paste the information into the .tlk file. It is also very handy having the PnP ability description in an easy to access location while you are scripting its abilities.
The second thing I do is open up a another text file that has a small template for the spell, feats, and classes.2da. Doing all the 2da work outside of the 2da's is good because you can copy/paste the data at your leisure. A few of us PRC members learned how nice it can be, especially when two people are both editing the same 2da file... One persons change can overwrite anothers, it is always a good idea to have a backup.
Throughout PrC making you have to edit quite a few files. I suggest using Textpad because you can have a small section of the window list all open files. This is great for switching from one file to another quickly, and leaving them all close at hand if you need to edit any of them. Most useful while compiling and debugging scripts.
Back to Top
PRC Rules and General Guidelines
The following are things that should or must be done for all classes. It is a short list of guidelines for those interested in making files compatible with the PRC.
- All files MUST be in a 16.3 naming format, no exceptions.
- No hex numbers for 2da enteries.
- No class abilities on rods or items. They must be integrated with the class.
- All permenant stat bonuses must conform to our existing system. Take a look at the prc_heartwarder for an example.
- Use the appropriate constants instead of integers in scripts:
- Add CLASS_TYPE_* constants to prc_class_const.nss.
- Add FEAT_* constants to prc_feat_const.nss.
- Add SPELL_* constants to prc_spell_const.nss.
- Add IP_CONST_* constants to prc_ipfeat_const.nss.
- Add RACIAL_TYPE_* constants to prc_racial_const.nss.
- Name all class scripts prc_className_abilityName. OR
Name all class scripts className_ablityName.
Back to Top
Classes.2da
Naturally, if you want to make a PrC, you are going to have to edit classes.2da. Upon first opening the file you might say, "What in the nine hells is all this junk?!"
The 2da's are setup much like a database, or spreadsheet, except of course they are only text files. The first column is the ID column, the number of the row.
I would like to note a few things before moving on. One major thing to note is how the tlk data works. Bioware has has reserved a ton of spaces so that no custom tlk should ever conflict with their own. When making classes we often use a custom tlk as you will see in the column descriptions below. When using a custom tlk we take our actual entry number and add, 16777216, to it.
All tlk entries before 16777216 are read from the standard default.tlk. Note: 16777217 is for BadStrRef and should not be used.
| Column | About the Column |
|---|---|
| ID Number | The value that the CLASS_TYPE_* constant should equal. |
| Label | Arbitrary column for naming the class. Useful for those looking at the 2da |
| Name | The tlk entry # containing the name of the class. For example, custom tlk #50000 = 16827216 |
| Plural | The tlk entry # containing the plural name of a class. |
| Lower | The tlk entry # containing the class name in lower case. |
| Description | The tlk entry # containing the class description. This includes information such as the level up table and such. |
| Icon | The name of the icon file. This is not case sensitive. Files must be 24-bit tga files to show up properly in game. File name should be less than 16 characters long. |
| HitDie | The die rolled when the class levels up. (Ex: 4, 6, 8, 10, 12) |
| AttackBonusTable | The name of the attack bonus table used by the class. This is usually one of the following: CLS_ATTACK_1 - Fighter BAB, max pre-epic +20. CLS_ATTACK_2 - Rogue BAB, max pre-epic +15. CLS_ATTACK_3 - Wizard BAB, max pre-epic +10. CLS_ATTACK_4 - A file added by the PRC, gives +0 BAB. |
| FeatsTable | CLS_FEAT_**** file. The feats your class gets, each class has its own file. You have to make one for your class. |
| SavingThrowTable | CLS_SAVTHR_**** file. You can make your own, though most classes use very similar saving throw tables. You will likely be able to use the same one as another class. |
| SkillsTable | CLS_SKILL_**** file. The file that lists class skills for this class. You have to make one for your class. |
| BonusFeatsTable | CLS_BFEAT_**** file. This file lists any "bonus" feats a class can select (like fighter, wizard, or rogue) at certain levels. You have to make one for your class. |
| SkillPointBase | The base skills per level of the class. |
| * SpellGainTable | |
| * SpellKnownTable | |
| PlayerClass | 1, unless you don't want people to play it. |
| SpellCaster | Can class cast spells? 1 = True, 0 = false. |
| Str, Dex, Con, Wis, Int Cha |
The classes ideal ability scores, used for recomended and auto-level. |
| PrimaryAbil | The classes primary ability score. Again, used for that recommended button. |
| AlignRestrict | Possible Values:
0x00 - No restrictions 0x01 - No Neutral 0x02 - No Lawful 0x03 - No Lawful, No Neutral 0x04 - No Chaotic 0x05 - No Chaotic, No Neutral 0x06 - No Chaotic, No Lawful 0x07 - No Chaotic, No Lawful, No Neutral 0x08 - No Good 0x09 - No Good, No Neutral 0x0A - No Good, No Lawful 0x0B - No Good, No Lawful, No Neutral 0x0C - No Good, No Chaotic 0x0D - No Good, No Chaotic, No Neutral 0x0E - No Good, No Chaotic, No Lawful 0x0F - No Good, No Chaotic, No Lawful, No Neutral 0x10 - No Evil 0x11 - No Evil, No Neutral 0x12 - No Evil, No Lawful 0x13 - No Evil, No Lawful, No Neutral 0x14 - No Evil, No Chaotic 0x15 - No Evil, No Chaotic, No Neutral 0x16 - No Evil, No Chaotic, No Lawful 0x17 - No Evil, No Chaotic, No Lawful, No Neutral 0x18 - No Evil, No Good 0x19 - No Evil, No Good, No Neutral 0x1A - No Evil, No Good, No Lawful 0x1B - No Evil, No Good, No Lawful, No Neutral 0x1C - No Evil, No Good, No Chaotic 0x1D - No Evil, No Good, No Chaotic, No Neutral 0x1E - No Evil, No Good, No Chaotic, No Lawful 0x1F - No Evil, No Good, No Chaotic, No Lawful, No Neutral |
| AlignRstrctType | Possible Values:
0x0 None 0x1 = Law/Chaos 0x2 = Good/Evil 0x3 = Both |
| InvertRestrict | Invert the alignment restriction? True = 1, False = 0. |
| Constant | CLASS_TYPE_* This refers to the constant that the class goes by in scripts. |
| EffCRLvl01 - EffCRLvl20 | 1 to 20 respectively... never seen it as anything else. |
| PreReqTable | CLS_PRES_**** file. The prerequisite file for the class. You have to make one for your class. |
| MaxLevel | The classes maximum level possible. |
| XPPenalty | Will this class cause an XP penalty? True = 1, False = 0. For PrC's this should always be 0. |
| * ArcSpellLvlMod | Arcane spell level modifier. |
| * DivSpellLvlMod | Divine spell level modifier. |
| EpicLevel | At what level does the class start being epic. |
| Package | The line number in Packages.2da. This refers to what the class starts with. |
It is often easier to just copy another class row and then modify the values you need to change.
Back to Top
Other Required 2da's
As you may have noticed while looking at the classes.2da section, there are several 2da files that will have to create for your new PrC. The required files include cls_pres_****.2da, cls_skill_****.2da, cls_feat_****.2da, and cls_bfeat_****.2da.
The **** in those file names should be something short, about 4-6 characters, for your PRC's name. For example for the Frenzied Berserker I used FREBZK. It must be different from any other class, and something you can remember later is always a good thing.
It is usually much easier to just copy another file and rename it. Then modify its contents to suite your needs.
Each of the files has their own data inside of them and their own uses. Firstly, the cls_pres_****.2da is used to set your PrC's prerequisites. The first column is index number, I am not sure if it is even required. It is recommended to make them sequential numbers starting at 0. The second column is just a text reminder of that the prerequisite is.
| ReqType | Description | ReqParam1 | ReqParam2 |
|---|---|---|---|
| FEAT | A feat required for the class. | feat # in feats.2da | **** |
| FEATOR | This feat OR another feat that uses FEATOR. | feat # in feats.2da | **** |
| RACE | Only races allowed to take this class. | race # in racialtypes.2da | **** |
| BAB | Minimum BAB required to take class. | any # | **** |
| ARCSPELL | (Do not use this with PRC) | spell level required | **** |
| SKILL | Skill points required for class. | skill # from skills.2da | skill ranks |
| VAR | Variable name that turns this class on or off. | 0 = on or 1 = off | **** |
You might be wondering why you should not use "ARCSPELL" with the PRC. It is because we actually have a script set for the Arcane or Divine Spell casting level detection. This was done because using the 2da's did not work properly, and because there were also other prerequisites that could not be done using the 2da. Some good examples of "impossible" class requirements include: gender, deity, cleric domain(s), etc. This information was easily accessible through scripting, so we chose to use a custom script as a prerequisite. If your PRC needs to do something that the 2da cannot do, then refer to prc_prereq.nss.
All classes should have at least one VAR requirement. Typically this is PRC_Allow_****. Of course, the ****'s are whatever you want to represent that class with. This variable can be used by module builders to turn the whole class off if they want too, it makes it easier for world builders if they feel the PrC causes imbalance in their world.
Some classes will have a second variable. This is typically associated with the custom prerequisite script. If a player's character fails to pass a check for the special requirements. This variable is turned off, causing the player to not have access to the class.
The second file is cls_skill_****.2da. Once again the first column is an index number. This file really only has two important things: the SkillIndex which points to a line in skills.2da, and the ClassSkill which is either 1 or 0. Any skill that has a 1 in the class skill column is a class skill. One thing to note is that any class that doesn't a have a skill listed at all, cannot take the skill at all. For instance, if you don't have Use Magic Device listed, you will not be able to put any points in it as a cross-class skill. Most classes should not have Use Magic Device or Animal Empathy in their class list, unless they do in PnP.
The third file is cls_feat_****.2da. This file contains all the feats your PrC will gain upon level up. It also contains all the bonus feats that the PrC can select, and all the epic feats available to the class.
| Column | Description |
|---|---|
| FeatLabel | Short name to describe what feat it is. Can be anything really. |
| FeatIndex | feat # in feat.2da |
| List | Possible Values: 0 = Selectable on level up 1 = Regular feat or bonus feat (Figher/Wizard bonus feats) 2 = Bonus feat only 3 = Automatically granted feat |
| GrantedOnLevel | The level PrC gains the feat, or -1 for any time. |
| OnMenu | Is shown on class radial menu? Yes = 1, No = 0 |
On to the last file, cls_bfeat_****.2da. This file just has a listing of levels and a 0 or 1. If the class gets a bonus feat at that level, then put a 1. If not, then put a 0.
One thing to be careful of when doing this file is to watch your epic level progression. For example if your PrC has a max level of 30 and starts being epic at level 10, then you will need to have a bonus feat every X levels starting at level 10. This is because all classes gain their feats during epic levels as bonus feats!
Back to Top
Feat.2da
There is not much I can really say about feat.2da. It is mostly quite straight forward. If you run into any questions the best place to look is the CCG. I even went ahead and got a direct link for you. Click here for feat.2da information!
Now to make this section helpful, I would like to note that almost all PrC abilities will actually need to be done using feats. Typically, if a PrC can cast something X times a day, we create a feat with the proper uses per day, and point it to the correct spell entry in spells.2da. The same principle applies to creating custom abilties. I will cover this again in better depth in the Creating Active Feats section.
Back to Top
Spells.2da
Spells.2da is much more confusing than the feat.2da. I definitely recommend bookmarking this guide, or the direct link to spells.2da page on the CCG. Speaking of the direct link, here it is.
Since most active PrC abilities end up being spells, you will likely find yourself in this file a lot more than you would like. That is why I recommend bookmarking the guide. I know I often forget what all the stuff means. The easiest way to make a new spell/feat is to simply copy a similiar one as a reference, and change everything you need to.
Back to Top
Creating Active Feats
What is an active feat? An active feat is a feat that the player must willingly activate. Something like Smite, Acrobatic Attack, Mimic, Wildshape, etc. Creating these feats is a rather straight forward process. Most of the following steps can be done in any order you prefer, though it sometimes makes more sense to do them in a certain order.
- Create all required entries in the .tlk file
- Write script(s) that perform the required action(s)
- Create icon(s)
- Create an entry in feat.2da
- Create an entry in spells.2da
- Create an entry in cls_feat_****.2da
- Create an entry in prc_feat_const.nss
- Compile script, test script, debug script
- Refer to step 8, until it works
You can also do each part in sections. Making the tlk entries, and then the 2da entries, then testing if the feat displays up in game. If it shows up properly, then you can code the script that'll make it work. There really is no set way to do it, as long as all of those steps get finished eventually.
Back to Top
Creating Combat Feats
A combat feat is a special kind of active feat. Combat feats are those that are directly linked to an attack of some sort. Some good examples are the Arcane Trickster's "Impromtu Sneak Attack", the Foe Hunter's "Death Attack", and the Ravager's "Cruelest Cut". All of those special abilities do something special when you hit the enemy. A feat with limited uses a day (usually) that deals special damage through an attack is a combat feat.
If you did not already know, the actual game engine's combat system is hard coded. You cannot simply write a script that says. "Add this players cha bonus as divine damage applied to the enemy if they hit them on the first strike of this attack round."
You are probably thinking right about now... Hey! The PRC has made those feats, it must be possible! ... Indeed, remember I said you could not "simply" tell the game to do that... At least not until the PRC created the "Combat Simulation System".
It all started with inc_combat.nss. While that script was very helpful it was still missing several nice features. Along came inc_combat2.nss. This file added even more functionality to the previous combat system. Things like elemental weapons, spell effect calculations, etc. It made the system much calculate attack bonus and damage more acurately than it did before. While inc_combat2.nss was being written and upgraded, Oni5115 started to develope prc_inc_combat.nss. He used the majority of the code from inc_combat.nss and inc_combat2.nss, piled on a bit of new functionality, documented the code, and made a system that is far more scripter friendly.
Note: You will need numerous PRC files in order to use the Combat Simulation System. The script is not standalone, though it is not tied to the older combat includes. The easiest way to find out what files you will need are to simply open "prc_inc_combat.nss" and take a quick look at the list of included files. The list is also helpful for scripters so that they do not include the same files multiple times.
Now, on to the good part! Coding a combat script.
A good example of what you might want to do is the Ravager's "Cruelist Cut". This ability is only usable up to three times per day. On a successful melee attack, the player deals 1d4 constitution damage to the enemy. This damage lasts 5 + Ravager level rounds.
First, you'll have to include the line [#include "prc_inc_combat"] without the brackets. This tells your script to load the include file. Then the script will have its void main. Inside the main function it would calculate everything required to perform its action.
Because this script does not deal any extra physical damage, there are a few less function calls required. written below is the actual script so you can take a look at how it works.
#include "prc_inc_combat"
void main()
{
//Declare major variables
object oPC = OBJECT_SELF;
object oTarget = GetSpellTargetObject();
object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
int iDur = 5 + GetLevelByClass(CLASS_TYPE_RAVAGER, oPC);
int bIsRangedAttack = GetWeaponRanged(oWeap);
effect eCon = EffectAbilityDecrease(ABILITY_CONSTITUTION, d4(1) );
eCon = SupernaturalEffect(eCon);
// script now uses combat system to hit and apply effect if appropriate
string sSuccess = "*Cruelist Cut Hit*";
string sMiss = "*Cruelist Cut Miss";
if (bIsRangedAttack)
{
SendMessageToPC(oPC,"You must use a melee weapon with this ability!");
IncrementRemainingFeatUses(oPC, 2348);
return;
}
// If they are not within 5 ft, they can't do a melee attack.
if(!bIsRangedAttack && GetIsInMeleeRange(oTarget, oPC))
{
SendMessageToPC(oPC,"You are not close enough to your target to attack!");
IncrementRemainingFeatUses(oPC, 2348);
return;
}
PerformAttackRound(oTarget, oPC, eCon, RoundsToSeconds(iDur), 0, 0, 0, FALSE, sSuccess, sMiss);
}
If you are used to script all of those functions should have been relatively familiar, except for "PerformAttackRound". That is the primary function in the include that makes your life as a scripter far, far easier. I reduced my original Impromtu Sneak Attack code from 200 lines down to about 60 lines. And it is also more accurately done, can deal elemental damage, and is generally much better all thanks to this function.
I'll do a break down of the parameters of this function so that everyone can see how to use it.
- oTarget - GetSpellTargetObject() - the person being smited!
- oPC - The person attacking, typically the player.
- eLink - A special effect or effects to apply to the player.
- eDuration - the duration of the effects applied to the object.
- 0.0 - DURATION_TYPE_INSTANT - effect lasts 0.0 seconds
- >0.0 - DURATION_TYPE_TEMPORARY - Effect lasts for the duration specified
- <0.0 - DURATION_TYPE_PERMAMENT - Effect lasts until dispelled, not recommended
- iAttackBonusMod - the attack bonus modifer for attack(s)
- iDamageModifier - damage added to attack
- If bonuses are only on first attack, this can be an int or a DAMAGE_BONUS_* constant.
- Otherwise, this must be a DAMAGE_BONUS_* constant.
- iDamageType - the DAMAGE_TYPE_* const of the iDamageModifier.
- bEffectAllAttacks - True or False.
- True - Effects all attacks.
- False - Effects only the first attack that round.
- sMessageSuccess - message to display on a successful hit. (i.e. "*Cruelist Cut Hit*")
- sMessageFailure - message to display on a failure to hit. (i.e. "*Cruelist Cut Miss*")
Any improvements to the combat script are typically added to that attack automatically, no recoding the feat. It takes care of the entire attack round, wether it be a ranged attack or a melee attack, two-handed weapon, two-weapon fighting, unarmed... Pretty much everything, certainly much more than could be scripted that easily.
If you happen to run into a feat that cannot be done with this, you can always open up the script. I'll warn you, as of the writing of this guide it is over 3,500 lines of code. However, the code is well organized and you should not have too much difficulty following it. Many of those "lines" are actually documentation.
Should there be any bugs in the system, please post a report in our forums. Also feel free to post any additional things that you would find useful while scripting. Oni5115 is interested in knowing anything the script cannot handle, so he can add it.
If more example scripts would be helpful feel free to check out the following scripts in the scripts directory (or hak).
- prc_at_isa.nss - Impromptu Sneak Attack
- prc_dj_selwrath.nss - Selvetarm's Wrath
- prc_dj_warstrike.nss - War Strike
Back to Top
Creating Passive Feats
What is a passive feat? A passive feat is any feat that automatically adjusts something on the character. Things like Absolute Ambidexterity, Sight of Gruumsh, etc. Creating these feats is not as straight forward as an active feat, but it is fairly easy once you get used to it.
Below is a basic list of what must be done to create a passive feat, notice it is very similiar to an active feat.
- Create all required entries in the .tlk file
- Write script(s) that perform the required player modifications(s)
- Create icon(s)
- Create an entry in feat.2da
- Create an entry in cls_feat_****.2da
- Create an entry in spells.2da
- Create an entry in prc_feat_const.nss
- Create an entry in prc_inc_function.nss.
- Compile script, test script, debug script
- Refer to step 9, until it works
To create an "entry" in prc_inc_function, you will need to check out the "EvalPRCFeats" function. Inside the function you should see a bunch of lines like the following:
if(GetLevelByClass(CLASS_TYPE_DUELIST, oPC) > 0) ExecuteScript("prc_duelist", oPC);
This function executes your passive feat script. Passive feats do not require a script entry in the 2da column as active feats do. Intead, they require a script entry here in this file. Make sure you use the approprate CLASS_TYPE_* constant as stored in "prc_class_const.nss".
Another important function is the "DeletePRCLocalInts" function. This function removes any local ints stored on a character. This is quite useful and ensures that your script will reset a new value when fired. An example line from this section is
DeleteLocalInt(oSkin,"CannyDefenseBonus");
Scripting the passive feat beyond that is not all that unlike scriping anything else in NwN. Here is an example function for a passive ability.
// Applies the Duelist's reflex bonuses as CompositeBonuses on the object's skin.
// iLevel = integer reflex save bonus
void DuelistGrace(object oPC, object oSkin, int iLevel)
{
if(GetLocalInt(oSkin, "GraceBonus") == iLevel) return;
if(iLevel > 0)
{
SetCompositeBonus(oSkin, "GraceBonus", iLevel, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_REFLEX);
if(GetLocalInt(oPC, "Grace") != TRUE)
FloatingTextStringOnCreature("Grace On", oPC);
SetLocalInt(oPC, "Grace", TRUE);
}
else
{
SetCompositeBonus(oSkin, "GraceBonus", 0, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_REFLEX);
if(GetLocalInt(oPC, "Grace") != FALSE)
FloatingTextStringOnCreature("Grace Off", oPC);
SetLocalInt(oPC, "Grace", FALSE);
}
}
You might be wondering what the "SetCompositeBonus" function is. This is another very important function. This function is responsible for storing and stacking bonuses on a character. For more information you can check out "inc_item_props.nss".
It should be fairly easy to make most passive feats with this system. Sometimes however you might also need to dig a little deeper. For instance, a class might need a passive feat that effects attacks or damage. While many such feats are typically active, there are some bonuses that end up being passive. A good example would be the Foe Hunter's Rancor Attack, which deals an additional Xd6 damage if the enemy is their Hated Enemy. Scripts like this need to go in "x2_s3_onhitcast.nss". This is in the spells directory (or hak). In this script you will see a lot of stuff that the PRC needs for one class or another. There are plenty of examples of what you might need to do in there.
Back to Top
Creating Multi-Function Feats (Sub Radials)
Somtimes you want to create an ability or spell that has multiple possible uses. Good examples of such an ability is the Orc Warlords Gather Horde ability. This class can summon an orc, and uses sub-radials to allow the player to summon several different types of orcs. The following instructions will help you create feats/spells that can do this as well.
- Make an entry in masterfeats.2da for you feat/spell.
- Create an entry in feat.2da for your ability.
Set the MASTERFEAT entry to the entry number of your entry in masterfeats.2da.
Set the SPELLID to the line number you plan to use for the master spell in spells.2da - Create a master spell entry in spells.2da.
You can copy an example one. If you have the PRC, copy line 2715 or 2716.
Set the SubRadSpell 1-5 entries to the appropriest spell entries.
(Typically I used the lines directly below the master spell).
Set one SubRadSpell entry per function the spell has. - Create the sub-spell entries.
When making a sub-radial you will want to pick unique numbers over 5000. This are your SubRadialNumbers.
Set the FeatID to (65536 * SubRadialNumber) + Feat Entry Number.
For example:
(65536 * 5001) + 898 = 327746434
(65536 * 5002) + 898 = 327811970
898 would be the line for the feat in feat.2da and 5001 and 5002 would be the unique numbers chosen for these two sub-radial items.
Back to Top