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
|
||||
{
|
||||
MsgDev( D_ERROR, "Mod_GetBounds: NULL model %i\n", handle );
|
||||
if( mins ) VectorSet( mins, -32, -32, -32 );
|
||||
if( maxs ) VectorSet( maxs, 32, 32, 32 );
|
||||
if( mins ) VectorClear( mins );
|
||||
if( maxs ) VectorClear( maxs );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1180,8 +1180,8 @@ void CM_ModelBounds( model_t handle, vec3_t mins, vec3_t maxs )
|
|||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "Mod_GetBounds: NULL model %i\n", handle );
|
||||
if( mins ) VectorSet( mins, -32, -32, -32 );
|
||||
if( maxs ) VectorSet( maxs, 32, 32, 32 );
|
||||
if( mins ) VectorClear( mins );
|
||||
if( maxs ) VectorClear( maxs );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ typedef struct entvars_s
|
|||
vec3_t oldorigin; // ENG [all], NET [all]
|
||||
vec3_t velocity;
|
||||
vec3_t basevelocity;
|
||||
vec3_t clbasevelocity; // ENG [player], NET [player]
|
||||
|
||||
vec3_t movedir;
|
||||
|
||||
|
@ -141,6 +142,7 @@ typedef struct entvars_s
|
|||
int flSwimTime; // In process of ducking or ducked already?
|
||||
int flDuckTime; // Time we started duck
|
||||
int iStepLeft; // 0 - 4
|
||||
float flJumpPadTime; // for scale falling damage
|
||||
float flFallVelocity; // falling velocity z
|
||||
int oldbuttons; // buttons last usercmd
|
||||
int groupinfo; // entities culling (on server)
|
||||
|
|
|
@ -291,5 +291,6 @@ viewpos
|
|||
*/
|
||||
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 stuck; // entity stucked in brush
|
||||
bool suspended; // suspended on a brush entity
|
||||
|
||||
// cached position to avoid redundant SV_CheckWaterTransition calls on monsters
|
||||
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 );
|
||||
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_UpdateBaseVelocity( edict_t *ent );
|
||||
bool SV_IsValidEdict( const edict_t *e );
|
||||
script_t *CM_GetEntityScript( void );
|
||||
|
||||
_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
|
||||
{
|
||||
// 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
|
||||
|
|
|
@ -46,7 +46,7 @@ Copy entvars into entity state
|
|||
*/
|
||||
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 )
|
||||
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[1] );
|
||||
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 );
|
||||
|
||||
if( client ) client->edict->v.fixangle = false;
|
||||
|
||||
// always keep an actual
|
||||
ent->pvServerData->s.number = ent->serialnumber;
|
||||
}
|
||||
|
|
|
@ -1452,7 +1452,6 @@ int pfnDropToFloor( edict_t* e )
|
|||
SV_LinkEdict( e, true );
|
||||
e->v.flags |= FL_ONGROUND;
|
||||
e->v.groundentity = trace.pHit;
|
||||
e->pvServerData->suspended = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1469,7 +1468,6 @@ int pfnDropToFloor( edict_t* e )
|
|||
SV_LinkEdict( e, true );
|
||||
e->v.flags |= FL_ONGROUND;
|
||||
e->v.groundentity = trace.pHit;
|
||||
e->pvServerData->suspended = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -465,6 +465,45 @@ int PM_PointContents( const vec3_t p )
|
|||
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
|
||||
|
@ -559,6 +598,8 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
|||
return;
|
||||
}
|
||||
|
||||
PM_CheckMovingGround( clent, ucmd->msec * 0.001f );
|
||||
|
||||
VectorCopy( clent->v.viewangles, svgame.pmove->oldangles ); // save oldangles
|
||||
if( !clent->v.fixangle )
|
||||
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;
|
||||
|
||||
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->realtime = svs.realtime * 0.001f;
|
||||
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->serverflags = svgame.globals->serverflags; // shared serverflags
|
||||
svgame.pmove->maxspeed = svgame.movevars.maxspeed;
|
||||
svgame.pmove->cmd = *ucmd; // setup current cmds
|
||||
svgame.pmove->player = clent; // ptr to client state
|
||||
svgame.pmove->numtouch = 0; // reset touchents
|
||||
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];
|
||||
|
||||
// setup playermove state
|
||||
PM_SetupMove( svgame.pmove, clent, ucmd, cl->physinfo );
|
||||
|
||||
// motor!
|
||||
svgame.dllFuncs.pfnPM_Move( svgame.pmove, true );
|
||||
|
||||
// copy results back to client
|
||||
clent->v.teleport_time = svgame.pmove->flWaterJumpTime;
|
||||
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];
|
||||
PM_FinishMove( svgame.pmove, clent );
|
||||
VectorCopy( clent->v.velocity, oldvel ); // save velocity
|
||||
|
||||
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
|
||||
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
|
||||
for( i = 0; i < svgame.pmove->numtouch; i++ )
|
||||
{
|
||||
if( i == MAX_PHYSENTS ) break;
|
||||
if( svgame.pmove->touchents[i] == clent ) continue;
|
||||
VectorCopy( svgame.pmove->touchvels[i], clent->v.velocity );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 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++ )
|
||||
{
|
||||
e = EDICT_NUM( i );
|
||||
if( e->free ) continue;
|
||||
if( !SV_IsValidEdict( e )) continue;
|
||||
|
||||
switch( e->v.movetype )
|
||||
{
|
||||
|
@ -84,8 +84,9 @@ void SV_CheckAllEnts( void )
|
|||
continue;
|
||||
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 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
============
|
||||
*/
|
||||
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, impact, numplanes;
|
||||
int i, j, numplanes, bumpcount, blocked;
|
||||
vec3_t dir, end, planes[MAX_CLIP_PLANES];
|
||||
vec3_t primal_velocity, original_velocity, new_velocity;
|
||||
float d, time_left;
|
||||
trace_t trace;
|
||||
|
||||
if( time <= 0.0f ) return 0;
|
||||
blocked = 0;
|
||||
VectorCopy( ent->v.velocity, original_velocity );
|
||||
VectorCopy( ent->v.velocity, primal_velocity );
|
||||
numplanes = 0;
|
||||
|
||||
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 ))
|
||||
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 );
|
||||
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.flFraction == 1.0f )
|
||||
{
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
break;
|
||||
if( trace.fAllSolid )
|
||||
{
|
||||
// entity is trapped in another solid
|
||||
VectorClear( ent->v.velocity );
|
||||
return 3;
|
||||
}
|
||||
|
||||
if( !trace.pHit )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if( trace.flFraction > 0.0f )
|
||||
{
|
||||
// actually covered some distance
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
VectorCopy( ent->v.velocity, original_velocity );
|
||||
numplanes = 0;
|
||||
}
|
||||
|
||||
// run the impact function
|
||||
if( impact )
|
||||
{
|
||||
SV_Impact( ent, &trace );
|
||||
if( trace.flFraction == 1.0f )
|
||||
break; // moved the entire distance
|
||||
|
||||
// break if removed by the impact function
|
||||
if( ent->free ) break;
|
||||
if( !trace.pHit )
|
||||
{
|
||||
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
|
||||
if( numplanes >= MAX_CLIP_PLANES )
|
||||
{
|
||||
// this shouldn't really happen
|
||||
VectorClear( ent->v.velocity );
|
||||
blocked = 3;
|
||||
break;
|
||||
return 3;
|
||||
}
|
||||
|
||||
VectorCopy( trace.vecPlaneNormal, planes[numplanes] );
|
||||
|
@ -586,9 +672,8 @@ int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
|||
{
|
||||
if( j != i )
|
||||
{
|
||||
// not ok
|
||||
if( DotProduct( new_velocity, planes[j] ) < 0.0f )
|
||||
break;
|
||||
break; // not ok
|
||||
}
|
||||
}
|
||||
if( j == numplanes ) break;
|
||||
|
@ -605,12 +690,10 @@ int SV_FlyMove( edict_t *ent, float time, vec3_t vecStepNormal )
|
|||
if( numplanes != 2 )
|
||||
{
|
||||
VectorClear( ent->v.velocity );
|
||||
blocked = 7;
|
||||
break;
|
||||
return 7;
|
||||
}
|
||||
|
||||
CrossProduct( planes[0], planes[1], dir );
|
||||
VectorNormalize( dir );
|
||||
d = DotProduct( dir, 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 )
|
||||
{
|
||||
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
|
||||
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 )
|
||||
return true;
|
||||
|
@ -756,8 +839,13 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
|||
pushltime = pusher->v.ltime;
|
||||
|
||||
// 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.angles, movetime, pusher->v.avelocity, pusher->v.angles );
|
||||
#endif
|
||||
pusher->v.ltime += movetime;
|
||||
SV_LinkEdict( pusher, false );
|
||||
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.
|
||||
=============
|
||||
*/
|
||||
void SV_Physics_Toss( edict_t *ent )
|
||||
void SV_Physics_Bounce( edict_t *ent )
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t move;
|
||||
|
@ -1090,14 +1178,6 @@ void SV_Physics_Toss( edict_t *ent )
|
|||
int bump;
|
||||
|
||||
// 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 );
|
||||
|
||||
// regular thinking
|
||||
|
@ -1111,22 +1191,9 @@ void SV_Physics_Toss( edict_t *ent )
|
|||
// don't stick to ground if onground and moving upward
|
||||
ent->v.flags &= ~FL_ONGROUND;
|
||||
}
|
||||
else if( ent->v.groundentity == EDICT_NUM( 0 ))
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
ent->pvServerData->suspended = false;
|
||||
SV_CheckVelocity( ent );
|
||||
|
||||
// add gravity
|
||||
|
@ -1188,29 +1255,15 @@ void SV_Physics_Toss( edict_t *ent )
|
|||
ent_gravity = ent->v.gravity;
|
||||
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 ));
|
||||
if( trace.vecPlaneNormal[2] > 0.7f && d < 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
|
||||
{
|
||||
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;
|
||||
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
|
||||
{
|
||||
|
@ -1219,9 +1272,6 @@ void SV_Physics_Toss( edict_t *ent )
|
|||
{
|
||||
ent->v.flags |= FL_ONGROUND;
|
||||
ent->v.groundentity = trace.pHit;
|
||||
|
||||
if( trace.pHit->v.solid == SOLID_BSP )
|
||||
ent->pvServerData->suspended = true;
|
||||
VectorClear( ent->v.velocity );
|
||||
VectorClear( ent->v.avelocity );
|
||||
}
|
||||
|
@ -1235,6 +1285,151 @@ void SV_Physics_Toss( edict_t *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 )
|
||||
{
|
||||
int flags = ent->v.flags;
|
||||
bool wasonground;
|
||||
bool inwater;
|
||||
float *vel;
|
||||
float speed, newspeed, control;
|
||||
float friction;
|
||||
|
||||
// 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 );
|
||||
wasonground = ent->v.flags & FL_ONGROUND;
|
||||
|
||||
if( !VectorIsNull( ent->v.avelocity ))
|
||||
SV_AddRotationalFriction( ent );
|
||||
|
||||
// don't fall at all if fly/swim
|
||||
if( !( flags & ( FL_FLY|FL_SWIM )))
|
||||
// add gravity except:
|
||||
// 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
|
||||
// freefall if not standing on a world surface (it may be a lift or trap door)
|
||||
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;
|
||||
}
|
||||
if(!( ent->v.flags & FL_SWIM && ent->v.waterlevel > 0 ))
|
||||
if( !inwater ) SV_AddGravity( ent );
|
||||
}
|
||||
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
|
||||
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 )
|
||||
if( !( ent->v.health <= 0.0f && !SV_CheckBottom( ent, WALKMOVE_NORMAL )))
|
||||
{
|
||||
// debug
|
||||
Msg( "landing\n" );
|
||||
vel = ent->v.velocity;
|
||||
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
|
||||
if( !SV_RunThink( ent ))
|
||||
return;
|
||||
|
||||
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 );
|
||||
}
|
||||
SV_RunThink ( ent );
|
||||
SV_CheckWaterTransition( ent );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1442,6 +1667,16 @@ void SV_Physics_None( 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 )
|
||||
{
|
||||
case MOVETYPE_PUSH:
|
||||
|
@ -1460,22 +1695,6 @@ static void SV_Physics_Entity( edict_t *ent )
|
|||
case MOVETYPE_PUSHSTEP:
|
||||
SV_Physics_Step( ent );
|
||||
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_TOSS:
|
||||
case MOVETYPE_BOUNCE:
|
||||
|
@ -1486,6 +1705,9 @@ static void SV_Physics_Entity( edict_t *ent )
|
|||
case MOVETYPE_CONVEYOR:
|
||||
SV_Physics_Conveyor( ent );
|
||||
break;
|
||||
case MOVETYPE_WALK:
|
||||
Host_Error( "SV_Physics: bad movetype %i\n", ent->v.movetype );
|
||||
break;
|
||||
default:
|
||||
svgame.dllFuncs.pfnPhysicsEntity( ent );
|
||||
break;
|
||||
|
@ -1500,8 +1722,8 @@ SV_Physics
|
|||
*/
|
||||
void SV_Physics( void )
|
||||
{
|
||||
int i;
|
||||
edict_t *ent;
|
||||
int i;
|
||||
|
||||
// let the progs know that a new frame has started
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
|
@ -1520,19 +1742,11 @@ void SV_Physics( void )
|
|||
}
|
||||
|
||||
// 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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -2461,6 +2461,13 @@ void PM_CheckFalling( void )
|
|||
{
|
||||
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 )
|
||||
{
|
||||
// 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
|
||||
// cascade into the second
|
||||
#if 0
|
||||
switch ( RandomLong(0,1) )
|
||||
switch ( RANDOM_LONG( 0, 1 ))
|
||||
{
|
||||
case 0:
|
||||
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 );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
fvol = 1.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( misc_teleporter_dest, CPointEntity );
|
||||
LINK_ENTITY_TO_CLASS( misc_portal_surface, CPortalSurface );
|
||||
LINK_ENTITY_TO_CLASS( info_null, CNullEntity);
|
||||
LINK_ENTITY_TO_CLASS( misc_model, CNullEntity);
|
||||
LINK_ENTITY_TO_CLASS( info_notnull, CPointEntity );
|
||||
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_compile_parameters, CNullEntity);
|
||||
LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission );
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
class CPointEntity : public CBaseEntity
|
||||
{
|
||||
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; }
|
||||
};
|
||||
|
||||
|
|
|
@ -26,15 +26,14 @@ void CItem::Spawn( void )
|
|||
pev->movetype = MOVETYPE_TOSS;
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SetObjectClass( ED_NORMAL );
|
||||
|
||||
UTIL_SetModel( ENT( pev ), pev->model, Model() );
|
||||
UTIL_SetOrigin( this, pev->origin );
|
||||
UTIL_SetSize( pev, g_vecZero, g_vecZero );
|
||||
UTIL_SetSize(pev, g_vecZero, g_vecZero );
|
||||
SetObjectClass( ED_NORMAL );
|
||||
|
||||
SetTouch( ItemTouch );
|
||||
SetThink( ItemFall );
|
||||
|
||||
UTIL_SetModel(ENT(pev), pev->model, Model() );
|
||||
SetNextThink( 0.1 );
|
||||
}
|
||||
|
||||
|
|
|
@ -146,10 +146,9 @@ void CGrenade::BounceTouch( CBaseEntity *pOther )
|
|||
m_fRegisteredSound = TRUE;
|
||||
}
|
||||
|
||||
if (pev->flags & FL_ONGROUND)
|
||||
if ( pev->flags & FL_ONGROUND )
|
||||
{
|
||||
// add a bit of static friction
|
||||
Msg( "On ground()\n" );
|
||||
pev->velocity = pev->velocity * 0.8;
|
||||
pev->sequence = 1;
|
||||
}
|
||||
|
@ -159,8 +158,8 @@ void CGrenade::BounceTouch( CBaseEntity *pOther )
|
|||
BounceSound();
|
||||
}
|
||||
pev->framerate = pev->velocity.Length() / 200.0;
|
||||
if (pev->framerate > 1.0) pev->framerate = 1;
|
||||
else if (pev->framerate < 0.5) pev->framerate = 0;
|
||||
if( pev->framerate > 1.0 ) pev->framerate = 1;
|
||||
else if( pev->framerate < 0.5 ) pev->framerate = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -231,8 +230,7 @@ void CGrenade:: Spawn( void )
|
|||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SetObjectClass( ED_NORMAL );
|
||||
UTIL_SetModel( ENT( pev ), "models/grenade.mdl");
|
||||
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
|
||||
UTIL_SetModel( ENT( pev ), "models/props/hgrenade.mdl");
|
||||
|
||||
pev->dmg = 100;
|
||||
m_fRegisteredSound = FALSE;
|
||||
|
@ -261,7 +259,8 @@ CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector v
|
|||
// Explode on contact
|
||||
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;
|
||||
|
||||
return pGrenade;
|
||||
|
@ -299,13 +298,14 @@ CGrenade * CGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector v
|
|||
pGrenade->pev->flags |= FL_PROJECTILE;
|
||||
|
||||
// Tumble through the air
|
||||
// pGrenade->pev->avelocity.x = -400;
|
||||
pGrenade->pev->avelocity.x = -400;
|
||||
|
||||
pGrenade->pev->gravity = 0.5;
|
||||
pGrenade->pev->friction = 0.8;
|
||||
pGrenade->pev->scale = 0.5; // original Valve model is too big :)
|
||||
|
||||
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;
|
||||
|
||||
return pGrenade;
|
||||
|
@ -712,6 +712,7 @@ void CWHRocket :: Spawn( void )
|
|||
SetTouch( NukeTouch );
|
||||
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
pev->angles.x = -(pev->angles.x);
|
||||
pev->velocity = gpGlobals->v_forward * pev->speed;
|
||||
m_Center = pev->angles;
|
||||
|
||||
|
|
|
@ -274,6 +274,8 @@ class CChangeFriction : public CBaseTrigger
|
|||
};
|
||||
LINK_ENTITY_TO_CLASS( func_friction, CChangeFriction );
|
||||
|
||||
#define SF_PUSH_ONCE 1
|
||||
|
||||
//=======================================================================
|
||||
// trigger_push - triger that pushes player
|
||||
//=======================================================================
|
||||
|
@ -281,11 +283,13 @@ class CTriggerPush : public CBaseTrigger
|
|||
{
|
||||
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;
|
||||
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;
|
||||
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
|
@ -304,11 +308,13 @@ class CTriggerPush : public CBaseTrigger
|
|||
pOwner = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
|
||||
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->movedir = pOwner->pev->origin - ((pev->absmin + pev->absmax) * 0.5f);
|
||||
pev->movedir.Normalize();
|
||||
pev->button = TRUE; // Q3A trigger_push
|
||||
}
|
||||
}
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
|
@ -331,11 +337,53 @@ class CTriggerPush : public CBaseTrigger
|
|||
case MOVETYPE_FOLLOW:
|
||||
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
|
||||
if( FBitSet( pev->spawnflags, 1 ))
|
||||
if( FBitSet( pev->spawnflags, SF_PUSH_ONCE ))
|
||||
{
|
||||
pOther->pev->velocity = pOther->pev->velocity + (pev->speed * pev->movedir);
|
||||
if( pOther->pev->velocity.z > 0 ) pOther->pev->flags &= ~FL_ONGROUND;
|
||||
|
@ -348,6 +396,7 @@ class CTriggerPush : public CBaseTrigger
|
|||
vecPush = vecPush + pOther->pev->basevelocity;
|
||||
pOther->pev->basevelocity = vecPush;
|
||||
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->solid = SOLID_BBOX;
|
||||
pev->sequence = 1; // set world animation
|
||||
|
||||
SetObjectClass( ED_NORMAL );
|
||||
UTIL_SetModel( ENT( pev ), iWorldModel( ));
|
||||
|
||||
UTIL_SetOrigin( this, pev->origin );
|
||||
|
||||
// pointsize until it lands on the ground.
|
||||
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
|
||||
|
||||
UTIL_SetModel( ENT( pev ), iWorldModel( ));
|
||||
SetObjectClass( ED_NORMAL );
|
||||
|
||||
SetTouch( DefaultTouch );
|
||||
SetThink( FallThink );
|
||||
|
||||
// pointsize until it lands on the ground.
|
||||
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
|
||||
|
||||
m_iSpot = 0;
|
||||
pev->animtime = gpGlobals->time + 0.1;
|
||||
b_restored = TRUE; // already restored
|
||||
|
|
|
@ -1146,7 +1146,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
|
|||
if( pNet->pev->fixangle )
|
||||
{
|
||||
to->ed_flags |= ESF_NO_PREDICTION;
|
||||
pNet->pev->fixangle = 0;
|
||||
}
|
||||
|
||||
if( pNet->pev->teleport_time )
|
||||
|
|
|
@ -2497,6 +2497,14 @@ void CBasePlayer::PostThink()
|
|||
{
|
||||
// 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)
|
||||
{
|
||||
// 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
|
||||
129. fixup sound orientation 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
|
||||
133. new sound\render system version replacement OK
|
||||
134. dx sound engine complete OK
|
||||
|
@ -187,5 +187,8 @@ Beta 13.12.09
|
|||
160. pfnGetPlayerStats OK
|
||||
161. fix basevelocity OK
|
||||
162. rewrote auto-classify OK
|
||||
163. rewrote sv_phys.c OK
|
||||
164. remove vprogs.dll OK
|
||||
163. rewrote sv_phys.c
|
||||
164. remove vprogs.dll OK
|
||||
165. fix bsplib error
|
||||
|
||||
|
Reference in New Issue