Patch 1.87.8193.35 added custom damage types. This tutorial will show you how to add new damage types relatively cleanly into the game.

Note there are still a few limitations around projectile ammo visual effects.

Patch Notes

The patch notes state this which may be useful to reference later:

  • Two new 2DA files have been added: damagetypes.2da and damagetypegroups.2da.
    • damagetypes.2da: each damage type in the game must have an entry.
      • Label is cosmetic, for developer ease only.
      • CharSheetStrref refers to the name of the damage type as seen on the character sheet.
      • DamageTypeGroup is a row ID into damagetypegroups.2da.
  • damagetypegroups.2da: each damage type is associated with a group. A group can be associated with more than one damage type. A group is a way to aggregate multiple damage types into one in the combat log. By default, it is used to aggregate the four physical sources of damage into a group that displays physical damage.
    • Label is cosmetic, for developer ease only.
    • FeedbackStrref refers to the name of the damage type as seen in the combat log. It uses the CUSTOM0 token to substitute the damage value.
    • ColorR/ColorG/ColorB (0-255) drives the color of the damage type.
  • Added a row for base damage to iprp_damagetype.2da and damagehitvisual.2da. This row is necessary to line up subsequent rows for custom damage types.
    • Rows in damagehitvisual.2da have a 1:1 mapping with rows in damagetypes.2da.
    • Rows in iprp_damagetype.2da have an almost 1:1 mapping, just pretend that Subdual and Physical don't exist.
    • In other words, row 13 in damagehitvisual.2da will apply to damage type 13 in damagetypes.2da, and row 15 in iprp_damagetype.2da will apply to damage type 13 in damagetypes.2da.
  • Added support for customizable weapon glow FX..
    • iprp_damagetypes.2da has been extended with a new column, VisualFX.
      • VisualFX is a row ID into iprp_visualfx.2da.
      • This allows you to remap item property damage types to different visual FX on the weapon.
      • Now you can fulfill your desire to make all damage types produce a beautiful golden glow, or you can add weapon glows for one of your custom damage types!

Understanding an Existing Damage Type

Existing damage types can now be renamed, and elemental damage types can be repurposed. However the physical damage types are still tied in the engine to weapon damage, and damage reduction, so it is much harder to make changes there (and highly recommended not to).

But let's say we want to check out an existing damage type. Let's use DAMAGE_TYPE_DIVINE. It has these properties:

It is line ID 6 - row 7 - in damagetypes.2da this gives it a value in nwscript of 64. This comes from the 7th position from the right in a bitwise representation of 32bits due to it's row number:

00000000000000000000000001000000
                         ^ 7th position from the right

Plug it into a calculator gets you out 64: https://www.rapidtables.com/convert/number/binary-to-decimal.html

This is DAMAGE_TYPE_DIVINE:

It has a CharsheetStrref of 58305 which is "Divine Damage".

It uses DamageTypeGroup value of 4. This references damagetypegroups.2da line 4, providing the string reference for feedback and the colour to use for that feedback in text form and floating numbers - in this case TLK line 10460 - "<CUSTOM0> Divine" - and yellow colour R 255 G 255 B 0.

The final 2da file damagehitvisual.2da uses the same ID line as damagetypes.2da - 6 - which points to VFX 289 in visualeffects.2da

For item properties in iprp_damagetype.2da it is line 8 and the TLK string 5155 is used which is just the word "Divine". This is constant IP_CONST_DAMAGETYPE_DIVINE. VisualFX column isn't set for this line (the VFX on any weapon it is applied to).

Note there is no way for divine to have a projectile visual effect. These are still hardcoded to the 5 default ones - acid, cold, electrical, fire and sonic, as per ammunitiontypes.2da

Adding a new Damage Type

Let's say we wanted to add a new damage type "Psychic" for your Mindflaters psionic abilities. This is reasonably easy and follows the above example. You need some 2da changes and 2 TLK strings, and perhaps a new constant for your damage:

First we add a new row to damagetypes.2da adding a new TLK reference and DamageTypeGroup IDs.

2DA V2.0

        Label           CharsheetStrref     DamageTypeGroup
0       Bludgeoning     58345               0
1       Piercing        58341               0
2       Slashing        58344               0
3       Magical         58302               1
4       Acid            58303               2
5       Cold            58304               3
6       Divine          58305               4
7       Electrical      58306               5
8       Fire            58308               6
9       Negative        58309               7
10      Positive        58310               8
11      Sonic           58311               9
12      Base            58301               0
13      Psychic         16877216            10

Secondly we add to damagetypegroups.2da the new line we reference before (10) and new colour (we choose a form of pink - find a RGB colour picker online eg this one) and TLK string in the form of "<CUSTOM0> Psychic":

2DA V2.0

        Label           FeedbackStrref      ColorR  ColorG  ColorB
0       Physical        5594                ****    ****    ****
1       Magical         5593                204     119     255
2       Acid            10458               0       102     0
3       Cold            10459               153     255     255
4       Divine          10460               255     255     0
5       Electrical      10461               0       102     255
6       Fire            10462               255     0       0
7       Negative        10463               153     153     153
8       Positive        10464               255     255     255
9       Sonic           10465               255     153     0
10      Psychic         16877217            255     0       255

Thirdly we add to damagehitvisuals.2da, same row ID as damagetypes.2da, in this case we are leaving it blank since we don't have a handy VFX for it but feel free to add one if you wanted:

2DA V2.0                                                   
                                                           
           Label         VisualEffectID   RangedEffectID   
0          Bludgeoning   ****             ****             
1          Piercing      ****             ****             
2          Slashing      ****             ****             
3          Magical       76               ****             
4          Acid          283              ****             
5          Cold          281              ****             
6          Divine        289              ****             
7          Electrical    282              ****             
8          Fire          280              ****             
9          Negative      282              ****             
10         Positive      289              ****             
11         Sonic         284              ****             
12         Base          ****             ****             
13         Psychic       ****             ****

Lastly we add a new constant for our damage type. It is row 14 so using the calculator a 1 with 13 zeroes after gives us 8192 - which we can double check in nwscript since DAMAGE_TYPE_CUSTOM1 should match it - and it does!

const int DAMAGE_TYPE_PSYCHIC = 8192;

Then we can test it, for instance with this simple script you can run on yourself using the script window. There is no custom TLK used it sets the strings using TLK overrides for now - you'll need to add them to your TLK file for the toolset to recognise it properly however!

const int DAMAGE_TYPE_PSYCHIC = 8192;

void main()
{
    SetTlkOverride(16877216, "Psychic Damage");
    SetTlkOverride(16877217, "<CUSTOM0> Psychic");
    
    effect eDamage = EffectDamage(5, DAMAGE_TYPE_PSYCHIC);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, OBJECT_SELF);
}

See the results in game:

Now you have a custom damage type!

Damage Type on Item Properties

This is pretty simple - you need another TLK string and line in iprp_damagetype.2da and off this you can generate a custom constant for nwscript purposes. The TLK String should be just the sole word "Psychic".

2DA V2.0                               
                                       
           Name         Label         Cost      VisualFX
0          1031         Bludgeoning   1.25      ****
1          1032         Piercing      1.25      ****
2          1033         Slashing      1.25      ****
3          ****         Subdual       ****      ****
4          ****         Physical      ****      ****
5          62487        Magical       0.35      ****
6          1027         Acid          0.35      0
7          1029         Cold          0.4       1
8          5155         Divine        0.4       ****
9          1030         Electrical    0.45      2
10         1028         Fire          0.5       3
11         5158         Negative      0.5      	****
12         5159         Positive      0.5       ****
13         2202         Sonic         0.5       4
14         ****         Base          ****      ****
15         16877218     Psychic       0.5       ****

We can add a new constant for this item property damage type following the others:

const int IP_CONST_DAMAGETYPE_PSYCHIC = 15;

Remember fix up your custom TLK file and you can add item properties too, a script for testing:

const int IP_CONST_DAMAGETYPE_PSYCHIC = 15;

void main()
{
    SetTlkOverride(16877216, "Psychic Damage");
    SetTlkOverride(16877217, "<CUSTOM0> Psychic");
    SetTlkOverride(16877218, "Psychic");

    object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, OBJECT_SELF);
    if(GetIsObjectValid(oItem))
    {
        itemproperty ipAddDamage = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_PSYCHIC, IP_CONST_DAMAGEBONUS_1d6);
        AddItemProperty(DURATION_TYPE_TEMPORARY, ipAddDamage, oItem, 60.0);
    }
}

You can also generate damage resistance properties and the like as well.

Congratulations hopefully you now know how to add up to 19 custom damage types to your game!

Some suggestions from threads online:

  • Damage - Basic untyped or typeless damage not usually resistible by anything. Bioware tended to use Magical for this, which works fine for most spells but doesn't look good for other cases.
  • Fatigue Damage - Again not usually resistible, caused by not resting
  • Sanctified and Vile Damage - from the Book of Vile Darkness, special rules for it
  • Force Damage - Used for some spells (Bioware basically uses "Magical" for these cases, but "Force" sounds so much cooler!)
  • Poison Damage - Some monsters who do "poison damage" not just ability score damage may use this
  • Falling Damage - splat!
  • Sacred, Profane, Axiomatic and Anarchic Damage - are for good, evil, law and chaos damage respectively - although the latter two might not exist usually it's fun to think about (while divine is basically "untyped but named" so shouldn't be resisted).

Example Material

Now that is all completed you now have a new damage type! You could add custom (or existing) VFX references as needed, or leave it to just be a spell effect and applying a suitably good impact VFX might be enough.

Any problems? You can download this guides files as a zip to play around: Tutorial_Psychic_Damage.zip

  • No labels