Patch for chat window, also new function

A forum for feature requests/discussions and user submitted patches that improve MQ2

Moderator: MacroQuest Developers

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Patch for chat window, also new function

Post by Lax » Wed Oct 29, 2003 3:57 pm

EQLib_Utilities.cpp

Code: Select all

VOID WriteChatColor(PCHAR Line, DWORD Color) {
   if (!gbInGame) return;
   if (gFilterMacro != FILTERMACRO_NONE) {
	if (!EQADDR_CHAR || !*EQADDR_CHAR || !strcmp(&((PSPAWNINFO)*EQADDR_CHAR)->Name[0],"load"))
	{
		gbInGame=false;
		return;
	}
   PEQCHATMGR pChatManager=*(PEQCHATMGR*)EQADDR_CHATMANAGER;
   __asm
   {
      push eax;
      push ecx;
      mov ecx, pChatManager;
      push Color;
      call [EQADDR_CCHATMANAGERGETRGBAFROMINDEX];
      mov [Color], eax;
      pop ecx;
      pop eax;
   };
   char out[MAX_STRING];
   int i = 0;
   int o = 0;
   while(Line[i]!=0)
   {
      switch(Line[i])
      {
      case '&':
[color=red]         out[o++]='&';[/color]
         out[o++]='A';
         out[o++]='M';
         out[o++]='P';
         out[o++]=';';
         break;
      case '%':
[color=red]         out[o++]='&';[/color]
         out[o++]='P';
         out[o++]='C';
         out[o++]='T';
         out[o++]=';';
         break;
      case '<':
[color=red]         out[o++]='&';[/color]
         out[o++]='L';
         out[o++]='T';
         out[o++]=';';
         break;
      case '>':
[color=red]         out[o++]='&';[/color]
         out[o++]='G';
         out[o++]='T';
         out[o++]=';';
         break;
      case '"':
[color=red]         out[o++]='&';[/color]
         out[o++]='Q';
         out[o++]='U';
         out[o++]='O';
         out[o++]='T';
         out[o++]=';';
         break;
      default:
         out[o++]=Line[i];
         break;
      }
      i++;
   }
[color=red]
	out[o++]=0;
[/color]

   Chat([color=red]&out[0][/color],Color);
        }
        else if (gTelnetServer && gTelnetConnection) {
      TelnetServer_Write(Line);
   }
};
NEW addition to EQLib_UI.cpp
(note: red line setting first color variable is added since first post)

Code: Select all

#define InsertColor(text,color) sprintf(text,"<c \"#%06X\">",color);TotalColors++;
#define InsertStopColor(text)   sprintf(text,"</c>");TotalColors--;

VOID Chat(PCHAR Text)
{
	DebugSpewAlways("Chat(%s)",Text);
   PEQCHATMGR pChatManager= *(PEQCHATMGR*)EQADDR_CHATMANAGER;
   if (!MQChatWnd) {
      MakeChatWindow();
   }

   if (!MQChatWnd) {
      return;
   }

   char out[MAX_STRING];
   int i = 0;
   int o = 0;
   bool bFirstColor=false;
   int CurrentColor=0xFFFFFFFF; // -1
   int TotalColors=0;
   while(Text[i]!=0)
   {
      switch(Text[i])
      {
	  case '\a':
		  // HANDLE COLOR
                  [color=red]bFirstColor=true;[/color]
		  i++;
		  if (Text[i]=='x')
		  {
			  CurrentColor=-1;
			  o+=InsertStopColor(&out[o]);
		  }
		  else
		  if (Text[i]=='#')
		  {
			  i++;
			  char temp[7];
			  for (int x = 0 ; x < 6 ; x++)
			  {
				temp[x++]=Text[i++];
			  }
			  i--;
			  temp[6]=0;
			  CurrentColor=-1;
			  o+=sprintf(&out[o],"<c \"#%s\">",&temp[0]);
			  TotalColors++;
		  }
		  else
		  {
			bool Dark=false;
			if (Text[i]=='-')
			{
				Dark=true;	
				i++;
			}
			int LastColor=CurrentColor;
			switch(Text[i])
			{
				case 'y': // yellow (green/red)
					if (Dark)
						CurrentColor=0x999900;
					else
						CurrentColor=0xFFFF00;
					break;
				case 'o': // orange (green/red)
					if (Dark)
						CurrentColor=0x996600;
					else
						CurrentColor=0xFF9900;
					break;
				case 'g': // green   (green)
					if (Dark)
						CurrentColor=0x009900;
					else
	  					CurrentColor=0x00FF00;
					break;
				case 'u': // blue   (blue)
					if (Dark)
						CurrentColor=0x000099;
					else
  						CurrentColor=0x0000FF;
					break;
				case 'r': // red     (red)
					if (Dark)
						CurrentColor=0x990000;
					else
	  					CurrentColor=0xFF0000;
					break;
				case 't': // teal (blue/green)
					if (Dark)
  						CurrentColor=0x009999;
					else
  						CurrentColor=0x00FFFF;
					break;
				case 'b': // black   (none)
  					CurrentColor=0x000000;
					break;
				case 'm': // magenta (blue/red)
					if (Dark)
	  					CurrentColor=0x990099;
					else
	  					CurrentColor=0xFF00FF;
					break;
				case 'p': // purple (blue/red)
					if (Dark)
						CurrentColor=0x660099;
					else
	  					CurrentColor=0x9900FF;
					break;
				case 'w': // white   (all)
					if (Dark)
						CurrentColor=0x999999;
					else
	  					CurrentColor=0xFFFFFF;
					break;
				}
				if (CurrentColor!=LastColor)
				{
					o+=InsertColor(&out[o],CurrentColor);
				}
			}
		  break;
      case '&':
         out[o++]='&';
         out[o++]='A';
         out[o++]='M';
         out[o++]='P';
         out[o++]=';';
         break;
      case '%':
         out[o++]='&';
         out[o++]='P';
         out[o++]='C';
         out[o++]='T';
         out[o++]=';';
         break;
      case '<':
         out[o++]='&';
         out[o++]='L';
         out[o++]='T';
         out[o++]=';';
         break;
      case '>':
         out[o++]='&';
         out[o++]='G';
         out[o++]='T';
         out[o++]=';';
         break;
      case '"':
         out[o++]='&';
         out[o++]='Q';
         out[o++]='U';
         out[o++]='O';
         out[o++]='T';
         out[o++]=';';
         break;
      default:
		  if (!bFirstColor)
		  {
			  bFirstColor=true;
			  CurrentColor=0xFFFFFF; // white
			  o+=InsertColor(&out[o],CurrentColor);
		  }
         out[o++]=Text[i];
         break;
      }
      i++;
   }
   for (TotalColors ; TotalColors>0 ; TotalColors--)
   {
	  o+=InsertStopColor(&out[o]);
   }
	out[o++]=0;
	DebugSpewAlways("Chat() output \"%s\"",&out[0]);
   CChatWindow__AddOutputText(MQChatWnd,&out[0],0);
}
MQ.h

Code: Select all

VOID		Chat					(PCHAR Text, DWORD Color);
[color=red]VOID		Chat					(PCHAR Text);[/color]
Note: keep both function prototypes, as shown.

The new, single parameter Chat function uses special characters to make it easier to use colors in MQ displays. The special character is \a which can't be typed within EQ. There are predefined colors:
m - magenta
p - purple
o - orange
u - blue
r - red
g - green
b - black
w - white
t - teal (blue-green)
y - yellow

They are used like so: \ay for yellow, \au for blue. Additionally, you can put a "-" in front of the color char to use a darker version of the same color.

Demonstration

Code: Select all

	Chat("Testing \ayc\aoh\aga\aut \arc\ato\abl\amo\awr\ats");
	Chat("Testing \a-yc\a-oh\a-ga\a-ut \a-rc\a-to\a-bl\a-mo\a-wr\ats");
You can also specify custom colors in the same way: \a#ffffff would be white, use the hex value for the color in #RRGGBB form.

To return to the previous color, use \ax. Example: This is white \ayyellow \axwhite.

The default color is white.
Last edited by Lax on Wed Oct 29, 2003 5:10 pm, edited 1 time in total.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Mckorr
Developer
Developer
Posts: 2326
Joined: Fri Oct 18, 2002 1:16 pm
Location: Texas

Post by Mckorr » Wed Oct 29, 2003 5:01 pm

Updated in CVS.
MQ2: Think of it as Evolution in action.

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Oct 29, 2003 5:11 pm

Add

Code: Select all

		  bFirstColor=true;
right under

Code: Select all

		  // HANDLE COLOR
in EQLib_UI.cpp new Chat function.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Mckorr
Developer
Developer
Posts: 2326
Joined: Fri Oct 18, 2002 1:16 pm
Location: Texas

Post by Mckorr » Wed Oct 29, 2003 5:21 pm

Argh, you're killing me! Done.
MQ2: Think of it as Evolution in action.

MacroFiend
a grimling bloodguard
a grimling bloodguard
Posts: 662
Joined: Mon Jul 28, 2003 2:47 am

Post by MacroFiend » Wed Oct 29, 2003 7:04 pm

Request/Suggestion ...

I noticed that your SMTL'ify the messages inside WriteChatColor and again in the Chat() function. Wouldn't it be better (more usefull in the future) to create a ConvertSMTL() function in the EQLib_Utilities that will do both the core SMTL conversion and your color changes in a single loop through the string?

As we get more control of the UI and our own output, it would be better to have the SMTL converter as a function so we can ... for example ... embed the readme.html for MQ inside a different chat window.

It would also make it easier to write in the routines to allow for bypassing the newer MQ window for those who prefer it going in to the normal chat window.

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Oct 29, 2003 7:42 pm

I thought about that but decided against it because it's really messy to require everyone to call MakeSTMLSafe; it should be handled by the display functions.. but yes a function that does the color conversions and stml safe parsing both would be good in the long run instead of reproducing it.

In order to use the normal chat window still it would be incredibly simple but not recommended... would take minor fiddling to set MQChatWnd equal to the main chat window and stop it from being freed by our routines.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Ohmz
Developer
Developer
Posts: 97
Joined: Tue Feb 04, 2003 12:54 pm

Post by Ohmz » Thu Oct 30, 2003 7:58 am

I think he means to have the generic chat functions call it also. Removing the current redundancy

azwildfire
Contributing Member
Contributing Member
Posts: 72
Joined: Fri Jul 05, 2002 5:12 am
Location: Phoenix arizona
Contact:

Post by azwildfire » Thu Oct 30, 2003 11:51 am

i really hate this chat window.. how can i turn it off?