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.
| Table of Contents |
|---|
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
...
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:
| Code Block |
|---|
// 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 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>):
| Code Block |
|---|
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, 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:
| Code Block |
|---|
const string COLOR_TOKEN = " ##################$%&'()*+,-./0123456789:;;==?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[[]^_`abcdefghijklmnopqrstuvwxyz{|}~~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¡¢£¤¥¦§¨©ª«¬¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþþ\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)); } |
...
| Code Block |
|---|
<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)Alternatively setting a handful manually may be more reliable:
| Code Block |
|---|
// 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:
| Code Block |
|---|
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:
| Code Block |
|---|
SetCustomToken(1001, GetRGBCToken(0xcc, 0x77, 0xff)); // Magical Damage |
| Colour Type | Hex RGB | Colour | Picture | Notes/Usage |
|---|---|---|---|---|
| Magical Damage | cc77ff | Now can be set in damagetypegroups.2da | ||
| Acid Damage | 01ff01 | Now can be set in damagetypegroups.2da | ||
| Cold Damage | 99ffff | Now can be set in damagetypegroups.2da | ||
Divine Damage | ffff01 | Now can be set in damagetypegroups.2da | ||
| Electrical Damage | 0166ff | Now can be set in damagetypegroups.2da | ||
| Fire Damage | ff0101 | Now can be set in damagetypegroups.2da | ||
| Negative Damage | 999999 | Now can be set in damagetypegroups.2da | ||
| Positive Damage | ffffff | Now can be set in damagetypegroups.2da | ||
| Sonic Damage | ff9901 | Now can be set in damagetypegroups.2da | ||
| Chat | ||||
| Chat: Feedback | ffff01 | Yellow | Feedback messages | |
Chat: Combat | ff6601 | Orange | Combat messages | |
Chat: Magic | cc77ff | Purple | Magic related messages | |
Chat: Skills | 0166ff | Dark Blue | Skill check messages | |
Chat: Saving | 66ccff | Pale Blue | Saving throw messages | |
Chat: Save Status | 20ff20 | Some kind of green | When saving the game | |
Chat: Pause State | ff0101 | Bright Red | When pausing or unpausing | |
Chat: Client Name | 99ffff | Cyan Blue | The players name | |
Chat: Other Name | cc99cc | Purple | Other creature names | |
Chat: Level Drain | ff0101 | Red | Level drain feedback | |
Chat Load Hints | ffff01 | Yellow | Load screen hints in the chat area (EE only) | |
Chat message: Talk | f0f0f0 | Light Grey | Possibly changeable in nwnplayer.ini under heading "Chat Colors" | |
Chat message: Shout | ffef50 | Yellow | ||
Chat message: Whisper | 808080 | Grey | ||
Chat message: Tell | 20ff20 | Green | ||
Chat message: Server | b0b0b0 | Dark Grey | ||
Chat message: Party | f0f0f0 | Light Grey | ||
Chat message: DM | 10dfff | Cyan | ||
Examine Window | ||||
Challenge Rating: Effortless | ffffff | White | ||
Challenge Rating: Easy | 01ff01 | Green | ||
Challenge Rating: Moderate | 0101ff | Blue | ||
Challenge Rating: Challenging | ffff01 | Yellow | ||
Challenge Rating: Very Difficult | ff7301 | Orange | ||
Challenge Rating: Overpowering | ff0101 | Red | ||
Challenge Rating: Impossible | dc01ff | Purple | ||
Challenge Rating: Error | 707070 | Grey | Shouldn't occur | |
Reputation: Neutral | 8080ff | Blue grey | ||
Reputation: Friendly | 80ff80 | Green | ||
Reputation: Hostile | ff5040 | Red | ||
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 | 0166ff | Blue | For temporarily applied item properites ("magical ones" usually, thus the blue) | |
Popups / Mouseovers | ||||
Item name on popup | ffc81e | Orange | ||
Normal placeable | 8080ff | Blue | ||
Trapped placeable | ff0101 | Red | ||
Charsheet | ||||
Charsheet: Highlight | aaaaaa | Grey | ||
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 | |||
| Action | 01fe01 | Green | <StartAction> tag | |
| Check | fe0101 | Red | <StartCheck> tag | |
| Highlight | 0101FE | Blue | <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:
| Code Block |
|---|
<c0000><<c000></c>Feat Section 1 <c0001><<c001></c>Feat 1 <c0001><<c001></c>Feat 4 <c0001><<c001></c>Feat 6 <c0002><<c002></c>Feat Section 2 <c0003><<c003></c>Feat 2 <c0003><<c003></c>Feat 3 <c0003><<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"
