engine: client: fix crash when loading a save that references non-existing word

This commit is contained in:
Alibek Omarov
2026-05-30 03:52:56 +05:00
parent ef5295c5ab
commit adca77672a
3 changed files with 27 additions and 13 deletions

View File

@@ -1155,7 +1155,7 @@ void S_StopStreaming( void );
void S_BeginRegistration( void );
sound_t S_RegisterSound( const char *sample );
void S_EndRegistration( void );
void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, int pitch, int flags, double sample, double end, int wordIndex );
void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, int pitch, int flags, double sample, double end, uint wordIndex );
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, int pitch, int flags );
void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, float attn, int pitch, int flags );
void S_SoundFade( int fade_percent, int hold_time, int fade_out_seconds, int fade_in_seconds );

View File

@@ -60,10 +60,6 @@ CL_ParseSoundPacket
*/
static void CL_ParseSoundPacket( sizebuf_t *msg, qboolean restore )
{
int wordIndex = 0;
sound_t handle = 0;
double samplePos = 0, forcedEnd = 0;
int flags = MSG_ReadUBitLong( msg, MAX_SND_FLAGS_BITS );
int sound = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
int chan = MSG_ReadUBitLong( msg, MAX_SND_CHAN_BITS );
@@ -90,6 +86,7 @@ static void CL_ParseSoundPacket( sizebuf_t *msg, qboolean restore )
vec3_t pos;
MSG_ReadVec3Coord( msg, pos );
sound_t handle = 0;
if( FBitSet( flags, SND_SENTENCE ))
{
char sentenceName[32];
@@ -102,6 +99,8 @@ static void CL_ParseSoundPacket( sizebuf_t *msg, qboolean restore )
}
else handle = cl.sound_index[sound]; // see precached sound
uint wordIndex = 0;
double samplePos = 0, forcedEnd = 0;
if( restore )
{
wordIndex = MSG_ReadByte( msg );

View File

@@ -740,7 +740,7 @@ S_RestoreSound
Restore a sound effect for the given entity on the given channel
====================
*/
void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, int pitch, int flags, double sample, double end, int wordIndex )
void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, int pitch, int flags, double sample, double end, uint wordIndex )
{
wavdata_t *pSource;
sfx_t *sfx = NULL;
@@ -804,15 +804,30 @@ void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float
// not a first word in sentence!
if( wordIndex != 0 )
{
VOX_FreeWord( target_chan ); // release first loaded word
target_chan->word_index = wordIndex; // restore current word
VOX_LoadWord( target_chan );
uint word_count = 0;
if( !FBitSet( target_chan->flags, FL_CHAN_SENTENCE_FINISHED ))
if( target_chan->words )
{
target_chan->sfx = target_chan->words[target_chan->word_index].sfx;
sfx = target_chan->sfx;
pSource = sfx->cache;
while( word_count < CVOXWORDMAX && target_chan->words[word_count].sfx )
word_count++;
}
if( wordIndex >= word_count )
{
SetBits( target_chan->flags, FL_CHAN_SENTENCE_FINISHED );
}
else
{
VOX_FreeWord( target_chan ); // release first loaded word
target_chan->word_index = wordIndex; // restore current word
VOX_LoadWord( target_chan );
if( !FBitSet( target_chan->flags, FL_CHAN_SENTENCE_FINISHED ))
{
target_chan->sfx = target_chan->words[target_chan->word_index].sfx;
sfx = target_chan->sfx;
pSource = sfx->cache;
}
}
}
else