17 Jun 2010
This commit is contained in:
parent
ce9a0409b7
commit
7efdf1ea1b
|
@ -396,7 +396,37 @@ void ClientCommand( edict_t *pEntity )
|
|||
GetClassPtr((CBasePlayer *)pev)->GiveNamedItem( STRING(iszItem) );
|
||||
}
|
||||
}
|
||||
else if ( FStrEq(pcmd, "fire") ) //LRC - trigger entities manually
|
||||
{
|
||||
if (g_flWeaponCheat)
|
||||
{
|
||||
CBaseEntity *pPlayer = CBaseEntity::Instance(pEntity);
|
||||
if (CMD_ARGC() > 1)
|
||||
{
|
||||
FireTargets(CMD_ARGV(1), pPlayer, pPlayer, USE_TOGGLE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_MakeVectors(pev->viewangles);
|
||||
UTIL_TraceLine(
|
||||
pev->origin + pev->view_ofs,
|
||||
pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000,
|
||||
dont_ignore_monsters, pEntity, &tr
|
||||
);
|
||||
|
||||
if (tr.pHit)
|
||||
{
|
||||
CBaseEntity *pHitEnt = CBaseEntity::Instance(tr.pHit);
|
||||
if (pHitEnt)
|
||||
{
|
||||
pHitEnt->Use(pPlayer, pPlayer, USE_TOGGLE, 0);
|
||||
ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "Fired %s \"%s\"\n", STRING(pHitEnt->pev->classname), STRING(pHitEnt->pev->targetname) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( FStrEq(pcmd, "drop" ) )
|
||||
{
|
||||
// player is dropping an item.
|
||||
|
@ -863,7 +893,7 @@ int AutoClassify( edict_t *pentToClassify )
|
|||
return ED_RIGIDBODY;
|
||||
else if ( pClass->pev->solid == SOLID_BSP )
|
||||
{
|
||||
if ( pClass->pev->movetype == MOVETYPE_CONVEYOR )
|
||||
if ( pClass->pev->flags & FL_CONVEYOR )
|
||||
return ED_MOVER;
|
||||
else if ( pClass->pev->flags & FL_WORLDBRUSH )
|
||||
return ED_BSPBRUSH;
|
||||
|
@ -876,6 +906,8 @@ int AutoClassify( edict_t *pentToClassify )
|
|||
return ED_MONSTER;
|
||||
else if ( pClass->pev->flags & FL_CLIENT )
|
||||
return ED_CLIENT;
|
||||
if ( pClass->pev->flags & FL_CONVEYOR )
|
||||
return ED_MOVER;
|
||||
else if ( !pClass->pev->modelindex && !pClass->pev->aiment )
|
||||
{
|
||||
if ( pClass->pev->noise || pClass->pev->noise1 || pClass->pev->noise2 || pClass->pev->noise3 )
|
||||
|
|
|
@ -640,7 +640,7 @@ void CWorld :: Precache( void )
|
|||
if ( pev->speed > 0 )
|
||||
CVAR_SET_FLOAT( "sv_zmax", pev->speed );
|
||||
else
|
||||
CVAR_SET_FLOAT( "sv_zmax", 4096 );
|
||||
CVAR_SET_FLOAT( "sv_zmax", 0 ); // let the renderer calculate optimal value
|
||||
|
||||
if ( pev->netname )
|
||||
{
|
||||
|
|
|
@ -647,22 +647,26 @@ void CTempEnts::FizzEffect( edict_t *pent, int modelIndex, int density )
|
|||
count = density + 1;
|
||||
density = count * 3 + 6;
|
||||
|
||||
GetModelBounds( modelIndex, mins, maxs );
|
||||
GetModelBounds( pent->v.modelindex, mins, maxs );
|
||||
|
||||
maxHeight = maxs[2] - mins[2];
|
||||
width = maxs[0] - mins[0];
|
||||
depth = maxs[1] - mins[1];
|
||||
speed = ((int)pent->v.rendercolor.y<<8|(int)pent->v.rendercolor.x);
|
||||
speed = ((int)pent->v.rendercolor.x<<8|(int)pent->v.rendercolor.y);
|
||||
if( pent->v.rendercolor.z ) speed = -speed;
|
||||
if( speed == 0.0f ) speed = 100.0f; // apply default value
|
||||
|
||||
ALERT( at_console, "FizzEffect: speed %g\n", speed );
|
||||
if( pent->v.angles[YAW] != 0.0f )
|
||||
{
|
||||
angle = pent->v.angles[YAW] * M_PI / 180;
|
||||
yspeed = sin( angle );
|
||||
xspeed = cos( angle );
|
||||
|
||||
angle = pent->v.angles[YAW] * M_PI / 180;
|
||||
yspeed = sin( angle );
|
||||
xspeed = cos( angle );
|
||||
xspeed *= speed;
|
||||
yspeed *= speed;
|
||||
}
|
||||
else xspeed = yspeed = 0.0f; // zonly
|
||||
|
||||
xspeed *= speed;
|
||||
yspeed *= speed;
|
||||
frameCount = GetModelFrames( modelIndex );
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
|
|
|
@ -88,7 +88,7 @@ void CM_CalcPHS( void )
|
|||
if( !worldmodel || !cm.pvs )
|
||||
return;
|
||||
|
||||
MsgDev( D_INFO, "Building PAS...\n" );
|
||||
MsgDev( D_NOTE, "Building PAS...\n" );
|
||||
timestart = Sys_Milliseconds();
|
||||
|
||||
num = worldmodel->numleafs;
|
||||
|
@ -168,8 +168,8 @@ void CM_CalcPHS( void )
|
|||
}
|
||||
}
|
||||
|
||||
MsgDev( D_INFO, "Average leaves visible / audible / total: %i / %i / %i\n", vcount / num, hcount / num, num );
|
||||
MsgDev( D_INFO, "PAS building time: %g secs\n", (Sys_Milliseconds() - timestart) * 0.001f );
|
||||
MsgDev( D_NOTE, "Average leaves visible / audible / total: %i / %i / %i\n", vcount / num, hcount / num, num );
|
||||
MsgDev( D_NOTE, "PAS building time: %g secs\n", (Sys_Milliseconds() - timestart) * 0.001f );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -174,6 +174,9 @@ loc0:
|
|||
return true; // empty
|
||||
}
|
||||
|
||||
if( num < hull->firstclipnode || num > hull->lastclipnode )
|
||||
Host_Error( "CM_RecursiveHullCheck: bad node number\n" );
|
||||
|
||||
// find the point distances
|
||||
node = hull->clipnodes + num;
|
||||
plane = hull->planes + node->planenum;
|
||||
|
@ -280,7 +283,7 @@ trace_t CM_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3
|
|||
VectorCopy( end, trace.vecEndPos );
|
||||
trace.flFraction = 1.0f;
|
||||
trace.fAllSolid = true;
|
||||
trace.iHitgroup = -1;
|
||||
trace.iHitgroup = -1;
|
||||
|
||||
// get the clipping hull
|
||||
hull = CM_HullForEntity( ent, mins, maxs, offset );
|
||||
|
@ -294,7 +297,8 @@ trace_t CM_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3
|
|||
vec3_t forward, right, up;
|
||||
vec3_t temp;
|
||||
|
||||
AngleVectors( ent->v.angles, forward, right, up );
|
||||
VectorCopy( ent->v.angles, temp );
|
||||
AngleVectors( temp, forward, right, up );
|
||||
|
||||
VectorCopy( start_l, temp );
|
||||
start_l[0] = DotProduct( temp, forward );
|
||||
|
|
|
@ -67,6 +67,11 @@ typedef struct ref_params_s
|
|||
|
||||
float fov_x;
|
||||
float fov_y; // fov_y = V_CalcFov( fov_x, viewport[2], viewport[3] );
|
||||
|
||||
vec3_t skyColor; // "sv_skycolor" come from server
|
||||
vec3_t skyVec; // "sv_skyvec" come from server
|
||||
float zFar; // "sv_zmax" come from server
|
||||
|
||||
} ref_params_t;
|
||||
|
||||
#endif//REF_PARAMS_H
|
|
@ -96,7 +96,7 @@ typedef struct enginefuncs_s
|
|||
void (*pfnTraceHull)( const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr );
|
||||
void (*pfnTraceModel)( const float *v1, const float *v2, edict_t *pent, TraceResult *ptr );
|
||||
const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 );
|
||||
int (*pfnTestEntityPosition)( edict_t *pTestEdict, const float *offset ); // was pfnTraceSphere
|
||||
int (*pfnTestEntityPosition)( edict_t *pTestEdict ); // was pfnTraceSphere
|
||||
void (*pfnGetAimVector)( edict_t* ent, float speed, float *rgflReturn );
|
||||
void (*pfnServerCommand)( const char* str );
|
||||
void (*pfnServerExecute)( void );
|
||||
|
|
|
@ -32,9 +32,6 @@ edict_t *CL_GetEdictByIndex( int index )
|
|||
MsgDev( D_ERROR, "CL_GetEntityByIndex: invalid entindex %i\n", index );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if( EDICT_NUM( index )->free )
|
||||
// return NULL;
|
||||
return EDICT_NUM( index );
|
||||
}
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ static TraceResult PM_PlayerTrace( const vec3_t start, const vec3_t end, int tra
|
|||
mins = clgame.pmove->player_mins[clgame.pmove->usehull];
|
||||
maxs = clgame.pmove->player_maxs[clgame.pmove->usehull];
|
||||
|
||||
result = CL_Move( start, mins, maxs, end, trace_type, clgame.pmove->player );
|
||||
result = CL_Move( start, mins, maxs, end, trace_type|FMOVE_SIMPLEBOX, clgame.pmove->player );
|
||||
Mem_Copy( &out, &result, sizeof( TraceResult ));
|
||||
|
||||
return out;
|
||||
|
|
|
@ -581,10 +581,27 @@ void CL_ParseConfigString( sizebuf_t *msg )
|
|||
}
|
||||
else if( i == CS_SERVERFLAGS )
|
||||
{
|
||||
// update shared serverflags
|
||||
clgame.globals->serverflags = com.atoi( cl.configstrings[CS_SERVERFLAGS] );
|
||||
}
|
||||
else if( i > CS_SERVERFLAGS && i < CS_MODELS )
|
||||
else if( i == CS_ZFAR )
|
||||
{
|
||||
cl.refdef.zFar = com.atof( cl.configstrings[CS_ZFAR] );
|
||||
}
|
||||
else if( i == CS_SKYCOLOR )
|
||||
{
|
||||
com.atov( cl.refdef.skyColor, cl.configstrings[CS_SKYCOLOR], 3 );
|
||||
}
|
||||
else if( i == CS_WATERAMP )
|
||||
{
|
||||
edict_t *world = CL_GetEdictByIndex( 0 );
|
||||
world->v.scale = com.atof( cl.configstrings[CS_WATERAMP] );
|
||||
Msg( "Global WaveHeight is %g\n", world->v.scale * 16 );
|
||||
}
|
||||
else if( i == CS_SKYVEC )
|
||||
{
|
||||
com.atov( cl.refdef.skyVec, cl.configstrings[CS_SKYVEC], 3 );
|
||||
}
|
||||
else if( i > CS_WATERAMP && i < CS_MODELS )
|
||||
{
|
||||
Host_Error( "CL_ParseConfigString: reserved configstring #%i are used\n", i );
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ bool CL_CheckWater( edict_t *ent )
|
|||
|
||||
ent->v.waterlevel = 0;
|
||||
ent->v.watertype = CONTENTS_EMPTY;
|
||||
cont = CL_PointContents( point );
|
||||
cont = CL_TruePointContents( point );
|
||||
|
||||
if( cont <= CONTENTS_WATER )
|
||||
{
|
||||
|
|
|
@ -559,7 +559,5 @@ edict_t *CL_TestPlayerPosition( const vec3_t origin, edict_t *pass, TraceResult
|
|||
result = CL_Move( origin, mins, maxs, origin, MOVE_NORMAL, pass );
|
||||
if( tr ) Mem_Copy( tr, &result, sizeof( *tr ));
|
||||
|
||||
if( result.pHit )
|
||||
return result.pHit;
|
||||
return NULL;
|
||||
return result.pHit;
|
||||
}
|
|
@ -104,33 +104,19 @@ void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_
|
|||
|
||||
trace_t World_CombineTraces( trace_t *cliptrace, trace_t *trace, edict_t *touch )
|
||||
{
|
||||
if( trace->fAllSolid )
|
||||
if( trace->fAllSolid || trace->fStartSolid || trace->flFraction < cliptrace->flFraction )
|
||||
{
|
||||
cliptrace->fAllSolid = true;
|
||||
trace->pHit = touch;
|
||||
|
||||
if( cliptrace->fStartSolid )
|
||||
{
|
||||
*cliptrace = *trace;
|
||||
cliptrace->fStartSolid = true;
|
||||
}
|
||||
else *cliptrace = *trace;
|
||||
}
|
||||
else if( trace->fStartSolid )
|
||||
{
|
||||
cliptrace->fStartSolid = true;
|
||||
trace->pHit = touch;
|
||||
}
|
||||
|
||||
if( trace->fInOpen )
|
||||
cliptrace->fInOpen = true;
|
||||
|
||||
if( trace->fInWater )
|
||||
cliptrace->fInWater = true;
|
||||
|
||||
if( trace->flFraction < cliptrace->flFraction )
|
||||
{
|
||||
bool oldStartSolid;
|
||||
|
||||
// make sure we keep a startsolid from a previous trace
|
||||
oldStartSolid = cliptrace->fStartSolid;
|
||||
|
||||
trace->pHit = touch;
|
||||
cliptrace = trace;
|
||||
cliptrace->fStartSolid |= oldStartSolid;
|
||||
}
|
||||
return *cliptrace;
|
||||
}
|
|
@ -140,8 +140,12 @@ static const net_desc_t NWDesc[] =
|
|||
#define CS_SKYNAME 2 // skybox shader name
|
||||
#define CS_BACKGROUND_TRACK 3 // basename of background track
|
||||
#define CS_SERVERFLAGS 4 // shared server flags
|
||||
#define CS_SKYCOLOR 5 // <float> <float> <float>
|
||||
#define CS_SKYVEC 6 // <float> <float> <float>
|
||||
#define CS_ZFAR 7 // zfar value came from server
|
||||
#define CS_WATERAMP 8 // water amplitude for world water surfaces
|
||||
|
||||
// 5 - 32 it's a reserved strings
|
||||
// 8 - 32 it's a reserved strings
|
||||
|
||||
#define CS_MODELS 32 // configstrings starts here
|
||||
#define CS_SOUNDS (CS_MODELS+MAX_MODELS) // sound names
|
||||
|
|
|
@ -946,11 +946,12 @@ void Host_Free( void )
|
|||
host.state = HOST_SHUTDOWN; // prepare host to normal shutdown
|
||||
com.strncpy( host.finalmsg, "Server shutdown\n", MAX_STRING );
|
||||
|
||||
SV_Shutdown( false );
|
||||
CL_Shutdown();
|
||||
Host_FreeRender();
|
||||
Host_FreeSound();
|
||||
Host_FreePhysic();
|
||||
|
||||
SV_Shutdown( false );
|
||||
CL_Shutdown();
|
||||
NET_Shutdown();
|
||||
Host_FreeCommon();
|
||||
}
|
||||
|
|
|
@ -330,7 +330,7 @@ void SV_CheckVelocity( edict_t *ent );
|
|||
bool SV_CheckWater( edict_t *ent );
|
||||
bool SV_RunThink( edict_t *ent );
|
||||
void SV_FreeOldEntities( void );
|
||||
bool SV_TestEntityPosition( edict_t *ent, const vec3_t offset ); // for EntityInSolid checks
|
||||
bool SV_TestEntityPosition( edict_t *ent ); // for EntityInSolid checks
|
||||
|
||||
//
|
||||
// sv_move.c
|
||||
|
|
|
@ -1660,7 +1660,7 @@ pfnTestEntityPosition
|
|||
returns true if the entity is in solid currently
|
||||
=============
|
||||
*/
|
||||
static int pfnTestEntityPosition( edict_t *pTestEdict, const float *offset )
|
||||
static int pfnTestEntityPosition( edict_t *pTestEdict )
|
||||
{
|
||||
if( !SV_IsValidEdict( pTestEdict ))
|
||||
{
|
||||
|
@ -1668,9 +1668,7 @@ static int pfnTestEntityPosition( edict_t *pTestEdict, const float *offset )
|
|||
return false;
|
||||
}
|
||||
|
||||
if( !offset ) offset = vec3_origin;
|
||||
|
||||
return SV_TestEntityPosition( pTestEdict, offset );
|
||||
return SV_TestEntityPosition( pTestEdict );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3597,6 +3595,16 @@ void SV_SpawnEntities( const char *mapname, script_t *entities )
|
|||
|
||||
MsgDev( D_NOTE, "SV_SpawnEntities()\n" );
|
||||
|
||||
// reset sky parms
|
||||
Cvar_Reset( "sv_zmax" );
|
||||
Cvar_Reset( "sv_wateramp" );
|
||||
Cvar_Reset( "sv_skycolor_r" );
|
||||
Cvar_Reset( "sv_skycolor_g" );
|
||||
Cvar_Reset( "sv_skycolor_b" );
|
||||
Cvar_Reset( "sv_skyvec_x" );
|
||||
Cvar_Reset( "sv_skyvec_y" );
|
||||
Cvar_Reset( "sv_skyvec_z" );
|
||||
|
||||
ent = EDICT_NUM( 0 );
|
||||
if( ent->free ) SV_InitEdict( ent );
|
||||
ent->v.model = MAKE_STRING( sv.configstrings[CS_MODELS+1] );
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
|
||||
netadr_t master_adr[MAX_MASTERS]; // address of group servers
|
||||
|
||||
cvar_t *sv_zmax;
|
||||
cvar_t *sv_fps;
|
||||
cvar_t *sv_enforcetime;
|
||||
cvar_t *sv_pausable;
|
||||
cvar_t *sv_newunit;
|
||||
cvar_t *sv_wateramp;
|
||||
cvar_t *timeout; // seconds without any message
|
||||
cvar_t *zombietime; // seconds to sink messages after disconnect
|
||||
cvar_t *rcon_password; // password for remote server commands
|
||||
|
@ -44,7 +46,15 @@ cvar_t *sv_reconnect_limit; // minimum seconds between connect messages
|
|||
cvar_t *serverinfo;
|
||||
cvar_t *physinfo;
|
||||
|
||||
void Master_Shutdown (void);
|
||||
// sky variables
|
||||
cvar_t *sv_skycolor_r;
|
||||
cvar_t *sv_skycolor_g;
|
||||
cvar_t *sv_skycolor_b;
|
||||
cvar_t *sv_skyvec_x;
|
||||
cvar_t *sv_skyvec_y;
|
||||
cvar_t *sv_skyvec_z;
|
||||
|
||||
void Master_Shutdown( void );
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
@ -159,6 +169,7 @@ send updates to client if changed
|
|||
void SV_UpdateMovevars( void )
|
||||
{
|
||||
static int oldserverflags = 0;
|
||||
string tmp;
|
||||
|
||||
if( svgame.globals->serverflags != oldserverflags )
|
||||
{
|
||||
|
@ -167,6 +178,32 @@ void SV_UpdateMovevars( void )
|
|||
oldserverflags = svgame.globals->serverflags;
|
||||
}
|
||||
|
||||
if( sv_zmax->modified )
|
||||
{
|
||||
SV_ConfigString( CS_ZFAR, sv_zmax->string );
|
||||
sv_zmax->modified = false;
|
||||
}
|
||||
|
||||
if( sv_wateramp->modified )
|
||||
{
|
||||
SV_ConfigString( CS_WATERAMP, sv_wateramp->string );
|
||||
sv_wateramp->modified = false;
|
||||
}
|
||||
|
||||
if( sv_skycolor_r->modified || sv_skycolor_g->modified || sv_skycolor_g->modified )
|
||||
{
|
||||
com.snprintf( tmp, sizeof( tmp ), "%d %d %d", sv_skycolor_r->integer, sv_skycolor_g->integer, sv_skycolor_b->integer );
|
||||
sv_skycolor_r->modified = sv_skycolor_g->modified = sv_skycolor_g->modified = false;
|
||||
SV_ConfigString( CS_SKYCOLOR, tmp );
|
||||
}
|
||||
|
||||
if( sv_skyvec_x->modified || sv_skyvec_y->modified || sv_skyvec_z->modified )
|
||||
{
|
||||
com.snprintf( tmp, sizeof( tmp ), "%f %f %f", sv_skyvec_x->value, sv_skyvec_y->value, sv_skyvec_z->value );
|
||||
sv_skyvec_x->modified = sv_skyvec_y->modified = sv_skyvec_z->modified = false;
|
||||
SV_ConfigString( CS_SKYVEC, tmp );
|
||||
}
|
||||
|
||||
if( !physinfo->modified ) return;
|
||||
|
||||
svgame.movevars.gravity = sv_gravity->value;
|
||||
|
@ -371,7 +408,7 @@ void SV_PrepWorldFrame( void )
|
|||
ent->v.effects &= ~EF_MUZZLEFLASH;
|
||||
|
||||
// clear NOINTERP flag automatically only for alive creatures
|
||||
if( ent->v.flags & ( FL_MONSTER|FL_CLIENT|FL_FAKECLIENT ) && ent->v.deadflag != DEAD_DEAD )
|
||||
if( ent->v.flags & ( FL_MONSTER|FL_CLIENT|FL_FAKECLIENT ) && ent->v.deadflag < DEAD_DEAD )
|
||||
ent->v.effects &= ~EF_NOINTERP;
|
||||
}
|
||||
}
|
||||
|
@ -590,13 +627,15 @@ void SV_Init( void )
|
|||
Cvar_Get ("showtriggers", "0", CVAR_LATCH, "debug cvar shows triggers" );
|
||||
Cvar_Get ("sv_aim", "1", 0, "enable auto-aiming" );
|
||||
|
||||
// half-life legacy
|
||||
Cvar_Get ("sv_skycolor_r", "0", 0, "skycolor red (hl1 legacy)" );
|
||||
Cvar_Get ("sv_skycolor_g", "0", 0, "skycolor green (hl1 legacy)" );
|
||||
Cvar_Get ("sv_skycolor_b", "0", 0, "skycolor blue (hl1 legacy)" );
|
||||
Cvar_Get ("sv_skyvec_x", "0", 0, "sky direction x (hl1 legacy)" );
|
||||
Cvar_Get ("sv_skyvec_y", "0", 0, "sky direction y (hl1 legacy)" );
|
||||
Cvar_Get ("sv_skyvec_z", "0", 0, "sky direction z (hl1 legacy)" );
|
||||
// half-life shared variables
|
||||
sv_zmax = Cvar_Get ("sv_zmax", "0", 0, "zfar server value" );
|
||||
sv_wateramp = Cvar_Get ("sv_wateramp", "0", 0, "global water wave height" );
|
||||
sv_skycolor_r = Cvar_Get ("sv_skycolor_r", "127", 0, "skycolor red (hl1 compatibility)" );
|
||||
sv_skycolor_g = Cvar_Get ("sv_skycolor_g", "127", 0, "skycolor green (hl1 compatibility)" );
|
||||
sv_skycolor_b = Cvar_Get ("sv_skycolor_b", "127", 0, "skycolor blue (hl1 compatibility)" );
|
||||
sv_skyvec_x = Cvar_Get ("sv_skyvec_x", "1", 0, "sky direction x (hl1 compatibility)" );
|
||||
sv_skyvec_y = Cvar_Get ("sv_skyvec_y", "0", 0, "sky direction y (hl1 compatibility)" );
|
||||
sv_skyvec_z = Cvar_Get ("sv_skyvec_z", "-1", 0, "sky direction z (hl1 compatibility)" );
|
||||
|
||||
sv_fps = Cvar_Get( "sv_fps", "72.1", CVAR_ARCHIVE, "running server physics at" );
|
||||
sv_stepheight = Cvar_Get( "sv_stepheight", "18", CVAR_ARCHIVE|CVAR_PHYSICINFO, "how high you can step up" );
|
||||
|
|
|
@ -362,7 +362,7 @@ static TraceResult PM_PlayerTrace( const vec3_t start, const vec3_t end, int tra
|
|||
mins = svgame.pmove->player_mins[svgame.pmove->usehull];
|
||||
maxs = svgame.pmove->player_maxs[svgame.pmove->usehull];
|
||||
|
||||
result = SV_Move( start, mins, maxs, end, trace_type, svgame.pmove->player );
|
||||
result = SV_Move( start, mins, maxs, end, trace_type|FMOVE_SIMPLEBOX, svgame.pmove->player );
|
||||
Mem_Copy( &out, &result, sizeof( TraceResult ));
|
||||
|
||||
return out;
|
||||
|
@ -610,7 +610,6 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
clent = cl->edict;
|
||||
if( !SV_IsValidEdict( clent )) return;
|
||||
|
||||
|
@ -626,7 +625,7 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
|||
|
||||
// angles
|
||||
// show 1/3 the pitch angle and all the roll angle
|
||||
if( clent->v.deadflag != DEAD_DEAD )
|
||||
if( clent->v.deadflag < DEAD_DEAD )
|
||||
{
|
||||
if( !clent->v.fixangle )
|
||||
{
|
||||
|
|
|
@ -28,15 +28,6 @@ solid_edge items only clip against bsp models.
|
|||
#define MOVE_EPSILON 0.01
|
||||
#define MAX_CLIP_PLANES 5
|
||||
|
||||
typedef struct
|
||||
{
|
||||
edict_t *ent;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
} pushed_t;
|
||||
|
||||
pushed_t sv_pushed[MAX_EDICTS];
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -51,28 +42,13 @@ SV_TestEntityPosition
|
|||
returns true if the entity is in solid currently
|
||||
============
|
||||
*/
|
||||
bool SV_TestEntityPosition( edict_t *ent, const vec3_t offset )
|
||||
bool SV_TestEntityPosition( edict_t *ent )
|
||||
{
|
||||
vec3_t org;
|
||||
trace_t trace;
|
||||
|
||||
VectorAdd( ent->v.origin, offset, org );
|
||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL|FMOVE_SIMPLEBOX, ent );
|
||||
|
||||
if( ent->v.flags & ( FL_CLIENT|FL_FAKECLIENT ))
|
||||
{
|
||||
// player can crouch, noclip etc
|
||||
if( SV_TestPlayerPosition( org, ent, NULL ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
trace = SV_Move( org, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NOMONSTERS, ent );
|
||||
if( trace.fStartSolid ) return true;
|
||||
|
||||
// if the trace found a better position for the entity, move it there
|
||||
if( VectorDistance2( trace.vecEndPos, ent->v.origin ) >= 0.0001f )
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
return false;
|
||||
return trace.fStartSolid;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -105,7 +81,7 @@ void SV_CheckAllEnts( void )
|
|||
break;
|
||||
}
|
||||
|
||||
if( SV_TestEntityPosition( e, vec3_origin ))
|
||||
if( SV_TestEntityPosition( e ))
|
||||
MsgDev( D_INFO, "Stuck entity %s\n", SV_ClassName( e ));
|
||||
}
|
||||
}
|
||||
|
@ -383,7 +359,7 @@ bool SV_CheckWater( edict_t *ent )
|
|||
|
||||
ent->v.waterlevel = 0;
|
||||
ent->v.watertype = CONTENTS_EMPTY;
|
||||
cont = SV_PointContents( point );
|
||||
cont = SV_TruePointContents( point );
|
||||
|
||||
if( cont <= CONTENTS_WATER )
|
||||
{
|
||||
|
@ -724,185 +700,35 @@ trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int
|
|||
return trace;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
SV_Push
|
||||
|
||||
Objects need to be moved back on a failed push,
|
||||
otherwise riders would continue to slide.
|
||||
============
|
||||
*/
|
||||
void SV_PushAngles( edict_t *pusher, float movetime )
|
||||
static bool SV_CanPushed( edict_t *ent )
|
||||
{
|
||||
int i, e, block;
|
||||
edict_t *check;
|
||||
vec3_t mins, maxs, move, amove;
|
||||
float oldsolid;
|
||||
pushed_t *p, *pushed_p;
|
||||
vec3_t org, org2, move2, forward, right, up;
|
||||
|
||||
if( VectorIsNull( pusher->v.velocity ) && VectorIsNull( pusher->v.avelocity ))
|
||||
// filter movetypes to collide with
|
||||
switch( ent->v.movetype )
|
||||
{
|
||||
// advances ltime when stop too for thinking
|
||||
pusher->v.ltime += movetime;
|
||||
return;
|
||||
case MOVETYPE_NONE:
|
||||
case MOVETYPE_PUSH:
|
||||
case MOVETYPE_FOLLOW:
|
||||
case MOVETYPE_NOCLIP:
|
||||
case MOVETYPE_COMPOUND:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
move[i] = pusher->v.velocity[i] * movetime;
|
||||
amove[i] = pusher->v.avelocity[i] * movetime;
|
||||
mins[i] = pusher->v.absmin[i] + move[i];
|
||||
maxs[i] = pusher->v.absmax[i] + move[i];
|
||||
}
|
||||
static bool SV_CanBlock( edict_t *ent )
|
||||
{
|
||||
if( ent->v.solid == SOLID_NOT || ent->v.solid == SOLID_TRIGGER )
|
||||
return false;
|
||||
|
||||
pushed_p = sv_pushed;
|
||||
// deadbody
|
||||
if( ent->v.deadflag >= DEAD_DEAD )
|
||||
return false;
|
||||
|
||||
// getting real bbox size
|
||||
SV_TransformedBBox( pusher, mins, maxs );
|
||||
// point entities never block push
|
||||
if( VectorCompare( ent->v.mins, ent->v.maxs ))
|
||||
return false;
|
||||
|
||||
// we need this for pushing things later
|
||||
VectorNegate( amove, org );
|
||||
AngleVectors( org, forward, right, up );
|
||||
|
||||
// save the pusher's original position
|
||||
pushed_p->ent = pusher;
|
||||
VectorCopy( pusher->v.origin, pushed_p->origin );
|
||||
VectorCopy( pusher->v.angles, pushed_p->angles );
|
||||
pushed_p++;
|
||||
|
||||
// move the pusher to it's final position
|
||||
VectorAdd( pusher->v.origin, move, pusher->v.origin );
|
||||
VectorAdd( pusher->v.angles, amove, pusher->v.angles );
|
||||
pusher->v.ltime += movetime;
|
||||
SV_LinkEdict( pusher, false );
|
||||
|
||||
// see if any solid entities are inside the final position
|
||||
for( e = 1; e < svgame.globals->numEntities; e++ )
|
||||
{
|
||||
check = EDICT_NUM( e );
|
||||
if ( check->free ) continue;
|
||||
|
||||
// filter movetypes to collide with
|
||||
switch( check->v.movetype )
|
||||
{
|
||||
case MOVETYPE_NONE:
|
||||
case MOVETYPE_PUSH:
|
||||
case MOVETYPE_FOLLOW:
|
||||
case MOVETYPE_NOCLIP:
|
||||
case MOVETYPE_COMPOUND:
|
||||
continue;
|
||||
default: break;
|
||||
}
|
||||
|
||||
oldsolid = pusher->v.solid;
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
block = SV_TestEntityPosition( check, vec3_origin );
|
||||
pusher->v.solid = oldsolid;
|
||||
if( block ) continue;
|
||||
|
||||
// if the entity is standing on the pusher, it will definitely be moved
|
||||
if(!( check->v.flags & FL_ONGROUND && check->v.groundentity == pusher ))
|
||||
{
|
||||
// see if the ent needs to be tested
|
||||
if( check->v.absmin[0] >= maxs[0]
|
||||
|| check->v.absmin[1] >= maxs[1]
|
||||
|| check->v.absmin[2] >= maxs[2]
|
||||
|| check->v.absmax[0] <= mins[0]
|
||||
|| check->v.absmax[1] <= mins[1]
|
||||
|| check->v.absmax[2] <= mins[2] )
|
||||
continue;
|
||||
}
|
||||
|
||||
if(( pusher->v.movetype == MOVETYPE_PUSH ) || ( check->v.groundentity == pusher ))
|
||||
{
|
||||
// move this entity
|
||||
pushed_p->ent = check;
|
||||
VectorCopy( check->v.origin, pushed_p->origin );
|
||||
VectorCopy( check->v.angles, pushed_p->angles );
|
||||
pushed_p++;
|
||||
|
||||
// try moving the contacted entity
|
||||
VectorAdd( check->v.origin, move, check->v.origin );
|
||||
VectorAdd( check->v.angles, amove, check->v.angles);
|
||||
|
||||
if( check->v.flags & FL_CLIENT )
|
||||
{
|
||||
sv_client_t *cl;
|
||||
|
||||
if(( cl = SV_ClientFromEdict( check, true )) != NULL )
|
||||
{
|
||||
// Because we can run multiple ticks per server frame,
|
||||
// accumulate a total offset here instead of straight
|
||||
// setting it. The engine will reset anglechange to 0
|
||||
// when the message is actually sent to the client
|
||||
cl->anglechangetotal += amove[1];
|
||||
cl->anglechangefinal = amove[1];
|
||||
check->v.fixangle = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// figure movement due to the pusher's amove
|
||||
VectorSubtract( check->v.origin, pusher->v.origin, org );
|
||||
org2[0] = DotProduct( org, forward );
|
||||
org2[1] = -DotProduct( org, right );
|
||||
org2[2] = DotProduct( org, up );
|
||||
VectorSubtract( org2, org, move2 );
|
||||
VectorAdd( check->v.origin, move2, check->v.origin );
|
||||
|
||||
check->v.flags &= ~FL_ONGROUND;
|
||||
|
||||
// may have pushed them off an edge
|
||||
if( check->v.groundentity != pusher )
|
||||
check->v.groundentity = 0;
|
||||
|
||||
block = SV_TestEntityPosition( check, vec3_origin );
|
||||
if( !block )
|
||||
{
|
||||
// pushed ok
|
||||
SV_LinkEdict( check, false );
|
||||
// impact?
|
||||
continue;
|
||||
}
|
||||
|
||||
// if it is ok to leave in the old position, do it
|
||||
// this is only relevent for riding entities, not pushed
|
||||
// FIXME: this doesn't acount for rotation
|
||||
VectorSubtract( check->v.origin, move, check->v.origin );
|
||||
block = SV_TestEntityPosition( check, vec3_origin );
|
||||
if( !block )
|
||||
{
|
||||
pushed_p--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if it is sitting on top. Do not block.
|
||||
if( check->v.mins[0] == check->v.maxs[0] )
|
||||
{
|
||||
SV_LinkEdict( check, false );
|
||||
continue;
|
||||
}
|
||||
|
||||
svgame.globals->time = (sv.time * 0.001f);
|
||||
svgame.dllFuncs.pfnBlocked( pusher, check );
|
||||
|
||||
// move back any entities we already moved
|
||||
// go backwards, so if the same entity was pushed
|
||||
// twice, it goes back to the original position
|
||||
for( p = pushed_p - 1; p >= sv_pushed; p-- )
|
||||
{
|
||||
VectorCopy( p->origin, p->ent->v.origin );
|
||||
VectorCopy( p->angles, p->ent->v.angles );
|
||||
SV_LinkEdict( p->ent, false );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: is there a better way to handle this?
|
||||
// see if anything we moved has touched a trigger
|
||||
for( p = pushed_p - 1; p >= sv_pushed; p-- )
|
||||
SV_TouchLinks( p->ent, sv_areanodes );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -911,16 +737,258 @@ SV_PushMove
|
|||
|
||||
============
|
||||
*/
|
||||
void SV_PushMove( edict_t *pusher, float movetime )
|
||||
static edict_t *SV_PushMove( edict_t *pusher, float movetime )
|
||||
{
|
||||
int i, e, block;
|
||||
int num_moved, oldsolid;
|
||||
vec3_t mins, maxs, lmove;
|
||||
vec3_t entorg, pushorg;
|
||||
edict_t *check, *moved_edict[MAX_EDICTS];
|
||||
|
||||
if( VectorIsNull( pusher->v.velocity ))
|
||||
{
|
||||
pusher->v.ltime += movetime;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
lmove[i] = pusher->v.velocity[i] * movetime;
|
||||
mins[i] = pusher->v.absmin[i] + lmove[i];
|
||||
maxs[i] = pusher->v.absmax[i] + lmove[i];
|
||||
}
|
||||
|
||||
VectorCopy( pusher->v.origin, pushorg );
|
||||
|
||||
// move the pusher to it's final position
|
||||
SV_LinearMove( pusher, movetime, pusher->v.friction );
|
||||
SV_LinkEdict( pusher, false );
|
||||
pusher->v.ltime += movetime;
|
||||
oldsolid = pusher->v.solid;
|
||||
|
||||
// see if any solid entities are inside the final position
|
||||
num_moved = 0;
|
||||
for( e = 1; e < svgame.globals->numEntities; e++ )
|
||||
{
|
||||
check = EDICT_NUM( e );
|
||||
if( !SV_IsValidEdict( check )) continue;
|
||||
|
||||
// filter movetypes to collide with
|
||||
if( !SV_CanPushed( check ))
|
||||
continue;
|
||||
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
block = SV_TestEntityPosition( check );
|
||||
pusher->v.solid = oldsolid;
|
||||
if( block ) continue;
|
||||
|
||||
// if the entity is standing on the pusher, it will definately be moved
|
||||
if( !(( check->v.flags & FL_ONGROUND ) && check->v.groundentity == pusher ))
|
||||
{
|
||||
if( check->v.absmin[0] >= maxs[0]
|
||||
|| check->v.absmin[1] >= maxs[1]
|
||||
|| check->v.absmin[2] >= maxs[2]
|
||||
|| check->v.absmax[0] <= mins[0]
|
||||
|| check->v.absmax[1] <= mins[1]
|
||||
|| check->v.absmax[2] <= mins[2] )
|
||||
continue;
|
||||
|
||||
// see if the ent's bbox is inside the pusher's final position
|
||||
if( !SV_TestEntityPosition( check ))
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy( check->v.origin, entorg );
|
||||
VectorCopy( check->v.origin, check->pvServerData->moved_origin );
|
||||
moved_edict[num_moved] = check;
|
||||
num_moved++;
|
||||
|
||||
// try moving the contacted entity
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
SV_PushEntity( check, lmove, vec3_origin, &block );
|
||||
pusher->v.solid = oldsolid;
|
||||
|
||||
// if it is still inside the pusher, block
|
||||
if( block || SV_TestEntityPosition( check ))
|
||||
{
|
||||
if( !SV_CanBlock( check ))
|
||||
continue;
|
||||
|
||||
// fail the move
|
||||
VectorCopy( entorg, check->v.origin );
|
||||
SV_LinkEdict( check, true );
|
||||
|
||||
VectorCopy( pushorg, pusher->v.origin );
|
||||
SV_LinkEdict( pusher, false );
|
||||
pusher->v.ltime -= movetime;
|
||||
|
||||
// move back any entities we already moved
|
||||
for( i = 0; i < num_moved; i++ )
|
||||
{
|
||||
edict_t *ed = moved_edict[i];
|
||||
|
||||
VectorCopy( ed->pvServerData->moved_origin, ed->v.origin );
|
||||
SV_LinkEdict( ed, false );
|
||||
}
|
||||
return check;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if leaving it where it was, allow it to drop to the floor again
|
||||
// (useful for plats that move downward)
|
||||
check->v.flags &= ~FL_ONGROUND;
|
||||
check->v.groundentity = NULL;
|
||||
|
||||
num_moved--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
SV_PushRotate
|
||||
|
||||
============
|
||||
*/
|
||||
static edict_t *SV_PushRotate( edict_t *pusher, float movetime )
|
||||
{
|
||||
int i, e, block;
|
||||
int num_moved, oldsolid;
|
||||
vec3_t lmove, a, amove, entorg, pushang;
|
||||
edict_t *check, *moved_edict[MAX_EDICTS];
|
||||
vec3_t forward, right, up;
|
||||
vec3_t org, org2;
|
||||
|
||||
if( VectorIsNull( pusher->v.avelocity ))
|
||||
{
|
||||
pusher->v.ltime += movetime;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
amove[i] = pusher->v.avelocity[i] * movetime;
|
||||
|
||||
VectorNegate( amove, a );
|
||||
AngleVectors( a, forward, right, up );
|
||||
|
||||
VectorCopy( pusher->v.angles, pushang );
|
||||
|
||||
// move the pusher to it's final position
|
||||
SV_AngularMove( pusher, movetime, pusher->v.friction );
|
||||
SV_LinkEdict( pusher, false );
|
||||
pusher->v.ltime += movetime;
|
||||
oldsolid = pusher->v.solid;
|
||||
|
||||
// see if any solid entities are inside the final position
|
||||
num_moved = 0;
|
||||
for( e = 1; e < svgame.globals->numEntities; e++ )
|
||||
{
|
||||
check = EDICT_NUM( e );
|
||||
if( !SV_IsValidEdict( check )) continue;
|
||||
|
||||
// filter movetypes to collide with
|
||||
if( !SV_CanPushed( check ))
|
||||
continue;
|
||||
|
||||
// if the entity is standing on the pusher, it will definately be moved
|
||||
if( !(( check->v.flags & FL_ONGROUND ) && check->v.groundentity == pusher ))
|
||||
{
|
||||
|
||||
if( check->v.absmin[0] >= pusher->v.absmax[0]
|
||||
|| check->v.absmin[1] >= pusher->v.absmax[1]
|
||||
|| check->v.absmin[2] >= pusher->v.absmax[2]
|
||||
|| check->v.absmax[0] <= pusher->v.absmin[0]
|
||||
|| check->v.absmax[1] <= pusher->v.absmin[1]
|
||||
|| check->v.absmax[2] <= pusher->v.absmin[2] )
|
||||
continue;
|
||||
|
||||
// see if the ent's bbox is inside the pusher's final position
|
||||
if( !SV_TestEntityPosition( check ))
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy( check->v.origin, entorg );
|
||||
VectorCopy( check->v.origin, check->pvServerData->moved_origin );
|
||||
VectorCopy( check->v.angles, check->pvServerData->moved_angles );
|
||||
moved_edict[num_moved] = check;
|
||||
num_moved++;
|
||||
|
||||
// calculate destination position
|
||||
VectorSubtract( check->v.origin, pusher->v.origin, org );
|
||||
org2[0] = DotProduct( org, forward );
|
||||
org2[1] = -DotProduct( org, right );
|
||||
org2[2] = DotProduct( org, up );
|
||||
VectorSubtract( org2, org, lmove );
|
||||
|
||||
// try moving the contacted entity
|
||||
#if 0
|
||||
VectorAdd( check->v.angles, amove, check->v.angles );
|
||||
VectorAdd( check->v.origin, lmove, check->v.origin );
|
||||
block = false;
|
||||
#else
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
SV_PushEntity( check, lmove, amove, &block );
|
||||
pusher->v.solid = oldsolid;
|
||||
#endif
|
||||
// if it is still inside the pusher, block
|
||||
if( block || SV_TestEntityPosition( check ))
|
||||
{
|
||||
if( !SV_CanBlock( check ))
|
||||
continue;
|
||||
|
||||
// fail the move
|
||||
VectorCopy( entorg, check->v.origin );
|
||||
SV_LinkEdict( check, true );
|
||||
|
||||
VectorCopy( pushang, pusher->v.angles );
|
||||
SV_LinkEdict( pusher, false );
|
||||
pusher->v.ltime -= movetime;
|
||||
|
||||
// move back any entities we already moved
|
||||
for( i = 0; i < num_moved; i++ )
|
||||
{
|
||||
edict_t *ed = moved_edict[i];
|
||||
sv_client_t *cl;
|
||||
|
||||
if( ed->v.flags & FL_CLIENT && ( cl = SV_ClientFromEdict( ed, true )) != NULL )
|
||||
{
|
||||
cl->anglechangetotal = cl->anglechangefinal = 0.0f;
|
||||
ed->v.fixangle = 0;
|
||||
}
|
||||
|
||||
VectorCopy( ed->pvServerData->moved_origin, ed->v.origin );
|
||||
VectorCopy( ed->pvServerData->moved_angles, ed->v.angles );
|
||||
SV_LinkEdict( ed, false );
|
||||
}
|
||||
return check;
|
||||
}
|
||||
else
|
||||
{
|
||||
SV_AngularMove( check, movetime, pusher->v.friction );
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
SV_PushComplex
|
||||
|
||||
============
|
||||
*/
|
||||
void SV_PushComplex( edict_t *pusher, float movetime )
|
||||
{
|
||||
int i, e, oldsolid, num_moved;
|
||||
vec3_t a, lmove, amove, org, org2, move2;
|
||||
vec3_t forward, right, up, pushorg, pushang;
|
||||
vec3_t forward, right, up, pushorg, pushang, test;
|
||||
edict_t *check, *pusherowner, *moved_edict[MAX_EDICTS];
|
||||
bool rotated, blocked;
|
||||
vec3_t mins, maxs;
|
||||
float pushltime;
|
||||
trace_t trace;
|
||||
chull_t *hull;
|
||||
|
||||
switch( pusher->v.solid )
|
||||
{
|
||||
|
@ -966,7 +1034,7 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
|||
pushltime = pusher->v.ltime;
|
||||
|
||||
// getting real bbox size
|
||||
SV_TransformedBBox( pusher, mins, maxs );
|
||||
// SV_TransformedBBox( pusher, mins, maxs );
|
||||
|
||||
// move the pusher to it's final position
|
||||
SV_LinearMove( pusher, movetime, pusher->v.friction );
|
||||
|
@ -1000,10 +1068,22 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
|||
if( pusherowner == check )
|
||||
continue;
|
||||
|
||||
// if the entity is standing on the pusher, it will definitely be moved
|
||||
// if the entity is standing on the pusher, it will definately be moved
|
||||
if( !(( check->v.flags & FL_ONGROUND ) && check->v.groundentity == pusher ))
|
||||
{
|
||||
// see if the ent needs to be tested
|
||||
if( !BoundsIntersect( check->v.absmin, check->v.absmax, mins, maxs ))
|
||||
continue;
|
||||
|
||||
hull = CM_HullForBsp( pusher, check->v.mins, check->v.maxs, test );
|
||||
|
||||
// offset the test point appropriately for this hull.
|
||||
VectorSubtract( check->v.origin, test, test );
|
||||
|
||||
// test hull for intersection with this model
|
||||
if( CM_HullPointContents( hull, hull->firstclipnode, test ) == CONTENTS_EMPTY )
|
||||
continue;
|
||||
/*
|
||||
if( check->v.absmin[0] >= maxs[0]
|
||||
|| check->v.absmin[1] >= maxs[1]
|
||||
|| check->v.absmin[2] >= maxs[2]
|
||||
|
@ -1011,11 +1091,10 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
|||
|| check->v.absmax[1] <= mins[1]
|
||||
|| check->v.absmax[2] <= mins[2] )
|
||||
continue;
|
||||
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
trace = CM_ClipMove( pusher, check->v.origin, check->v.mins, check->v.maxs, check->v.origin, FMOVE_SIMPLEBOX );
|
||||
pusher->v.solid = oldsolid; // was SOLID_BSP
|
||||
if( !trace.fStartSolid ) continue; // not touched
|
||||
*/
|
||||
// see if the ent's bbox is inside the pusher's final position
|
||||
// if( !SV_TestEntityPosition( check ))
|
||||
// continue;
|
||||
}
|
||||
|
||||
VectorCopy( check->v.origin, check->pvServerData->moved_origin );
|
||||
|
@ -1052,13 +1131,13 @@ void SV_PushMove( edict_t *pusher, float movetime )
|
|||
check->v.flags &= ~FL_ONGROUND;
|
||||
|
||||
// if it is still inside the pusher, block
|
||||
if( blocked || SV_TestEntityPosition( check, vec3_origin ))
|
||||
if( blocked || SV_TestEntityPosition( check ))
|
||||
{
|
||||
// fail the move
|
||||
if( check->v.mins[0] == check->v.maxs[0] )
|
||||
continue;
|
||||
|
||||
if( check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER || check->v.deadflag == DEAD_DEAD )
|
||||
if( check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER || check->v.deadflag >= DEAD_DEAD )
|
||||
{
|
||||
// corpse
|
||||
check->v.mins[0] = check->v.mins[1] = 0;
|
||||
|
@ -1107,36 +1186,70 @@ SV_Physics_Pusher
|
|||
*/
|
||||
void SV_Physics_Pusher( edict_t *ent )
|
||||
{
|
||||
float thinktime;
|
||||
float oldltime;
|
||||
float movetime;
|
||||
float oldtime, oldtime2;
|
||||
float thinktime, movetime;
|
||||
edict_t *pBlocker;
|
||||
|
||||
oldltime = ent->v.ltime;
|
||||
pBlocker = NULL;
|
||||
oldtime = ent->v.ltime;
|
||||
thinktime = ent->v.nextthink;
|
||||
|
||||
if( thinktime < ent->v.ltime + ( sv.frametime * 0.001f ))
|
||||
if( thinktime < ent->v.ltime + svgame.globals->frametime )
|
||||
{
|
||||
movetime = thinktime - ent->v.ltime;
|
||||
if( movetime < 0.0f ) movetime = 0.0f;
|
||||
}
|
||||
else movetime = (sv.frametime * 0.001f);
|
||||
else movetime = svgame.globals->frametime;
|
||||
|
||||
if( movetime )
|
||||
{
|
||||
SV_PushMove( ent, movetime ); // advances ent->v.ltime if not blocked
|
||||
if( VectorLength2( ent->v.avelocity ) > STOP_EPSILON )
|
||||
{
|
||||
if( VectorLength2( ent->v.velocity ) > STOP_EPSILON )
|
||||
{
|
||||
pBlocker = SV_PushRotate( ent, movetime );
|
||||
|
||||
if( !pBlocker )
|
||||
{
|
||||
oldtime2 = ent->v.ltime;
|
||||
|
||||
// reset the local time to what it was before we rotated
|
||||
ent->v.ltime = oldtime;
|
||||
pBlocker = SV_PushMove( ent, movetime );
|
||||
if( ent->v.ltime < oldtime2 )
|
||||
ent->v.ltime = oldtime2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pBlocker = SV_PushRotate( ent, movetime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pBlocker = SV_PushMove( ent, movetime );
|
||||
}
|
||||
}
|
||||
|
||||
if( thinktime > oldltime && thinktime <= ent->v.ltime )
|
||||
// if the pusher has a "blocked" function, call it
|
||||
// otherwise, just stay in place until the obstacle is gone
|
||||
if( pBlocker )
|
||||
{
|
||||
Msg( "%s is blocked by %s\n", SV_ClassName( ent ), SV_ClassName( pBlocker ));
|
||||
svgame.dllFuncs.pfnBlocked( ent, pBlocker );
|
||||
}
|
||||
|
||||
if( thinktime > oldtime && thinktime <= ent->v.ltime )
|
||||
{
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = (sv.time * 0.001f);
|
||||
svgame.globals->time = svgame.globals->time;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
if( ent->free ) return;
|
||||
}
|
||||
else if( ent->v.flags & FL_ALWAYSTHINK )
|
||||
{
|
||||
ent->v.nextthink = 0;
|
||||
svgame.globals->time = (sv.time * 0.001f);
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = svgame.globals->time;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -947,6 +947,14 @@ int SV_LoadGameState( char const *level, bool createPlayers )
|
|||
|
||||
SV_ConfigString( CS_SKYNAME, header.skyName );
|
||||
|
||||
// restore sky parms
|
||||
Cvar_SetValue( "sv_skycolor_r", header.skyColor_r );
|
||||
Cvar_SetValue( "sv_skycolor_g", header.skyColor_g );
|
||||
Cvar_SetValue( "sv_skycolor_b", header.skyColor_b );
|
||||
Cvar_SetValue( "sv_skyvec_x", header.skyVec_x );
|
||||
Cvar_SetValue( "sv_skyvec_y", header.skyVec_y );
|
||||
Cvar_SetValue( "sv_skyvec_z", header.skyVec_z );
|
||||
|
||||
// re-base the savedata since we re-ordered the entity/table / restore fields
|
||||
SaveRestore_Rebase( pSaveData );
|
||||
|
||||
|
@ -1467,7 +1475,8 @@ bool SV_LoadGame( const char *pName )
|
|||
|
||||
if( !validload )
|
||||
{
|
||||
CL_Disconnect();
|
||||
com.snprintf( host.finalmsg, MAX_STRING, "Couldn't load %s.sav\n", pName );
|
||||
SV_Shutdown( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -380,7 +380,7 @@ static void SV_ClipToLinks( areanode_t *node, moveclip_t *clip )
|
|||
{
|
||||
vec3_t point;
|
||||
|
||||
// we can ignore brushes with rendermode != kRenderNormal
|
||||
// we ignore brushes with rendermode != kRenderNormal
|
||||
switch( touch->v.rendermode )
|
||||
{
|
||||
case kRenderTransTexture:
|
||||
|
@ -587,12 +587,8 @@ edict_t *SV_TestPlayerPosition( const vec3_t origin, edict_t *pass, TraceResult
|
|||
mins = svgame.pmove->player_mins[svgame.pmove->usehull];
|
||||
maxs = svgame.pmove->player_maxs[svgame.pmove->usehull];
|
||||
|
||||
if( pass ) SV_SetMinMaxSize( pass, mins, maxs );
|
||||
|
||||
result = SV_Move( origin, mins, maxs, origin, MOVE_NORMAL, pass );
|
||||
if( tr ) *tr = result;
|
||||
|
||||
if( result.pHit )
|
||||
return result.pHit;
|
||||
return NULL;
|
||||
return result.pHit;
|
||||
}
|
|
@ -4053,6 +4053,7 @@ wfile_t *W_Open( const char *filename, const char *mode )
|
|||
hdr.numlumps = LittleLong( wad->numlumps );
|
||||
hdr.infotableofs = LittleLong(sizeof( dwadinfo_t ));
|
||||
FS_Write( wad->file, &hdr, sizeof( hdr ));
|
||||
FS_Print( wad->file, "Generated by Xash WadLib. " );
|
||||
wad->infotableofs = FS_Tell( wad->file );
|
||||
}
|
||||
else if( mode[0] == 'r' || mode[0] == 'a' )
|
||||
|
@ -4081,7 +4082,8 @@ wfile_t *W_Open( const char *filename, const char *mode )
|
|||
wad->mode = O_RDONLY; // set read-only mode
|
||||
}
|
||||
break;
|
||||
case IDWAD3HEADER: break; // WAD3 allow r\w mode
|
||||
case IDWAD3HEADER:
|
||||
break; // WAD3 allow r\w mode
|
||||
default:
|
||||
MsgDev( D_ERROR, "W_Open: %s unknown wadtype\n", filename );
|
||||
W_Close( wad );
|
||||
|
|
|
@ -893,6 +893,7 @@ console variables
|
|||
#define Cvar_Set com.Cvar_SetString
|
||||
#define Cvar_FullSet com.Cvar_FullSet
|
||||
#define Cvar_SetLatched com.Cvar_SetLatched
|
||||
#define Cvar_Reset( name ) Cvar_SetLatched( name, NULL )
|
||||
#define Cvar_SetValue com.Cvar_SetValue
|
||||
#define Cvar_VariableValue com.Cvar_GetValue
|
||||
#define Cvar_VariableInteger com.Cvar_GetInteger
|
||||
|
|
|
@ -356,6 +356,7 @@ class CFuncConveyor : public CBaseBrush
|
|||
public:
|
||||
void Spawn( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void UpdateSpeed( float speed );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( func_conveyor, CFuncConveyor );
|
||||
|
||||
|
@ -382,6 +383,21 @@ void CFuncConveyor :: Spawn( void )
|
|||
Use( this, this, USE_ON, 0 );
|
||||
}
|
||||
|
||||
// HACKHACK -- This is ugly, but encode the speed in the rendercolor to avoid adding more data to the network stream
|
||||
void CFuncConveyor :: UpdateSpeed( float speed )
|
||||
{
|
||||
// Encode it as an integer with 4 fractional bits
|
||||
int speedCode = (int)(fabs(speed) * 16.0);
|
||||
|
||||
if ( speed < 0 )
|
||||
pev->rendercolor.x = 1;
|
||||
else
|
||||
pev->rendercolor.x = 0;
|
||||
|
||||
pev->rendercolor.y = (speedCode >> 8);
|
||||
pev->rendercolor.z = (speedCode & 0xFF);
|
||||
}
|
||||
|
||||
void CFuncConveyor :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
m_hActivator = pActivator;
|
||||
|
@ -397,6 +413,7 @@ void CFuncConveyor :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY
|
|||
if( useType == USE_ON )
|
||||
{
|
||||
pev->speed = pev->frags; // restore speed
|
||||
UpdateSpeed( pev->speed );
|
||||
UTIL_FireTargets( pev->target, this, this, USE_ON, pev->speed );
|
||||
if(!( pev->spawnflags & SF_NOTSOLID )) // don't push
|
||||
pev->solid = SOLID_BSP;
|
||||
|
@ -405,6 +422,7 @@ void CFuncConveyor :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY
|
|||
else if( useType == USE_OFF )
|
||||
{
|
||||
pev->speed = 0.0f;
|
||||
UpdateSpeed( pev->speed );
|
||||
UTIL_FireTargets( pev->target, this, this, USE_OFF, pev->speed );
|
||||
pev->solid = SOLID_NOT;
|
||||
m_iState = STATE_OFF;
|
||||
|
@ -413,7 +431,11 @@ void CFuncConveyor :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY
|
|||
{
|
||||
if( value != 0.0f ) pev->frags = value; // set new speed ( can be negative )
|
||||
else pev->frags = -pev->frags; // just reverse
|
||||
if( m_iState == STATE_ON ) pev->speed = pev->frags;
|
||||
if( m_iState == STATE_ON )
|
||||
{
|
||||
pev->speed = pev->frags;
|
||||
UpdateSpeed( pev->speed );
|
||||
}
|
||||
}
|
||||
else if( useType == USE_RESET ) // restore default speed
|
||||
{
|
||||
|
|
|
@ -1053,7 +1053,7 @@ int AutoClassify( edict_t *pentToClassify )
|
|||
return ED_RIGIDBODY;
|
||||
else if ( pClass->pev->solid == SOLID_BSP )
|
||||
{
|
||||
if ( pClass->pev->movetype == MOVETYPE_CONVEYOR )
|
||||
if ( pClass->pev->flags & FL_CONVEYOR )
|
||||
return ED_MOVER;
|
||||
else if ( pClass->pev->flags & FL_WORLDBRUSH )
|
||||
return ED_BSPBRUSH;
|
||||
|
@ -1066,6 +1066,8 @@ int AutoClassify( edict_t *pentToClassify )
|
|||
return ED_MONSTER;
|
||||
else if ( pClass->pev->flags & FL_CLIENT )
|
||||
return ED_CLIENT;
|
||||
else if ( pClass->pev->flags & FL_CONVEYOR )
|
||||
return ED_MOVER;
|
||||
else if ( !pClass->pev->modelindex && !pClass->pev->aiment )
|
||||
{
|
||||
if ( pClass->pev->noise || pClass->pev->noise1 || pClass->pev->noise2 || pClass->pev->noise3 )
|
||||
|
@ -1744,5 +1746,5 @@ void InitWorld( void )
|
|||
else ALERT( at_console, "\n*Graph Loaded!\n" );
|
||||
}
|
||||
|
||||
CVAR_SET_FLOAT( "sv_zmax", MAP_SIZE );
|
||||
CVAR_SET_FLOAT( "sv_zmax", 0 ); // let the renderer calculate optimal value
|
||||
}
|
|
@ -1021,7 +1021,7 @@ int AutoClassify( edict_t *pentToClassify )
|
|||
return ED_RIGIDBODY;
|
||||
else if ( pClass->pev->solid == SOLID_BSP )
|
||||
{
|
||||
if ( pClass->pev->movetype == MOVETYPE_CONVEYOR )
|
||||
if ( pClass->pev->flags & FL_CONVEYOR )
|
||||
return ED_MOVER;
|
||||
else if ( pClass->pev->flags & FL_WORLDBRUSH )
|
||||
return ED_BSPBRUSH;
|
||||
|
@ -1034,6 +1034,8 @@ int AutoClassify( edict_t *pentToClassify )
|
|||
return ED_MONSTER;
|
||||
else if ( pClass->pev->flags & FL_CLIENT )
|
||||
return ED_CLIENT;
|
||||
else if ( pClass->pev->flags & FL_CONVEYOR )
|
||||
return ED_MOVER;
|
||||
else if ( !pClass->pev->modelindex && !pClass->pev->aiment )
|
||||
{
|
||||
if ( pClass->pev->noise || pClass->pev->noise1 || pClass->pev->noise2 || pClass->pev->noise3 )
|
||||
|
|
|
@ -632,7 +632,7 @@ void CWorld :: Precache( void )
|
|||
if ( pev->speed > 0 )
|
||||
CVAR_SET_FLOAT( "sv_zmax", pev->speed );
|
||||
else
|
||||
CVAR_SET_FLOAT( "sv_zmax", 4096 );
|
||||
CVAR_SET_FLOAT( "sv_zmax", 0 ); // let the renderer calculate optimal value
|
||||
|
||||
if ( pev->netname )
|
||||
{
|
||||
|
|
|
@ -643,6 +643,9 @@ void R_DeformVertices( void )
|
|||
args[2] = deformv->func.args[2] + deformv->func.args[3] * r_currentShaderTime;
|
||||
args[3] = deformv->args[0];
|
||||
|
||||
if( args[1] == 0.0f )
|
||||
args[1] = RI.currententity->waveHeight;
|
||||
|
||||
for( j = 0; j < r_backacc.numVerts; j++ )
|
||||
{
|
||||
temp = args[2] + args[3] * ( inVertsArray[j][0] + inVertsArray[j][1] + inVertsArray[j][2] );
|
||||
|
@ -1053,12 +1056,13 @@ static bool R_VertexTCBase( const ref_stage_t *pass, int unit, matrix4x4 matrix
|
|||
return false;
|
||||
}
|
||||
case TCGEN_WARP:
|
||||
for( i = 0; r_currentShader->tessSize != 0.0f && i < r_backacc.numVerts; i++ )
|
||||
outCoords = tUnitCoordsArray[unit][0];
|
||||
for( i = 0; r_currentShader->tessSize != 0.0f && i < r_backacc.numVerts; i++, outCoords += 2 )
|
||||
{
|
||||
coordsArray[i][0] += r_warpsintable[((int)((inCoordsArray[i][1] * 8.0 + r_currentShaderTime) * (256.0/M_PI2))) & 255] * (1.0 / r_currentShader->tessSize );
|
||||
coordsArray[i][1] += r_warpsintable[((int)((inCoordsArray[i][0] * 8.0 + r_currentShaderTime) * (256.0/M_PI2))) & 255] * (1.0 / r_currentShader->tessSize );
|
||||
outCoords[0] = inCoordsArray[i][0] + r_warpsintable[((int)((inCoordsArray[i][1] * 8.0f + r_currentShaderTime) * (256.0/M_PI2))) & 255] * (1.0f / r_currentShader->tessSize );
|
||||
outCoords[1] = inCoordsArray[i][1] + r_warpsintable[((int)((inCoordsArray[i][0] * 8.0f + r_currentShaderTime) * (256.0/M_PI2))) & 255] * (1.0f / r_currentShader->tessSize );
|
||||
}
|
||||
R_UpdateVertexBuffer( tr.tcoordBuffer[unit], coordsArray, r_backacc.numVerts * sizeof( vec2_t ));
|
||||
R_UpdateVertexBuffer( tr.tcoordBuffer[unit], tUnitCoordsArray[unit], r_backacc.numVerts * sizeof( vec2_t ));
|
||||
pglTexCoordPointer( 2, GL_FLOAT, 0, tr.tcoordBuffer[unit]->pointer );
|
||||
return true;
|
||||
case TCGEN_REFLECTION_CELLSHADE:
|
||||
|
@ -1182,9 +1186,10 @@ R_ApplyTCMods
|
|||
static void R_ApplyTCMods( const ref_stage_t *pass, matrix4x4 result )
|
||||
{
|
||||
int i;
|
||||
double f, t1, t2, sint, cost;
|
||||
double t1, t2, sint, cost;
|
||||
matrix4x4 m1, m2;
|
||||
const tcMod_t *tcmod;
|
||||
float flConveyorSpeed, flRate, flAngle;
|
||||
waveFunc_t func;
|
||||
|
||||
for( i = 0, tcmod = pass->tcMods; i < pass->numtcMods; i++, tcmod++ )
|
||||
|
@ -1236,17 +1241,26 @@ static void R_ApplyTCMods( const ref_stage_t *pass, matrix4x4 result )
|
|||
Matrix4x4_Concat2D( result, m1, m2 );
|
||||
break;
|
||||
case TCMOD_CONVEYOR:
|
||||
if( RI.currententity->framerate == 0.0f ) return;
|
||||
f = (RI.currententity->framerate * r_currentShaderTime) * 0.0039; // magic number :-)
|
||||
t1 = RI.currententity->movedir[0];
|
||||
t2 = RI.currententity->movedir[1];
|
||||
flConveyorSpeed = (RI.currententity->rendercolor[1]<<8|RI.currententity->rendercolor[2]) / 16.0f;
|
||||
if( RI.currententity->rendercolor[0] ) flConveyorSpeed = -flConveyorSpeed;
|
||||
flRate = abs( flConveyorSpeed ) / (float)pass->textures[0]->srcWidth;
|
||||
flAngle = (flConveyorSpeed >= 0) ? 180 : 0;
|
||||
|
||||
t1 = f * t1;
|
||||
t1 -= floor( t1 );
|
||||
t2 = f * t2;
|
||||
t2 -= floor( t2 );
|
||||
t1 = r_currentShaderTime * com.cos( flAngle * ( M_PI / 180.0f )) * flRate;
|
||||
t2 = r_currentShaderTime * com.sin( flAngle * ( M_PI / 180.0f )) * flRate;
|
||||
|
||||
// make sure that we are positive
|
||||
if( t1 < 0.0f ) t1 += 1.0f + -floor( t1 );
|
||||
if( t2 < 0.0f ) t2 += 1.0f + -floor( t2 );
|
||||
|
||||
Matrix4x4_Translate2D( result, -t1, t2 );
|
||||
if( pass->program_type != PROGRAM_TYPE_DISTORTION )
|
||||
{
|
||||
// HACKHACK
|
||||
t1 = t1 - floor( t1 );
|
||||
t2 = t2 - floor( t2 );
|
||||
}
|
||||
|
||||
Matrix4x4_Translate2D( result, t1, t2 );
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
|
|
@ -299,7 +299,8 @@ static void R_ReadLightGrid( const vec3_t origin, vec3_t lightDir )
|
|||
|
||||
if( !r_worldbrushmodel->lightgrid )
|
||||
{
|
||||
VectorSet( lightDir, 1.0f, 0.0f, -1.0f );
|
||||
// pre-defined light vector
|
||||
VectorCopy( RI.refdef.skyVec, lightDir );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -246,6 +246,7 @@ typedef struct ref_entity_s
|
|||
vec3_t movedir; // forward vector that computed on a server
|
||||
vec3_t origin, origin2;
|
||||
vec3_t lightingOrigin;
|
||||
float waveHeight;
|
||||
|
||||
// RT_SPRITE stuff
|
||||
struct ref_shader_s *customShader; // client drawing stuff
|
||||
|
|
|
@ -903,11 +903,11 @@ static float R_FarClip( void )
|
|||
{
|
||||
float farclip_dist;
|
||||
|
||||
if( r_worldmodel && !( RI.refdef.flags & RDF_NOWORLDMODEL ) )
|
||||
if( r_worldmodel && !( RI.refdef.flags & RDF_NOWORLDMODEL ))
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
vec3_t tmp;
|
||||
int i;
|
||||
float dist;
|
||||
vec3_t tmp;
|
||||
|
||||
farclip_dist = 0;
|
||||
for( i = 0; i < 8; i++ )
|
||||
|
@ -920,7 +920,8 @@ static float R_FarClip( void )
|
|||
farclip_dist = max( farclip_dist, dist );
|
||||
}
|
||||
|
||||
farclip_dist = sqrt( farclip_dist );
|
||||
farclip_dist = com.sqrt( farclip_dist );
|
||||
farclip_dist = max( RI.refdef.zFar, farclip_dist );
|
||||
|
||||
if( r_worldbrushmodel->globalfog )
|
||||
{
|
||||
|
@ -1212,6 +1213,7 @@ R_CategorizeEntities
|
|||
static void R_CategorizeEntities( void )
|
||||
{
|
||||
uint i, j;
|
||||
edict_t *world;
|
||||
|
||||
r_numnullentities = 0;
|
||||
r_numbmodelentities = 0;
|
||||
|
@ -1219,6 +1221,10 @@ static void R_CategorizeEntities( void )
|
|||
if( !r_drawentities->integer )
|
||||
return;
|
||||
|
||||
// apply global waveheight to world entity
|
||||
world = ri.GetClientEdict( 0 );
|
||||
if( world ) r_worldent->waveHeight = world->v.scale * 16.0f;
|
||||
|
||||
for( i = 1; i < r_numEntities; i++ )
|
||||
{
|
||||
RI.previousentity = RI.currententity;
|
||||
|
@ -2320,6 +2326,7 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
|
|||
case mod_brush:
|
||||
if( !refent->model->extradata )
|
||||
return false;
|
||||
refent->waveHeight = refent->scale * 16.0f;
|
||||
refent->scale = 1.0f; // ignore scale for brush models
|
||||
refent->frame = pRefEntity->v.frame; // brush properly animating
|
||||
break;
|
||||
|
|
|
@ -553,6 +553,13 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf )
|
|||
int i, j, e;
|
||||
float *v;
|
||||
|
||||
if( surf->flags & SURF_DRAWTURB )
|
||||
{
|
||||
surf->extents[0] = surf->extents[1] = 16384;
|
||||
surf->textureMins[0] = surf->textureMins[1] = -8192;
|
||||
return;
|
||||
}
|
||||
|
||||
mins[0] = mins[1] = 999999;
|
||||
maxs[0] = maxs[1] = -999999;
|
||||
|
||||
|
@ -1143,6 +1150,7 @@ static ref_shader_t *Mod_LoadCachedImage( cachedimage_t *image )
|
|||
{
|
||||
mip_t *mt = image->base;
|
||||
int i, shader_type = SHADER_TEXTURE;
|
||||
texture_t *tx;
|
||||
|
||||
// see if already loaded
|
||||
if( image->shader )
|
||||
|
@ -1160,32 +1168,41 @@ static ref_shader_t *Mod_LoadCachedImage( cachedimage_t *image )
|
|||
else R_SetInternalTexture( NULL );
|
||||
|
||||
// build the unique shadername because we don't want keep this for other maps
|
||||
if( mt->offsets[0] > 0 )
|
||||
#if 0
|
||||
if( mt->offsets[0] > 0 && com.strncmp( mt->name, "sky", 3 ))
|
||||
com.snprintf( image->name, sizeof( image->name ), "%s/%s", cached.modelname, mt->name );
|
||||
#endif
|
||||
|
||||
// determine shader parms by texturename
|
||||
if( !com.strncmp( mt->name, "scroll", 6 ))
|
||||
R_ShaderSetMiptexFlags( MIPTEX_CONVEYOR );
|
||||
|
||||
if( mt->name[0] == '*' || mt->name[0] == '!' )
|
||||
R_ShaderSetMiptexFlags( MIPTEX_WARPSURFACE|MIPTEX_NOLIGHTMAP );
|
||||
|
||||
if( image->animated )
|
||||
{
|
||||
float fps = ( cached.version == HLBSP_VERSION ) ? 10.0f : 5.0f;
|
||||
|
||||
R_SetAnimFrequency( fps ); // set primary animation
|
||||
for( i = 0; i < image->anim_total[0]; i++ )
|
||||
Mod_LoadTexture( image->anim_frames[0][i] );
|
||||
tx = Mod_LoadTexture( image->anim_frames[0][i] );
|
||||
|
||||
R_SetAnimFrequency( fps ); // set alternate animation
|
||||
for( i = 0; i < image->anim_total[1]; i++ )
|
||||
Mod_LoadTexture( image->anim_frames[1][i] );
|
||||
tx = Mod_LoadTexture( image->anim_frames[1][i] );
|
||||
}
|
||||
else Mod_LoadTexture( mt ); // load the base image
|
||||
else tx = Mod_LoadTexture( mt ); // load the base image
|
||||
|
||||
// force to get it from texture
|
||||
if( tx == tr.defaultTexture )
|
||||
image->width = image->height = -1;
|
||||
|
||||
load_shader:
|
||||
if( !com.strncmp( mt->name, "sky", 3 ))
|
||||
if( !com.strncmp( mt->name, "sky", 3 ) && cached.version == Q1BSP_VERSION )
|
||||
shader_type = SHADER_SKY;
|
||||
|
||||
image->shader = R_LoadShader( image->name, SHADER_TEXTURE, false, 0, SHADER_INVALID );
|
||||
image->shader = R_LoadShader( image->name, shader_type, false, 0, SHADER_INVALID );
|
||||
|
||||
return image->shader;
|
||||
}
|
||||
|
@ -1468,9 +1485,8 @@ static void Mod_LoadSubmodels( const dlump_t *l )
|
|||
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
// spread the mins / maxs by a pixel
|
||||
out->mins[j] = LittleFloat( in->mins[j] ) - 1;
|
||||
out->maxs[j] = LittleFloat( in->maxs[j] ) + 1;
|
||||
out->mins[j] = LittleFloat( in->mins[j] );
|
||||
out->maxs[j] = LittleFloat( in->maxs[j] );
|
||||
out->origin[j] = LittleFloat( in->origin[j] );
|
||||
}
|
||||
|
||||
|
@ -1562,6 +1578,12 @@ static void Mod_LoadSurfaces( const dlump_t *l )
|
|||
out->shader = texture->shader;
|
||||
out->fog = NULL; // FIXME: build conception of realtime fogs
|
||||
|
||||
if( !com.strncmp( texture->name, "sky", 3 ))
|
||||
out->flags |= (SURF_DRAWSKY|SURF_DRAWTILED);
|
||||
|
||||
if( texture->name[0] == '*' || texture->name[0] == '!' )
|
||||
out->flags |= (SURF_DRAWTURB|SURF_DRAWTILED);
|
||||
|
||||
Mod_CalcSurfaceBounds( out );
|
||||
Mod_CalcSurfaceExtents( out );
|
||||
|
||||
|
@ -1569,12 +1591,6 @@ static void Mod_LoadSurfaces( const dlump_t *l )
|
|||
out->lmWidth = (out->extents[0] >> 4) + 1;
|
||||
out->lmHeight = (out->extents[1] >> 4) + 1;
|
||||
|
||||
if( !com.strncmp( texture->name, "sky", 3 ))
|
||||
out->flags |= (SURF_DRAWSKY|SURF_DRAWTILED);
|
||||
|
||||
if( texture->name[0] == '*' || texture->name[0] == '!' )
|
||||
out->flags |= (SURF_DRAWTURB|SURF_DRAWTILED);
|
||||
|
||||
if( out->flags & SURF_DRAWTILED ) lightofs = -1;
|
||||
else lightofs = LittleLong( in->lightofs );
|
||||
|
||||
|
@ -2538,14 +2554,12 @@ Mod_Finish
|
|||
*/
|
||||
static void Mod_Finish( const dlump_t *faces, const dlump_t *light, vec3_t ambient )
|
||||
{
|
||||
int i;
|
||||
|
||||
// set up lightgrid
|
||||
// R_BuildLightGrid( loadbmodel );
|
||||
|
||||
// ambient lighting
|
||||
for( i = 0; i < 3; i++ )
|
||||
mapConfig.ambient[i] = bound( 0, ambient[i] * ( 1.0f /255.0f ), 1 );
|
||||
VectorCopy( RI.refdef.skyColor, mapConfig.environmentColor );
|
||||
mapConfig.environmentColor[3] = 255;
|
||||
|
||||
Mem_EmptyPool( cached_mempool );
|
||||
}
|
||||
|
@ -2560,7 +2574,7 @@ void Mod_BrushLoadModel( ref_model_t *mod, const void *buffer )
|
|||
dheader_t *header;
|
||||
mmodel_t *bm;
|
||||
vec3_t ambient;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
header = (dheader_t *)buffer;
|
||||
cached.version = LittleLong( header->version );
|
||||
|
@ -2636,6 +2650,15 @@ void Mod_BrushLoadModel( ref_model_t *mod, const void *buffer )
|
|||
VectorCopy( bm->mins, starmod->mins );
|
||||
starmod->radius = bm->radius;
|
||||
|
||||
for( j = 0; i != 0 && j < bmodel->nummodelsurfaces; j++ )
|
||||
{
|
||||
msurface_t *surf = bmodel->firstmodelsurface + j;
|
||||
|
||||
// kill water backplanes for submodels (half-life rules)
|
||||
if( surf->flags & SURF_DRAWTURB && surf->mins[2] == bm->mins[2] )
|
||||
surf->mesh = NULL;
|
||||
}
|
||||
|
||||
if( i == 0 ) *mod = *starmod;
|
||||
else bmodel->numsubmodels = 0;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef struct
|
|||
#define MIPTEX_TRANSPARENT BIT( 2 ) // transparent texture
|
||||
#define MIPTEX_RENDERMODE BIT( 3 ) // this surface requires a rendermode stuff
|
||||
#define MIPTEX_NOLIGHTMAP BIT( 4 ) // this surface if fullbright
|
||||
#define MIPTEX_WARPSURFACE BIT( 5 ) // this surface is warped
|
||||
|
||||
#define SURF_PLANEBACK BIT( 0 )
|
||||
#define SURF_DRAWSKY BIT( 1 ) // sky surface
|
||||
|
@ -75,8 +76,8 @@ typedef struct mtexinfo_s
|
|||
{
|
||||
float vecs[2][4];
|
||||
short texturenum; // number in cached.textures
|
||||
word width;
|
||||
word height;
|
||||
short width;
|
||||
short height;
|
||||
} mtexinfo_t;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -3782,25 +3782,44 @@ static ref_shader_t *Shader_CreateDefault( ref_shader_t *shader, int type, int a
|
|||
}
|
||||
else
|
||||
{
|
||||
int size;
|
||||
int size, offset;
|
||||
bool hasLightmap = ( r_miptexFeatures & MIPTEX_NOLIGHTMAP ) ? false : true;
|
||||
|
||||
shader->type = SHADER_TEXTURE;
|
||||
shader->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT|SHADER_RENDERMODE;
|
||||
if( hasLightmap ) shader->flags |= SHADER_HASLIGHTMAP;
|
||||
shader->features = MF_STCOORDS|MF_LMCOORDS;
|
||||
shader->features = MF_STCOORDS;
|
||||
if( hasLightmap ) shader->features |= MF_LMCOORDS;
|
||||
shader->sort = SORT_OPAQUE;
|
||||
shader->num_stages = ( hasLightmap ) ? 2 : 1;
|
||||
size = length + 1 + sizeof( ref_stage_t ) * shader->num_stages;
|
||||
if( r_miptexFeatures & MIPTEX_CONVEYOR ) size += sizeof( tcMod_t );
|
||||
|
||||
if( r_miptexFeatures & MIPTEX_WARPSURFACE ) size += sizeof( deform_t );
|
||||
|
||||
shader->name = Shader_Malloc( size );
|
||||
com.strcpy( shader->name, shortname );
|
||||
shader->stages = (ref_stage_t *)((byte *)shader->name + length + 1 );
|
||||
pass = &shader->stages[0];
|
||||
pass->flags = SHADERSTAGE_RENDERMODE|SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_REPLACE;
|
||||
pass->glState = GLSTATE_DEPTHWRITE;
|
||||
pass->tcgen = TCGEN_BASE;
|
||||
if( r_miptexFeatures & MIPTEX_WARPSURFACE )
|
||||
{
|
||||
pass->tcgen = TCGEN_WARP;
|
||||
shader->tessSize = 64.0f;
|
||||
|
||||
// apply waves
|
||||
offset = length + 1 + sizeof( ref_stage_t ) * shader->num_stages;
|
||||
if( r_miptexFeatures & MIPTEX_CONVEYOR ) offset += sizeof( tcMod_t );
|
||||
shader->features |= (MF_DEFORMVS|MF_NORMALS);
|
||||
|
||||
shader->deforms = (deform_t *)((byte *)shader->name + offset );
|
||||
shader->deforms->type = DEFORM_WAVE;
|
||||
shader->deforms->func.type = WAVEFORM_SIN;
|
||||
shader->deforms->args[0] = 0.01f;
|
||||
shader->deforms->func.args[3] = 0.5f;
|
||||
shader->numDeforms++;
|
||||
}
|
||||
else pass->tcgen = TCGEN_BASE;
|
||||
|
||||
if( r_numStageTextures > 1 )
|
||||
{
|
||||
|
|
|
@ -70,6 +70,9 @@ bool R_CullSurface( msurface_t *surf, uint clipflags )
|
|||
if( r_nocull->integer )
|
||||
return false;
|
||||
|
||||
if( shader->tessSize )
|
||||
return false;
|
||||
|
||||
if( shader->flags & SHADER_AUTOSPRITE )
|
||||
return false;
|
||||
|
||||
|
|
Reference in New Issue