31 Aug 2010

This commit is contained in:
g-cont 2010-08-31 00:00:00 +04:00 committed by Alibek Omarov
parent dd3011ccf2
commit 5471cbcdc9
21 changed files with 180 additions and 166 deletions

View File

@ -57,7 +57,8 @@ CHud :: ~CHud( void )
m_pHudList = NULL;
}
free( m_pSpriteList );
// release hud.txt file
gEngfuncs.COM_FreeFile( m_pSpriteList );
m_pSpriteList = NULL;
}

View File

@ -181,8 +181,8 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
}
else pWeapon->hAmmo2 = 0;
// in original Half-Life this was a leak
free( pList );
// release weapon file
gEngfuncs.COM_FreeFile( pList );
}
// Returns the first weapon for a given slot.

View File

@ -931,12 +931,14 @@ void CPushable :: Move( CBaseEntity *pOther, int push )
return;
}
// g-cont. fix pushable acceleration bug
if ( pOther->IsPlayer() )
{
if ( push && !(pevToucher->button & (IN_FORWARD|IN_USE)) ) // Don't push unless the player is pushing forward and NOT use (pull)
// Don't push unless the player is pushing forward and NOT use (pull)
if ( push && !(pevToucher->button & (IN_FORWARD|IN_MOVERIGHT|IN_MOVELEFT|IN_BACK)) )
return;
playerTouch = 1;
if ( !push && !(pevToucher->button & (IN_BACK)) ) return;
playerTouch = 1;
}
float factor;

View File

@ -174,11 +174,10 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
if( CM_GetModelType( state->modelindex ) == mod_studio )
CL_UpdateStudioVars( ent, state );
if( !VectorCompare( state->origin, ent->curstate.origin ))
CL_LinkEdict( ent ); // relink entity
// set right current state
ent->curstate = *state;
CL_LinkEdict( ent ); // relink entity
}
/*
@ -517,24 +516,56 @@ void CL_AddEntities( void )
//
// sound engine implementation
//
void CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity )
bool CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity )
{
cl_entity_t *ent;
bool from_baseline = false;
ent = CL_GetEntityByIndex( entnum );
if( !ent ) return; // leave uncahnged
if( entnum < 0 || entnum > clgame.numEntities )
return false;
// setup origin and velocity
if( origin ) VectorCopy( ent->origin, origin );
if( velocity ) VectorCopy( ent->curstate.velocity, velocity );
ent = EDICT_NUM( entnum );
// if a brush model, offset the origin
if( origin && CM_GetModelType( ent->curstate.modelindex ) == mod_brush )
if( ent->index == -1 || ent->curstate.number != entnum )
{
vec3_t mins, maxs, midPoint;
Mod_GetBounds( ent->curstate.modelindex, mins, maxs );
VectorAverage( mins, maxs, midPoint );
VectorAdd( origin, midPoint, origin );
// this entity isn't visible but maybe it have baseline ?
if( ent->baseline.number != entnum )
return false;
from_baseline = true;
}
if( from_baseline )
{
// setup origin and velocity
if( origin ) VectorCopy( ent->baseline.origin, origin );
if( velocity ) VectorCopy( ent->baseline.velocity, velocity );
// if a brush model, offset the origin
if( origin && CM_GetModelType( ent->baseline.modelindex ) == mod_brush )
{
vec3_t mins, maxs, midPoint;
Mod_GetBounds( ent->baseline.modelindex, mins, maxs );
VectorAverage( mins, maxs, midPoint );
VectorAdd( origin, midPoint, origin );
}
}
else
{
// setup origin and velocity
if( origin ) VectorCopy( ent->origin, origin );
if( velocity ) VectorCopy( ent->curstate.velocity, velocity );
// if a brush model, offset the origin
if( origin && CM_GetModelType( ent->curstate.modelindex ) == mod_brush )
{
vec3_t mins, maxs, midPoint;
Mod_GetBounds( ent->curstate.modelindex, mins, maxs );
VectorAverage( mins, maxs, midPoint );
VectorAdd( origin, midPoint, origin );
}
}
return true;
}

View File

@ -966,8 +966,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
Com_ReadUlong( script, SC_ALLOW_NEWLINES, &numSprites );
// name, res, pic, x, y, w, h
// NOTE: we intentionally use malloc to let client.dll freeing it with standard methods
pList = malloc( sizeof( *pList ) * numSprites );
pList = Mem_Alloc( cls.mempool, sizeof( client_sprite_t ) * numSprites );
for( index = 0; index < numSprites; index++ )
{
@ -2504,7 +2503,6 @@ void CL_UnloadProgs( void )
FS_FreeLibrary( clgame.hInstance );
Mem_FreePool( &cls.mempool );
Mem_FreePool( &clgame.mempool );
Mem_FreePool( &clgame.private );
Mem_Set( &clgame, 0, sizeof( clgame ));
}
@ -2523,7 +2521,6 @@ bool CL_LoadProgs( const char *name )
cls.mempool = Mem_AllocPool( "Client Static Pool" );
clgame.mempool = Mem_AllocPool( "Client Edicts Zone" );
clgame.private = Mem_AllocPool( "Client Private Zone" );
clgame.entities = NULL;
clgame.hInstance = FS_LoadLibrary( name, false );

View File

@ -806,6 +806,7 @@ void CL_PrepVideo( void )
com.strncpy( mapname, cl.configstrings[CS_MODELS+1], MAX_STRING );
CM_BeginRegistration( mapname, true, &map_checksum );
re->BeginRegistration( mapname );
cl.worldmodel = CM_ClipHandleToModel( 1 ); // get world pointer
SCR_RegisterShaders(); // update with new sequence
SCR_UpdateScreen();
@ -857,6 +858,9 @@ void CL_PrepVideo( void )
SCR_UpdateScreen ();
CL_RunLightStyles ();
// initialize world and clients
CL_InitWorld ();
cl.video_prepped = true;
cl.force_refdef = true;
}

View File

@ -366,7 +366,7 @@ void CL_ParseSoundPacket( sizebuf_t *msg, bool is_ambient )
int chan, sound;
float volume, attn;
int flags, pitch, entnum;
sound_t handle;
sound_t handle = 0;
flags = BF_ReadWord( msg );
sound = BF_ReadWord( msg );
@ -551,6 +551,7 @@ void CL_ParseServerData( sizebuf_t *msg )
clgame.maxEntities = BF_ReadWord( msg );
com.strncpy( clgame.mapname, BF_ReadString( msg ), MAX_STRING );
com.strncpy( clgame.maptitle, BF_ReadString( msg ), MAX_STRING );
cl.refdef.viewentity = cl.playernum + 1; // always keep viewent an actual
gameui.globals->maxClients = cl.maxclients;
com.strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
@ -581,9 +582,6 @@ void CL_ParseServerData( sizebuf_t *msg )
Mem_Set( &clgame.movevars, 0, sizeof( clgame.movevars ));
Mem_Set( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
// initialize world and clients
CL_InitWorld ();
}
/*
@ -616,7 +614,6 @@ void CL_ParseBaseline( sizebuf_t *msg )
else timebase = 1000; // sv.state == ss_loading
MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, timebase );
CL_LinkEdict( ent ); // relink entity
}
/*

View File

@ -32,23 +32,18 @@ bool CL_CopyEntityToPhysEnt( physent_t *pe, cl_entity_t *ent )
// client or bot
com.strncpy( pe->name, "player", sizeof( pe->name ));
}
else if( ent == clgame.entities )
{
// it's a world
com.strncpy( pe->name, "world", sizeof( pe->name ));
}
else
{
// otherwise copy the modelname
com.strncpy( pe->name, mod->name, sizeof( pe->name ));
}
if( ent->curstate.movetype == MOVETYPE_PUSHSTEP || mod->type == mod_studio && mod->extradata )
if( mod->type == mod_studio )
{
pe->studiomodel = mod;
pe->model = NULL;
}
else if( mod->type == mod_brush || mod->type == mod_world )
else
{
pe->studiomodel = NULL;
pe->model = mod;

View File

@ -43,7 +43,7 @@ areanode_t *CL_CreateAreaNode( int depth, vec3_t mins, vec3_t maxs )
anode->axis = 0;
else anode->axis = 1;
anode->dist = 0.5f * (maxs[anode->axis] + mins[anode->axis]);
anode->dist = 0.5f * ( maxs[anode->axis] + mins[anode->axis] );
VectorCopy( mins, mins1 );
VectorCopy( mins, mins2 );
VectorCopy( maxs, maxs1 );
@ -64,13 +64,10 @@ CL_ClearWorld
*/
void CL_ClearWorld( void )
{
vec3_t mins, maxs;
int worldIndex = 1;
cl_numareanodes = 0;
Mod_GetBounds( worldIndex, mins, maxs );
Mem_Set( cl_areanodes, 0, sizeof( cl_areanodes ));
CL_CreateAreaNode( 0, mins, maxs );
cl_numareanodes = 0;
CL_CreateAreaNode( 0, cl.worldmodel->mins, cl.worldmodel->maxs );
}
/*

View File

@ -95,6 +95,8 @@ typedef struct
char configstrings[MAX_CONFIGSTRINGS][CS_SIZE];
entity_state_t entity_curstates[MAX_PARSE_ENTITIES]; // FIXME: this is must match with max_edicts ?
model_t *worldmodel; // pointer to world
// locally derived information from server state
model_t models[MAX_MODELS];
sound_t sound_precache[MAX_SOUNDS];
@ -211,7 +213,6 @@ typedef struct
void *hInstance; // pointer to client.dll
HUD_FUNCTIONS dllFuncs; // dll exported funcs
byte *mempool; // client edicts pool
byte *private; // client.dll private pool
string mapname; // map name
string maptitle; // display map title
string itemspath; // path to items description for auto-complete func
@ -476,7 +477,7 @@ bool CL_IsPredicted( void );
//
void CL_ParseFrame( sizebuf_t *msg );
void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate );
void CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity );
bool CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity );
//
// cl_tent.c

View File

@ -245,7 +245,7 @@ void Tri_DrawTriangles( int fTrans );
int CL_PointContents( const vec3_t point );
char *COM_ParseFile( char *data, char *token );
void CL_StudioFxTransform( struct cl_entity_s *ent, float transform[4][4] );
void CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity );
bool CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity );
void CL_StudioEvent( struct mstudioevent_s *event, struct cl_entity_s *ent );
bool CL_GetComment( const char *demoname, char *comment );
struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );

View File

@ -51,6 +51,8 @@ typedef struct clipmap_s
byte *phs;
byte nullrow[MAX_MAP_LEAFS/8];
vec3_t hull_sizes[4]; // hull sizes
script_t *entityscript; // only actual for world
// run local lightstyles to get SV_LightPoint grab the actual information

View File

@ -686,6 +686,7 @@ static void BSP_LoadClipnodes( dlump_t *l )
hull->planes = loadmodel->planes;
VectorCopy( GI->client_mins[1], hull->clip_mins ); // copy human hull
VectorCopy( GI->client_maxs[1], hull->clip_maxs );
VectorSubtract( hull->clip_maxs, hull->clip_mins, cm.hull_sizes[1] );
hull = &loadmodel->hulls[2];
hull->clipnodes = out;
@ -694,6 +695,7 @@ static void BSP_LoadClipnodes( dlump_t *l )
hull->planes = loadmodel->planes;
VectorCopy( GI->client_mins[2], hull->clip_mins ); // copy large hull
VectorCopy( GI->client_maxs[2], hull->clip_maxs );
VectorSubtract( hull->clip_maxs, hull->clip_mins, cm.hull_sizes[2] );
hull = &loadmodel->hulls[3];
hull->clipnodes = out;
@ -702,6 +704,7 @@ static void BSP_LoadClipnodes( dlump_t *l )
hull->planes = loadmodel->planes;
VectorCopy( GI->client_mins[3], hull->clip_mins ); // copy head hull
VectorCopy( GI->client_maxs[3], hull->clip_maxs );
VectorSubtract( hull->clip_maxs, hull->clip_mins, cm.hull_sizes[3] );
for( i = 0; i < count; i++, out++, in++ )
{

View File

@ -518,6 +518,9 @@ pmtrace_t PM_PlayerTrace( playermove_t *pmove, vec3_t start, vec3_t end, int fla
if( pmFilter && pmFilter( pe ))
continue;
if(( i > 0 ) && !VectorIsNull( mins ) && VectorIsNull( pe->mins ))
continue; // points never interact
// might intersect, so do an exact clip
if( total.allsolid ) return total;

View File

@ -1356,7 +1356,8 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
// can't track this entity on the client.
// write static sound
if( !ent->v.modelindex ) flags |= SND_FIXED_ORIGIN;
if( !ent->v.modelindex || !ent->v.model )
flags |= SND_FIXED_ORIGIN;
// ultimate method for detect bsp models with invalid solidity (e.g. func_pushable)
if( CM_GetModelType( ent->v.modelindex ) == mod_brush )
@ -1399,7 +1400,7 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
sound_idx = SV_SoundIndex( sample );
}
if( !ent->v.modelindex )
if( !ent->v.modelindex || !ent->v.model )
entityIndex = 0;
else if( SV_IsValidEdict( ent->v.aiment ))
entityIndex = ent->v.aiment->serialnumber;

View File

@ -26,9 +26,11 @@ int SV_FindIndex( const char *name, int start, int end, bool create )
if( !name || !name[0] ) return 0;
for( i = 1; i < end && sv.configstrings[start+i][0]; i++ )
if(!com.strcmp( sv.configstrings[start+i], name ))
if( !com.strcmp( sv.configstrings[start+i], name ))
return i;
if( !create ) return 0;
if( i == end )
{
MsgDev( D_WARN, "SV_FindIndex: %d out of range [%d - %d]\n", start, end );
@ -97,27 +99,6 @@ void SV_CreateBaseline( void )
}
}
/*
=================
SV_CheckForSavegame
=================
*/
void SV_CheckForSavegame( const char *savename )
{
sv.loadgame = false;
if( savename )
{
sv.loadgame = true; // predicting state
if( sv_noreload->value ) sv.loadgame = false;
if( svgame.globals->deathmatch || svgame.globals->coop || svgame.globals->teamplay )
sv.loadgame = false;
if( !savename ) sv.loadgame = false;
if( !FS_FileExists( va( "save/%s", savename )))
sv.loadgame = false;
}
}
/*
================
SV_ActivateServer
@ -139,15 +120,12 @@ void SV_ActivateServer( void )
// Activate the DLL server code
svgame.dllFuncs.pfnServerActivate( svgame.edicts, svgame.numEntities, svgame.globals->maxClients );
if( !sv.loadgame )
{
// run two frames to allow everything to settle
for( i = 0; i < 2; i++ )
SV_Physics();
// create a baseline for more efficient communications
SV_CreateBaseline();
// create a baseline for more efficient communications
SV_CreateBaseline();
}
// run two frames to allow everything to settle
for( i = 0; !sv.loadgame && i < 2; i++ )
SV_Physics();
// invoke to refresh all movevars
Mem_Set( &svgame.oldmovevars, 0, sizeof( movevars_t ));

View File

@ -1160,11 +1160,15 @@ void SV_Physics_Toss( edict_t *ent )
SV_CheckVelocity( ent );
if( trace.fAllSolid )
// make sure what we don't collide with like entity (e.g. gib with gib)
if( trace.fAllSolid && SV_IsValidEdict( trace.pHit ) && trace.pHit->v.movetype != ent->v.movetype )
{
// entity is trapped in another solid
ent->v.groundentity = trace.pHit;
ent->v.flags |= FL_ONGROUND;
if( trace.vecPlaneNormal[2] > 0.7f )
{
ent->v.groundentity = trace.pHit;
ent->v.flags |= FL_ONGROUND;
}
VectorClear( ent->v.velocity );
return;
}
@ -1241,7 +1245,6 @@ void SV_Physics_Step( edict_t *ent )
bool wasonground;
bool inwater;
bool hitsound = false;
bool isfalling = false;
edict_t *pHit;
trace_t trace;
@ -1254,35 +1257,39 @@ void SV_Physics_Step( edict_t *ent )
// swimming monsters who are in the water
inwater = SV_CheckWater( ent );
if( !wasonground )
if( ent->v.movetype == MOVETYPE_PUSHSTEP )
{
if( !( ent->v.flags & FL_FLY ))
if( inwater && ( ent->v.flags & FL_FLOAT ))
{
if(!( ent->v.flags & (FL_SWIM|FL_FLOAT) && ent->v.waterlevel > 0 ))
// floating pushables
if( ent->v.waterlevel == 2 )
{
if( ent->v.velocity[2] < ( sv_gravity->value * -sv_frametime( )))
{
hitsound = true;
}
if( !inwater )
{
SV_AddHalfGravity( ent, sv_frametime( ));
isfalling = true;
}
VectorScale( ent->v.velocity, 1.0f - (svgame.globals->frametime * 0.5f), ent->v.velocity );
ent->v.velocity[2] += (ent->v.skin * svgame.globals->frametime);
}
else if( ent->v.waterlevel > 0 )
else if( ent->v.waterlevel == 0 )
{
if( ent->v.waterlevel > 1 )
}
else
{
ent->v.velocity[2] -= (ent->v.skin * svgame.globals->frametime);
}
}
else if( !wasonground )
{
SV_AddGravity( ent );
}
}
else
{
// monster gravity
if( !wasonground )
{
if(!( ent->v.flags & FL_FLY ))
{
if(!( ent->v.flags & FL_SWIM && ent->v.waterlevel > 0 ))
{
VectorScale( ent->v.velocity, 0.9f, ent->v.velocity );
ent->v.velocity[2] += (ent->v.skin * svgame.globals->frametime);
}
else if( ent->v.waterlevel == 1 )
{
if( ent->v.velocity[2] > 0.0f )
ent->v.velocity[2] = svgame.globals->frametime;
ent->v.velocity[2] -= (ent->v.skin * svgame.globals->frametime);
if( !inwater ) SV_AddGravity( ent );
}
}
}
@ -1295,7 +1302,6 @@ void SV_Physics_Step( edict_t *ent )
int x, y;
friction *= ent->v.friction;
ent->v.flags &= ~FL_ONGROUND;
// apply friction
@ -1303,9 +1309,14 @@ void SV_Physics_Step( edict_t *ent )
if( wasonground )
{
float speed, newspeed;
float control;
speed = VectorLength( ent->v.velocity );
float *vel, control;
vel = ent->v.velocity;
speed = com.sqrt( vel[0] * vel[0] + vel[1] * vel[1] );
// add ground speed
if( ent->v.groundentity->v.flags & FL_CONVEYOR )
speed += ent->v.groundentity->v.speed;
if( speed )
{
@ -1322,14 +1333,9 @@ void SV_Physics_Step( edict_t *ent )
}
VectorAdd( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
SV_AngularMove( ent, sv_frametime(), friction );
SV_CheckVelocity( ent );
SV_FlyMove( ent, sv_frametime(), NULL );
SV_CheckVelocity( ent );
VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
SV_CheckVelocity( ent );
// determine if it's on solid ground at all
@ -1362,18 +1368,16 @@ void SV_Physics_Step( edict_t *ent )
SV_LinkEdict( ent, true );
}
if(!( ent->v.flags & FL_ONGROUND ) && isfalling )
if( ent->v.movetype == MOVETYPE_STEP )
{
SV_AddHalfGravity( ent, sv_frametime( ));
// check monster with another monster intersect (e.g. tentacle damage)
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent );
pHit = trace.pHit;
if( SV_IsValidEdict( pHit ) && pHit->v.flags & FL_MONSTER && pHit->v.deadflag == DEAD_NO )
SV_Impact( ent, &trace );
}
// check monster with another monster (e.g. tentacle damage)
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent );
pHit = trace.pHit;
if( SV_IsValidEdict( pHit ) && pHit->v.flags & FL_MONSTER && pHit->v.deadflag == DEAD_NO )
SV_Impact( ent, &trace );
if( !SV_RunThink( ent )) return;
SV_CheckWaterTransition( ent );

View File

@ -19,19 +19,6 @@ bool SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed, bool player_trace )
pe->player = false;
if( player_trace )
{
// player completely ignore some movetypes here
switch( ed->v.movetype )
{
case MOVETYPE_TOSS:
case MOVETYPE_NOCLIP:
case MOVETYPE_BOUNCE:
case MOVETYPE_BOUNCEMISSILE:
return false;
}
}
if( ed->v.flags & ( FL_CLIENT|FL_FAKECLIENT ))
{
// client or bot

View File

@ -120,24 +120,29 @@ hull_t *SV_HullForEntity( edict_t *ent, int hullNumber, vec3_t mins, vec3_t maxs
if( hullNumber == -1 )
{
// FIXME: these constant doesn't works with user-defined hulls
// revisit this
if( size[0] < 3 )
hull = &model->hulls[0]; // point hull
else if( size[0] <= 36 )
float curdiff;
float lastdiff = 999;
int i;
hullNumber = 0; // assume we fail
// select the hull automatically
for( i = 0; i < 4; i++ )
{
if( size[2] <= 36 )
hull = &model->hulls[3]; // head hull (ducked)
else hull = &model->hulls[1]; // human hull
curdiff = floor( VectorAvg( size )) - floor( VectorAvg( cm.hull_sizes[i] ));
curdiff = fabs( curdiff );
if( curdiff < lastdiff )
{
hullNumber = i;
lastdiff = curdiff;
}
}
else hull = &model->hulls[2]; // large hull
}
else
{
// TraceHull stuff
hull = &model->hulls[hullNumber];
}
// TraceHull stuff
hull = &model->hulls[hullNumber];
// calculate an offset value to center the origin
VectorSubtract( hull->clip_mins, mins, offset );
VectorAdd( offset, ent->v.origin, offset );
@ -182,7 +187,9 @@ hull_t *SV_HullForBsp( edict_t *ent, const vec3_t mins, const vec3_t maxs, float
hull_t *hull;
model_t *model;
vec3_t size;
float curdiff, lastdiff = 999;
int i, hullNumber = 0;
// decide which clipping hull to use, based on the size
model = CM_ClipHandleToModel( ent->v.modelindex );
@ -191,17 +198,20 @@ hull_t *SV_HullForBsp( edict_t *ent, const vec3_t mins, const vec3_t maxs, float
VectorSubtract( maxs, mins, size );
// FIXME: these constant doesn't works with user-defined hulls
// revisit this
if( size[0] < 3 )
hull = &model->hulls[0]; // point hull
else if( size[0] <= 36 )
// select the hull automatically
for( i = 0; i < 4; i++ )
{
if( size[2] <= 36 )
hull = &model->hulls[3]; // head hull (ducked)
else hull = &model->hulls[1]; // human hull
curdiff = floor( VectorAvg( size )) - floor( VectorAvg( cm.hull_sizes[i] ));
curdiff = fabs( curdiff );
if( curdiff < lastdiff )
{
hullNumber = i;
lastdiff = curdiff;
}
}
else hull = &model->hulls[2]; // large hull
hull = &model->hulls[hullNumber];
// calculate an offset value to center the origin
VectorSubtract( hull->clip_mins, mins, offset );

View File

@ -63,7 +63,7 @@ typedef struct vsound_imp_s
// interface validator
size_t api_size; // must matched with sizeof(vsound_imp_t)
void (*GetEntitySpatialization)( int entnum, vec3_t origin, vec3_t velocity );
bool (*GetEntitySpatialization)( int entnum, vec3_t origin, vec3_t velocity );
void (*AmbientLevels)( const vec3_t p, byte *pvolumes );
struct cl_entity_s *(*GetClientEdict)( int index );
float (*GetServerTime)( void );

View File

@ -345,7 +345,8 @@ void SND_Spatialize( channel_t *ch )
if( !ch->staticsound )
{
si.GetEntitySpatialization( ch->entnum, ch->origin, NULL );
if( !si.GetEntitySpatialization( ch->entnum, ch->origin, NULL ))
return; // entity not exist on client
}
// calculate stereo seperation and distance attenuation
@ -560,7 +561,7 @@ void S_StaticSound( const vec3_t pos, int ent, int chan, sound_t handle, float f
if( !pos ) pos = origin;
si.GetEntitySpatialization( ent, origin, NULL );
if( ent != 0 ) si.GetEntitySpatialization( ent, origin, NULL );
// pick a channel to play on from the static area
ch = SND_PickStaticChannel( ent, sfx ); // autolooping sounds are always fixed origin(?)