I noticed that a lot of bandwidth is consumed when trying to display a HUD Message. To fix this I coded a new type of message system that uses a lot less bandwidth. My first attempt to recode it was ruined when I took a look at message.cpp, I thought the client and server was coded in C++, not bit-bashing C. So I decided to recode the entire thing.
First things first, go to your client workspace and create a new file called custom_message.cpp or something similar, it doesnt really matter, just remember to call it something that you can remember.
Somewhere in hud.h add the following:
| | // Pongles [ class CCustomMessage { public: byte r, g, b; float y; float fadein; float fadeout; float holdtime; char *pText; float time; char szText[64];
CCustomMessage() {} CCustomMessage(byte rr, byte gg, byte bb, float yy, float fo, float ht, float st, char *szt); };
const int maxCustomMessages = 16;
class CHudCustomMsg : public CHudBase { CCustomMessage *m_pCustomMsgs[maxCustomMessages];
public: int Init(void); int VidInit( void ); int Draw(float flTime); int MsgFunc_CustomMsg(const char *pszName, int iSize, void *pbuf); int CenterPos(char *szMessage); void MessageAdd( int type, float time, char *text ); void Reset( void );
~CHudCustomMsg(); }; // Pongles ]
|
While in hud.h you need to let the base class know about it otherwise it cannot be initialised.
So under public in CHud add the following:
| | // Pongles [ CHudCustomMsg m_CustomMsg; // Pongles ]
|
Close hud.h and open up hud.cpp, under the function void CHud :: Init( void ) add the following:
| | // Pongles [ m_CustomMsg.Init(); // Pongles ]
|
Slightly further on in the code you find the function void CHud :: VidInit( void ) add this following:
| | // Pongles [ m_CustomMsg.VidInit(); // Pongles ]
|
In your newly created source file create , add this:
| | // // custom_message.cpp // // implementation of CHudCustomMsg class // // Coded By: Pongles
#include "hud.h" #include "cl_util.h" #include "parsemsg.h" #include <string.h> #include <stdio.h>
#define MSG_RESPAWN 1 #define MSG_GAME 2 #define MSG_FIRSTBLOOD 3 #define MSG_NAME 4 #define MSG_VICTIM 5 #define MSG_KILLER 6 #define MSG_WEAPON 7
CCustomMessage::CCustomMessage(byte rr, byte gg, byte bb, float yy, float fo, float ht, float st, char *szt) { r = rr; g = gg; b = bb; y = yy; fadeout = fo; holdtime = ht; time = st; strcpy(szText, szt); }
DECLARE_MESSAGE(m_CustomMsg, CustomMsg);
int CHudCustomMsg::Init(void) { HOOK_MESSAGE(CustomMsg);
gHUD.AddHudElem(this);
Reset();
return 1; }
int CHudCustomMsg::VidInit(void) { return 1; }
void CHudCustomMsg::Reset( void ) { for(int i = 0; i < maxCustomMessages; i++) { if (m_pCustomMsgs[i]) delete m_pCustomMsgs[i]; m_pCustomMsgs[i] = NULL; } }
CHudCustomMsg::~CHudCustomMsg( ) { for(int i = 0; i < maxCustomMessages; i++) { if(m_pCustomMsgs[i]) { delete m_pCustomMsgs[i]; } } }
int CHudCustomMsg::Draw(float flTime) { int Index; bool BeingDrawn = false;
float factor, endTime, holdTime;
CCustomMessage *pMessage;
// loop though 0 - 16 for ( Index = 0; Index < maxCustomMessages; Index++ ) { // is there one here? if ( m_pCustomMsgs[Index] ) { pMessage = m_pCustomMsgs[Index];
endTime = pMessage->time + pMessage->fadeout + pMessage->holdtime; holdTime = pMessage->time + pMessage->holdtime;
BeingDrawn = true; if ( flTime <= holdTime ) { // hold factor = 1; } else { // fade out factor = 1 - ((flTime - holdTime) / pMessage->fadeout); } gHUD.DrawHudString( (ScreenWidth - CenterPos(pMessage->szText)) / 2, pMessage->y, ScreenWidth, pMessage->szText, factor * (pMessage->r), factor * (pMessage->g), factor * (pMessage->b) ); // finished ? if(flTime >= endTime) { m_pCustomMsgs[Index] = NULL; delete pMessage; } } }
if ( !BeingDrawn ) m_iFlags &= ~HUD_ACTIVE;
return 1; }
int CHudCustomMsg::MsgFunc_CustomMsg(const char*pszName, int iSize, void *pbuf) { BEGIN_READ(pbuf,iSize);
int x = READ_BYTE();
// reads string sent from server char *szText = READ_STRING();
MessageAdd( x, gHUD.m_flTime, szText );
m_iFlags |= HUD_ACTIVE;
return 1; }
int CHudCustomMsg::CenterPos( char *szMessage ) { int width = 0;
for (; *szMessage != 0 && *szMessage != '\n'; szMessage++ ) { width += gHUD.m_scrinfo.charWidths[ *szMessage ]; }
return width; }
void CHudCustomMsg::MessageAdd( int type, float time, char *text ) { // check if there is an instance already
char tempBuffer[64]; if(m_pCustomMsgs[type] != NULL) { delete m_pCustomMsgs[type]; }
// add new instance
switch ( type ) { case MSG_RESPAWN: m_pCustomMsgs[type] = new CCustomMessage(0, 255, 0, (ScreenHeight / 2) + (ScreenHeight / 4),1.5, 1, time, "Press [Fire] To Respawn"); break; case MSG_GAME: m_pCustomMsgs[type] = new CCustomMessage(192, 192, 192, ScreenHeight / 2, 1.5, 5, time, text); break; case MSG_FIRSTBLOOD: sprintf(tempBuffer, "%s Drew First Blood", text); m_pCustomMsgs[type] = new CCustomMessage(255, 0, 0, ScreenHeight / 4.5, 1.5, 5, time, tempBuffer); break; case MSG_NAME: sprintf(tempBuffer, "Name: %s", text); m_pCustomMsgs[type] = new CCustomMessage(0, 255, 0, ScreenHeight / 2 + (ScreenHeight / 4),1, 1.5, time, tempBuffer); break; case MSG_VICTIM: sprintf(tempBuffer, "You were killed by %s", text); m_pCustomMsgs[type] = new CCustomMessage(0, 0, 255, ScreenHeight / 4, 1.5, 1, time, tempBuffer); break; case MSG_KILLER: sprintf(tempBuffer, "You Killed %s", text); m_pCustomMsgs[type] = new CCustomMessage(255, 0, 0, ScreenHeight / 4.5, 1.5, 1, time, tempBuffer); break; case MSG_WEAPON: sprintf(tempBuffer, "You got a %s", text); m_pCustomMsgs[type] = new CCustomMessage(200, 200, 200, ScreenHeight / 2 + (ScreenHeight / 4.5), 1.5, 5, time, tempBuffer); break; } }
|
I have created a UT style message system to use.
Thats it for client side, skip over to server side and open up util.cpp. Add the following somewhere in the file:
| | // Pongles [ extern int gmsgCustomMsg;
void UTIL_CustomMessage( CBaseEntity *pEntity, int type, const char *pMessage ) { if ( !pEntity || !pEntity->IsNetClient() ) return;
MESSAGE_BEGIN( MSG_ONE, gmsgCustomMsg, NULL, pEntity->edict() );
WRITE_BYTE( type );
if( type > MSG_RESPAWN ) WRITE_STRING( pMessage );
MESSAGE_END(); }
void UTIL_CustomMessageAll( int type, const char *pMessage ) { MESSAGE_BEGIN( MSG_ALL, gmsgCustomMsg, NULL ); WRITE_BYTE( type ); if( type > MSG_RESPAWN ) WRITE_STRING( pMessage ); MESSAGE_END(); } // Pongles ]
|
Define it in util.h with the following:
| | // Pongles [ void UTIL_CustomMessage( CBaseEntity *pEntity, int type, const char *pMessage = NULL ); void UTIL_CustomMessageAll( int type, const char *pMessage = NULL ); // Pongles ]
|
While your there add these following defines somewhere:
| | // Pongles [ #define MSG_RESPAWN 1 #define MSG_GAME 2 #define MSG_FIRSTBLOOD 3 #define MSG_NAME 4 #define MSG_VICTIM 5 #define MSG_KILLER 6 #define MSG_WEAPON 7 // Pongles ]
|
We have defined an external integer, so we better go define it in player.cpp.
In the massive block of definitions [ edit: around line 149 - Entropy ] add the following:
| | // Pongles [ int gmsgCustomMsg = 0; // Pongles ]
|
Remember to register it otherwise the engine wont know what to do with it: [ edit: this line needs to be in the LinkUserMessages function - Entropy ]
| | // Pongles [ gmsgCustomMsg = REG_USER_MSG("CustomMsg", -1); // Pongles ]
|
And there you have it a much simpler message system! |