02 Dec 2009
This commit is contained in:
parent
5139a05ba0
commit
4db3ea9d03
|
@ -883,8 +883,8 @@ void CM_ModelBounds( model_t handle, vec3_t mins, vec3_t maxs )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MsgDev( D_ERROR, "Mod_GetBounds: NULL model %i\n", handle );
|
MsgDev( D_ERROR, "Mod_GetBounds: NULL model %i\n", handle );
|
||||||
if( mins ) VectorSet( mins, -32, -32, -32 );
|
if( mins ) VectorClear( mins );
|
||||||
if( maxs ) VectorSet( maxs, 32, 32, 32 );
|
if( maxs ) VectorClear( maxs );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1180,8 +1180,8 @@ void CM_ModelBounds( model_t handle, vec3_t mins, vec3_t maxs )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MsgDev( D_ERROR, "Mod_GetBounds: NULL model %i\n", handle );
|
MsgDev( D_ERROR, "Mod_GetBounds: NULL model %i\n", handle );
|
||||||
if( mins ) VectorSet( mins, -32, -32, -32 );
|
if( mins ) VectorClear( mins );
|
||||||
if( maxs ) VectorSet( maxs, 32, 32, 32 );
|
if( maxs ) VectorClear( maxs );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ typedef struct entvars_s
|
||||||
vec3_t oldorigin; // ENG [all], NET [all]
|
vec3_t oldorigin; // ENG [all], NET [all]
|
||||||
vec3_t velocity;
|
vec3_t velocity;
|
||||||
vec3_t basevelocity;
|
vec3_t basevelocity;
|
||||||
|
vec3_t clbasevelocity; // ENG [player], NET [player]
|
||||||
|
|
||||||
vec3_t movedir;
|
vec3_t movedir;
|
||||||
|
|
||||||
|
@ -141,6 +142,7 @@ typedef struct entvars_s
|
||||||
int flSwimTime; // In process of ducking or ducked already?
|
int flSwimTime; // In process of ducking or ducked already?
|
||||||
int flDuckTime; // Time we started duck
|
int flDuckTime; // Time we started duck
|
||||||
int iStepLeft; // 0 - 4
|
int iStepLeft; // 0 - 4
|
||||||
|
float flJumpPadTime; // for scale falling damage
|
||||||
float flFallVelocity; // falling velocity z
|
float flFallVelocity; // falling velocity z
|
||||||
int oldbuttons; // buttons last usercmd
|
int oldbuttons; // buttons last usercmd
|
||||||
int groupinfo; // entities culling (on server)
|
int groupinfo; // entities culling (on server)
|
||||||
|
|
|
@ -291,5 +291,6 @@ viewpos
|
||||||
*/
|
*/
|
||||||
void SCR_Viewpos_f( void )
|
void SCR_Viewpos_f( void )
|
||||||
{
|
{
|
||||||
Msg( "( %g %g %g )\n", cl.refdef.vieworg[0], cl.refdef.vieworg[1], cl.refdef.vieworg[2] );
|
Msg( "org ( %g %g %g )\n", cl.refdef.vieworg[0], cl.refdef.vieworg[1], cl.refdef.vieworg[2] );
|
||||||
|
Msg( "ang ( %g %g %g )\n", cl.refdef.viewangles[0], cl.refdef.viewangles[1], cl.refdef.viewangles[2] );
|
||||||
}
|
}
|
|
@ -149,7 +149,6 @@ struct sv_priv_s
|
||||||
bool linked; // passed through SV_LinkEdict
|
bool linked; // passed through SV_LinkEdict
|
||||||
|
|
||||||
bool stuck; // entity stucked in brush
|
bool stuck; // entity stucked in brush
|
||||||
bool suspended; // suspended on a brush entity
|
|
||||||
|
|
||||||
// cached position to avoid redundant SV_CheckWaterTransition calls on monsters
|
// cached position to avoid redundant SV_CheckWaterTransition calls on monsters
|
||||||
bool forceupdate; // force an update on this entity
|
bool forceupdate; // force an update on this entity
|
||||||
|
@ -403,6 +402,8 @@ const char *SV_GetString( string_t iString );
|
||||||
void SV_SetClientMaxspeed( sv_client_t *cl, float fNewMaxspeed );
|
void SV_SetClientMaxspeed( sv_client_t *cl, float fNewMaxspeed );
|
||||||
bool SV_MapIsValid( const char *filename, const char *spawn_entity );
|
bool SV_MapIsValid( const char *filename, const char *spawn_entity );
|
||||||
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
|
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
|
||||||
|
void SV_UpdateBaseVelocity( edict_t *ent );
|
||||||
|
bool SV_IsValidEdict( const edict_t *e );
|
||||||
script_t *CM_GetEntityScript( void );
|
script_t *CM_GetEntityScript( void );
|
||||||
|
|
||||||
_inline edict_t *SV_EDICT_NUM( int n, const char * file, const int line )
|
_inline edict_t *SV_EDICT_NUM( int n, const char * file, const int line )
|
||||||
|
|
|
@ -596,6 +596,16 @@ void SV_PutClientInServer( edict_t *ent )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// needs to setup angles on restore
|
||||||
|
if( ent->v.fixangle )
|
||||||
|
{
|
||||||
|
MSG_WriteByte( &sv.multicast, svc_setangle );
|
||||||
|
MSG_WriteAngle32( &sv.multicast, ent->v.angles[0] );
|
||||||
|
MSG_WriteAngle32( &sv.multicast, ent->v.angles[1] );
|
||||||
|
MSG_WriteAngle32( &sv.multicast, 0 );
|
||||||
|
MSG_DirectSend( MSG_ONE, vec3_origin, client->edict );
|
||||||
|
ent->v.fixangle = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client->pViewEntity = NULL; // reset pViewEntity
|
client->pViewEntity = NULL; // reset pViewEntity
|
||||||
|
|
|
@ -46,7 +46,7 @@ Copy entvars into entity state
|
||||||
*/
|
*/
|
||||||
void SV_UpdateEntityState( const edict_t *ent, bool baseline )
|
void SV_UpdateEntityState( const edict_t *ent, bool baseline )
|
||||||
{
|
{
|
||||||
sv_client_t *client = ent->pvServerData->client;
|
sv_client_t *client = SV_ClientFromEdict( ent, true );
|
||||||
|
|
||||||
if( !ent->pvServerData->s.classname )
|
if( !ent->pvServerData->s.classname )
|
||||||
ent->pvServerData->s.classname = SV_ClassIndex( STRING( ent->v.classname ));
|
ent->pvServerData->s.classname = SV_ClassIndex( STRING( ent->v.classname ));
|
||||||
|
@ -61,12 +61,14 @@ void SV_UpdateEntityState( const edict_t *ent, bool baseline )
|
||||||
MSG_WriteAngle32( &sv.multicast, ent->v.angles[0] );
|
MSG_WriteAngle32( &sv.multicast, ent->v.angles[0] );
|
||||||
MSG_WriteAngle32( &sv.multicast, ent->v.angles[1] );
|
MSG_WriteAngle32( &sv.multicast, ent->v.angles[1] );
|
||||||
MSG_WriteAngle32( &sv.multicast, 0 );
|
MSG_WriteAngle32( &sv.multicast, 0 );
|
||||||
MSG_Send( MSG_ONE, vec3_origin, client->edict );
|
MSG_DirectSend( MSG_ONE, vec3_origin, client->edict );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
svgame.dllFuncs.pfnUpdateEntityState( &ent->pvServerData->s, (edict_t *)ent, baseline );
|
svgame.dllFuncs.pfnUpdateEntityState( &ent->pvServerData->s, (edict_t *)ent, baseline );
|
||||||
|
|
||||||
|
if( client ) client->edict->v.fixangle = false;
|
||||||
|
|
||||||
// always keep an actual
|
// always keep an actual
|
||||||
ent->pvServerData->s.number = ent->serialnumber;
|
ent->pvServerData->s.number = ent->serialnumber;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1452,7 +1452,6 @@ int pfnDropToFloor( edict_t* e )
|
||||||
SV_LinkEdict( e, true );
|
SV_LinkEdict( e, true );
|
||||||
e->v.flags |= FL_ONGROUND;
|
e->v.flags |= FL_ONGROUND;
|
||||||
e->v.groundentity = trace.pHit;
|
e->v.groundentity = trace.pHit;
|
||||||
e->pvServerData->suspended = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1469,7 +1468,6 @@ int pfnDropToFloor( edict_t* e )
|
||||||
SV_LinkEdict( e, true );
|
SV_LinkEdict( e, true );
|
||||||
e->v.flags |= FL_ONGROUND;
|
e->v.flags |= FL_ONGROUND;
|
||||||
e->v.groundentity = trace.pHit;
|
e->v.groundentity = trace.pHit;
|
||||||
e->pvServerData->suspended = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -465,6 +465,45 @@ int PM_PointContents( const vec3_t p )
|
||||||
return World_ConvertContents( SV_BaseContents( p, svgame.pmove->player ));
|
return World_ConvertContents( SV_BaseContents( p, svgame.pmove->player ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PM_CheckMovingGround( edict_t *ent, float frametime )
|
||||||
|
{
|
||||||
|
SV_UpdateBaseVelocity( ent );
|
||||||
|
|
||||||
|
if(!( ent->v.flags & FL_BASEVELOCITY ))
|
||||||
|
{
|
||||||
|
// apply momentum (add in half of the previous frame of velocity first)
|
||||||
|
VectorMA( ent->v.velocity, 1.0f + (frametime * 0.5f), ent->v.basevelocity, ent->v.velocity );
|
||||||
|
VectorClear( ent->v.basevelocity );
|
||||||
|
}
|
||||||
|
ent->v.flags &= ~FL_BASEVELOCITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM_SetupMove( playermove_t *pmove, edict_t *clent, usercmd_t *ucmd, const char *physinfo )
|
||||||
|
{
|
||||||
|
pmove->realtime = svgame.globals->time;
|
||||||
|
pmove->frametime = ucmd->msec * 0.001f;
|
||||||
|
com.strncpy( pmove->physinfo, physinfo, MAX_INFO_STRING );
|
||||||
|
pmove->clientmaxspeed = clent->v.maxspeed;
|
||||||
|
pmove->cmd = *ucmd; // setup current cmds
|
||||||
|
pmove->player = clent; // ptr to client state
|
||||||
|
pmove->numtouch = 0; // reset touchents
|
||||||
|
pmove->dead = (clent->v.health <= 0.0f) ? true : false;
|
||||||
|
pmove->flWaterJumpTime = clent->v.teleport_time;
|
||||||
|
pmove->onground = clent->v.groundentity;
|
||||||
|
pmove->usehull = (clent->v.flags & FL_DUCKING) ? 1 : 0; // reset hull
|
||||||
|
pmove->bInDuck = clent->v.bInDuck;
|
||||||
|
VectorCopy( clent->v.origin, pmove->origin );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM_FinishMove( playermove_t *pmove, edict_t *clent )
|
||||||
|
{
|
||||||
|
clent->v.teleport_time = pmove->flWaterJumpTime;
|
||||||
|
clent->v.groundentity = pmove->onground;
|
||||||
|
VectorCopy( pmove->angles, clent->v.viewangles );
|
||||||
|
VectorCopy( pmove->origin, clent->v.origin );
|
||||||
|
clent->v.bInDuck = pmove->bInDuck;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
SV_InitClientMove
|
SV_InitClientMove
|
||||||
|
@ -559,6 +598,8 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PM_CheckMovingGround( clent, ucmd->msec * 0.001f );
|
||||||
|
|
||||||
VectorCopy( clent->v.viewangles, svgame.pmove->oldangles ); // save oldangles
|
VectorCopy( clent->v.viewangles, svgame.pmove->oldangles ); // save oldangles
|
||||||
if( !clent->v.fixangle )
|
if( !clent->v.fixangle )
|
||||||
VectorCopy( ucmd->viewangles, clent->v.viewangles );
|
VectorCopy( ucmd->viewangles, clent->v.viewangles );
|
||||||
|
@ -586,38 +627,25 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
||||||
svgame.globals->frametime = ucmd->msec * 0.001f;
|
svgame.globals->frametime = ucmd->msec * 0.001f;
|
||||||
|
|
||||||
SV_RunThink( clent );
|
SV_RunThink( clent );
|
||||||
|
|
||||||
|
// If conveyor, or think, set basevelocity, then send to client asap too.
|
||||||
|
if( VectorLength( clent->v.basevelocity ) > 0.0f )
|
||||||
|
VectorCopy( clent->v.basevelocity, clent->v.clbasevelocity );
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup playermove state
|
// setup playermove globals
|
||||||
svgame.pmove->multiplayer = (sv_maxclients->integer > 1) ? true : false;
|
svgame.pmove->multiplayer = (sv_maxclients->integer > 1) ? true : false;
|
||||||
svgame.pmove->realtime = svs.realtime * 0.001f;
|
svgame.pmove->serverflags = svgame.globals->serverflags; // shared serverflags
|
||||||
svgame.pmove->frametime = ucmd->msec * 0.001f;
|
|
||||||
com.strncpy( svgame.pmove->physinfo, cl->physinfo, MAX_INFO_STRING );
|
|
||||||
svgame.pmove->serverflags = svgame.globals->serverflags;
|
|
||||||
svgame.pmove->clientmaxspeed = clent->v.maxspeed;
|
|
||||||
svgame.pmove->maxspeed = svgame.movevars.maxspeed;
|
svgame.pmove->maxspeed = svgame.movevars.maxspeed;
|
||||||
svgame.pmove->cmd = *ucmd; // setup current cmds
|
|
||||||
svgame.pmove->player = clent; // ptr to client state
|
// setup playermove state
|
||||||
svgame.pmove->numtouch = 0; // reset touchents
|
PM_SetupMove( svgame.pmove, clent, ucmd, cl->physinfo );
|
||||||
svgame.pmove->dead = (clent->v.health <= 0.0f) ? true : false;
|
|
||||||
svgame.pmove->flWaterJumpTime = clent->v.teleport_time;
|
|
||||||
svgame.pmove->onground = clent->v.groundentity;
|
|
||||||
svgame.pmove->usehull = (clent->v.flags & FL_DUCKING) ? 1 : 0; // reset hull
|
|
||||||
svgame.pmove->bInDuck = clent->v.bInDuck;
|
|
||||||
for( i = 0; i < 3; i++ )
|
|
||||||
svgame.pmove->origin[i] = clent->v.origin[i];
|
|
||||||
|
|
||||||
// motor!
|
// motor!
|
||||||
svgame.dllFuncs.pfnPM_Move( svgame.pmove, true );
|
svgame.dllFuncs.pfnPM_Move( svgame.pmove, true );
|
||||||
|
|
||||||
// copy results back to client
|
// copy results back to client
|
||||||
clent->v.teleport_time = svgame.pmove->flWaterJumpTime;
|
PM_FinishMove( svgame.pmove, clent );
|
||||||
clent->v.groundentity = svgame.pmove->onground;
|
|
||||||
VectorCopy( svgame.pmove->angles, clent->v.viewangles );
|
|
||||||
clent->v.bInDuck = svgame.pmove->bInDuck;
|
|
||||||
|
|
||||||
for( i = 0; i < 3; i++ )
|
|
||||||
clent->v.origin[i] = svgame.pmove->origin[i];
|
|
||||||
VectorCopy( clent->v.velocity, oldvel ); // save velocity
|
VectorCopy( clent->v.velocity, oldvel ); // save velocity
|
||||||
|
|
||||||
if(!( clent->v.flags & FL_SPECTATOR ))
|
if(!( clent->v.flags & FL_SPECTATOR ))
|
||||||
|
@ -625,17 +653,25 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
||||||
// link into place and touch triggers
|
// link into place and touch triggers
|
||||||
SV_LinkEdict( clent, true );
|
SV_LinkEdict( clent, true );
|
||||||
|
|
||||||
|
// NOTE: one of triggers apply new velocity to client
|
||||||
|
// e.g trigger_teleport resets it or add new
|
||||||
|
// so we need to apply new velocity immediately here
|
||||||
|
if( clent->v.fixangle || clent->v.flJumpPadTime )
|
||||||
|
VectorCopy( clent->v.velocity, oldvel );
|
||||||
|
|
||||||
// touch other objects
|
// touch other objects
|
||||||
for( i = 0; i < svgame.pmove->numtouch; i++ )
|
for( i = 0; i < svgame.pmove->numtouch; i++ )
|
||||||
{
|
{
|
||||||
if( i == MAX_PHYSENTS ) break;
|
if( i == MAX_PHYSENTS ) break;
|
||||||
if( svgame.pmove->touchents[i] == clent ) continue;
|
if( svgame.pmove->touchents[i] == clent ) continue;
|
||||||
VectorCopy( svgame.pmove->touchvels[i], clent->v.velocity );
|
VectorCopy( svgame.pmove->touchvels[i], clent->v.velocity );
|
||||||
|
|
||||||
svgame.dllFuncs.pfnTouch( svgame.pmove->touchents[i], clent );
|
svgame.dllFuncs.pfnTouch( svgame.pmove->touchents[i], clent );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy( oldvel, clent->v.velocity ); // save velocity
|
// restore velocity
|
||||||
|
VectorCopy( oldvel, clent->v.velocity );
|
||||||
svgame.pmove->numtouch = 0;
|
svgame.pmove->numtouch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ solid_edge items only clip against bsp models.
|
||||||
*/
|
*/
|
||||||
#define DIST_EPSILON (0.03125) // 1/32 epsilon to keep floating point happy
|
#define DIST_EPSILON (0.03125) // 1/32 epsilon to keep floating point happy
|
||||||
#define MOVE_EPSILON 0.01
|
#define MOVE_EPSILON 0.01
|
||||||
#define MAX_CLIP_PLANES 32
|
#define MAX_CLIP_PLANES 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -73,7 +73,7 @@ void SV_CheckAllEnts( void )
|
||||||
for( i = svgame.globals->maxClients + 1; i < svgame.globals->numEntities; i++ )
|
for( i = svgame.globals->maxClients + 1; i < svgame.globals->numEntities; i++ )
|
||||||
{
|
{
|
||||||
e = EDICT_NUM( i );
|
e = EDICT_NUM( i );
|
||||||
if( e->free ) continue;
|
if( !SV_IsValidEdict( e )) continue;
|
||||||
|
|
||||||
switch( e->v.movetype )
|
switch( e->v.movetype )
|
||||||
{
|
{
|
||||||
|
@ -84,8 +84,9 @@ void SV_CheckAllEnts( void )
|
||||||
continue;
|
continue;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_UnstickEntity( e );
|
if( e->pvServerData->stuck )
|
||||||
|
SV_UnstickEntity( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +121,35 @@ void SV_CheckVelocity( edict_t *ent )
|
||||||
VectorScale( ent->v.velocity, maxvel / VectorLength( ent->v.velocity ), ent->v.velocity );
|
VectorScale( ent->v.velocity, maxvel / VectorLength( ent->v.velocity ), ent->v.velocity );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
SV_UpdateBaseVelocity
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void SV_UpdateBaseVelocity( edict_t *ent )
|
||||||
|
{
|
||||||
|
if( ent->v.flags & FL_ONGROUND )
|
||||||
|
{
|
||||||
|
edict_t *groundentity = ent->v.groundentity;
|
||||||
|
|
||||||
|
if( SV_IsValidEdict( groundentity ))
|
||||||
|
{
|
||||||
|
// On conveyor belt that's moving?
|
||||||
|
if( groundentity->v.flags & FL_CONVEYOR )
|
||||||
|
{
|
||||||
|
vec3_t new_basevel;
|
||||||
|
|
||||||
|
VectorScale( groundentity->v.movedir, groundentity->v.speed, new_basevel );
|
||||||
|
if( ent->v.flags & FL_BASEVELOCITY )
|
||||||
|
VectorAdd( new_basevel, ent->v.basevelocity, new_basevel );
|
||||||
|
|
||||||
|
ent->v.flags |= FL_BASEVELOCITY;
|
||||||
|
VectorCopy( new_basevel, ent->v.basevelocity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
SV_RunThink
|
SV_RunThink
|
||||||
|
@ -260,6 +290,72 @@ void SV_TransformedBBox( edict_t *ent, vec3_t mins, vec3_t maxs )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
SV_AngularMove
|
||||||
|
|
||||||
|
may use friction for smooth stopping
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
void SV_AngularMove( edict_t *ent, float frametime, float friction )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float adjustment;
|
||||||
|
|
||||||
|
VectorMA( ent->v.angles, frametime, ent->v.avelocity, ent->v.angles );
|
||||||
|
if( friction == 0.0f ) return;
|
||||||
|
adjustment = frametime * (sv_stopspeed->value / 10) * sv_friction->value * fabs( friction );
|
||||||
|
|
||||||
|
for( i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
if( ent->v.avelocity[i] > 0.0f )
|
||||||
|
{
|
||||||
|
ent->v.avelocity[i] -= adjustment;
|
||||||
|
if( ent->v.avelocity[i] < 0.0f )
|
||||||
|
ent->v.avelocity[i] = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ent->v.avelocity[i] += adjustment;
|
||||||
|
if( ent->v.avelocity[i] > 0.0f )
|
||||||
|
ent->v.avelocity[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
SV_LinearMove
|
||||||
|
|
||||||
|
use friction for smooth stopping
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
void SV_LinearMove( edict_t *ent, float frametime, float friction )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float adjustment;
|
||||||
|
|
||||||
|
VectorMA( ent->v.origin, frametime, ent->v.velocity, ent->v.origin );
|
||||||
|
if( friction == 0.0f ) return;
|
||||||
|
adjustment = frametime * (sv_stopspeed->value / 10) * sv_friction->value * fabs( friction );
|
||||||
|
|
||||||
|
for( i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
if( ent->v.velocity[i] > 0.0f )
|
||||||
|
{
|
||||||
|
ent->v.velocity[i] -= adjustment;
|
||||||
|
if( ent->v.velocity[i] < 0.0f )
|
||||||
|
ent->v.velocity[i] = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ent->v.velocity[i] += adjustment;
|
||||||
|
if( ent->v.velocity[i] > 0.0f )
|
||||||
|
ent->v.velocity[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
SV_CheckWater
|
SV_CheckWater
|
||||||
|
@ -486,23 +582,22 @@ Returns the clipflags if the velocity was modified (hit something solid)
|
||||||
if stepnormal is not NULL, the plane normal of any vertical wall hit will be stored
|
if stepnormal is not NULL, the plane normal of any vertical wall hit will be stored
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
int SV_FlyMove( edict_t *ent, float time, trace_t *steptrace )
|
||||||
{
|
{
|
||||||
int blocked = 0, bumpcount;
|
int i, j, numplanes, bumpcount, blocked;
|
||||||
int i, j, impact, numplanes;
|
|
||||||
vec3_t dir, end, planes[MAX_CLIP_PLANES];
|
vec3_t dir, end, planes[MAX_CLIP_PLANES];
|
||||||
vec3_t primal_velocity, original_velocity, new_velocity;
|
vec3_t primal_velocity, original_velocity, new_velocity;
|
||||||
float d, time_left;
|
float d, time_left;
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
|
|
||||||
if( time <= 0.0f ) return 0;
|
blocked = 0;
|
||||||
VectorCopy( ent->v.velocity, original_velocity );
|
VectorCopy( ent->v.velocity, original_velocity );
|
||||||
VectorCopy( ent->v.velocity, primal_velocity );
|
VectorCopy( ent->v.velocity, primal_velocity );
|
||||||
numplanes = 0;
|
numplanes = 0;
|
||||||
|
|
||||||
time_left = time;
|
time_left = time;
|
||||||
|
|
||||||
for( bumpcount = 0; bumpcount < MAX_CLIP_PLANES - 1; bumpcount++ )
|
for( bumpcount = 0; bumpcount < MAX_CLIP_PLANES; bumpcount++ )
|
||||||
{
|
{
|
||||||
if( VectorIsNull( ent->v.velocity ))
|
if( VectorIsNull( ent->v.velocity ))
|
||||||
break;
|
break;
|
||||||
|
@ -510,69 +605,60 @@ int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
||||||
VectorMA( ent->v.origin, time_left, ent->v.velocity, end );
|
VectorMA( ent->v.origin, time_left, ent->v.velocity, end );
|
||||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
|
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
|
||||||
|
|
||||||
// break if it moved the entire distance
|
if( trace.fAllSolid )
|
||||||
if( trace.flFraction == 1.0f )
|
{
|
||||||
{
|
// entity is trapped in another solid
|
||||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
VectorClear( ent->v.velocity );
|
||||||
break;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !trace.pHit )
|
if( trace.flFraction > 0.0f )
|
||||||
{
|
{
|
||||||
MsgDev( D_ERROR, "SV_FlyMove: trace.pHit == NULL\n" );
|
|
||||||
trace.pHit = EDICT_NUM( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
impact = !(ent->v.flags & FL_ONGROUND) || ent->v.groundentity != trace.pHit;
|
|
||||||
|
|
||||||
if( trace.vecPlaneNormal[2] )
|
|
||||||
{
|
|
||||||
if( trace.vecPlaneNormal[2] > 0.7f )
|
|
||||||
{
|
|
||||||
// floor
|
|
||||||
blocked |= 1;
|
|
||||||
ent->v.flags |= FL_ONGROUND;
|
|
||||||
ent->v.groundentity = trace.pHit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// step
|
|
||||||
blocked |= 2;
|
|
||||||
|
|
||||||
if( vecStepNormal )
|
|
||||||
{
|
|
||||||
// save the trace normal for player extrafriction
|
|
||||||
VectorCopy( trace.vecPlaneNormal, vecStepNormal );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( trace.flFraction >= 0.001f )
|
|
||||||
{
|
|
||||||
// actually covered some distance
|
// actually covered some distance
|
||||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||||
VectorCopy( ent->v.velocity, original_velocity );
|
VectorCopy( ent->v.velocity, original_velocity );
|
||||||
numplanes = 0;
|
numplanes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the impact function
|
if( trace.flFraction == 1.0f )
|
||||||
if( impact )
|
break; // moved the entire distance
|
||||||
{
|
|
||||||
SV_Impact( ent, &trace );
|
|
||||||
|
|
||||||
// break if removed by the impact function
|
if( !trace.pHit )
|
||||||
if( ent->free ) break;
|
{
|
||||||
|
MsgDev( D_ERROR, "SV_FlyMove: trace.pHit == NULL\n" );
|
||||||
|
trace.pHit = EDICT_NUM( 0 ); // world
|
||||||
}
|
}
|
||||||
|
|
||||||
time_left *= 1 - trace.flFraction;
|
if( trace.vecPlaneNormal[2] > 0.7f )
|
||||||
|
{
|
||||||
|
blocked |= 1; // floor
|
||||||
|
if( trace.pHit->v.solid == SOLID_BSP )
|
||||||
|
{
|
||||||
|
ent->v.flags |= FL_ONGROUND;
|
||||||
|
ent->v.groundentity = trace.pHit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( trace.vecPlaneNormal[2] == 0.0f )
|
||||||
|
{
|
||||||
|
blocked |= 2; // step
|
||||||
|
if( steptrace ) *steptrace = trace; // save for player extrafriction
|
||||||
|
}
|
||||||
|
|
||||||
|
// run the impact function
|
||||||
|
SV_Impact( ent, &trace );
|
||||||
|
|
||||||
|
// break if removed by the impact function
|
||||||
|
if( ent->free ) break;
|
||||||
|
|
||||||
|
time_left -= time_left - trace.flFraction;
|
||||||
|
|
||||||
// clipped to another plane
|
// clipped to another plane
|
||||||
if( numplanes >= MAX_CLIP_PLANES )
|
if( numplanes >= MAX_CLIP_PLANES )
|
||||||
{
|
{
|
||||||
// this shouldn't really happen
|
// this shouldn't really happen
|
||||||
VectorClear( ent->v.velocity );
|
VectorClear( ent->v.velocity );
|
||||||
blocked = 3;
|
return 3;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy( trace.vecPlaneNormal, planes[numplanes] );
|
VectorCopy( trace.vecPlaneNormal, planes[numplanes] );
|
||||||
|
@ -586,9 +672,8 @@ int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
||||||
{
|
{
|
||||||
if( j != i )
|
if( j != i )
|
||||||
{
|
{
|
||||||
// not ok
|
|
||||||
if( DotProduct( new_velocity, planes[j] ) < 0.0f )
|
if( DotProduct( new_velocity, planes[j] ) < 0.0f )
|
||||||
break;
|
break; // not ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( j == numplanes ) break;
|
if( j == numplanes ) break;
|
||||||
|
@ -605,12 +690,10 @@ int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
||||||
if( numplanes != 2 )
|
if( numplanes != 2 )
|
||||||
{
|
{
|
||||||
VectorClear( ent->v.velocity );
|
VectorClear( ent->v.velocity );
|
||||||
blocked = 7;
|
return 7;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CrossProduct( planes[0], planes[1], dir );
|
CrossProduct( planes[0], planes[1], dir );
|
||||||
VectorNormalize( dir );
|
|
||||||
d = DotProduct( dir, ent->v.velocity );
|
d = DotProduct( dir, ent->v.velocity );
|
||||||
VectorScale( dir, d, ent->v.velocity );
|
VectorScale( dir, d, ent->v.velocity );
|
||||||
}
|
}
|
||||||
|
@ -620,7 +703,7 @@ int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
||||||
if( DotProduct( ent->v.velocity, primal_velocity ) <= 0.0f )
|
if( DotProduct( ent->v.velocity, primal_velocity ) <= 0.0f )
|
||||||
{
|
{
|
||||||
VectorClear( ent->v.velocity );
|
VectorClear( ent->v.velocity );
|
||||||
break;
|
return blocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +759,7 @@ static bool SV_PushEntity( trace_t *trace, edict_t *ent, vec3_t push, bool failO
|
||||||
type = MOVE_NOMONSTERS; // only clip against bmodels
|
type = MOVE_NOMONSTERS; // only clip against bmodels
|
||||||
else type = MOVE_NORMAL;
|
else type = MOVE_NORMAL;
|
||||||
|
|
||||||
*trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, end, type, ent );
|
*trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, end, type|FTRACE_SIMPLEBOX, ent );
|
||||||
|
|
||||||
if( trace->fStartStuck && failOnStartStuck )
|
if( trace->fStartStuck && failOnStartStuck )
|
||||||
return true;
|
return true;
|
||||||
|
@ -756,8 +839,13 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
||||||
pushltime = pusher->v.ltime;
|
pushltime = pusher->v.ltime;
|
||||||
|
|
||||||
// move the pusher to its final position
|
// move the pusher to its final position
|
||||||
|
#if 1
|
||||||
|
SV_LinearMove( pusher, movetime, pusher->v.friction );
|
||||||
|
SV_AngularMove( pusher, movetime, pusher->v.friction );
|
||||||
|
#else
|
||||||
VectorMA( pusher->v.origin, movetime, pusher->v.velocity, pusher->v.origin );
|
VectorMA( pusher->v.origin, movetime, pusher->v.velocity, pusher->v.origin );
|
||||||
VectorMA( pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles );
|
VectorMA( pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles );
|
||||||
|
#endif
|
||||||
pusher->v.ltime += movetime;
|
pusher->v.ltime += movetime;
|
||||||
SV_LinkEdict( pusher, false );
|
SV_LinkEdict( pusher, false );
|
||||||
savesolid = pusher->v.solid;
|
savesolid = pusher->v.solid;
|
||||||
|
@ -1077,12 +1165,12 @@ void SV_CheckWaterTransition( edict_t *ent )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
SV_Physics_Toss
|
SV_Physics_Bounce
|
||||||
|
|
||||||
Toss, bounce, and fly movement. When onground, do nothing.
|
Toss, bounce, and fly movement. When onground, do nothing.
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void SV_Physics_Toss( edict_t *ent )
|
void SV_Physics_Bounce( edict_t *ent )
|
||||||
{
|
{
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
vec3_t move;
|
vec3_t move;
|
||||||
|
@ -1090,14 +1178,6 @@ void SV_Physics_Toss( edict_t *ent )
|
||||||
int bump;
|
int bump;
|
||||||
|
|
||||||
// check for in water
|
// check for in water
|
||||||
SV_CheckWaterTransition( ent );
|
|
||||||
|
|
||||||
// check for conveyor
|
|
||||||
if( ent->v.groundentity && ent->v.groundentity->v.flags & FL_CONVEYOR )
|
|
||||||
VectorScale( ent->v.groundentity->v.movedir, ent->v.groundentity->v.speed, ent->v.basevelocity );
|
|
||||||
else VectorClear( ent->v.basevelocity );
|
|
||||||
|
|
||||||
SV_CheckVelocity( ent );
|
|
||||||
SV_CheckWater( ent );
|
SV_CheckWater( ent );
|
||||||
|
|
||||||
// regular thinking
|
// regular thinking
|
||||||
|
@ -1111,22 +1191,9 @@ void SV_Physics_Toss( edict_t *ent )
|
||||||
// don't stick to ground if onground and moving upward
|
// don't stick to ground if onground and moving upward
|
||||||
ent->v.flags &= ~FL_ONGROUND;
|
ent->v.flags &= ~FL_ONGROUND;
|
||||||
}
|
}
|
||||||
else if( ent->v.groundentity == EDICT_NUM( 0 ))
|
else return;
|
||||||
{
|
|
||||||
// we can trust FL_ONGROUND if groundentity is world because it never moves
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if( ent->pvServerData->suspended && ( ent->v.groundentity == NULL || ent->v.groundentity->free ))
|
|
||||||
{
|
|
||||||
// if ent was supported by a brush model on previous frame,
|
|
||||||
// and groundentity is now freed, set groundentity to 0 (world)
|
|
||||||
// which leaves it suspended in the air
|
|
||||||
ent->v.groundentity = EDICT_NUM( 0 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ent->pvServerData->suspended = false;
|
|
||||||
SV_CheckVelocity( ent );
|
SV_CheckVelocity( ent );
|
||||||
|
|
||||||
// add gravity
|
// add gravity
|
||||||
|
@ -1188,29 +1255,15 @@ void SV_Physics_Toss( edict_t *ent )
|
||||||
ent_gravity = ent->v.gravity;
|
ent_gravity = ent->v.gravity;
|
||||||
else ent_gravity = 1.0;
|
else ent_gravity = 1.0;
|
||||||
|
|
||||||
if( 1 )
|
d = fabs( DotProduct( trace.vecPlaneNormal, ent->v.velocity ));
|
||||||
|
if( trace.vecPlaneNormal[2] > 0.7f && d < sv_gravity->value * bouncestop * ent_gravity )
|
||||||
{
|
{
|
||||||
d = fabs( DotProduct( trace.vecPlaneNormal, ent->v.velocity ));
|
ent->v.flags |= FL_ONGROUND;
|
||||||
if( trace.vecPlaneNormal[2] > 0.7f && d < sv_gravity->value * bouncestop * ent_gravity )
|
ent->v.groundentity = trace.pHit;
|
||||||
{
|
VectorClear( ent->v.velocity );
|
||||||
ent->v.flags |= FL_ONGROUND;
|
VectorClear( ent->v.avelocity );
|
||||||
ent->v.groundentity = trace.pHit;
|
|
||||||
VectorClear( ent->v.velocity );
|
|
||||||
VectorClear( ent->v.avelocity );
|
|
||||||
}
|
|
||||||
else ent->v.flags &= ~FL_ONGROUND;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( trace.vecPlaneNormal[2] > 0.7f && ent->v.velocity[2] < sv_gravity->value * bouncestop * ent_gravity )
|
|
||||||
{
|
|
||||||
ent->v.flags |= FL_ONGROUND;
|
|
||||||
ent->v.groundentity = trace.pHit;
|
|
||||||
VectorClear( ent->v.velocity );
|
|
||||||
VectorClear( ent->v.avelocity );
|
|
||||||
}
|
|
||||||
else ent->v.flags &= ~FL_ONGROUND;
|
|
||||||
}
|
}
|
||||||
|
else ent->v.flags &= ~FL_ONGROUND;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1219,9 +1272,6 @@ void SV_Physics_Toss( edict_t *ent )
|
||||||
{
|
{
|
||||||
ent->v.flags |= FL_ONGROUND;
|
ent->v.flags |= FL_ONGROUND;
|
||||||
ent->v.groundentity = trace.pHit;
|
ent->v.groundentity = trace.pHit;
|
||||||
|
|
||||||
if( trace.pHit->v.solid == SOLID_BSP )
|
|
||||||
ent->pvServerData->suspended = true;
|
|
||||||
VectorClear( ent->v.velocity );
|
VectorClear( ent->v.velocity );
|
||||||
VectorClear( ent->v.avelocity );
|
VectorClear( ent->v.avelocity );
|
||||||
}
|
}
|
||||||
|
@ -1235,6 +1285,151 @@ void SV_Physics_Toss( edict_t *ent )
|
||||||
SV_CheckWaterTransition( ent );
|
SV_CheckWaterTransition( ent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
SV_Physics_Toss
|
||||||
|
|
||||||
|
Toss, bounce, and fly movement. When onground, do nothing.
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
void SV_Physics_Toss( edict_t *ent )
|
||||||
|
{
|
||||||
|
trace_t trace;
|
||||||
|
vec3_t move;
|
||||||
|
float backoff;
|
||||||
|
|
||||||
|
SV_CheckWaterTransition( ent );
|
||||||
|
SV_CheckWater( ent );
|
||||||
|
|
||||||
|
// regular thinking
|
||||||
|
if( !SV_RunThink( ent )) return;
|
||||||
|
|
||||||
|
// if onground, return without moving
|
||||||
|
if( ent->v.flags & FL_ONGROUND )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( ent->v.velocity[2] > DIST_EPSILON )
|
||||||
|
{
|
||||||
|
ent->v.flags &= ~FL_ONGROUND;
|
||||||
|
ent->v.groundentity = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If on ground and not moving, return.
|
||||||
|
if( SV_IsValidEdict( ent->v.groundentity ))
|
||||||
|
{
|
||||||
|
if( VectorIsNull( ent->v.basevelocity ) && VectorIsNull( ent->v.velocity ))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SV_CheckVelocity( ent );
|
||||||
|
|
||||||
|
// add gravity
|
||||||
|
switch( ent->v.movetype )
|
||||||
|
{
|
||||||
|
case MOVETYPE_FLY:
|
||||||
|
case MOVETYPE_BOUNCEMISSILE:
|
||||||
|
case MOVETYPE_FLYMISSILE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SV_AddGravity( ent );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move angles (with friction)
|
||||||
|
switch( ent->v.movetype )
|
||||||
|
{
|
||||||
|
case MOVETYPE_TOSS:
|
||||||
|
case MOVETYPE_BOUNCE:
|
||||||
|
SV_AngularMove( ent, svgame.globals->frametime, ent->v.friction );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SV_AngularMove( ent, svgame.globals->frametime, 0.0f );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// move origin
|
||||||
|
// Base velocity is not properly accounted for since this entity will move again
|
||||||
|
// after the bounce without taking it into account
|
||||||
|
VectorAdd( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
|
||||||
|
|
||||||
|
SV_CheckVelocity( ent );
|
||||||
|
VectorScale( ent->v.velocity, svgame.globals->frametime, move );
|
||||||
|
VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
|
||||||
|
|
||||||
|
if( !SV_PushEntity( &trace, ent, move, false, true ))
|
||||||
|
return; // teleported
|
||||||
|
|
||||||
|
if( ent->free ) return;
|
||||||
|
|
||||||
|
if( trace.fStartStuck )
|
||||||
|
{
|
||||||
|
// try to unstick the entity
|
||||||
|
SV_UnstickEntity( ent );
|
||||||
|
if( !SV_PushEntity( &trace, ent, move, false, true ))
|
||||||
|
return; // teleported
|
||||||
|
if( ent->free ) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SV_CheckVelocity( ent );
|
||||||
|
|
||||||
|
if( trace.fAllSolid )
|
||||||
|
{
|
||||||
|
// entity is trapped in another solid
|
||||||
|
ent->v.flags |= FL_ONGROUND;
|
||||||
|
ent->v.groundentity = trace.pHit;
|
||||||
|
ent->pvServerData->stuck = true;
|
||||||
|
VectorClear( ent->v.velocity );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( trace.flFraction == 1.0f )
|
||||||
|
{
|
||||||
|
SV_CheckWaterTransition( ent );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ent->v.movetype == MOVETYPE_BOUNCE )
|
||||||
|
backoff = 2.0f - ent->v.friction;
|
||||||
|
else if( ent->v.movetype == MOVETYPE_BOUNCEMISSILE )
|
||||||
|
backoff = 2.0f;
|
||||||
|
else backoff = 1.0f;
|
||||||
|
|
||||||
|
SV_ClipVelocity( ent->v.velocity, trace.vecPlaneNormal, ent->v.velocity, backoff );
|
||||||
|
|
||||||
|
// stop if on ground
|
||||||
|
if( trace.vecPlaneNormal[2] > 0.7f )
|
||||||
|
{
|
||||||
|
float vel;
|
||||||
|
|
||||||
|
if( ent->v.velocity[2] < sv_gravity->value * svgame.globals->frametime )
|
||||||
|
{
|
||||||
|
// we're rolling on the ground, add static friction.
|
||||||
|
ent->v.groundentity = trace.pHit;
|
||||||
|
ent->v.velocity[2] = 0.0f;
|
||||||
|
ent->v.flags |= FL_ONGROUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
vel = DotProduct( ent->v.velocity, ent->v.velocity );
|
||||||
|
|
||||||
|
if( vel < 900 || ( ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_BOUNCEMISSILE ))
|
||||||
|
{
|
||||||
|
ent->v.flags |= FL_ONGROUND;
|
||||||
|
ent->v.groundentity = trace.pHit;
|
||||||
|
VectorClear( ent->v.velocity );
|
||||||
|
VectorClear( ent->v.avelocity );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VectorScale( ent->v.velocity, (1.0f - trace.flFraction) * svgame.globals->frametime * 0.9f, move );
|
||||||
|
if( !SV_PushEntity( &trace, ent, move, false, true ))
|
||||||
|
return; // teleported
|
||||||
|
if( ent->free ) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for in water
|
||||||
|
SV_CheckWater( ent );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
|
@ -1280,63 +1475,93 @@ will fall if the floor is pulled out from under them.
|
||||||
*/
|
*/
|
||||||
void SV_Physics_Step( edict_t *ent )
|
void SV_Physics_Step( edict_t *ent )
|
||||||
{
|
{
|
||||||
int flags = ent->v.flags;
|
bool wasonground;
|
||||||
|
bool inwater;
|
||||||
|
float *vel;
|
||||||
|
float speed, newspeed, control;
|
||||||
|
float friction;
|
||||||
|
|
||||||
// check for conveyor
|
wasonground = ent->v.flags & FL_ONGROUND;
|
||||||
if( ent->v.groundentity && ent->v.groundentity->v.flags & FL_CONVEYOR )
|
|
||||||
VectorScale( ent->v.groundentity->v.movedir, ent->v.groundentity->v.speed, ent->v.basevelocity );
|
|
||||||
else VectorClear( ent->v.basevelocity );
|
|
||||||
|
|
||||||
SV_CheckVelocity( ent );
|
|
||||||
|
|
||||||
if( !VectorIsNull( ent->v.avelocity ))
|
if( !VectorIsNull( ent->v.avelocity ))
|
||||||
SV_AddRotationalFriction( ent );
|
SV_AddRotationalFriction( ent );
|
||||||
|
|
||||||
// don't fall at all if fly/swim
|
// add gravity except:
|
||||||
if( !( flags & ( FL_FLY|FL_SWIM )))
|
// flying monsters
|
||||||
|
// swimming monsters who are in the water
|
||||||
|
inwater = SV_CheckWater( ent );
|
||||||
|
|
||||||
|
if( !wasonground )
|
||||||
{
|
{
|
||||||
if( flags & FL_ONGROUND )
|
if( !( ent->v.flags & FL_FLY ))
|
||||||
{
|
{
|
||||||
// freefall if onground and moving upward
|
if(!( ent->v.flags & FL_SWIM && ent->v.waterlevel > 0 ))
|
||||||
// freefall if not standing on a world surface (it may be a lift or trap door)
|
if( !inwater ) SV_AddGravity( ent );
|
||||||
if( ent->v.velocity[2] >= DIST_EPSILON || ent->v.groundentity )
|
|
||||||
{
|
|
||||||
ent->v.flags &= ~FL_ONGROUND;
|
|
||||||
SV_CheckVelocity( ent );
|
|
||||||
SV_FlyMove( ent, svgame.globals->frametime, NULL );
|
|
||||||
SV_LinkEdict( ent, true );
|
|
||||||
ent->pvServerData->forceupdate = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if( !VectorIsNull( ent->v.velocity ) || !VectorIsNull( ent->v.basevelocity ))
|
||||||
|
{
|
||||||
|
vec3_t mins, maxs, point;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
ent->v.flags &= ~FL_ONGROUND;
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
// let dead monsters who aren't completely onground slide
|
||||||
|
if( wasonground )
|
||||||
{
|
{
|
||||||
// freefall if not onground
|
if( !( ent->v.health <= 0.0f && !SV_CheckBottom( ent, WALKMOVE_NORMAL )))
|
||||||
int hitsound = ent->v.velocity[2] < sv_gravity->value * -0.1f;
|
|
||||||
|
|
||||||
SV_CheckVelocity( ent );
|
|
||||||
SV_FlyMove( ent, svgame.globals->frametime, NULL );
|
|
||||||
SV_LinkEdict( ent, true );
|
|
||||||
|
|
||||||
// just hit ground
|
|
||||||
if( hitsound && ent->v.flags & FL_ONGROUND )
|
|
||||||
{
|
{
|
||||||
// debug
|
vel = ent->v.velocity;
|
||||||
Msg( "landing\n" );
|
speed = com.sqrt( vel[0] * vel[0] + vel[1] * vel[1] );
|
||||||
|
|
||||||
|
if( speed )
|
||||||
|
{
|
||||||
|
friction = sv_friction->value;
|
||||||
|
|
||||||
|
control = speed < sv_stopspeed->value ? sv_stopspeed->value : speed;
|
||||||
|
newspeed = speed - svgame.globals->frametime * control * friction;
|
||||||
|
|
||||||
|
if( newspeed < 0 ) newspeed = 0;
|
||||||
|
newspeed /= speed;
|
||||||
|
|
||||||
|
vel[0] = vel[0] * newspeed;
|
||||||
|
vel[1] = vel[1] * newspeed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ent->pvServerData->forceupdate = true;
|
}
|
||||||
|
|
||||||
|
VectorAdd( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
|
||||||
|
SV_FlyMove( ent, svgame.globals->frametime, NULL );
|
||||||
|
VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
|
||||||
|
|
||||||
|
// determine if it's on solid ground at all
|
||||||
|
VectorAdd( ent->v.origin, ent->v.mins, mins );
|
||||||
|
VectorAdd( ent->v.origin, ent->v.maxs, maxs );
|
||||||
|
|
||||||
|
point[2] = mins[2] - 1;
|
||||||
|
for( x = 0; x <= 1; x++ )
|
||||||
|
{
|
||||||
|
for( y = 0; y <= 1; y++ )
|
||||||
|
{
|
||||||
|
point[0] = x ? maxs[0] : mins[0];
|
||||||
|
point[1] = y ? maxs[1] : mins[1];
|
||||||
|
|
||||||
|
if( SV_PointContents( point ) == CONTENTS_SOLID )
|
||||||
|
{
|
||||||
|
ent->v.flags |= FL_ONGROUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
SV_LinkEdict( ent, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// regular thinking
|
// regular thinking
|
||||||
if( !SV_RunThink( ent ))
|
SV_RunThink ( ent );
|
||||||
return;
|
SV_CheckWaterTransition( ent );
|
||||||
|
|
||||||
if( ent->pvServerData->forceupdate || !VectorCompare( ent->v.origin, ent->pvServerData->water_origin ))
|
|
||||||
{
|
|
||||||
ent->pvServerData->forceupdate = false;
|
|
||||||
VectorCopy( ent->v.origin, ent->pvServerData->water_origin );
|
|
||||||
SV_CheckWaterTransition( ent );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1442,6 +1667,16 @@ void SV_Physics_None( edict_t *ent )
|
||||||
|
|
||||||
static void SV_Physics_Entity( edict_t *ent )
|
static void SV_Physics_Entity( edict_t *ent )
|
||||||
{
|
{
|
||||||
|
SV_UpdateBaseVelocity( ent );
|
||||||
|
|
||||||
|
if(!( ent->v.flags & FL_BASEVELOCITY ) && !VectorIsNull( ent->v.basevelocity ))
|
||||||
|
{
|
||||||
|
// Apply momentum (add in half of the previous frame of velocity first)
|
||||||
|
VectorMA( ent->v.velocity, 1.0f + (svgame.globals->frametime * 0.5f), ent->v.basevelocity, ent->v.velocity );
|
||||||
|
VectorClear( ent->v.basevelocity );
|
||||||
|
}
|
||||||
|
ent->v.flags &= ~FL_BASEVELOCITY;
|
||||||
|
|
||||||
switch( ent->v.movetype )
|
switch( ent->v.movetype )
|
||||||
{
|
{
|
||||||
case MOVETYPE_PUSH:
|
case MOVETYPE_PUSH:
|
||||||
|
@ -1460,22 +1695,6 @@ static void SV_Physics_Entity( edict_t *ent )
|
||||||
case MOVETYPE_PUSHSTEP:
|
case MOVETYPE_PUSHSTEP:
|
||||||
SV_Physics_Step( ent );
|
SV_Physics_Step( ent );
|
||||||
break;
|
break;
|
||||||
case MOVETYPE_WALK:
|
|
||||||
if( SV_RunThink( ent ))
|
|
||||||
{
|
|
||||||
sv_client_t *cl = SV_ClientFromEdict( ent, true );
|
|
||||||
|
|
||||||
if( cl && ent->v.flags & FL_FAKECLIENT )
|
|
||||||
{
|
|
||||||
SV_PreRunCmd( cl, &cl->lastcmd );
|
|
||||||
SV_RunCmd( cl, &cl->lastcmd );
|
|
||||||
SV_PostRunCmd( cl );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Host_Error( "SV_Physics: bad movetype %i\n", ent->v.movetype );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MOVETYPE_FLY:
|
case MOVETYPE_FLY:
|
||||||
case MOVETYPE_TOSS:
|
case MOVETYPE_TOSS:
|
||||||
case MOVETYPE_BOUNCE:
|
case MOVETYPE_BOUNCE:
|
||||||
|
@ -1486,6 +1705,9 @@ static void SV_Physics_Entity( edict_t *ent )
|
||||||
case MOVETYPE_CONVEYOR:
|
case MOVETYPE_CONVEYOR:
|
||||||
SV_Physics_Conveyor( ent );
|
SV_Physics_Conveyor( ent );
|
||||||
break;
|
break;
|
||||||
|
case MOVETYPE_WALK:
|
||||||
|
Host_Error( "SV_Physics: bad movetype %i\n", ent->v.movetype );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
svgame.dllFuncs.pfnPhysicsEntity( ent );
|
svgame.dllFuncs.pfnPhysicsEntity( ent );
|
||||||
break;
|
break;
|
||||||
|
@ -1500,8 +1722,8 @@ SV_Physics
|
||||||
*/
|
*/
|
||||||
void SV_Physics( void )
|
void SV_Physics( void )
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
edict_t *ent;
|
edict_t *ent;
|
||||||
|
int i;
|
||||||
|
|
||||||
// let the progs know that a new frame has started
|
// let the progs know that a new frame has started
|
||||||
svgame.globals->time = sv.time * 0.001f;
|
svgame.globals->time = sv.time * 0.001f;
|
||||||
|
@ -1520,19 +1742,11 @@ void SV_Physics( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
// treat each object in turn
|
// treat each object in turn
|
||||||
for( i = i = svgame.globals->maxClients + 1; !sv_playersonly->integer && i < svgame.globals->numEntities; i++ )
|
for( i = svgame.globals->maxClients + 1; !sv_playersonly->integer && i < svgame.globals->numEntities; i++ )
|
||||||
{
|
{
|
||||||
ent = EDICT_NUM( i );
|
ent = EDICT_NUM( i );
|
||||||
if( ent->free ) continue;
|
if( ent->free ) continue;
|
||||||
|
|
||||||
if(!( ent->v.flags & FL_BASEVELOCITY ) && !VectorIsNull( ent->v.basevelocity ))
|
|
||||||
{
|
|
||||||
// Apply momentum (add in half of the previous frame of velocity first)
|
|
||||||
VectorMA( ent->v.velocity, 1.0f + (svgame.globals->frametime * 0.5f), ent->v.basevelocity, ent->v.velocity );
|
|
||||||
VectorClear( ent->v.basevelocity );
|
|
||||||
}
|
|
||||||
|
|
||||||
ent->v.flags &= ~FL_BASEVELOCITY;
|
|
||||||
SV_Physics_Entity( ent );
|
SV_Physics_Entity( ent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2461,6 +2461,13 @@ void PM_CheckFalling( void )
|
||||||
{
|
{
|
||||||
float fvol = 0.5;
|
float fvol = 0.5;
|
||||||
|
|
||||||
|
if( pev->flJumpPadTime && pev->flJumpPadTime < pmove->realtime )
|
||||||
|
{
|
||||||
|
// scale delta if was pushed by jump pad
|
||||||
|
float delta = (1.0f + pmove->realtime - pev->flJumpPadTime) * 0.5f;
|
||||||
|
pev->flFallVelocity /= delta;
|
||||||
|
}
|
||||||
|
|
||||||
if( pev->waterlevel > 0 )
|
if( pev->waterlevel > 0 )
|
||||||
{
|
{
|
||||||
// does nothing
|
// does nothing
|
||||||
|
@ -2469,8 +2476,7 @@ void PM_CheckFalling( void )
|
||||||
{
|
{
|
||||||
// NOTE: In the original game dll, there were no breaks after these cases, causing the first one to
|
// NOTE: In the original game dll, there were no breaks after these cases, causing the first one to
|
||||||
// cascade into the second
|
// cascade into the second
|
||||||
#if 0
|
switch ( RANDOM_LONG( 0, 1 ))
|
||||||
switch ( RandomLong(0,1) )
|
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
EmitSound( CHAN_VOICE, "player/pl_fallpain2.wav", 1, ATTN_NORM, PITCH_NORM );
|
EmitSound( CHAN_VOICE, "player/pl_fallpain2.wav", 1, ATTN_NORM, PITCH_NORM );
|
||||||
|
@ -2479,7 +2485,6 @@ void PM_CheckFalling( void )
|
||||||
EmitSound( CHAN_VOICE, "player/pl_fallpain3.wav", 1, ATTN_NORM, PITCH_NORM );
|
EmitSound( CHAN_VOICE, "player/pl_fallpain3.wav", 1, ATTN_NORM, PITCH_NORM );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
fvol = 1.0f;
|
fvol = 1.0f;
|
||||||
}
|
}
|
||||||
else if( pev->flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2.0f )
|
else if( pev->flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2.0f )
|
||||||
|
|
|
@ -350,8 +350,9 @@ LINK_ENTITY_TO_CLASS( target_location, CPointEntity );
|
||||||
LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
|
LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
|
||||||
LINK_ENTITY_TO_CLASS( misc_teleporter_dest, CPointEntity );
|
LINK_ENTITY_TO_CLASS( misc_teleporter_dest, CPointEntity );
|
||||||
LINK_ENTITY_TO_CLASS( misc_portal_surface, CPortalSurface );
|
LINK_ENTITY_TO_CLASS( misc_portal_surface, CPortalSurface );
|
||||||
LINK_ENTITY_TO_CLASS( info_null, CNullEntity);
|
LINK_ENTITY_TO_CLASS( info_notnull, CPointEntity );
|
||||||
LINK_ENTITY_TO_CLASS( misc_model, CNullEntity);
|
LINK_ENTITY_TO_CLASS( info_null, CNullEntity );
|
||||||
|
LINK_ENTITY_TO_CLASS( misc_model, CNullEntity );
|
||||||
LINK_ENTITY_TO_CLASS( info_texlights, CNullEntity);
|
LINK_ENTITY_TO_CLASS( info_texlights, CNullEntity);
|
||||||
LINK_ENTITY_TO_CLASS( info_compile_parameters, CNullEntity);
|
LINK_ENTITY_TO_CLASS( info_compile_parameters, CNullEntity);
|
||||||
LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission );
|
LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission );
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
class CPointEntity : public CBaseEntity
|
class CPointEntity : public CBaseEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Spawn( void ){ pev->solid = SOLID_NOT; }
|
void Spawn( void ){ SetBits( pev->flags, FL_POINTENTITY ); pev->solid = SOLID_NOT; }
|
||||||
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,14 @@ void CItem::Spawn( void )
|
||||||
pev->movetype = MOVETYPE_TOSS;
|
pev->movetype = MOVETYPE_TOSS;
|
||||||
pev->solid = SOLID_BBOX;
|
pev->solid = SOLID_BBOX;
|
||||||
|
|
||||||
SetObjectClass( ED_NORMAL );
|
|
||||||
|
|
||||||
UTIL_SetModel( ENT( pev ), pev->model, Model() );
|
|
||||||
UTIL_SetOrigin( this, pev->origin );
|
UTIL_SetOrigin( this, pev->origin );
|
||||||
UTIL_SetSize( pev, g_vecZero, g_vecZero );
|
UTIL_SetSize(pev, g_vecZero, g_vecZero );
|
||||||
|
SetObjectClass( ED_NORMAL );
|
||||||
|
|
||||||
SetTouch( ItemTouch );
|
SetTouch( ItemTouch );
|
||||||
SetThink( ItemFall );
|
SetThink( ItemFall );
|
||||||
|
|
||||||
|
UTIL_SetModel(ENT(pev), pev->model, Model() );
|
||||||
SetNextThink( 0.1 );
|
SetNextThink( 0.1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,10 +146,9 @@ void CGrenade::BounceTouch( CBaseEntity *pOther )
|
||||||
m_fRegisteredSound = TRUE;
|
m_fRegisteredSound = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pev->flags & FL_ONGROUND)
|
if ( pev->flags & FL_ONGROUND )
|
||||||
{
|
{
|
||||||
// add a bit of static friction
|
// add a bit of static friction
|
||||||
Msg( "On ground()\n" );
|
|
||||||
pev->velocity = pev->velocity * 0.8;
|
pev->velocity = pev->velocity * 0.8;
|
||||||
pev->sequence = 1;
|
pev->sequence = 1;
|
||||||
}
|
}
|
||||||
|
@ -159,8 +158,8 @@ void CGrenade::BounceTouch( CBaseEntity *pOther )
|
||||||
BounceSound();
|
BounceSound();
|
||||||
}
|
}
|
||||||
pev->framerate = pev->velocity.Length() / 200.0;
|
pev->framerate = pev->velocity.Length() / 200.0;
|
||||||
if (pev->framerate > 1.0) pev->framerate = 1;
|
if( pev->framerate > 1.0 ) pev->framerate = 1;
|
||||||
else if (pev->framerate < 0.5) pev->framerate = 0;
|
else if( pev->framerate < 0.5 ) pev->framerate = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +230,7 @@ void CGrenade:: Spawn( void )
|
||||||
pev->solid = SOLID_BBOX;
|
pev->solid = SOLID_BBOX;
|
||||||
|
|
||||||
SetObjectClass( ED_NORMAL );
|
SetObjectClass( ED_NORMAL );
|
||||||
UTIL_SetModel( ENT( pev ), "models/grenade.mdl");
|
UTIL_SetModel( ENT( pev ), "models/props/hgrenade.mdl");
|
||||||
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
|
|
||||||
|
|
||||||
pev->dmg = 100;
|
pev->dmg = 100;
|
||||||
m_fRegisteredSound = FALSE;
|
m_fRegisteredSound = FALSE;
|
||||||
|
@ -261,7 +259,8 @@ CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector v
|
||||||
// Explode on contact
|
// Explode on contact
|
||||||
pGrenade->SetTouch( ExplodeTouch );
|
pGrenade->SetTouch( ExplodeTouch );
|
||||||
|
|
||||||
UTIL_SetModel( ENT( pGrenade->pev ), "models/props/grenade.mdl");
|
UTIL_SetModel( ENT( pGrenade->pev ), "models/weapons/w_grenade.mdl");
|
||||||
|
UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
|
||||||
pGrenade->pev->dmg = M203_DMG;
|
pGrenade->pev->dmg = M203_DMG;
|
||||||
|
|
||||||
return pGrenade;
|
return pGrenade;
|
||||||
|
@ -299,13 +298,14 @@ CGrenade * CGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector v
|
||||||
pGrenade->pev->flags |= FL_PROJECTILE;
|
pGrenade->pev->flags |= FL_PROJECTILE;
|
||||||
|
|
||||||
// Tumble through the air
|
// Tumble through the air
|
||||||
// pGrenade->pev->avelocity.x = -400;
|
pGrenade->pev->avelocity.x = -400;
|
||||||
|
|
||||||
pGrenade->pev->gravity = 0.5;
|
pGrenade->pev->gravity = 0.5;
|
||||||
pGrenade->pev->friction = 0.8;
|
pGrenade->pev->friction = 0.8;
|
||||||
pGrenade->pev->scale = 0.5; // original Valve model is too big :)
|
pGrenade->pev->scale = 0.5; // original Valve model is too big :)
|
||||||
|
|
||||||
UTIL_SetModel( ENT( pGrenade->pev ), "models/props/hgrenade.mdl" );
|
UTIL_SetModel( ENT( pGrenade->pev ), "models/props/hgrenade.mdl" );
|
||||||
|
UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
|
||||||
pGrenade->pev->dmg = 100;
|
pGrenade->pev->dmg = 100;
|
||||||
|
|
||||||
return pGrenade;
|
return pGrenade;
|
||||||
|
@ -712,6 +712,7 @@ void CWHRocket :: Spawn( void )
|
||||||
SetTouch( NukeTouch );
|
SetTouch( NukeTouch );
|
||||||
|
|
||||||
UTIL_MakeVectors( pev->angles );
|
UTIL_MakeVectors( pev->angles );
|
||||||
|
pev->angles.x = -(pev->angles.x);
|
||||||
pev->velocity = gpGlobals->v_forward * pev->speed;
|
pev->velocity = gpGlobals->v_forward * pev->speed;
|
||||||
m_Center = pev->angles;
|
m_Center = pev->angles;
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,8 @@ class CChangeFriction : public CBaseTrigger
|
||||||
};
|
};
|
||||||
LINK_ENTITY_TO_CLASS( func_friction, CChangeFriction );
|
LINK_ENTITY_TO_CLASS( func_friction, CChangeFriction );
|
||||||
|
|
||||||
|
#define SF_PUSH_ONCE 1
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// trigger_push - triger that pushes player
|
// trigger_push - triger that pushes player
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -281,11 +283,13 @@ class CTriggerPush : public CBaseTrigger
|
||||||
{
|
{
|
||||||
void Spawn( void )
|
void Spawn( void )
|
||||||
{
|
{
|
||||||
if( pev->angles == g_vecZero ) pev->angles.y = 360;
|
if( pev->angles == g_vecZero )
|
||||||
|
pev->angles.y = 360;
|
||||||
if( pev->speed == 0 ) pev->speed = 100;
|
if( pev->speed == 0 ) pev->speed = 100;
|
||||||
UTIL_LinearVector( this );
|
UTIL_LinearVector( this );
|
||||||
|
|
||||||
if ( FBitSet (pev->spawnflags, 2) ) pev->solid = SOLID_NOT;
|
if ( FBitSet( pev->spawnflags, 2 ))
|
||||||
|
pev->solid = SOLID_NOT;
|
||||||
else pev->solid = SOLID_TRIGGER;
|
else pev->solid = SOLID_TRIGGER;
|
||||||
|
|
||||||
pev->movetype = MOVETYPE_NONE;
|
pev->movetype = MOVETYPE_NONE;
|
||||||
|
@ -304,11 +308,13 @@ class CTriggerPush : public CBaseTrigger
|
||||||
pOwner = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
|
pOwner = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
|
||||||
if( !pOwner ) return; // dir set with angles
|
if( !pOwner ) return; // dir set with angles
|
||||||
|
|
||||||
if( FClassnameIs( pOwner->pev, "target_position" ))
|
if( pOwner->pev->flags & FL_POINTENTITY )
|
||||||
{
|
{
|
||||||
|
// xash allows to precache from random place
|
||||||
|
UTIL_PrecacheSound( "world/jumppad.wav" );
|
||||||
|
|
||||||
pev->owner = pOwner->edict();
|
pev->owner = pOwner->edict();
|
||||||
pev->movedir = pOwner->pev->origin - ((pev->absmin + pev->absmax) * 0.5f);
|
pev->button = TRUE; // Q3A trigger_push
|
||||||
pev->movedir.Normalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||||
|
@ -331,11 +337,53 @@ class CTriggerPush : public CBaseTrigger
|
||||||
case MOVETYPE_FOLLOW:
|
case MOVETYPE_FOLLOW:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pOther->pev->solid != SOLID_NOT && pOther->pev->solid != SOLID_BSP )
|
if( pev->button )
|
||||||
|
{
|
||||||
|
if( m_flWait >= gpGlobals->time ) return;
|
||||||
|
|
||||||
|
if( !pOther->IsPlayer() || pOther->pev->movetype != MOVETYPE_WALK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
float time, dist, f;
|
||||||
|
Vector origin, velocity;
|
||||||
|
|
||||||
|
origin = (pev->absmin + pev->absmax) * 0.5f;
|
||||||
|
CBaseEntity *pTarg = CBaseEntity::Instance( pev->owner );
|
||||||
|
|
||||||
|
// assume pev->owner is valid
|
||||||
|
time = sqrt (( pTarg->pev->origin.z - origin.z ) / (0.5f * CVAR_GET_FLOAT( "sv_gravity" )));
|
||||||
|
if( !time )
|
||||||
|
{
|
||||||
|
UTIL_Remove( this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity = pTarg->pev->origin - origin;
|
||||||
|
velocity.z = 0.0f;
|
||||||
|
dist = velocity.Length();
|
||||||
|
velocity = velocity.Normalize();
|
||||||
|
|
||||||
|
f = dist / time;
|
||||||
|
velocity *= f;
|
||||||
|
velocity.z = time * CVAR_GET_FLOAT( "sv_gravity" );
|
||||||
|
|
||||||
|
pOther->pev->flJumpPadTime = gpGlobals->time;
|
||||||
|
pOther->pev->basevelocity = velocity;
|
||||||
|
pOther->pev->velocity = g_vecZero;
|
||||||
|
pOther->pev->flags &= ~FL_BASEVELOCITY;
|
||||||
|
|
||||||
|
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "world/jumppad.wav", VOL_NORM, ATTN_IDLE );
|
||||||
|
|
||||||
|
m_flWait = gpGlobals->time + (2.0f * gpGlobals->frametime);
|
||||||
|
|
||||||
|
if( FBitSet( pev->spawnflags, SF_PUSH_ONCE ))
|
||||||
|
UTIL_Remove( this );
|
||||||
|
}
|
||||||
|
else if( pOther->pev->solid != SOLID_NOT && pOther->pev->solid != SOLID_BSP )
|
||||||
{
|
{
|
||||||
// instant trigger, just transfer velocity and remove
|
// instant trigger, just transfer velocity and remove
|
||||||
if( FBitSet( pev->spawnflags, 1 ))
|
if( FBitSet( pev->spawnflags, SF_PUSH_ONCE ))
|
||||||
{
|
{
|
||||||
pOther->pev->velocity = pOther->pev->velocity + (pev->speed * pev->movedir);
|
pOther->pev->velocity = pOther->pev->velocity + (pev->speed * pev->movedir);
|
||||||
if( pOther->pev->velocity.z > 0 ) pOther->pev->flags &= ~FL_ONGROUND;
|
if( pOther->pev->velocity.z > 0 ) pOther->pev->flags &= ~FL_ONGROUND;
|
||||||
|
@ -348,6 +396,7 @@ class CTriggerPush : public CBaseTrigger
|
||||||
vecPush = vecPush + pOther->pev->basevelocity;
|
vecPush = vecPush + pOther->pev->basevelocity;
|
||||||
pOther->pev->basevelocity = vecPush;
|
pOther->pev->basevelocity = vecPush;
|
||||||
pOther->pev->flags |= FL_BASEVELOCITY;
|
pOther->pev->flags |= FL_BASEVELOCITY;
|
||||||
|
ALERT( at_console, "Valve trigger_push: vel %g %g %g\n", vecPush.x, vecPush.y, vecPush.z );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,18 +284,17 @@ void CBasePlayerWeapon :: Spawn( void )
|
||||||
pev->movetype = MOVETYPE_TOSS;
|
pev->movetype = MOVETYPE_TOSS;
|
||||||
pev->solid = SOLID_BBOX;
|
pev->solid = SOLID_BBOX;
|
||||||
pev->sequence = 1; // set world animation
|
pev->sequence = 1; // set world animation
|
||||||
|
|
||||||
SetObjectClass( ED_NORMAL );
|
|
||||||
UTIL_SetModel( ENT( pev ), iWorldModel( ));
|
|
||||||
UTIL_SetOrigin( this, pev->origin );
|
UTIL_SetOrigin( this, pev->origin );
|
||||||
|
UTIL_SetModel( ENT( pev ), iWorldModel( ));
|
||||||
// pointsize until it lands on the ground.
|
SetObjectClass( ED_NORMAL );
|
||||||
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
|
|
||||||
|
|
||||||
|
|
||||||
SetTouch( DefaultTouch );
|
SetTouch( DefaultTouch );
|
||||||
SetThink( FallThink );
|
SetThink( FallThink );
|
||||||
|
|
||||||
|
// pointsize until it lands on the ground.
|
||||||
|
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
|
||||||
|
|
||||||
m_iSpot = 0;
|
m_iSpot = 0;
|
||||||
pev->animtime = gpGlobals->time + 0.1;
|
pev->animtime = gpGlobals->time + 0.1;
|
||||||
b_restored = TRUE; // already restored
|
b_restored = TRUE; // already restored
|
||||||
|
|
|
@ -1146,7 +1146,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
|
||||||
if( pNet->pev->fixangle )
|
if( pNet->pev->fixangle )
|
||||||
{
|
{
|
||||||
to->ed_flags |= ESF_NO_PREDICTION;
|
to->ed_flags |= ESF_NO_PREDICTION;
|
||||||
pNet->pev->fixangle = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pNet->pev->teleport_time )
|
if( pNet->pev->teleport_time )
|
||||||
|
|
|
@ -2497,6 +2497,14 @@ void CBasePlayer::PostThink()
|
||||||
{
|
{
|
||||||
// ALERT ( at_console, "%f\n", m_flFallVelocity );
|
// ALERT ( at_console, "%f\n", m_flFallVelocity );
|
||||||
|
|
||||||
|
if( pev->flJumpPadTime && pev->flJumpPadTime < gpGlobals->time )
|
||||||
|
{
|
||||||
|
// scale delta if was pushed by jump pad
|
||||||
|
float delta = (1.0f + gpGlobals->time - pev->flJumpPadTime) * 0.5f;
|
||||||
|
m_flFallVelocity /= delta;
|
||||||
|
pev->flJumpPadTime = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (pev->watertype == CONTENTS_WATER)
|
if (pev->watertype == CONTENTS_WATER)
|
||||||
{
|
{
|
||||||
// Did he hit the world or a non-moving entity?
|
// Did he hit the world or a non-moving entity?
|
||||||
|
|
9
todo.log
9
todo.log
|
@ -155,7 +155,7 @@ Beta 13.12.09
|
||||||
128. fixup sprites lerping OK
|
128. fixup sprites lerping OK
|
||||||
129. fixup sound orientation OK
|
129. fixup sound orientation OK
|
||||||
130. don't show console on changelevel OK
|
130. don't show console on changelevel OK
|
||||||
131. fixup teleports and trigger push's
|
131. fixup teleports and trigger push's OK
|
||||||
132. prepare configs and gameinfo
|
132. prepare configs and gameinfo
|
||||||
133. new sound\render system version replacement OK
|
133. new sound\render system version replacement OK
|
||||||
134. dx sound engine complete OK
|
134. dx sound engine complete OK
|
||||||
|
@ -187,5 +187,8 @@ Beta 13.12.09
|
||||||
160. pfnGetPlayerStats OK
|
160. pfnGetPlayerStats OK
|
||||||
161. fix basevelocity OK
|
161. fix basevelocity OK
|
||||||
162. rewrote auto-classify OK
|
162. rewrote auto-classify OK
|
||||||
163. rewrote sv_phys.c OK
|
163. rewrote sv_phys.c
|
||||||
164. remove vprogs.dll OK
|
164. remove vprogs.dll OK
|
||||||
|
165. fix bsplib error
|
||||||
|
|
||||||
|
|
Reference in New Issue