Page 1 of 1

Patch for chat window, also new function

Posted: Wed Oct 29, 2003 3:57 pm
by Lax
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.

Posted: Wed Oct 29, 2003 5:01 pm
by Mckorr
Updated in CVS.

Posted: Wed Oct 29, 2003 5:11 pm
by Lax
Add

Code: Select all

		  bFirstColor=true;
right under

Code: Select all

		  // HANDLE COLOR
in EQLib_UI.cpp new Chat function.

Posted: Wed Oct 29, 2003 5:21 pm
by Mckorr
Argh, you're killing me! Done.

Posted: Wed Oct 29, 2003 7:04 pm
by MacroFiend
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.

Posted: Wed Oct 29, 2003 7:42 pm
by Lax
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.

Posted: Thu Oct 30, 2003 7:58 am
by Ohmz
I think he means to have the generic chat functions call it also. Removing the current redundancy

Posted: Thu Oct 30, 2003 11:51 am
by azwildfire
i really hate this chat window.. how can i turn it off?