22 Aug 2017

This commit is contained in:
g-cont 2017-08-22 00:00:00 +03:00 committed by Alibek Omarov
parent f2b2b8df99
commit 547b56497e
15 changed files with 345 additions and 174 deletions

View File

@ -998,7 +998,6 @@ void CL_LinkPlayers( frame_t *frame )
VectorCopy( state->origin, ent->prevstate.origin );
VectorCopy( state->origin, ent->curstate.origin );
VectorCopy( ent->curstate.angles, ent->angles );
local_added = true;
}
if( FBitSet( ent->curstate.effects, EF_NOINTERP ))
@ -1029,7 +1028,11 @@ void CL_LinkPlayers( frame_t *frame )
VectorCopy( ent->origin, ent->attachment[2] );
VectorCopy( ent->origin, ent->attachment[3] );
CL_AddVisibleEntity( ent, ET_PLAYER );
if( CL_AddVisibleEntity( ent, ET_PLAYER ))
{
if( i == cl.playernum )
local_added = true;
}
}
// apply local player effects if entity is not added
@ -1278,6 +1281,7 @@ qboolean CL_GetEntitySpatialization( channel_t *ch )
{
// entity is never has updates on the client
// so we should use static origin instead
ch->staticsound = true;
return valid_origin;
}
#if 0

View File

@ -144,7 +144,7 @@ void SCR_NetSpeeds( void )
if( cur_clfps > max_clfps ) max_clfps = cur_clfps;
}
Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal received from server: %s\nTotal sended to server: %s\n",
Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal received from server: %s\nTotal sent to server: %s\n",
min_svfps, cur_svfps, max_svfps, min_clfps, cur_clfps, max_clfps, (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_received ), Q_memprint( cls.netchan.total_sended ));
x = glState.width - 320;

View File

@ -878,11 +878,150 @@ void DrawSingleDecal( decal_t *pDecal, msurface_t *fa )
pglEnd();
}
void DrawSurfaceDecals( void )
void DrawSurfaceDecals( msurface_t *fa, qboolean single )
{
decal_t *p;
cl_entity_t *e;
if( !fa->pdecals ) return;
e = RI.currententity;
ASSERT( e != NULL );
if( single )
{
if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha )
{
pglDepthMask( GL_FALSE );
pglEnable( GL_BLEND );
if( e->curstate.rendermode == kRenderTransAlpha )
pglDisable( GL_ALPHA_TEST );
}
if( e->curstate.rendermode == kRenderTransColor )
pglEnable( GL_TEXTURE_2D );
if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd )
GL_Cull( GL_NONE );
if( gl_polyoffset->value )
{
pglEnable( GL_POLYGON_OFFSET_FILL );
pglPolygonOffset( -1.0f, -gl_polyoffset->value );
}
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
if( FBitSet( fa->flags, SURF_TRANSPARENT ) && glState.stencilEnabled )
{
mtexinfo_t *tex = fa->texinfo;
for( p = fa->pdecals; p; p = p->pnext )
{
if( p->texture )
{
float *o, *v;
int i, numVerts;
o = R_DecalSetupVerts( p, fa, p->texture, &numVerts );
pglEnable( GL_STENCIL_TEST );
pglStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF );
pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
pglStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
pglBegin( GL_POLYGON );
for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE )
{
v[5] = ( DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] ) / tex->texture->width;
v[6] = ( DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] ) / tex->texture->height;
pglTexCoord2f( v[5], v[6] );
pglVertex3fv( v );
}
pglEnd();
pglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
pglEnable( GL_ALPHA_TEST );
pglBegin( GL_POLYGON );
for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE )
{
pglTexCoord2f( v[5], v[6] );
pglVertex3fv( v );
}
pglEnd();
pglDisable( GL_ALPHA_TEST );
pglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
pglStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF );
pglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
}
}
}
for( p = fa->pdecals; p; p = p->pnext )
{
if( p->texture )
{
gltexture_t *glt = R_GetTexture( p->texture );
// normal HL decal with alpha-channel
if( glt->flags & TF_HAS_ALPHA )
{
// draw transparent decals with GL_MODULATE
if( glt->fogParams[3] > DECAL_TRANSPARENT_THRESHOLD )
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
else
{
// color decal like detail texture. Base color is 127 127 127
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
}
DrawSingleDecal( p, fa );
}
}
if( FBitSet( fa->flags, SURF_TRANSPARENT ) && glState.stencilEnabled )
pglDisable( GL_STENCIL_TEST );
if( single )
{
if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha )
{
pglDepthMask( GL_TRUE );
pglDisable( GL_BLEND );
if( e->curstate.rendermode == kRenderTransAlpha )
pglEnable( GL_ALPHA_TEST );
}
if( gl_polyoffset->value )
pglDisable( GL_POLYGON_OFFSET_FILL );
if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd )
GL_Cull( GL_FRONT );
if( e->curstate.rendermode == kRenderTransColor )
pglDisable( GL_TEXTURE_2D );
// restore blendfunc here
if( e->curstate.rendermode == kRenderTransAdd || e->curstate.rendermode == kRenderGlow )
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
}
}
void DrawDecalsBatch( void )
{
cl_entity_t *e;
msurface_t *fa;
decal_t *p;
int i;
if( !tr.num_draw_decals )
@ -909,93 +1048,7 @@ void DrawSurfaceDecals( void )
for( i = 0; i < tr.num_draw_decals; i++ )
{
fa = tr.draw_decals[i];
if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled )
{
mtexinfo_t *tex = fa->texinfo;
texture_t *t = R_TextureAnimation( fa );
// sigh! we need to draw poly again here
pglEnable( GL_ALPHA_TEST );
GL_Bind( GL_TEXTURE0, t->gl_texturenum );
DrawGLPoly( fa->polys, 0.0f, 0.0f );
pglDisable( GL_ALPHA_TEST );
for( p = fa->pdecals; p; p = p->pnext )
{
if( p->texture )
{
float *o, *v;
int i, numVerts;
o = R_DecalSetupVerts( p, fa, p->texture, &numVerts );
pglEnable( GL_STENCIL_TEST );
pglStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF );
pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
pglStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
pglBegin( GL_POLYGON );
for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE )
{
v[5] = ( DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] ) / tex->texture->width;
v[6] = ( DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] ) / tex->texture->height;
pglTexCoord2f( v[5], v[6] );
pglVertex3fv( v );
}
pglEnd();
pglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
pglEnable( GL_ALPHA_TEST );
pglBegin( GL_POLYGON );
for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE )
{
pglTexCoord2f( v[5], v[6] );
pglVertex3fv( v );
}
pglEnd();
pglDisable( GL_ALPHA_TEST );
pglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
pglStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF );
pglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
}
}
}
for( p = fa->pdecals; p; p = p->pnext )
{
if( p->texture )
{
gltexture_t *glt = R_GetTexture( p->texture );
// normal HL decal with alpha-channel
if( glt->flags & TF_HAS_ALPHA )
{
// draw transparent decals with GL_MODULATE
if( glt->fogParams[3] > DECAL_TRANSPARENT_THRESHOLD )
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
else
{
// color decal like detail texture. Base color is 127 127 127
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
}
DrawSingleDecal( p, fa );
}
}
if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled )
pglDisable( GL_STENCIL_TEST );
DrawSurfaceDecals( tr.draw_decals[i], false );
}
if( e->curstate.rendermode != kRenderTransTexture )

View File

@ -780,6 +780,83 @@ byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int out
return scaledImage;
}
float GL_SimpleSpline( float value )
{
float valueSquared = value * value * value;
// nice little ease-in, ease-out spline-like curve
return (4.0f * valueSquared - 3.0f * valueSquared * value);
}
/*
=================
GL_BoxFilter3x3
box filter 3x3
=================
*/
void GL_BoxFilter3x3( byte *out, const byte *in, int w, int h, int x, int y )
{
int r = 0, g = 0, b = 0, a = 0;
int count = 0, acount = 0;
int i, j, u, v;
const byte *pixel;
for( i = 0; i < 3; i++ )
{
u = ( i - 1 ) + x;
for( j = 0; j < 3; j++ )
{
v = ( j - 1 ) + y;
if( u >= 0 && u < w && v >= 0 && v < h )
{
pixel = &in[( u + v * w ) * 4];
if( pixel[3] != 0 )
{
r += pixel[0];
g += pixel[1];
b += pixel[2];
a += pixel[3];
acount++;
}
}
}
}
if( acount == 0 )
acount = 1;
out[0] = r / acount;
out[1] = g / acount;
out[2] = b / acount;
// out[3] = (int)( SimpleSpline( ( a / 9.0f ) / 255.0f ) * 255 );
}
/*
=================
GL_ApplyFilter
Apply box-filter to 1-bit alpha
=================
*/
byte *GL_ApplyFilter( const byte *source, int width, int height )
{
byte *in = (byte *)source;
byte *out = (byte *)source;
int i;
for( i = 0; source && i < width * height; i++, in += 4 )
{
if( in[0] == 0 && in[1] == 0 && in[2] == 0 && in[3] == 0 )
GL_BoxFilter3x3( in, source, width, height, i % width, i / width );
}
return out;
}
/*
=================
GL_ApplyGamma
@ -1106,6 +1183,9 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic )
if( !ImageDXT( pic->type ) && !FBitSet( tex->flags, TF_NOMIPMAP|TF_SKYSIDE ))
data = GL_ApplyGamma( data, tex->width * tex->height * tex->depth, FBitSet( tex->flags, TF_NORMALMAP ));
if( !ImageDXT( pic->type ) && FBitSet( tex->flags, TF_HAS_ALPHA ))
data = GL_ApplyFilter( data, tex->width, tex->height );
// mips will be auto-generated if desired
for( j = 0; j < mipCount; j++ )
{

View File

@ -290,10 +290,11 @@ qboolean R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags
//
// gl_decals.c
//
void DrawSurfaceDecals( void );
void DrawSurfaceDecals( msurface_t *fa, qboolean single );
float *R_DecalSetupVerts( decal_t *pDecal, msurface_t *surf, int texture, int *outCount );
void DrawSingleDecal( decal_t *pDecal, msurface_t *fa );
void R_EntityRemoveDecals( model_t *mod );
void DrawDecalsBatch( void );
void R_ClearDecals( void );
//
@ -623,7 +624,6 @@ typedef struct
int faceCull;
qboolean drawTrans;
qboolean stencilEnabled;
qboolean in2DMode;
} glstate_t;

View File

@ -106,13 +106,13 @@ static qboolean R_OpaqueEntity( cl_entity_t *ent )
{
if( ent->curstate.rendermode == kRenderNormal )
return true;
#if 0
if( ent->model->type != mod_brush )
return false;
if( ent->curstate.rendermode == kRenderTransAlpha )
return true;
#endif
return false;
}
@ -127,36 +127,36 @@ static int R_TransEntityCompare( const cl_entity_t **a, const cl_entity_t **b )
{
cl_entity_t *ent1, *ent2;
vec3_t vecLen, org;
float len1, len2;
float dist1, dist2;
ent1 = (cl_entity_t *)*a;
ent2 = (cl_entity_t *)*b;
// then by distance
if( ent1->model->type == mod_brush )
// sort by distance
if( ent1->curstate.rendermode != kRenderTransAlpha )
{
VectorAverage( ent1->model->mins, ent1->model->maxs, org );
VectorAdd( ent1->origin, org, org );
VectorSubtract( RI.vieworg, org, vecLen );
dist1 = DotProduct( vecLen, vecLen );
}
else VectorSubtract( RI.vieworg, ent1->origin, vecLen );
len1 = VectorLength( vecLen );
else dist1 = 1000000000;
if( ent2->model->type == mod_brush )
if( ent2->curstate.rendermode != kRenderTransAlpha )
{
VectorAverage( ent2->model->mins, ent2->model->maxs, org );
VectorAdd( ent2->origin, org, org );
VectorSubtract( RI.vieworg, org, vecLen );
dist2 = DotProduct( vecLen, vecLen );
}
else VectorSubtract( RI.vieworg, ent2->origin, vecLen );
len2 = VectorLength( vecLen );
else dist2 = 1000000000;
if( len1 > len2 )
if( dist1 > dist2 )
return -1;
if( len1 < len2 )
if( dist1 < dist2 )
return 1;
// now sort by rendermode
// then sort by rendermode
if( R_RankForRenderMode( ent1 ) > R_RankForRenderMode( ent2 ))
return 1;
if( R_RankForRenderMode( ent1 ) < R_RankForRenderMode( ent2 ))
@ -809,8 +809,8 @@ void R_DrawEntitiesOnList( void )
{
int i;
glState.drawTrans = false;
tr.blend = 1.0f;
GL_CheckForErrors();
// first draw solid entities
for( i = 0; i < tr.num_solid_entities && !RI.onlyClientDraw; i++ )
@ -837,9 +837,13 @@ void R_DrawEntitiesOnList( void )
}
}
GL_CheckForErrors();
// quake-specific feature
R_DrawAlphaTextureChains();
GL_CheckForErrors();
// draw sprites seperately, because of alpha blending
for( i = 0; i < tr.num_solid_entities && !RI.onlyClientDraw; i++ )
{
@ -857,15 +861,19 @@ void R_DrawEntitiesOnList( void )
}
}
GL_CheckForErrors();
if( !RI.onlyClientDraw )
{
CL_DrawBeams( false );
}
GL_CheckForErrors();
if( RI.drawWorld )
clgame.dllFuncs.pfnDrawNormalTriangles();
glState.drawTrans = true;
GL_CheckForErrors();
// then draw translucent entities
for( i = 0; i < tr.num_trans_entities && !RI.onlyClientDraw; i++ )
@ -897,12 +905,16 @@ void R_DrawEntitiesOnList( void )
}
}
GL_CheckForErrors();
if( RI.drawWorld )
{
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
clgame.dllFuncs.pfnDrawTransparentTriangles ();
}
GL_CheckForErrors();
if( !RI.onlyClientDraw )
{
R_AllowFog( false );
@ -912,12 +924,15 @@ void R_DrawEntitiesOnList( void )
R_AllowFog( true );
}
glState.drawTrans = false;
GL_CheckForErrors();
pglDisable( GL_BLEND ); // Trinity Render issues
if( !RI.onlyClientDraw )
R_DrawViewModel();
CL_ExtraUpdate();
GL_CheckForErrors();
}
/*

View File

@ -1157,11 +1157,17 @@ void R_RenderBrushPoly( msurface_t *fa )
DrawGLPoly( fa->polys, 0.0f, 0.0f );
if( is_mirror ) R_EndDrawMirror();
if( tr.num_draw_decals < MAX_DECAL_SURFS )
tr.draw_decals[tr.num_draw_decals++] = fa;
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
DrawSurfaceDecals();
if( RI.currententity->curstate.rendermode == kRenderNormal )
{
// batch decals to draw later
if( tr.num_draw_decals < MAX_DECAL_SURFS && fa->pdecals )
tr.draw_decals[tr.num_draw_decals++] = fa;
}
else
{
// if rendermode != kRenderNormal draw decals sequentially
DrawSurfaceDecals( fa, true );
}
// NOTE: draw mirror through in mirror show dummy lightmapped texture
if( fa->flags & SURF_REFLECT && RP_NORMALPASS( ))
@ -1315,6 +1321,7 @@ void R_DrawAlphaTextureChains( void )
// restore worldmodel
RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model;
RI.currententity->curstate.rendermode = kRenderTransAlpha;
draw_alpha_surfaces = false;
for( i = 0; i < cl.worldmodel->numtextures; i++ )
@ -1332,9 +1339,9 @@ void R_DrawAlphaTextureChains( void )
t->texturechain = NULL;
}
DrawSurfaceDecals();
GL_ResetFogColor();
R_BlendLightmaps();
RI.currententity->curstate.rendermode = kRenderNormal; // restore world rendermode
pglAlphaFunc( GL_GREATER, 0.0f );
}
@ -1438,7 +1445,7 @@ void R_SetRenderMode( cl_entity_t *e )
case kRenderTransColor:
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, e->curstate.renderamt );
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ALPHA );
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglDisable( GL_TEXTURE_2D );
pglEnable( GL_BLEND );
break;
@ -1566,7 +1573,7 @@ void R_DrawBrushModel( cl_entity_t *e )
if( e->curstate.rendermode == kRenderTransColor )
pglEnable( GL_TEXTURE_2D );
DrawSurfaceDecals();
DrawDecalsBatch();
GL_ResetFogColor();
R_BlendLightmaps();
R_RenderFullbrights();
@ -1987,7 +1994,7 @@ void R_DrawWorld( void )
if( !CL_IsDevOverviewMode( ))
{
DrawSurfaceDecals();
DrawDecalsBatch();
GL_ResetFogColor();
R_BlendLightmaps();
R_RenderFullbrights();

View File

@ -980,7 +980,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
color2[1] = (float)lightColor.g * ( 1.0f / 255.0f );
color2[2] = (float)lightColor.b * ( 1.0f / 255.0f );
// NOTE: sprites with 'lightmap' looks ugly when alpha func is GL_GREATER 0.0
pglAlphaFunc( GL_GEQUAL, 0.25f );
pglAlphaFunc( GL_GREATER, 0.25f );
}
if( R_SpriteAllowLerping( e, psprite ))

View File

@ -189,7 +189,7 @@ void S_UpdateSoundFade( void )
}
// spline it.
f = S_SimpleSpline( f );
f = SimpleSpline( f );
f = bound( 0.0f, f, 1.0f );
soundfade.percent = soundfade.initial_percent * f;

View File

@ -20,24 +20,6 @@ GNU General Public License for more details.
#define ZERO_X_8( b ) (( b ) < 2 && ( b ) > -2 )
#define ZERO_X_16( b ) (( b ) < 512 && ( b ) > -512 )
/*
=================
S_SimpleSpline
NOTE: ripped from hl2 source
hermite basis function for smooth interpolation
Similar to Gain() above, but very cheap to call
value should be between 0 & 1 inclusive
=================
*/
float S_SimpleSpline( float value )
{
float valueSquared = value * value;
// nice little ease-in, ease-out spline-like curve
return (3.0f * valueSquared - 2.0f * valueSquared * value);
}
//-----------------------------------------------------------------------------
// Purpose: Search backward for a zero crossing starting at sample
// Input : sample - starting point

View File

@ -344,7 +344,6 @@ int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample );
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, qboolean use_loop );
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition );
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition );
float S_SimpleSpline( float value );
//
// s_vox.c

View File

@ -51,6 +51,24 @@ float anglemod( float a )
return a;
}
/*
=================
SimpleSpline
NOTE: ripped from hl2 source
hermite basis function for smooth interpolation
Similar to Gain() above, but very cheap to call
value should be between 0 & 1 inclusive
=================
*/
float SimpleSpline( float value )
{
float valueSquared = value * value;
// nice little ease-in, ease-out spline-like curve
return (3.0f * valueSquared - 2.0f * valueSquared * value);
}
word FloatToHalf( float v )
{
unsigned int i = *((unsigned int *)&v);

View File

@ -122,6 +122,7 @@ float rsqrt( float number );
float anglemod( float a );
word FloatToHalf( float v );
float HalfToFloat( word h );
float SimpleSpline( float value );
void RoundUpHullSize( vec3_t size );
int SignbitsForPlane( const vec3_t normal );
int PlaneTypeForNormal( const vec3_t normal );

View File

@ -152,9 +152,10 @@ void SV_SetModel( edict_t *ent, const char *name )
case mod_brush:
case mod_sprite:
Mod_GetBounds( ent->v.modelindex, mins, maxs );
SV_SetMinMaxSize( ent, mins, maxs, true );
break;
}
SV_SetMinMaxSize( ent, mins, maxs, true );
}
float SV_AngleMod( float ideal, float current, float speed )
@ -230,8 +231,7 @@ qboolean SV_CheckClientVisiblity( sv_client_t *cl, const byte *mask )
vec3_t vieworg;
mleaf_t *leaf;
if( !mask || svs.maxclients <= 1 )
return true; // GoldSrc rules
if( !mask ) return true; // GoldSrc rules
clientnum = cl - svs.clients;
VectorCopy( viewPoint[clientnum], vieworg );
@ -308,7 +308,8 @@ int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, qboolean us
// intentional fallthrough
case MSG_PAS:
if( origin == NULL ) return false;
Mod_FatPVS( origin, FATPHS_RADIUS, fatphs, world.fatbytes, false, false );
// NOTE: GoldSource not using PHS for singleplayer
Mod_FatPVS( origin, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 ));
mask = fatphs; // using the FatPVS like a PHS
break;
case MSG_PVS_R:
@ -3843,7 +3844,10 @@ void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex,
// setup pvs cluster for invoker
if( !FBitSet( flags, FEV_GLOBAL ))
mask = Mod_GetPVSForPoint( pvspoint );
{
Mod_FatPVS( pvspoint, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 ));
mask = fatphs; // using the FatPVS like a PHS
}
// process all the clients
for( slot = 0, cl = svs.clients; slot < svs.maxclients; slot++, cl++ )

View File

@ -1170,7 +1170,7 @@ void SV_Physics_Pusher( edict_t *ent )
// reset the local time to what it was before we rotated
ent->v.ltime = oldtime;
pBlocker = SV_PushMove( ent, movetime );
if( oldtime2 < ent->v.ltime )
if( ent->v.ltime < oldtime2 )
ent->v.ltime = oldtime2;
}
}
@ -1200,7 +1200,6 @@ void SV_Physics_Pusher( edict_t *ent )
ent->v.nextthink = 0.0f;
svgame.globals->time = sv.time;
svgame.dllFuncs.pfnThink( ent );
if( ent->free ) return;
}
}
@ -1437,13 +1436,14 @@ void SV_Physics_Toss( edict_t *ent )
ground = ent->v.groundentity;
if( ent->v.velocity[2] > 0.0f || !SV_IsValidEdict( ground ) || ground->v.flags & (FL_MONSTER|FL_CLIENT) || svgame.globals->changelevel )
{
ent->v.flags &= ~FL_ONGROUND;
}
if( ent->v.velocity[2] > 0 )
ClearBits( ent->v.flags, FL_ONGROUND );
if( !SV_IsValidEdict( ground ) || FBitSet( ground->v.flags, FL_MONSTER|FL_CLIENT ))
ClearBits( ent->v.flags, FL_ONGROUND );
// if on ground and not moving, return.
if( ent->v.flags & FL_ONGROUND && VectorIsNull( ent->v.velocity ))
if( FBitSet( ent->v.flags, FL_ONGROUND ) && VectorIsNull( ent->v.velocity ))
{
VectorClear( ent->v.avelocity );
@ -1593,37 +1593,46 @@ void SV_Physics_Step( edict_t *ent )
ent->v.velocity[2] += buoyancy;
}
if( !wasonground && !( ent->v.flags & FL_FLY ) && (!( ent->v.flags & FL_SWIM ) || ent->v.waterlevel <= 0 ))
if( !wasonground )
{
if( !inwater )
SV_AddGravity( ent );
if( !FBitSet( ent->v.flags, FL_FLY ))
{
if( !FBitSet( ent->v.flags, FL_SWIM ) && ( ent->v.waterlevel > 0 ))
{
if( !inwater )
SV_AddGravity( ent );
}
}
}
if( !VectorIsNull( ent->v.velocity ) || !VectorIsNull( ent->v.basevelocity ))
{
ent->v.flags &= ~FL_ONGROUND;
if(( wasonground || wasonmover ) && ( ent->v.health > 0 || SV_CheckBottom( ent, MOVE_NORMAL )))
if( wasonground || wasonmover )
{
float *vel = ent->v.velocity;
float control, speed, newspeed;
float friction;
speed = sqrt(( vel[0] * vel[0] ) + ( vel[1] * vel[1] )); // DotProduct2D
if( speed )
if(!( ent->v.health <= 0 && !SV_CheckBottom( ent, MOVE_NORMAL )))
{
friction = sv_friction.value * ent->v.friction; // factor
ent->v.friction = 1.0f; // g-cont. ???
if( wasonmover ) friction *= 0.5f; // add a little friction
float *vel = ent->v.velocity;
float control, speed, newspeed;
float friction;
control = (speed < sv_stopspeed.value) ? sv_stopspeed.value : speed;
newspeed = speed - (sv.frametime * control * friction);
if( newspeed < 0 ) newspeed = 0;
newspeed /= speed;
speed = sqrt(( vel[0] * vel[0] ) + ( vel[1] * vel[1] )); // DotProduct2D
vel[0] = vel[0] * newspeed;
vel[1] = vel[1] * newspeed;
if( speed )
{
friction = sv_friction.value * ent->v.friction; // factor
ent->v.friction = 1.0f; // g-cont. ???
if( wasonmover ) friction *= 0.5f; // add a little friction
control = (speed < sv_stopspeed.value) ? sv_stopspeed.value : speed;
newspeed = speed - (sv.frametime * control * friction);
if( newspeed < 0 ) newspeed = 0;
newspeed /= speed;
vel[0] = vel[0] * newspeed;
vel[1] = vel[1] * newspeed;
}
}
}
@ -1635,7 +1644,6 @@ void SV_Physics_Step( edict_t *ent )
SV_CheckVelocity( ent );
VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
SV_CheckVelocity( ent );
VectorAdd( ent->v.origin, ent->v.mins, mins );