17 Jun 2010

This commit is contained in:
g-cont 2010-06-17 00:00:00 +04:00 committed by Alibek Omarov
parent ce9a0409b7
commit 7efdf1ea1b
37 changed files with 2399 additions and 350 deletions

View File

@ -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 )

View File

@ -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 )
{

View File

@ -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++ )

View File

@ -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 );
}
/*

View File

@ -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 );

View File

@ -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

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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;

View File

@ -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 );
}

View File

@ -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 )
{

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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] );

View File

@ -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" );

View File

@ -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 )
{

View File

@ -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 );
}
}

1739
engine/server/sv_phys.old Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 );

View File

@ -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

View File

@ -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
{

View File

@ -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
}

View File

@ -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 )

View File

@ -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 )
{

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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 )
{

View File

@ -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;