XML Question - change color

The function SetNoticeText is used in one of my scripts. Here’s what the Toolset says about the function:

//RWT-OEI 04/30/07
// This sends a text string to the player that will appear
// on the player's screen inside their Notice Window GUI.
// A notice window can be any text field that has
// the UIText_OnUpdate_DisplayNoticeText() callback running
// on it.
// oPlayer - The player to send the notice message to.
// sMessage - The text to display. Cannot be an empty
//            string.

This made me believe I could copy the noticewindow.xml from the game UI folder and just change the color in that xml script. However, doing that and putting the xml file in my campaign folder does nothing ingame it seems. Maybe there’s another xml file I need to use? Or maybe I’ve made some other mistake?

1 Like

@andgalf

Rather than alter the xml, why not just alter the colour of the text sent?

I mean I believe you can alter the default text colour value that the xml displays, but it will be “stuck” at that colour for everything sent by default (without colour ref).

If that is what you want to do, here is an example of where I set a colour that I knew I would not be changing … Try something like this, where you need to alter the colour. (NB: Spelt color in the UI.)

<UIText name="SECOND_PAGE_TEXT" width=PARENT_WIDTH height=DYNAMIC align=left valign=top color="413C2B" fontfamily="Read_Book_Big"/>

FROM THE ACTUAL XML:

<UIText name="NOTICE_TEXT" x=ALIGN_CENTER y=168 width=800 height=200 fontfamily="Special_Font" style="2" multiline=true maxlines=3
	        align=center valign=top uppercase=true hidden=true update=true ignoreevents="true" 
	        capturemouseevents=false capturemouseclicks=false color="yellow" scalewithscene=true
	        OnUpdate=UIText_OnUpdate_DisplayNoticeText(15.0,5.0) />

Just change “yellow” to something else I would have thought.

Although, it sounds like you tried this already, so let me test my end …

TEST RESULT: The text colour changed fine in my own test: Altered colour and used new XML in campaign directory. Did you make sure you had the following in the UIScreen?

scriptloadable=true

For more info, check my tutorial …

https://neverwintervault.org/project/nwn2/other/gui/nwn2-xml-gui-coding-beginners

PAGE 8: “UIScene: Most of this … Finally, the scriptloadable is always required as TRUE, as this allows the module to use the GUI.”

1 Like

If you are just looking to change the notice text color, try this:

void main()
{
	object oPC = GetFirstPC();
	
	SetNoticeText(oPC, "<color=red>red, <color=yellow>yellow, <color=blue>blue\n<color=orange>orange, <color=green>green, <color=purple>purple\n<color=white>white, <color=gray>gray, <color=black>black");
}
1 Like

Thanks for the replies. Thinking about it a bit more, I think I might want to change more than color. I think I would like to change the font too.

Here’s the original XML (noticewindow.xml):

<?xml version="1.0" encoding="utf-8"?>
<!-- Neverwinter Nights 2                     -->
<!-- Copyright � Obsidian Entertainment, Inc. -->

<UIScene name="SCREEN_NOTICEWINDOW" x=0 y=0 width="SCREEN_WIDTH" height="SCREEN_HEIGHT" 
         capturemouseevents=false capturemouseclicks=false ignoreevents="true"
         scriptloadable="true" priority="SCENE_SCRIPT" fullscreen="true" />

	<UIText name="NOTICE_TEXT" x=ALIGN_CENTER y=168 width=800 height=200 fontfamily="Special_Font" style="2" multiline=true maxlines=3
	        align=center valign=top uppercase=true hidden=true update=true ignoreevents="true" 
	        capturemouseevents=false capturemouseclicks=false color="yellow" scalewithscene=true
	        OnUpdate=UIText_OnUpdate_DisplayNoticeText(15.0,5.0) />

	<UIText name="PAUSE_NOTIFICATION" x=0 y=ALIGN_CENTER width=1024 height=100 fontfamily="Special_Font" style="4" scalewithscene=true 
		align=center valign=middle uppercase=true strref=174270 hidden=true ignoreevents="true"
        capturemouseevents=false capturemouseclicks=false
		update=true OnUpdate=UIText_OnUpdate_ShowPauseNotification() />

And here’s my changed version:

<?xml version="1.0" encoding="utf-8"?>
<!-- Neverwinter Nights 2                     -->
<!-- Copyright � Obsidian Entertainment, Inc. -->

<UIScene name="SCREEN_NOTICEWINDOW" x=0 y=0 width="SCREEN_WIDTH" height="SCREEN_HEIGHT" 
         capturemouseevents=false capturemouseclicks=false ignoreevents="true"
         scriptloadable="true" priority="SCENE_SCRIPT" fullscreen="true" />

	<UIText name="NOTICE_TEXT" x=ALIGN_CENTER y=168 width=800 height=200 fontfamily="Special_Font" style="2" multiline=true maxlines=3
	        align=center valign=top uppercase=true hidden=true update=true ignoreevents="true" 
	        capturemouseevents=false capturemouseclicks=false color="FFFFFF" scalewithscene=true
	        OnUpdate=UIText_OnUpdate_DisplayNoticeText(15.0,5.0) />

	<UIText name="PAUSE_NOTIFICATION" x=0 y=ALIGN_CENTER width=1024 height=100 fontfamily="Special_Font" style="4" scalewithscene=true 
		align=center valign=middle uppercase=true strref=174270 hidden=true ignoreevents="true"
        capturemouseevents=false capturemouseclicks=false
		update=true OnUpdate=UIText_OnUpdate_ShowPauseNotification() />

I even tried with color=“white” but neither did anything. The scriptloadable=“true” is set for the first UIScene name but maybe that’s not enough…

EDIT: I wanted to use this for the ga_influence script I have in my modules. These scripts I haven’t made myself, but from reading them it seems like they just use SetNoticeText.

I’m away from my computer, so I can’t be sure, but I noticed that most XML files have X1 or X2 appended to their name depending on whether you have the OC, MotB or SoZ installed. Maybe it’s the case here too?

Mmmm, well, I found this xml script under “UI” in the NWN2Complete folder (not the one under Documents). I don’t know if any X1 or X2 is attached to this one.

I’m off to work now, but I’ll try to take a closer look at all this tonight. If you all can see if I made some kind of mistake in my post above, please let me know.

Here’s from the ginc_influence script I use as include script:

// Report influence change to the player
void ReportInfluenceChange(string sCompanion, string sChange)
{ 
	string sName = GetName(GetObjectByTag(sCompanion)); 			   // companion name
	int nInfluence = GetGlobalInt(GetInfluenceVariable(sCompanion));   // influence variable
	
	if (StringToInt(sChange) < 0) // influence loss
	{
   		SendMessageToPC(oPC, "Lost influence with " + sName + ": " + sChange + " (Total: " + IntToString(nInfluence) + ")");
   		SetNoticeText(oPC, "Lost influence with " + sName + ": " + sChange + " (Total: " + IntToString(nInfluence) + ")");
		PlaySound(SOUND_INFLUENCE_LOSS);
	}	
	else // influence gain
	{
		SendMessageToPC(oPC, "Gained influence with " + sName + ": +" + sChange + " (Total: " + IntToString(nInfluence) + ")");
   		SetNoticeText(oPC, "Gained influence with " + sName + ": +" + sChange + " (Total: " + IntToString(nInfluence) + ")");
		PlaySound(SOUND_INFLUENCE_GAIN);
	}
}

Tchos UI edits that same xml file. Your new xml might be conflicting with the Tchos UI file of the same name. Make sure you have no other xml with the same name in your override or ui/custom folder.

2 Likes

OH! That could totally be it! Thanks for pointing that out. I didn’t think of that I could maybe have this xml file already in the override folder.

EDIT: Just checked you were totally right! No wonder nothing happened when I edited my version.
EDIT2: After removing the the xml file from the override and using my own in my campaign folder it still looks the same. I must be doing something wrong somewhere.
EDIT3: Tried putting the xml in the override instead, making sure the other one was gone, and still no difference. I just don’t get it!

This is how the xml file looks at the moment that I’m using:

<?xml version="1.0" encoding="utf-8"?>
<!-- Neverwinter Nights 2                     -->
<!-- Copyright © Obsidian Entertainment, Inc. -->

<UIScene name="SCREEN_NOTICEWINDOW" x=0 y=0 width="SCREEN_WIDTH" height="SCREEN_HEIGHT" 
         capturemouseevents=false capturemouseclicks=false ignoreevents="true"
         scriptloadable="true" priority="SCENE_SCRIPT" fullscreen="true"  fadein=1.0 fadeout=1.0 />
<!-- Fade in and out added -->

	<UIText name="NOTICE_TEXT" x=ALIGN_CENTER y=168 width=1024 height=DYNAMIC fontfamily="Body_Font" style="2" multiline=true maxlines=3
	        align=center valign=top uppercase=true hidden=true update=true ignoreevents="true" 
	        capturemouseevents=false capturemouseclicks=false color="FFFFFF" scalewithscene=true
	        OnUpdate=UIText_OnUpdate_DisplayNoticeText(6.0,5.0) />
<!-- was 15.0,5.0 -->

	<UIText name="PAUSE_NOTIFICATION" x=0 y=ALIGN_CENTER width=1024 height=100 fontfamily="Special_Font" style="4" scalewithscene=true 
		align=center valign=middle uppercase=true strref=174270 hidden=true ignoreevents="true"
        capturemouseevents=false capturemouseclicks=false
		update=true OnUpdate=UIText_OnUpdate_ShowPauseNotification() />

What’s really weird is that if I change the above xml file to this:

<?xml version="1.0" encoding="utf-8"?>
<!-- Neverwinter Nights 2                     -->
<!-- Copyright © Obsidian Entertainment, Inc. -->

<UIScene name="SCREEN_NOTICEWINDOW" x=0 y=0 width="SCREEN_WIDTH" height="SCREEN_HEIGHT" 
         capturemouseevents=false capturemouseclicks=false ignoreevents="true"
         scriptloadable="true" priority="SCENE_SCRIPT" fullscreen="true"  fadein=1.0 fadeout=1.0 />
<!-- Fade in and out added -->

	<UIText name="NOTICE_TEXT" x=ALIGN_CENTER y=168 width=1024 height=200 fontfamily="Special_Font" style="2" multiline=true maxlines=3
	        align=center valign=top uppercase=false hidden=true update=true ignoreevents="true" 
	        capturemouseevents=false capturemouseclicks=false color="yellow" scalewithscene=true
	        OnUpdate=UIText_OnUpdate_DisplayNoticeText(6.0,5.0) />
<!-- was 15.0,5.0 -->

<!-- Get rid of "GAME PAUSED" in the middle of the screen -->

<!-- 	<UIText name="PAUSE_NOTIFICATION" x=0 y=ALIGN_CENTER width=1024 height=100 fontfamily="Special_Font" style="4" scalewithscene=true 
		align=center valign=middle uppercase=true strref=174270 hidden=true ignoreevents="true"
        capturemouseevents=false capturemouseclicks=false
		update=true OnUpdate=UIText_OnUpdate_ShowPauseNotification() />
 -->

Then the pause notification in the middle of the screen is gone, which tells me that the game aknlowledges my file in some way and uses it. But WHY in the 7th heavens (or something) does it not recognize that I change the font and the color? It’s still yellow and not white, and the font hasn’t changed. And as you saw above, the script uses the function SetNoticeText. Is that function hardcoded somehow so it won’t recognize this?

Hmmm, I think I’ll actually do another test, like adding a quest, and see if that changes color now…

EDIT: That was REALLY interesting. When updating a quest, it is now white and with uppercase letters. Isn’t SetNoticeText related to this xml file then? Could it be something like that?

EDIT2: Here is the full ga_influnce and ginc_influence_modi that I use, that I thought would show the text like in my noticewindow.xml

ginc_influence_modi

//::///////////////////////////////////////////////
//:: Nalencer's Companion Influence System
//:: ginc_influence
//:: Copyright (c) 2009 Ethan Meanor
//:://////////////////////////////////////////////
/*
    The main include file to handle companion
	influence.
*/
//:://////////////////////////////////////////////
//:: Created By: Ethan Meanor
//:: Created On: February 1, 2009
//:://////////////////////////////////////////////

#include "ginc_var_ops"


//-------------------------------------------------
// Prototypes
//-------------------------------------------------
void ModifyInfluence(string sCompanion, string sChange);
void ReportInfluenceChange(string sCompanion, string sChange);
void UpdateInfluenceBand(string sCompanion);
void ApplyInfluenceEffects(string sCompanion);
void SetIsPossessable(object oCompanion, int bPossessable);
void SetPlayerInventoryAccess(object oCompanion, int bCanAccessInventory);

int GetCompanionInfluence(string sCompanion);
int GetCompanionInfluenceBand(string sCompanion);

string GetInfluenceVariable(string sCompanion);
string GetInfluenceBandVariable(string sCompanion);


//-------------------------------------------------
// Constants
//-------------------------------------------------
// *** USER PREFERENCES -- THIS SECTION CAN BE EDITED ***
// Maximum influence level
const int MAXIMUM_INFLUENCE = 100;
// Minimum influence level
const int MINIMUM_INFLUENCE = -100;
// If TRUE, bWillLeaveParty will be set to TRUE when the companion reaches minimum influence
// This is just for convenience, and can be used in whatever way you wish
const int COMPANIONS_LEAVE_PARTY = TRUE; 

// Influence range definitions
// These can be set to whatever values you wish
const int INFLUENCE_RANGE_REBELLIOUS 	= -76;
const int INFLUENCE_RANGE_DISILLUSIONED = -51;
const int INFLUENCE_RANGE_WAVERING 		= -26;
const int INFLUENCE_RANGE_NEUTRAL 		= 25;
const int INFLUENCE_RANGE_TRUSTING 		= 50;
const int INFLUENCE_RANGE_LOYAL 		= 75;
const int INFLUENCE_RANGE_DEVOTED 		= 99;
const int INFLUENCE_RANGE_LOVE	 		= 100;


// *** SYSTEM CONSTANTS -- DO NOT EDIT THIS SECTION ***
const int INFLUENCE_BAND_REBELLIOUS 	= -3;
const int INFLUENCE_BAND_DISILLUSIONED 	= -2;
const int INFLUENCE_BAND_WAVERING 		= -1;
const int INFLUENCE_BAND_NEUTRAL 		= 0;
const int INFLUENCE_BAND_TRUSTING 		= 1;
const int INFLUENCE_BAND_LOYAL 			= 2;
const int INFLUENCE_BAND_DEVOTED 		= 3;

const string PREFIX_INFLUENCE = "i_";
const string PREFIX_INFLUENCE_BAND = "ib_";
const string PREFIX_LEAVE_PARTY = "bWillLeaveParty_";

const string SOUND_INFLUENCE_GAIN = "gui_influence";
const string SOUND_INFLUENCE_LOSS = "gui_infuenceloss01";


//-------------------------------------------------
// Global Variables
//-------------------------------------------------
object oPC = GetFirstPC();


//-------------------------------------------------
// Definitions
//-------------------------------------------------

// Modify companion influence
void ModifyInfluence(string sCompanion, string sChange)
{
	string sName = GetName(GetObjectByTag(sCompanion)); 	// companion name
	string sInfluence = GetInfluenceVariable(sCompanion); 	// influence variable
	int nOldValue = GetGlobalInt(sInfluence); 				// original influence
	int nNewValue = 0; 										// new influence value

	nNewValue = CalcNewIntValue(nOldValue, sChange, TRUE);  // calculate new value
	
	// make sure that the new value is between the minimum and maximum values
	if (nNewValue < MINIMUM_INFLUENCE)
		nNewValue = MINIMUM_INFLUENCE; 
	else if (nNewValue > MAXIMUM_INFLUENCE)
		nNewValue = MAXIMUM_INFLUENCE;
	
	// if COMPANIONS_LEAVE_PARTY = TRUE and influence is at minimum, flag the companion as ready
	// to leave the party	
	if (COMPANIONS_LEAVE_PARTY == TRUE && nNewValue == MINIMUM_INFLUENCE)
	{
		SetGlobalInt(PREFIX_LEAVE_PARTY + sName, 1); // companion will leave party
	}
	else
	{	
		SetGlobalInt(PREFIX_LEAVE_PARTY + sName, 0); // companion will not leave party
		
		SetGlobalInt(sInfluence, nNewValue); // set new influence value
	
		ReportInfluenceChange(sCompanion, sChange); // report change to player
	
		UpdateInfluenceBand(sCompanion);	// update influence band
		ApplyInfluenceEffects(sCompanion);  // apply influence effects
	}
}


// Report influence change to the player
void ReportInfluenceChange(string sCompanion, string sChange)
{ 
	string sName = GetName(GetObjectByTag(sCompanion)); 			   // companion name
	int nInfluence = GetGlobalInt(GetInfluenceVariable(sCompanion));   // influence variable
	
	if (StringToInt(sChange) < 0) // influence loss
	{
   		SendMessageToPC(oPC, "Lost influence with " + sName + ": " + sChange + " (Total: " + IntToString(nInfluence) + ")");
   		SetNoticeText(oPC, "Lost influence with " + sName + ": " + sChange + " (Total: " + IntToString(nInfluence) + ")");
		PlaySound(SOUND_INFLUENCE_LOSS);
	}	
	else // influence gain
	{
		SendMessageToPC(oPC, "Gained influence with " + sName + ": +" + sChange + " (Total: " + IntToString(nInfluence) + ")");
   		SetNoticeText(oPC, "Gained influence with " + sName + ": +" + sChange + " (Total: " + IntToString(nInfluence) + ")");
		PlaySound(SOUND_INFLUENCE_GAIN);
	}
}
	

// Update the variable which keeps track of the companion's influence band.	
void UpdateInfluenceBand(string sCompanion)
{
	int nInfluence = GetGlobalInt(GetInfluenceVariable(sCompanion));   // influence variable
	string sInfluenceBand = PREFIX_INFLUENCE_BAND + sCompanion; 	   // influence band variable
	
	// check influence level and set the appropriate influence band
	if (nInfluence <= INFLUENCE_RANGE_REBELLIOUS)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_REBELLIOUS);
	else if (nInfluence <= INFLUENCE_RANGE_DISILLUSIONED)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_DISILLUSIONED);
	else if (nInfluence <= INFLUENCE_RANGE_WAVERING)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_WAVERING);
	else if (nInfluence <= INFLUENCE_RANGE_NEUTRAL)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_NEUTRAL);
	else if (nInfluence <= INFLUENCE_RANGE_TRUSTING)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_TRUSTING);
	else if (nInfluence <= INFLUENCE_RANGE_LOYAL)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_LOYAL);
	else if (nInfluence <= INFLUENCE_RANGE_DEVOTED)
		SetGlobalInt(sInfluenceBand, INFLUENCE_BAND_DEVOTED);
}


// Apply influence effects
void ApplyInfluenceEffects(string sCompanion)
{
	object oCompanion = GetObjectByTag(sCompanion);					
	int nInfluenceBand = GetGlobalInt(PREFIX_INFLUENCE_BAND + sCompanion); // influence band variable
	
	// restore defaults
	int bPossessable = TRUE;		 // possessable
	int bCanAccessInventory = TRUE;  // inventory accessible
	
	// check influence band and apply the appropriate effects
	switch (nInfluenceBand)
	{
		case INFLUENCE_BAND_REBELLIOUS:
			bPossessable = FALSE;		 // unpossessable
			bCanAccessInventory = FALSE; // inventory not accessed
			break;
		
		case INFLUENCE_BAND_DISILLUSIONED:
			bPossessable = TRUE;		 // possessable
			bCanAccessInventory = FALSE; // inventory not accessible
			break;
			
		case INFLUENCE_BAND_WAVERING:
			// add effects here
			break;
			
		case INFLUENCE_BAND_NEUTRAL:
			// add effects here
			break;

		case INFLUENCE_BAND_TRUSTING:
			// add effects here
			break;
			
		case INFLUENCE_BAND_LOYAL:
			// add effects here	
			break;
			
		case INFLUENCE_BAND_DEVOTED:
			// add effects here
			break;
	}
	
	SetIsPossessable(oCompanion, bPossessable); 				// set possessability
	SetPlayerInventoryAccess(oCompanion, bCanAccessInventory);  // set inventory access
}


// Set whether player can possess companion
void SetIsPossessable(object oCompanion, int bPossessable)
{
	int bBlocked = !bPossessable;
	SetIsCompanionPossessionBlocked(oCompanion, bBlocked);
}


// Set whether player can access companion inventory
void SetPlayerInventoryAccess(object oCompanion, int bCanAccessInventory)
{
	int bDisableEquip = !bCanAccessInventory;
	// TRUE = equipment disabled
	SetLocalInt(oCompanion, "X2_JUST_A_DISABLEEQUIP", bDisableEquip);
}


// return current companion influence level
int GetCompanionInfluence(string sCompanion)
{
	string sInfluence = GetInfluenceVariable(sCompanion);
	int nInfluence = GetGlobalInt(sInfluence);
	
	return nInfluence;	
}


// return current companion influence band
int GetCompanionInfluenceBand(string sCompanion)
{
	string sInfluenceBand = GetInfluenceBandVariable(sCompanion);
	int nInfluenceBand = GetGlobalInt(sInfluenceBand);
	
	return nInfluenceBand;	
}


// return name of the companion's influence variable
string GetInfluenceVariable(string sCompanion)
{
	string sInfluence = PREFIX_INFLUENCE + sCompanion;
	return sInfluence;	
}


// return name of the companion's influence band variable
string GetInfluenceBandVariable(string sCompanion)
{
	string sInfluenceBand = PREFIX_INFLUENCE_BAND + sCompanion;
	return sInfluenceBand;	
}

and the ga_influence used in the dialogue (and when using this the text is still yellow and all that)

// ga_influence
// Modify companion influence
//
// sCompanion = the companion whose influence we want to modify
// sChange    = the change we want to make (integer)

#include "ginc_influence_modi"

void main(string sCompanion, string sChange)
{
	ModifyInfluence(sCompanion, sChange);
}

EDIT3: It gets even werider now. If I use ga_influence at the end of a NWN2 style dialogue (at the last node) the text is now white and uppercase like in the xml file. However, if I use it in the middle of an ongoing dialogue (Iike I tested with before) the text is still yellow and another font. What’s going on here!? How do one change the notice text in the MIDDLE of a NWN2 style dialogue. Does that somehow use a DIFFERENT notice text? Gaah!! What’s wrong with NWN2?!

I solved it!

It turned out, since I had used SetCutsceneMode for this particular conversation, it uses cutscene.xml where there’s another Notice Text. Changing that did the trick.

2 Likes

Sometimes, it’s the little things …

1 Like