Tokens can be used to introduce different colours in almost any text element in the game.

See the nwnlexicon tutorial on custom tokens for more information.

Colour Custom Tokens

A subset of custom tokens - you can use <cRGB></c> where RGB is a RGB code but, of course since this isn't simple, it's not in number form but ASCII character reference...very odd (smile)

This means you can use a long ASCII string to find the right "number", eg;

const string COLOR_TOKEN = "                  ##################$%&'()*+,-./0123456789:;;==?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[[]^_`abcdefghijklmnopqrstuvwxyz{|}~~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¡¢£¤¥¦§¨©ª«¬¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþþ";

string GetStringColoredRGB(string sString, int nRed=255, int nGreen=255, int nBlue=255)
{
    return "<c" + GetSubString(COLOR_TOKEN, nRed, 1) + GetSubString(COLOR_TOKEN, nGreen, 1) + GetSubString(COLOR_TOKEN, nBlue, 1) + ">" + sString + "</c>";
}

This function can make a complete string that then could be passed, say, to a custom token for inclusion in a conversation. It can also be used in other text locations (eg; SpeakString, SendMessageToPC, etc.)

A simpler version is available in x0_i0_string.nss

The game uses the <cRGB></c> format internally so it can be used by modders to create any coloured text.

If you want to add these tokens directly into a TLK file you can use webpages such as this: https://colortoken.nwn1.net/

For more information on colour tokens in general see: https://neverwintervault.org/project/nwn1/other/hitchhikers-guide-color-tokens

You can find a more advanced set of scripts for color tokens here: https://github.com/silm/silm/blob/master/mod/nss/includes/inc_colors.n

In the latest versions of NWN:EE you can now escape any ASCII character (except 0) with \x in NWScript:

// COLOR_TOKEN originally by rdjparadis. Used to generate colors from RGB values. NEVER modify this string.
// This requires a later version of NWN:EE to use the \x escape character
// For more information: https://nwn.wiki/display/NWN1/Colour+Tokens
// NB: First character is "nearest to 00" since we can't use \x00 itself (means you can't get completely black is all)
const string COLOR_TOKEN = "\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
 
// Gets a suitable <cXXX> token to use at the start of a block of colored text. Must be terminated by </c>
// - nRed - Red amount (0-255)
// - nGreen - Green amount (0-255)
// - nBlue - Blue amount (0-255)
string GetColorCode(int nRed=255, int nGreen=255, int nBlue=255)
{
    return "<c" + GetSubString(COLOR_TOKEN, nRed, 1) + GetSubString(COLOR_TOKEN, nGreen, 1) + GetSubString(COLOR_TOKEN, nBlue, 1) + ">";
}
 
void main()
{
    SpeakString(GetColorCode(255, 20, 147) + "Speaking in Deep Pink!" + "</c>");
}

Having Custom Colour Tokens in Conversations, Journals, and Descriptions

To use <cXXX> code in a conversation/journal/description, you either need to add an additional "<" in from of each colour token when using the toolset editors (so that <c***>text</c> becomes <<c***>text<</c>):

void main()
{
    SetTlkOverride(5593, "<</c><<\x0B\x0C\x0D><CUSTOM0> Something Painful");
}


or alternatively, rely on <CUSTOMXXX> tokens set in scripts and reference those. The latter solution will give you more control of the colours since the various editors do not support all characters.

To use the custom token method, have a script like this in the OnModuleLoad:

const string COLOR_TOKEN = "\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";

string GetRGBCToken(int nRed=255, int nGreen=255, int nBlue=255)
{
    return "<c" + GetSubString(COLOR_TOKEN, nRed, 1) + GetSubString(COLOR_TOKEN, nGreen, 1) + GetSubString(COLOR_TOKEN, nBlue, 1) + ">";
}
 
void main()
{
    SetCustomToken(1000, "</c>");
    SetCustomToken(1001, GetRGBCToken(255, 0, 0));
    SetCustomToken(1002, GetRGBCToken(0, 255, 0));
    SetCustomToken(1003, GetRGBCToken(0, 0, 255));
}

Then in the conversation editor you can do this:

<CUSTOM1001>Hello in red.<CUSTOM1000> Normal text. <CUSTOM1002>Hello in green.<CUSTOM1000> Normal text. <CUSTOM1003>Hello in blue.<CUSTOM1000> Normal Text. <CUSTOM1004>Hello in black.<CUSTOM1000> Normal Text. <CUSTOM1005>Hello in white.<CUSTOM1000>

Ending up like this:

This can be some good code to use for manually doing it (to be updated with a better code when newer patch comes out + some idea about default colours is obtained):

// OnModuleLoad
void main()
{
    SetCustomToken(1000, "</c>"); // CLOSE tag
    SetCustomToken(1001, "<cþ  >"); // red
    SetCustomToken(1002, "<c þ >"); // green
    SetCustomToken(1003, "<c  þ>"); // blue
    SetCustomToken(1004, "<c þþ>"); // cyan
    SetCustomToken(1005, "<cþ þ>"); // magenta
    SetCustomToken(1006, "<cþþ >"); // yellow
    SetCustomToken(1007, "<c   >"); // black
    SetCustomToken(1008, "<c¥  >"); // dark red
    SetCustomToken(1009, "<c ¥ >"); // dark green
    SetCustomToken(1010, "<c  ¥>"); // dark blue
    SetCustomToken(1011, "<c ¥¥>"); // dark cyan
    SetCustomToken(1012, "<c¥ ¥>"); // dark magenta
    SetCustomToken(1013, "<c¥¥ >"); // dark yellow
    SetCustomToken(1014, "<c¥¥¥>"); // grey
    SetCustomToken(1017, "<cŒŒŒ>"); // dark grey
    SetCustomToken(1015, "<cþ¥ >"); // orange
    SetCustomToken(1016, "<cþŒ >"); // dark orange
    SetCustomToken(1017, "<cÚ¥#>"); // brown
    SetCustomToken(1018, "<c† >"); // dark brown
}

Custom Damage Example

You can use a mixture of SetTlkOverride and SetCustomToken to make something like custom damage, eg reusing "Divine" damage since it is generally unresisted can give this:

With this in an OnUsed event of a lever:

void main()
{
    SetCustomToken(100, "</c>");
    SetCustomToken(101, "<cÿ´ô>");
    SetTlkOverride(5593, "<CUSTOM100><CUSTOM101><CUSTOM0> Something Painful");
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(1, DAMAGE_TYPE_DIVINE), GetLastUsedBy());
    // Reset so usual divine damage looks ok (or go replace divine damage in all scripts with positive damage or something).
    SetTlkOverride(5593, "");
}

You might want Hardcoded TLK Lines to reference some of the games TLK references to override.

Default Colour References

A semi-complete list of the default colours Bioware use, so in case you want to replicate an existing thing like "You're damaged by magical damage!" in a conversation.

Use Hex RGB like so:

SetCustomToken(1001, GetRGBCToken(0xcc, 0x77, 0xff)); // Magical Damage


Colour TypeHex RGBColourPictureNotes/Usage
Magical Damagecc77ff

Now can be set in damagetypegroups.2da
Acid Damage01ff01

Now can be set in damagetypegroups.2da
Cold Damage99ffff

Now can be set in damagetypegroups.2da

Divine Damage

ffff01

Now can be set in damagetypegroups.2da
Electrical Damage0166ff

Now can be set in damagetypegroups.2da
Fire Damageff0101

Now can be set in damagetypegroups.2da
Negative Damage999999

Now can be set in damagetypegroups.2da
Positive Damageffffff

Now can be set in damagetypegroups.2da
Sonic Damageff9901

Now can be set in damagetypegroups.2da
Chat



Chat: Feedbackffff01Yellow
Feedback messages

Chat: Combat

ff6601Orange
Combat messages

Chat: Magic

cc77ffPurple
Magic related messages

Chat: Skills

0166ffDark Blue
Skill check messages

Chat: Saving

66ccffPale Blue
Saving throw messages

Chat: Save Status

20ff20Some kind of green
When saving the game

Chat: Pause State

ff0101Bright Red
When pausing or unpausing

Chat: Client Name

99ffff

Cyan Blue

The players name

Chat: Other Name

cc99ccPurple
Other creature names

Chat: Level Drain

ff0101Red
Level drain feedback

Chat Load Hints

ffff01Yellow
Load screen hints in the chat area (EE only)

Chat message: Talk

f0f0f0Light Grey
Possibly changeable in nwnplayer.ini under heading "Chat Colors"

Chat message: Shout

ffef50Yellow

Chat message: Whisper

808080Grey

Chat message: Tell

20ff20Green

Chat message: Server

b0b0b0Dark Grey

Chat message: Party

f0f0f0Light Grey

Chat message: DM

10dfffCyan

Examine Window





Challenge Rating: Effortless

ffffffWhite

Challenge Rating: Easy

01ff01Green

Challenge Rating: Moderate

0101ffBlue

Challenge Rating: Challenging

ffff01Yellow

Challenge Rating: Very Difficult

ff7301Orange

Challenge Rating: Overpowering

ff0101Red

Challenge Rating: Impossible

dc01ffPurple

Challenge Rating: Error

707070Grey
Shouldn't occur

Reputation: Neutral

8080ffBlue grey

Reputation: Friendly

80ff80Green

Reputation: Hostile

ff5040Red

Damage level: Uninjured

80ff80


Damage level: Barely injured

c8ff01


Damage level: Injured

ffc801


Damage level: Heavily Wounded

ff6401


Damage level: Near Death

ff5040


Damage level: Dead

808080


Item Descriptions: Temporary Item Properties

0166ffBlue
For temporarily applied item properites ("magical ones" usually, thus the blue)

Popups / Mouseovers





Item name on popup

ffc81eOrange

Normal placeable

8080ffBlue

Trapped placeable

ff0101Red

Charsheet





Charsheet: Highlight

aaaaaaGrey

Conversation: Replies Color

RGB: 0.4, 0.7, 1.0

Also the Speaker Color

Conversation: Hilite Color

RGB: 1.0, 1.0, 1.0


Conversation: Picked Color

RGB: 0.7, 0.4, 0.2


Conversation: Pickedother Color

RGB: 0.7, 0.2, 0.4


Conversation: Disabled Color

RGB: 0.5, 0.5, 0.5


Action01fe01Green
<StartAction> tag
Checkfe0101Red
<StartCheck> tag
Highlight0101FEBlue
<StartHighlight> tag

Ordering Lists

Anything that orders on the contents of a string - eg the feats or skills in a character sheet - can be made into a custom order using empty colour strings, eg:

<c000></c>Feat Section 1
<c001></c>Feat 1
<c001></c>Feat 4
<c001></c>Feat 6
<c002></c>Feat Section 2
<c003></c>Feat 2
<c003></c>Feat 3
<c003></c>Feat 5

Without the colour codes you will get the order "Feat 1, 2, 3, 4, 5, 6 Section 1, Section 2" but with them you get "Feat Section 1, 1, 4, 6, Section 2, 2, 3, 5"

  • No labels