You should forget completely trying to reference network messages by their ID numbers only. Forget the ID numbers, they're not explicit, not readable, complicated etc etc.
Why don't you write a set of functions that would query for you a small database of message name/ID pairs each time you request a message ?
Like metamod's GET_USER_MSG_NAME() and GET_USER_MSG_ID()...
I already have written something like this. The basis is in pfnRegUserMsg() since it's where all messages are registered. First off, the message structure...
Code:
// user message record structure definition
typedef struct
{
const char *name;
int id;
} usermsg_t;
usermsg_t usermsgs[255]; // max of 256 different network messages
and then the pfnRegUserMsg() function
Code:
int pfnRegUserMsg (const char *pszName, int iSize)
{
int index = -1;
int msg = (*g_engfuncs.pfnRegUserMsg) (pszName, iSize); // register the message
// is this message NOT already registered ?
for (index = 0; index < usermsgs_count; index++)
if (strcmp (usermsgs[index].name, pszName) == 0)
break; // cycle through usermsgs types array and break if found
// now keep track (or update if necessary) this user message in our array...
usermsgs[index].name = pszName; // record this message's name
usermsgs[index].id = msg; // record this message's index
// are we certain this message has not been registered in the past ?
if (index == usermsgs_count)
usermsgs_count++; // we know now one user message more
return (msg); // ...and return the message ID number the engine gave us
}
and then each time you're in need for a particular message, for example let's say you want to send a TempEntity message to display a colorful welcome text with hudtextparms and stuff, you use these two nice helper functions :
Code:
int GetUserMsgId (const char *msg_name)
{
register int i;
// is it a standard engine message (i.e, already registered by engine) ?
if (strcmp ("TempEntity", msg_name) == 0)
return (SVC_TEMPENTITY); // return the correct message ID
else if (strcmp ("Intermission", msg_name) == 0)
return (SVC_INTERMISSION); // return the correct message ID
else if (strcmp ("CDTrack", msg_name) == 0)
return (SVC_CDTRACK); // return the correct message ID
else if (strcmp ("WeaponAnim", msg_name) == 0)
return (SVC_WEAPONANIM); // return the correct message ID
else if (strcmp ("RoomType", msg_name) == 0)
return (SVC_ROOMTYPE); // return the correct message ID
else if (strcmp ("Director", msg_name) == 0)
return (SVC_DIRECTOR); // return the correct message ID
// cycle through our known user message types array
for (i = 0; i < usermsgs_count; i++)
if (strcmp (usermsgs[i].name, msg_name) == 0)
return (usermsgs[i].id); // return the id of the message named msg_name
return (-1); // message not found, wtf?
}
const char *GetUserMsgName (int msg_type)
{
register int i;
// is it a standard engine message (i.e, already registered by engine) ?
if (msg_type == SVC_TEMPENTITY)
return ("TempEntity"); // return the correct message name
else if (msg_type == SVC_INTERMISSION)
return ("Intermission"); // return the correct message name
else if (msg_type == SVC_CDTRACK)
return ("CDTrack"); // return the correct message name
else if (msg_type == SVC_WEAPONANIM)
return ("WeaponAnim"); // return the correct message name
else if (msg_type == SVC_ROOMTYPE)
return ("RoomType"); // return the correct message name
else if (msg_type == SVC_DIRECTOR)
return ("Director"); // return the correct message name
// cycle through our known user message types array
for (i = 0; i < usermsgs_count; i++)
if (usermsgs[i].id == msg_type)
return (usermsgs[i].name); // return the name of the message having the msg_type id
return (NULL); // unknown user message
}
and it gives you something like this, for example :
Code:
MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, GetUserMsgId ("TempEntity"), NULL, pClient);
WRITE_BYTE (TE_TEXTMESSAGE);
WRITE_BYTE (1); // etc...
Note the use of GetUserMsgId(). So what do you think ? l33t, eh ?