mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-11 14:42:05 +08:00
engine: implement small Message Rewrite Facitility that allows to run mods that directly write internal GoldSrc messages
This commit is contained in:
@@ -329,6 +329,8 @@ typedef struct
|
||||
int msg_realsize; // left in bytes
|
||||
int msg_index; // for debug messages
|
||||
int msg_dest; // msg destination ( MSG_ONE, MSG_ALL etc )
|
||||
int msg_rewrite_index;
|
||||
int msg_rewrite_pos;
|
||||
qboolean msg_started; // to avoid recursive included messages
|
||||
edict_t *msg_ent; // user message member entity
|
||||
vec3_t msg_org; // user message member origin
|
||||
|
||||
+92
-5
@@ -2501,6 +2501,62 @@ int GAME_EXPORT pfnDecalIndex( const char *m )
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int SV_CanRewriteMessage( int msg_num )
|
||||
{
|
||||
// feature is disabled
|
||||
if( !FBitSet( host.bugcomp, BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG ))
|
||||
return 0;
|
||||
|
||||
switch( msg_num )
|
||||
{
|
||||
case svc_goldsrc_spawnstaticsound:
|
||||
return svc_sound;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qboolean SV_RewriteMessage( void )
|
||||
{
|
||||
vec3_t origin;
|
||||
const char *sample = NULL;
|
||||
float vol, attn;
|
||||
int ent, pitch, flags, idx;
|
||||
int cmd;
|
||||
|
||||
MSG_SeekToBit( &sv.multicast, svgame.msg_rewrite_pos, SEEK_SET );
|
||||
|
||||
cmd = MSG_ReadCmd( &sv.multicast, NS_SERVER );
|
||||
|
||||
switch( cmd )
|
||||
{
|
||||
case svc_goldsrc_spawnstaticsound:
|
||||
MSG_ReadVec3Coord( &sv.multicast, origin );
|
||||
idx = MSG_ReadShort( &sv.multicast );
|
||||
vol = MSG_ReadByte( &sv.multicast );
|
||||
attn = MSG_ReadByte( &sv.multicast ) / 64.0f;
|
||||
ent = MSG_ReadShort( &sv.multicast );
|
||||
pitch = MSG_ReadByte( &sv.multicast );
|
||||
flags = MSG_ReadByte( &sv.multicast );
|
||||
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
sample = va( "!%i", idx );
|
||||
else if( idx >= 0 && idx < MAX_SOUNDS )
|
||||
sample = sv.sound_precache[idx];
|
||||
|
||||
if( !COM_CheckString( sample ))
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: unrecognized sample in svc_spawnstaticsound, index %d, flags 0x%x\n", __func__, idx, flags );
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_SeekToBit( &sv.multicast, svgame.msg_rewrite_pos, SEEK_SET );
|
||||
return SV_BuildSoundMsg( &sv.multicast, EDICT_NUM( ent ), CHAN_STATIC, sample, vol, attn, flags, pitch, origin );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnMessageBegin
|
||||
@@ -2518,10 +2574,24 @@ static void GAME_EXPORT pfnMessageBegin( int msg_dest, int msg_num, const float
|
||||
// check range
|
||||
msg_num = bound( svc_bad, msg_num, 255 );
|
||||
|
||||
svgame.msg_rewrite_index = 0;
|
||||
svgame.msg_rewrite_pos = 0;
|
||||
|
||||
if( msg_num <= svc_lastmsg )
|
||||
{
|
||||
svgame.msg_index = -msg_num; // this is a system message
|
||||
svgame.msg_name = svc_strings[msg_num];
|
||||
// check if we should rewrite this message into something else...
|
||||
if( SV_CanRewriteMessage( msg_num ))
|
||||
{
|
||||
svgame.msg_index = -SV_CanRewriteMessage( msg_num );
|
||||
svgame.msg_name = svc_goldsrc_strings[msg_num] ? svc_goldsrc_strings[msg_num] : svc_strings[msg_num];
|
||||
svgame.msg_rewrite_index = msg_num;
|
||||
svgame.msg_rewrite_pos = MSG_TellBit( &sv.multicast );
|
||||
}
|
||||
else
|
||||
{
|
||||
svgame.msg_index = -msg_num; // this is a system message
|
||||
svgame.msg_name = svc_strings[msg_num];
|
||||
}
|
||||
|
||||
if( msg_num == svc_temp_entity )
|
||||
iSize = -1; // temp entity have variable size
|
||||
@@ -2596,6 +2666,25 @@ static void GAME_EXPORT pfnMessageEnd( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( svgame.msg_rewrite_index != 0 )
|
||||
{
|
||||
if( SV_RewriteMessage( ))
|
||||
{
|
||||
if( MSG_CheckOverflow( &sv.multicast ))
|
||||
{
|
||||
Con_Printf( S_ERROR "MessageEnd: %s has overflow multicast buffer (post-rewrite)\n", name );
|
||||
MSG_Clear( &sv.multicast );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_ERROR "MessageEnd: failed to rewrite message %s\n", name );
|
||||
MSG_Clear( &sv.multicast );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check for system message
|
||||
if( svgame.msg_index < 0 )
|
||||
{
|
||||
@@ -2662,9 +2751,7 @@ static void GAME_EXPORT pfnMessageEnd( void )
|
||||
// update some messages in case their was format was changed and we want to keep backward compatibility
|
||||
if( svgame.msg_index < 0 )
|
||||
{
|
||||
int svc_msg = abs( svgame.msg_index );
|
||||
|
||||
if(( svc_msg == svc_finale || svc_msg == svc_cutscene ) && svgame.msg_realsize == 0 )
|
||||
if(( svgame.msg_index == -svc_finale || svgame.msg_index == -svc_cutscene ) && svgame.msg_realsize == 0 )
|
||||
MSG_WriteChar( &sv.multicast, 0 ); // write null string
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user