Page tree
Skip to end of metadata
Go to start of metadata

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, eg:

// 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 have a <cXXX> code in a conversation/journal/description you can't input it directly. Instead you need to wrap it in a <CUSTOMXXX> token. To do this have a script like this in the OnModuleLoad:

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

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 RGBPictureNotes/Usage
Magical Damagecc77ff

Acid Damage01ff01

Cold Damage99ffff

Divine Damage

ffff01

Electrical Damage0166ff

Fire Damageff0101

Negative Damage999999

Positive Damageffffff

Sonic Damageff9901

Feedbackffff01
Feedback messages

Combat

ff6601
Combat messages

Magic

cc77ff
Magic related messages

Skills

0166ff
Skill check messages

Saving

66ccff
Saving throw messages

Save Status

20ff20
When saving the game

Pause State

ff0101
When pausing or unpausing

Client Name

99ffff

The players name

Other Name

cc99cc

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