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
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
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 Type | Hex RGB | Picture | Notes/Usage |
|---|---|---|---|
| Magical Damage | cc77ff | ||
| Acid Damage | 01ff01 | ||
| Cold Damage | 99ffff | ||
Divine Damage | ffff01 | ||
| Electrical Damage | 0166ff | ||
| Fire Damage | ff0101 | ||
| Negative Damage | 999999 | ||
| Positive Damage | ffffff | ||
| Sonic Damage | ff9901 | ||
| Feedback | ffff01 | Feedback messages | |
Combat | ff6601 | Combat messages | |
Magic | cc77ff | Magic related messages | |
Skills | 0166ff | Skill check messages | |
Saving | 66ccff | When saving the game | |
Save Status | 20ff20 | When Saved | |
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:
<c0000></c>Feat Section 1 <c0001></c>Feat 1 <c0001></c>Feat 4 <c0001></c>Feat 6 <c0002></c>Feat Section 2 <c0003></c>Feat 2 <c0003></c>Feat 3 <c0003></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"
