26 Jun 2012
This commit is contained in:
parent
1e7343b3f6
commit
0b296ece60
|
@ -0,0 +1,29 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "cl_dll"=.\cl_dll.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -18,6 +18,9 @@ GNU General Public License for more details.
|
|||
|
||||
#include "bspfile.h" // we need some declarations from it
|
||||
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec4_t[4];
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
@ -310,8 +313,6 @@ typedef struct model_s
|
|||
cache_user_t cache; // only access through Mod_Extradata
|
||||
} model_t;
|
||||
|
||||
typedef vec_t vec4_t[4];
|
||||
|
||||
typedef struct alight_s
|
||||
{
|
||||
int ambientlight; // clip at 128
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
#define SOLID_BBOX 2 // touch on edge, block
|
||||
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
|
||||
#define SOLID_BSP 4 // bsp clip, touch on edge, block
|
||||
#define SOLID_CUSTOM 5 // call external callbacks for tracing
|
||||
|
||||
// edict->deadflag values
|
||||
#define DEAD_NO 0 // alive
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <math.h>
|
||||
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4]; // x,y,z,w
|
||||
typedef vec_t vec5_t[5];
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef enum
|
|||
#define TRI_LINES 4
|
||||
#define TRI_TRIANGLE_STRIP 5
|
||||
#define TRI_QUAD_STRIP 6
|
||||
#define TRI_POINTS 7
|
||||
|
||||
typedef struct triangleapi_s
|
||||
{
|
||||
|
|
|
@ -48,11 +48,22 @@ public:
|
|||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
float m_flAltitude;
|
||||
float m_flCachedLength; // tongue cached length
|
||||
float m_flKillVictimTime;
|
||||
int m_cGibs;// barnacle loads up on gibs each time it kills something.
|
||||
int m_cGibs; // barnacle loads up on gibs each time it kills something.
|
||||
BOOL m_fTongueExtended;
|
||||
BOOL m_fLiftingPrey;
|
||||
float m_flTongueAdj;
|
||||
|
||||
// FIXME: need a custom barnacle model with non-generic hitgroup
|
||||
// otherwise we can apply to damage to tongue instead of body
|
||||
#ifdef BARNACLE_FIX_VISIBILITY
|
||||
void SetObjectCollisionBox( void )
|
||||
{
|
||||
pev->absmin = pev->origin + Vector( -16, -16, -m_flCachedLength );
|
||||
pev->absmax = pev->origin + Vector( 16, 16, 0 );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( monster_barnacle, CBarnacle );
|
||||
|
||||
|
@ -64,6 +75,7 @@ TYPEDESCRIPTION CBarnacle::m_SaveData[] =
|
|||
DEFINE_FIELD( CBarnacle, m_fTongueExtended, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBarnacle, m_fLiftingPrey, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBarnacle, m_flTongueAdj, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( CBarnacle, m_flCachedLength, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CBarnacle, CBaseMonster );
|
||||
|
@ -116,7 +128,8 @@ void CBarnacle :: Spawn()
|
|||
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
m_flKillVictimTime = 0;
|
||||
m_cGibs = 0;
|
||||
m_flCachedLength = 32; // mins.z
|
||||
m_cGibs = 0;
|
||||
m_fLiftingPrey = FALSE;
|
||||
m_flTongueAdj = -100;
|
||||
|
||||
|
@ -148,6 +161,14 @@ void CBarnacle :: BarnacleThink ( void )
|
|||
CBaseMonster *pVictim;
|
||||
float flLength;
|
||||
|
||||
#ifdef BARNACLE_FIX_VISIBILITY
|
||||
if( m_flCachedLength != ( m_flAltitude + m_flTongueAdj ) || ( pev->absmin.z != pev->origin.z + -m_flCachedLength ))
|
||||
{
|
||||
// recalc collision box here to avoid barnacle disappears bug
|
||||
m_flCachedLength = (m_flAltitude + m_flTongueAdj);
|
||||
UTIL_SetOrigin( pev, pev->origin );
|
||||
}
|
||||
#endif
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
if ( m_hEnemy != NULL )
|
||||
|
|
|
@ -181,7 +181,7 @@ qboolean CL_SnapshotGetName( int lastnum, char *filename )
|
|||
lastnum -= c * 10;
|
||||
d = lastnum;
|
||||
|
||||
Q_sprintf( filename, "../%s%i%i%i%i.bmp", clgame.mapname, a, b, c, d );
|
||||
Q_sprintf( filename, "../%s_%i%i%i%i.bmp", clgame.mapname, a, b, c, d );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ void CL_UpdateEntityFields( cl_entity_t *ent )
|
|||
{
|
||||
CL_SetTraceHull( 0 ); // g-cont. player hull for better detect moving platforms
|
||||
VectorSet( vecSrc, ent->origin[0], ent->origin[1], ent->origin[2] + ent->model->maxs[2] );
|
||||
VectorSet( vecEnd, vecSrc[0], vecSrc[1], vecSrc[2] - ent->model->mins[2] - 32 );
|
||||
VectorSet( vecEnd, vecSrc[0], vecSrc[1], vecSrc[2] - ent->model->mins[2] - 8 );
|
||||
CL_PlayerTraceExt( vecSrc, vecEnd, PM_STUDIO_IGNORE, CL_PushMoveFilter, &trace );
|
||||
m_pGround = CL_GetEntityByIndex( pfnIndexFromTrace( &trace ));
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean n
|
|||
ent->latched.prevcontroller[i] = newstate->controller[i];
|
||||
|
||||
// copy blends
|
||||
for( i = 0; i < 4; i++ )
|
||||
for( i = 0; i < 2; i++ )
|
||||
ent->latched.prevblending[i] = newstate->blending[i];
|
||||
return;
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean n
|
|||
else ent->latched.sequencetime = ent->curstate.animtime + 0.1f;
|
||||
|
||||
// save current blends to right lerping from last sequence
|
||||
for( i = 0; i < 4; i++ )
|
||||
for( i = 0; i < 2; i++ )
|
||||
ent->latched.prevseqblending[i] = ent->curstate.blending[i];
|
||||
ent->latched.prevsequence = ent->curstate.sequence; // save old sequence
|
||||
ent->syncbase = -0.01f; // back up to get 0'th frame animations
|
||||
|
@ -469,7 +469,7 @@ void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean n
|
|||
}
|
||||
|
||||
// copy blends
|
||||
for( i = 0; i < 4; i++ )
|
||||
for( i = 0; i < 2; i++ )
|
||||
ent->latched.prevblending[i] = ent->curstate.blending[i];
|
||||
|
||||
if( !VectorCompare( newstate->origin, ent->curstate.origin ))
|
||||
|
|
|
@ -86,6 +86,7 @@ static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
|
|||
{ "HUD_ChatInputPosition", (void **)&clgame.dllFuncs.pfnChatInputPosition },
|
||||
{ "HUD_GetRenderInterface", (void **)&clgame.dllFuncs.pfnGetRenderInterface },
|
||||
{ "HUD_GetPlayerTeam", (void **)&clgame.dllFuncs.pfnGetPlayerTeam },
|
||||
{ "HUD_ClipMoveToEntity", (void **)&clgame.dllFuncs.pfnClipMoveToEntity },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -1063,7 +1064,6 @@ void CL_InitEdicts( void )
|
|||
cls.packet_entities = Z_Realloc( cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
|
||||
clgame.entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities );
|
||||
clgame.static_entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
|
||||
clgame.efrags = Mem_Alloc( clgame.mempool, sizeof( efrag_t ) * MAX_EFRAGS );
|
||||
clgame.numStatics = 0;
|
||||
|
||||
if(( clgame.maxRemapInfos - 1 ) != clgame.maxEntities )
|
||||
|
@ -1084,10 +1084,6 @@ void CL_FreeEdicts( void )
|
|||
Mem_Free( clgame.static_entities );
|
||||
clgame.static_entities = NULL;
|
||||
|
||||
if( clgame.efrags )
|
||||
Mem_Free( clgame.efrags );
|
||||
clgame.efrags = NULL;
|
||||
|
||||
if( cls.packet_entities )
|
||||
Z_Free( cls.packet_entities );
|
||||
|
||||
|
@ -1674,7 +1670,7 @@ pfnDrawConsoleString
|
|||
drawing string like a console string
|
||||
=============
|
||||
*/
|
||||
static int pfnDrawConsoleString( int x, int y, char *string )
|
||||
int pfnDrawConsoleString( int x, int y, char *string )
|
||||
{
|
||||
int drawLen;
|
||||
|
||||
|
@ -1696,7 +1692,7 @@ pfnDrawSetTextColor
|
|||
set color for anything
|
||||
=============
|
||||
*/
|
||||
static void pfnDrawSetTextColor( float r, float g, float b )
|
||||
void pfnDrawSetTextColor( float r, float g, float b )
|
||||
{
|
||||
// bound color and convert to byte
|
||||
clgame.ds.textColor[0] = (byte)bound( 0, r * 255, 255 );
|
||||
|
@ -1705,7 +1701,7 @@ static void pfnDrawSetTextColor( float r, float g, float b )
|
|||
clgame.ds.textColor[3] = (byte)0xFF;
|
||||
}
|
||||
|
||||
static void pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
|
||||
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
|
||||
{
|
||||
Con_SetFont( con_fontsize->integer );
|
||||
Con_DrawStringLen( pText, length, height );
|
||||
|
@ -2926,6 +2922,9 @@ void TriBegin( int mode )
|
|||
{
|
||||
switch( mode )
|
||||
{
|
||||
case TRI_POINTS:
|
||||
mode = GL_POINTS;
|
||||
break;
|
||||
case TRI_TRIANGLES:
|
||||
mode = GL_TRIANGLES;
|
||||
break;
|
||||
|
|
|
@ -550,10 +550,14 @@ pfnDrawCharacter
|
|||
quakefont draw character
|
||||
=============
|
||||
*/
|
||||
static void pfnDrawCharacter( int x, int y, int width, int height, int ch, int ulRGBA, HIMAGE hFont )
|
||||
static void pfnDrawCharacter( int ix, int iy, int iwidth, int iheight, int ch, int ulRGBA, HIMAGE hFont )
|
||||
{
|
||||
rgba_t color;
|
||||
float row, col, size;
|
||||
float s1, t1, s2, t2;
|
||||
float x = ix, y = iy;
|
||||
float width = iwidth;
|
||||
float height = iheight;
|
||||
|
||||
ch &= 255;
|
||||
|
||||
|
@ -566,23 +570,32 @@ static void pfnDrawCharacter( int x, int y, int width, int height, int ch, int u
|
|||
color[2] = (ulRGBA & 0xFF) >> 0;
|
||||
pglColor4ubv( color );
|
||||
|
||||
col = (ch & 15) * 0.0625 + (0.5f / 256.0f);
|
||||
row = (ch >> 4) * 0.0625 + (0.5f / 256.0f);
|
||||
col = (ch & 15) * 0.0625f + (0.5f / 256.0f);
|
||||
row = (ch >> 4) * 0.0625f + (0.5f / 256.0f);
|
||||
size = 0.0625f - (1.0f / 256.0f);
|
||||
|
||||
s1 = col;
|
||||
t1 = row;
|
||||
s2 = s1 + size;
|
||||
t2 = t1 + size;
|
||||
|
||||
// pass scissor test if supposed
|
||||
if( menu.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
|
||||
return;
|
||||
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, col, row, col + size, row + size, hFont );
|
||||
R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, hFont );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnDrawConsoleString
|
||||
UI_DrawConsoleString
|
||||
|
||||
drawing string like a console string
|
||||
=============
|
||||
*/
|
||||
static int pfnDrawConsoleString( int x, int y, const char *string )
|
||||
static int UI_DrawConsoleString( int x, int y, const char *string )
|
||||
{
|
||||
int drawLen;
|
||||
|
||||
|
@ -600,7 +613,7 @@ pfnDrawSetTextColor
|
|||
set color for anything
|
||||
=============
|
||||
*/
|
||||
static void pfnDrawSetTextColor( int r, int g, int b, int alpha )
|
||||
static void UI_DrawSetTextColor( int r, int g, int b, int alpha )
|
||||
{
|
||||
// bound color and convert to byte
|
||||
menu.ds.textColor[0] = r;
|
||||
|
@ -889,8 +902,8 @@ static ui_enginefuncs_t gEngfuncs =
|
|||
UI_GetLogoHeight,
|
||||
UI_GetLogoLength,
|
||||
pfnDrawCharacter,
|
||||
pfnDrawConsoleString,
|
||||
pfnDrawSetTextColor,
|
||||
UI_DrawConsoleString,
|
||||
UI_DrawSetTextColor,
|
||||
Con_DrawStringLen,
|
||||
Con_DefaultColor,
|
||||
pfnGetPlayerModel,
|
||||
|
|
|
@ -29,6 +29,22 @@ void CL_ClearPhysEnts( void )
|
|||
clgame.pmove->numphysent = 0;
|
||||
}
|
||||
|
||||
void CL_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr )
|
||||
{
|
||||
ASSERT( tr != NULL );
|
||||
|
||||
if( clgame.dllFuncs.pfnClipMoveToEntity != NULL )
|
||||
{
|
||||
// do custom sweep test
|
||||
clgame.dllFuncs.pfnClipMoveToEntity( pe, start, mins, maxs, end, tr );
|
||||
}
|
||||
else
|
||||
{
|
||||
// function is missed, so we didn't hit anything
|
||||
tr->allsolid = false;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean CL_CopyEntityToPhysEnt( physent_t *pe, cl_entity_t *ent )
|
||||
{
|
||||
model_t *mod = Mod_Handle( ent->curstate.modelindex );
|
||||
|
@ -64,6 +80,12 @@ qboolean CL_CopyEntityToPhysEnt( physent_t *pe, cl_entity_t *ent )
|
|||
VectorCopy( ent->curstate.mins, pe->mins );
|
||||
VectorCopy( ent->curstate.maxs, pe->maxs );
|
||||
break;
|
||||
case SOLID_CUSTOM:
|
||||
pe->model = (mod->type == mod_brush) ? mod : NULL;
|
||||
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
|
||||
VectorCopy( ent->curstate.mins, pe->mins );
|
||||
VectorCopy( ent->curstate.maxs, pe->maxs );
|
||||
break;
|
||||
default:
|
||||
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
|
||||
VectorCopy( ent->curstate.mins, pe->mins );
|
||||
|
|
|
@ -923,6 +923,9 @@ void CL_BreakModel( const vec3_t pos, const vec3_t size, const vec3_t direction,
|
|||
vecSpot[1] = pos[1] + Com_RandomFloat( -0.5f, 0.5f ) * size[1];
|
||||
vecSpot[2] = pos[2] + Com_RandomFloat( -0.5f, 0.5f ) * size[2];
|
||||
|
||||
if( CL_PointContents( vecSpot ) == CONTENTS_SOLID )
|
||||
continue; // a piece stuck in the wall, ignore it
|
||||
|
||||
pTemp = CL_TempEntAlloc( vecSpot, Mod_Handle( modelIndex ));
|
||||
if( !pTemp ) return;
|
||||
|
||||
|
@ -2693,6 +2696,8 @@ EFRAGS MANAGEMENT
|
|||
|
||||
==============================================================
|
||||
*/
|
||||
efrag_t cl_efrags[MAX_EFRAGS];
|
||||
|
||||
/*
|
||||
==============
|
||||
CL_ClearEfrags
|
||||
|
@ -2702,10 +2707,10 @@ void CL_ClearEfrags( void )
|
|||
{
|
||||
int i;
|
||||
|
||||
Q_memset( clgame.efrags, 0, sizeof( clgame.efrags ));
|
||||
Q_memset( cl_efrags, 0, sizeof( cl_efrags ));
|
||||
|
||||
// allocate the efrags and chain together into a free list
|
||||
clgame.free_efrags = clgame.efrags;
|
||||
clgame.free_efrags = cl_efrags;
|
||||
for( i = 0; i < MAX_EFRAGS - 1; i++ )
|
||||
clgame.free_efrags[i].entnext = &clgame.free_efrags[i+1];
|
||||
clgame.free_efrags[i].entnext = NULL;
|
||||
|
|
|
@ -380,6 +380,7 @@ void V_PostRender( void )
|
|||
SCR_RSpeeds();
|
||||
SCR_NetSpeeds();
|
||||
SCR_DrawFPS();
|
||||
SV_DrawOrthoTriangles();
|
||||
CL_DrawDemoRecording();
|
||||
R_ShowTextures();
|
||||
CL_DrawHUD( CL_CHANGELEVEL );
|
||||
|
|
|
@ -351,6 +351,7 @@ typedef struct
|
|||
void (*pfnCalcRefdef)( ref_params_t *pparams );
|
||||
int (*pfnGetRenderInterface)( int version, render_api_t *renderfuncs, render_interface_t *callback );
|
||||
int (*pfnGetPlayerTeam)( int playerIndex );
|
||||
void (*pfnClipMoveToEntity)( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr );
|
||||
} HUD_FUNCTIONS;
|
||||
|
||||
typedef struct
|
||||
|
@ -403,7 +404,6 @@ typedef struct
|
|||
|
||||
net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more
|
||||
|
||||
efrag_t *efrags; // efrags pool
|
||||
efrag_t *free_efrags; // linked efrags
|
||||
cl_entity_t viewent; // viewmodel
|
||||
} clgame_static_t;
|
||||
|
|
|
@ -387,8 +387,10 @@ void R_DrawWaterSurfaces( void );
|
|||
void R_DrawBrushModel( cl_entity_t *e );
|
||||
void GL_SubdivideSurface( msurface_t *fa );
|
||||
void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa );
|
||||
void GL_SetupFogColorForSurfaces( void );
|
||||
void GL_RebuildLightmaps( void );
|
||||
void GL_BuildLightmaps( void );
|
||||
void GL_ResetFogColor( void );
|
||||
|
||||
//
|
||||
// gl_sprite.c
|
||||
|
|
|
@ -310,7 +310,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3
|
|||
|
||||
int R_LightTraceFilter( physent_t *pe )
|
||||
{
|
||||
if( !pe || pe->solid != SOLID_BSP )
|
||||
if( !pe || pe->solid != SOLID_BSP || pe->info == 0 )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -327,6 +327,7 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
|
|||
pmtrace_t trace;
|
||||
cl_entity_t *m_pGround;
|
||||
vec3_t start, end, dir;
|
||||
qboolean secondpass = false;
|
||||
float dist, add;
|
||||
model_t *pmodel;
|
||||
mnode_t *pnodes;
|
||||
|
@ -348,6 +349,7 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
|
|||
return;
|
||||
}
|
||||
|
||||
get_light:
|
||||
// Get lighting at this point
|
||||
VectorCopy( point, start );
|
||||
VectorCopy( point, end );
|
||||
|
@ -367,11 +369,12 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
|
|||
pnodes = pmodel->nodes;
|
||||
m_pGround = NULL;
|
||||
|
||||
if( r_lighting_extended->integer )
|
||||
if( r_lighting_extended->integer && !secondpass )
|
||||
{
|
||||
CL_SetTraceHull( 2 );
|
||||
CL_PlayerTraceExt( start, end, PM_STUDIO_IGNORE, R_LightTraceFilter, &trace );
|
||||
m_pGround = CL_GetEntityByIndex( pfnIndexFromTrace( &trace ));
|
||||
if( trace.startsolid || trace.allsolid ) m_pGround = NULL; // trace in solid
|
||||
}
|
||||
|
||||
if( m_pGround && m_pGround->model && m_pGround->model->type == mod_brush )
|
||||
|
@ -424,6 +427,14 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
|
|||
ambientLight->b = 255 * ambient;
|
||||
}
|
||||
|
||||
if( ambientLight->r == 0 && ambientLight->g == 0 && ambientLight->b == 0 && !secondpass )
|
||||
{
|
||||
// in some cases r_lighting_extended 1 does a wrong results
|
||||
// make another pass and try to get lighting info from world
|
||||
secondpass = true;
|
||||
goto get_light;
|
||||
}
|
||||
|
||||
// add dynamic lights
|
||||
if( radius && r_dynamic->integer )
|
||||
{
|
||||
|
|
|
@ -1040,7 +1040,8 @@ void R_DrawEntitiesOnList( void )
|
|||
while( pglGetError() != GL_NO_ERROR );
|
||||
|
||||
// don't fogging translucent surfaces
|
||||
pglDisable( GL_FOG );
|
||||
if( !RI.fogCustom )
|
||||
pglDisable( GL_FOG );
|
||||
pglDepthMask( GL_FALSE );
|
||||
glState.drawTrans = true;
|
||||
|
||||
|
|
|
@ -215,6 +215,35 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts
|
|||
Q_memcpy( poly->verts[i+1], poly->verts[1], sizeof( poly->verts[0] ));
|
||||
}
|
||||
|
||||
void GL_SetupFogColorForSurfaces( void )
|
||||
{
|
||||
vec3_t fogColor;
|
||||
float factor, div;
|
||||
|
||||
if(( !RI.fogEnabled && !RI.fogCustom ) || RI.refdef.onlyClientDraw )
|
||||
return;
|
||||
|
||||
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
|
||||
{
|
||||
pglFogfv( GL_FOG_COLOR, RI.fogColor );
|
||||
return;
|
||||
}
|
||||
|
||||
div = (r_detailtextures->integer) ? 2.0f : 1.0f;
|
||||
factor = (r_detailtextures->integer) ? 3.0f : 2.0f;
|
||||
fogColor[0] = pow( RI.fogColor[0] / div, ( 1.0f / factor ));
|
||||
fogColor[1] = pow( RI.fogColor[1] / div, ( 1.0f / factor ));
|
||||
fogColor[2] = pow( RI.fogColor[2] / div, ( 1.0f / factor ));
|
||||
pglFogfv( GL_FOG_COLOR, fogColor );
|
||||
}
|
||||
|
||||
void GL_ResetFogColor( void )
|
||||
{
|
||||
// restore fog here
|
||||
if(( RI.fogEnabled || RI.fogCustom ) && !RI.refdef.onlyClientDraw )
|
||||
pglFogfv( GL_FOG_COLOR, RI.fogColor );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
GL_SubdivideSurface
|
||||
|
@ -257,6 +286,8 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
|
|||
int i, lindex, lnumverts;
|
||||
medge_t *pedges, *r_pedge;
|
||||
int vertpage;
|
||||
texture_t *tex;
|
||||
gltexture_t *glt;
|
||||
float *vec;
|
||||
float s, t;
|
||||
glpoly_t *poly;
|
||||
|
@ -267,6 +298,20 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
|
|||
if( !fa->texinfo || !fa->texinfo->texture )
|
||||
return; // bad polygon ?
|
||||
|
||||
if( fa->flags & SURF_CONVEYOR && fa->texinfo->texture->gl_texturenum != 0 )
|
||||
{
|
||||
glt = R_GetTexture( fa->texinfo->texture->gl_texturenum );
|
||||
tex = fa->texinfo->texture;
|
||||
ASSERT( glt != NULL && tex != NULL );
|
||||
// DEBUG
|
||||
if( glt->srcWidth != tex->width )
|
||||
Msg( "Texture %s updates conveyor width from %i to %i\n", tex->name, glt->srcWidth, tex->width );
|
||||
|
||||
// update conveyor widths for properly scrolling speed
|
||||
glt->srcWidth = tex->width;
|
||||
glt->srcHeight = tex->height;
|
||||
}
|
||||
|
||||
// reconstruct the polygon
|
||||
pedges = mod->edges;
|
||||
lnumverts = fa->numedges;
|
||||
|
@ -634,6 +679,10 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
|
|||
cl_entity_t *e = RI.currententity;
|
||||
int i, hasScale = false;
|
||||
|
||||
// special hack for non-lightmapped surfaces
|
||||
if( p->flags & SURF_DRAWTILED )
|
||||
GL_ResetFogColor();
|
||||
|
||||
if( p->flags & SURF_CONVEYOR )
|
||||
{
|
||||
gltexture_t *texture;
|
||||
|
@ -679,6 +728,10 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
|
|||
}
|
||||
|
||||
pglEnd();
|
||||
|
||||
// special hack for non-lightmapped surfaces
|
||||
if( p->flags & SURF_DRAWTILED )
|
||||
GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -727,6 +780,8 @@ void R_BlendLightmaps( void )
|
|||
if( r_fullbright->integer || !cl.worldmodel->lightdata )
|
||||
return;
|
||||
|
||||
GL_SetupFogColorForSurfaces ();
|
||||
|
||||
if( RI.currententity )
|
||||
{
|
||||
// check for rendermode
|
||||
|
@ -868,6 +923,9 @@ void R_BlendLightmaps( void )
|
|||
pglDisable( GL_ALPHA_TEST );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||
}
|
||||
|
||||
// restore fog here
|
||||
GL_ResetFogColor();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -883,7 +941,7 @@ void R_RenderFullbrights( void )
|
|||
if( !draw_fullbrights )
|
||||
return;
|
||||
|
||||
if( !RI.fogCustom )
|
||||
if( RI.fogEnabled && !RI.refdef.onlyClientDraw )
|
||||
pglDisable( GL_FOG );
|
||||
|
||||
pglEnable( GL_BLEND );
|
||||
|
@ -935,6 +993,8 @@ void R_RenderDetails( void )
|
|||
if( !draw_details )
|
||||
return;
|
||||
|
||||
GL_SetupFogColorForSurfaces();
|
||||
|
||||
pglEnable( GL_BLEND );
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
|
||||
|
@ -967,6 +1027,9 @@ void R_RenderDetails( void )
|
|||
pglDepthFunc( GL_LEQUAL );
|
||||
|
||||
draw_details = false;
|
||||
|
||||
// restore fog here
|
||||
GL_ResetFogColor();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1026,12 +1089,35 @@ void R_RenderBrushPoly( msurface_t *fa )
|
|||
draw_fullbrights = true;
|
||||
}
|
||||
|
||||
if( r_detailtextures->integer && t->dt_texturenum )
|
||||
if( r_detailtextures->integer )
|
||||
{
|
||||
mextrasurf_t *es = SURF_INFO( fa, RI.currentmodel );
|
||||
es->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = es;
|
||||
draw_details = true;
|
||||
|
||||
if( RI.fogEnabled || RI.fogCustom )
|
||||
{
|
||||
// don't apply detail textures for windows in the fog
|
||||
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
|
||||
{
|
||||
if( t->dt_texturenum )
|
||||
{
|
||||
es->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = es;
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw stub detail texture for underwater surfaces
|
||||
es->detailchain = detail_surfaces[tr.grayTexture];
|
||||
detail_surfaces[tr.grayTexture] = es;
|
||||
}
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
else if( t->dt_texturenum )
|
||||
{
|
||||
es->detailchain = detail_surfaces[t->dt_texturenum];
|
||||
detail_surfaces[t->dt_texturenum] = es;
|
||||
draw_details = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( is_mirror ) R_BeginDrawMirror( fa );
|
||||
|
@ -1110,6 +1196,8 @@ void R_DrawTextureChains( void )
|
|||
pglColor4ub( 255, 255, 255, 255 );
|
||||
R_LoadIdentity(); // set identity matrix
|
||||
|
||||
GL_SetupFogColorForSurfaces();
|
||||
|
||||
// restore worldmodel
|
||||
RI.currententity = clgame.entities;
|
||||
RI.currentmodel = RI.currententity->model;
|
||||
|
@ -1141,6 +1229,8 @@ void R_DrawTextureChains( void )
|
|||
}
|
||||
t->texturechain = NULL;
|
||||
}
|
||||
|
||||
GL_ResetFogColor();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1306,6 +1396,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
|
||||
// setup the rendermode
|
||||
GL_SetRenderMode( e->curstate.rendermode );
|
||||
GL_SetupFogColorForSurfaces ();
|
||||
|
||||
// setup the color and alpha
|
||||
switch( e->curstate.rendermode )
|
||||
|
@ -1360,6 +1451,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
if( e->curstate.rendermode == kRenderTransColor )
|
||||
pglEnable( GL_TEXTURE_2D );
|
||||
|
||||
GL_ResetFogColor();
|
||||
R_BlendLightmaps();
|
||||
R_RenderFullbrights();
|
||||
R_RenderDetails();
|
||||
|
|
|
@ -959,6 +959,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
break;
|
||||
case kRenderGlow:
|
||||
case kRenderTransAdd:
|
||||
pglDisable( GL_FOG );
|
||||
pglEnable( GL_BLEND );
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
break;
|
||||
|
@ -1108,4 +1109,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
|
|||
pglDepthFunc( GL_LEQUAL );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
|
||||
if( RI.fogCustom || ( RI.fogEnabled && !glState.drawTrans ))
|
||||
pglEnable( GL_FOG );
|
||||
}
|
|
@ -57,6 +57,12 @@ typedef struct studiolight_s
|
|||
int numelights;
|
||||
} studiolight_t;
|
||||
|
||||
typedef struct sortedmesh_s
|
||||
{
|
||||
mstudiomesh_t *mesh;
|
||||
int flags; // face flags
|
||||
} sortedmesh_t;
|
||||
|
||||
convar_t *r_studio_lerping;
|
||||
convar_t *r_studio_lambert;
|
||||
convar_t *r_studio_lighting;
|
||||
|
@ -71,6 +77,7 @@ static matrix3x4 g_aliastransform; // software renderer transform
|
|||
static matrix3x4 g_rotationmatrix;
|
||||
static vec3_t g_chrome_origin;
|
||||
static vec2_t g_chrome[MAXSTUDIOVERTS]; // texture coords for surface normals
|
||||
static sortedmesh_t g_sortedMeshes[MAXSTUDIOMESHES];
|
||||
static matrix3x4 g_bonestransform[MAXSTUDIOBONES];
|
||||
static matrix3x4 g_lighttransform[MAXSTUDIOBONES];
|
||||
static matrix3x4 g_rgCachedBonesTransform[MAXSTUDIOBONES];
|
||||
|
@ -1416,7 +1423,14 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo )
|
|||
plight->numdlights = 0; // clear previous dlights
|
||||
|
||||
if( r_studio_lighting->integer == 2 )
|
||||
{
|
||||
Matrix3x4_OriginFromMatrix( g_lighttransform[0], origin );
|
||||
|
||||
// NOTE: in some cases bone origin may be stuck in the geometry
|
||||
// and produced completely black model. Run additional check for this case
|
||||
if( CL_PointContents( origin ) == CONTENTS_SOLID )
|
||||
Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
|
||||
}
|
||||
else Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
|
||||
|
||||
// setup light dir
|
||||
|
@ -1527,7 +1541,14 @@ void R_StudioEntityLight( alight_t *lightinfo )
|
|||
plight->numelights = 0; // clear previous elights
|
||||
|
||||
if( r_studio_lighting->integer == 2 )
|
||||
{
|
||||
Matrix3x4_OriginFromMatrix( g_lighttransform[0], origin );
|
||||
|
||||
// NOTE: in some cases bone origin may be stuck in the geometry
|
||||
// and produced completely black model. Run additional check for this case
|
||||
if( CL_PointContents( origin ) == CONTENTS_SOLID )
|
||||
Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
|
||||
}
|
||||
else Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
|
||||
|
||||
for( lnum = 0, el = cl_elights; lnum < MAX_ELIGHTS; lnum++, el++ )
|
||||
|
@ -1779,6 +1800,24 @@ mstudiotexture_t *R_StudioGetTexture( cl_entity_t *e )
|
|||
return ptexture;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SolidEntityCompare
|
||||
|
||||
Sorting opaque entities by model type
|
||||
===============
|
||||
*/
|
||||
static int R_StudioMeshCompare( const sortedmesh_t *a, const sortedmesh_t *b )
|
||||
{
|
||||
if( a->flags & STUDIO_NF_ADDITIVE )
|
||||
return 1;
|
||||
|
||||
if( a->flags & STUDIO_NF_TRANSPARENT )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioDrawPoints
|
||||
|
@ -1840,6 +1879,10 @@ static void R_StudioDrawPoints( void )
|
|||
{
|
||||
g_nFaceFlags = ptexture[pskinref[pmesh[j].skinref]].flags;
|
||||
|
||||
// fill in sortedmesh info
|
||||
g_sortedMeshes[j].mesh = &pmesh[j];
|
||||
g_sortedMeshes[j].flags = g_nFaceFlags;
|
||||
|
||||
for( i = 0; i < pmesh[j].numnorms; i++, lv += 3, pstudionorms++, pnormbone++ )
|
||||
{
|
||||
R_StudioLighting( lv, *pnormbone, g_nFaceFlags, (float *)pstudionorms );
|
||||
|
@ -1849,18 +1892,25 @@ static void R_StudioDrawPoints( void )
|
|||
}
|
||||
}
|
||||
|
||||
// sort opaque and translucent for right results
|
||||
qsort( g_sortedMeshes, m_pSubModel->nummesh, sizeof( sortedmesh_t ), R_StudioMeshCompare );
|
||||
|
||||
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
||||
{
|
||||
float s, t, alpha;
|
||||
short *ptricmds;
|
||||
|
||||
pmesh = (mstudiomesh_t *)((byte *)m_pStudioHeader + m_pSubModel->meshindex) + j;
|
||||
pmesh = g_sortedMeshes[j].mesh;
|
||||
ptricmds = (short *)((byte *)m_pStudioHeader + pmesh->triindex);
|
||||
|
||||
g_nFaceFlags = ptexture[pskinref[pmesh->skinref]].flags;
|
||||
s = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].width;
|
||||
t = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].height;
|
||||
|
||||
if( g_iRenderMode != kRenderTransAdd )
|
||||
pglDepthMask( GL_TRUE );
|
||||
else pglDepthMask( GL_FALSE );
|
||||
|
||||
// check bounds
|
||||
if( ptexture[pskinref[pmesh->skinref]].index < 0 || ptexture[pskinref[pmesh->skinref]].index > MAX_TEXTURES )
|
||||
ptexture[pskinref[pmesh->skinref]].index = tr.defaultTexture;
|
||||
|
@ -1881,7 +1931,8 @@ static void R_StudioDrawPoints( void )
|
|||
{
|
||||
GL_SetRenderMode( kRenderTransAdd );
|
||||
alpha = RI.currententity->curstate.renderamt * (1.0f / 255.0f);
|
||||
pglBlendFunc( GL_ONE, GL_ONE );
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
pglDepthMask( GL_FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1999,6 +2050,10 @@ static void R_StudioDrawPoints( void )
|
|||
pglEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// restore depthmask for next call StudioDrawPoints
|
||||
if( g_iRenderMode != kRenderTransAdd )
|
||||
pglDepthMask( GL_TRUE );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2449,8 +2504,9 @@ static void R_StudioRestoreRenderer( void )
|
|||
pglShadeModel( GL_FLAT );
|
||||
|
||||
// restore depthmask state for sprites etc
|
||||
if( glState.drawTrans && g_iRenderMode != kRenderTransAdd )
|
||||
if( glState.drawTrans )
|
||||
pglDepthMask( GL_FALSE );
|
||||
else pglDepthMask( GL_TRUE );
|
||||
|
||||
m_fDoRemap = false;
|
||||
}
|
||||
|
|
|
@ -1297,6 +1297,8 @@ void R_Free_OpenGL( void )
|
|||
{
|
||||
VID_RestoreGamma ();
|
||||
|
||||
GL_DeleteContext ();
|
||||
|
||||
VID_DestroyWindow ();
|
||||
|
||||
Sys_FreeLibrary( &opengl_dll );
|
||||
|
@ -1355,6 +1357,9 @@ static void GL_SetDefaults( void )
|
|||
pglEnable( GL_TEXTURE_2D );
|
||||
pglShadeModel( GL_FLAT );
|
||||
|
||||
pglPointSize( 1.2f );
|
||||
pglLineWidth( 1.2f );
|
||||
|
||||
GL_Cull( 0 );
|
||||
GL_FrontFace( 0 );
|
||||
|
||||
|
@ -1453,7 +1458,7 @@ void GL_InitCommands( void )
|
|||
gl_texture_lodbias = Cvar_Get( "gl_texture_lodbias", "0.0", CVAR_ARCHIVE, "LOD bias for mipmapped textures" );
|
||||
gl_compress_textures = Cvar_Get( "gl_compress_textures", "0", CVAR_GLCONFIG, "compress textures to safe video memory" );
|
||||
gl_luminance_textures = Cvar_Get( "gl_luminance_textures", "0", CVAR_GLCONFIG, "force all textures to luminance" );
|
||||
gl_allow_static = Cvar_Get( "gl_allow_static", "1", CVAR_ARCHIVE, "force to drawing non-moveable brushes as part of world (save FPS)" );
|
||||
gl_allow_static = Cvar_Get( "gl_allow_static", "0", CVAR_ARCHIVE, "force to drawing non-moveable brushes as part of world (save FPS)" );
|
||||
gl_allow_mirrors = Cvar_Get( "gl_allow_mirrors", "1", CVAR_ARCHIVE, "allow to draw mirror surfaces" );
|
||||
gl_showtextures = Cvar_Get( "r_showtextures", "0", CVAR_CHEAT, "show all uploaded textures (type values from 1 to 13)" );
|
||||
gl_finish = Cvar_Get( "gl_finish", "0", CVAR_ARCHIVE, "use glFinish instead of glFlush" );
|
||||
|
|
|
@ -594,6 +594,9 @@ void EmitWaterPolys( glpoly_t *polys, qboolean noCull )
|
|||
// set the current waveheight
|
||||
waveHeight = RI.currentWaveHeight;
|
||||
|
||||
// reset fog color for nonlightmapped water
|
||||
GL_ResetFogColor();
|
||||
|
||||
for( p = polys; p; p = p->next )
|
||||
{
|
||||
pglBegin( GL_POLYGON );
|
||||
|
@ -625,6 +628,8 @@ void EmitWaterPolys( glpoly_t *polys, qboolean noCull )
|
|||
|
||||
// restore culling
|
||||
if( noCull ) pglEnable( GL_CULL_FACE );
|
||||
|
||||
GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1741,9 +1741,9 @@ qboolean S_Init( void )
|
|||
s_refdist = Cvar_Get( "s_refdist", "36", 0, "soundlevel reference distance" );
|
||||
s_refdb = Cvar_Get( "s_refdb", "60", 0, "soundlevel refernce dB" );
|
||||
snd_gain = Cvar_Get( "snd_gain", "1", 0, "sound default gain" );
|
||||
s_cull = Cvar_Get( "s_cull", "1", CVAR_ARCHIVE, "cull sounds by geometry" );
|
||||
s_cull = Cvar_Get( "s_cull", "0", CVAR_ARCHIVE, "cull sounds by geometry" );
|
||||
s_test = Cvar_Get( "s_test", "0", 0, "engine developer cvar for quick testing new features" );
|
||||
s_phs = Cvar_Get( "s_phs", "1", CVAR_ARCHIVE, "cull sounds by PHS" );
|
||||
s_phs = Cvar_Get( "s_phs", "0", CVAR_ARCHIVE, "cull sounds by PHS" );
|
||||
|
||||
Cmd_AddCommand( "play", S_Play_f, "playing a specified sound file" );
|
||||
Cmd_AddCommand( "stopsound", S_StopSound_f, "stop all sounds" );
|
||||
|
|
|
@ -624,6 +624,9 @@ cvar_t *pfnCvar_RegisterVariable( const char *szName, const char *szValue, int f
|
|||
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
|
||||
byte* COM_LoadFileForMe( const char *filename, int *pLength );
|
||||
cvar_t *pfnCVarGetPointer( const char *szVarName );
|
||||
int pfnDrawConsoleString( int x, int y, char *string );
|
||||
void pfnDrawSetTextColor( float r, float g, float b );
|
||||
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height );
|
||||
int pfnAddClientCommand( const char *cmd_name, xcommand_t func );
|
||||
void *Cache_Check( byte *mempool, struct cache_user_s *c );
|
||||
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
|
||||
|
@ -742,6 +745,7 @@ struct cl_entity_s *CL_GetEntityByIndex( int index );
|
|||
struct cl_entity_s *CL_GetLocalPlayer( void );
|
||||
struct player_info_s *CL_GetPlayerInfo( int playerIndex );
|
||||
void SV_DrawDebugTriangles( void );
|
||||
void SV_DrawOrthoTriangles( void );
|
||||
qboolean UI_CreditsActive( void );
|
||||
void CL_ExtraUpdate( void );
|
||||
int CL_GetMaxClients( void );
|
||||
|
@ -749,6 +753,8 @@ qboolean CL_IsPlaybackDemo( void );
|
|||
qboolean CL_LoadProgs( const char *name );
|
||||
qboolean SV_GetComment( const char *savename, char *comment );
|
||||
qboolean SV_NewGame( const char *mapName, qboolean loadGame );
|
||||
void SV_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
|
||||
void CL_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
|
||||
void SV_SysError( const char *error_string );
|
||||
void SV_InitGameProgs( void );
|
||||
void SV_FreeGameProgs( void );
|
||||
|
|
|
@ -673,6 +673,13 @@ void _Q_memset( void *dest, int set, size_t count, const char *filename, int fil
|
|||
memset( dest, set, count );
|
||||
}
|
||||
|
||||
int _Q_memcmp( const void *src0, const void *src1, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
if( src0 == NULL ) Sys_Error( "memcmp: src1 == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if( src1 == NULL ) Sys_Error( "memcmp: src2 == NULL (called at %s:%i)\n", filename, fileline );
|
||||
return memcmp( src0, src1, count );
|
||||
}
|
||||
|
||||
void CRT_Init( void )
|
||||
{
|
||||
Memory_Init();
|
||||
|
|
|
@ -175,8 +175,10 @@ char *Q_pretifymem( float value, int digitsafterdecimal );
|
|||
char *va( const char *format, ... );
|
||||
#define Q_memcpy( dest, src, size ) _Q_memcpy( dest, src, size, __FILE__, __LINE__ )
|
||||
#define Q_memset( dest, val, size ) _Q_memset( dest, val, size, __FILE__, __LINE__ )
|
||||
#define Q_memcmp( src0, src1, siz ) _Q_memcmp( src0, src1, siz, __FILE__, __LINE__ )
|
||||
void _Q_memset( void *dest, int set, size_t count, const char *filename, int fileline );
|
||||
void _Q_memcpy( void *dest, const void *src, size_t count, const char *filename, int fileline );
|
||||
int _Q_memcmp( const void *src0, const void *src1, size_t count, const char *filename, int fileline );
|
||||
|
||||
//
|
||||
// zone.c
|
||||
|
|
|
@ -68,8 +68,8 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize )
|
|||
// bogus info header check
|
||||
if( bhdr.fileSize != filesize )
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadBMP: incorrect file size %i should be %i\n", filesize, bhdr.fileSize );
|
||||
return false;
|
||||
// Sweet Half-Life issues. splash.bmp have bogus filesize
|
||||
MsgDev( D_WARN, "Image_LoadBMP: %s have incorrect file size %i should be %i\n", name, filesize, bhdr.fileSize );
|
||||
}
|
||||
|
||||
// bogus compression? Only non-compressed supported.
|
||||
|
|
|
@ -554,6 +554,8 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam )
|
|||
// intentional fallthrough
|
||||
case WM_KEYDOWN:
|
||||
Key_Event( Host_MapKey( lParam ), true );
|
||||
if( Host_MapKey( lParam ) == K_ALT )
|
||||
return 0; // prevent WC_SYSMENU call
|
||||
break;
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
|
|
|
@ -328,9 +328,18 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
|
|||
if(( flags & PM_GLASS_IGNORE ) && pe->rendermode != kRenderNormal )
|
||||
continue;
|
||||
|
||||
if(( flags & PM_CUSTOM_IGNORE ) && pe->solid == SOLID_CUSTOM )
|
||||
continue;
|
||||
|
||||
hullcount = 1;
|
||||
|
||||
if( !pe->model )
|
||||
if( pe->solid == SOLID_CUSTOM )
|
||||
{
|
||||
VectorCopy( pmove->player_mins[pmove->usehull], mins );
|
||||
VectorCopy( pmove->player_maxs[pmove->usehull], maxs );
|
||||
VectorClear( offset );
|
||||
}
|
||||
else if( !pe->model )
|
||||
{
|
||||
if( !pe->studiomodel )
|
||||
{
|
||||
|
@ -414,6 +423,13 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
|
|||
// g-cont. probably this never happens
|
||||
trace_bbox.allsolid = false;
|
||||
}
|
||||
else if( pe->solid == SOLID_CUSTOM )
|
||||
{
|
||||
// run custom sweep callback
|
||||
if( pmove->server )
|
||||
SV_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox );
|
||||
else CL_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox );
|
||||
}
|
||||
else if( hullcount == 1 )
|
||||
{
|
||||
PM_RecursiveHullCheck( hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace_bbox );
|
||||
|
@ -424,7 +440,7 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
|
|||
|
||||
for( last_hitgroup = 0, j = 0; j < hullcount; j++ )
|
||||
{
|
||||
Q_memset(&trace_hitbox, 0, sizeof( trace_hitbox ));
|
||||
Q_memset( &trace_hitbox, 0, sizeof( trace_hitbox ));
|
||||
VectorCopy( end, trace_hitbox.endpos );
|
||||
trace_hitbox.allsolid = true;
|
||||
trace_hitbox.fraction = 1.0f;
|
||||
|
@ -506,7 +522,13 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
|
|||
|
||||
hullcount = 1;
|
||||
|
||||
if( pe->model )
|
||||
if( pe->solid == SOLID_CUSTOM )
|
||||
{
|
||||
VectorCopy( pmove->player_mins[pmove->usehull], mins );
|
||||
VectorCopy( pmove->player_maxs[pmove->usehull], maxs );
|
||||
VectorClear( offset );
|
||||
}
|
||||
else if( pe->model )
|
||||
{
|
||||
hull = PM_HullForBsp( pe, pmove, offset );
|
||||
}
|
||||
|
@ -558,7 +580,25 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
|
|||
VectorSubtract( pos, offset, pos_l );
|
||||
}
|
||||
|
||||
if( hullcount == 1 )
|
||||
if( pe->solid == SOLID_CUSTOM )
|
||||
{
|
||||
pmtrace_t trace;
|
||||
|
||||
Q_memset( &trace, 0, sizeof( trace ));
|
||||
VectorCopy( pos, trace.endpos );
|
||||
trace.allsolid = true;
|
||||
trace.fraction = 1.0f;
|
||||
|
||||
// run custom sweep callback
|
||||
if( pmove->server )
|
||||
SV_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace );
|
||||
else CL_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace );
|
||||
|
||||
// if we inside the custom hull
|
||||
if( trace.allsolid )
|
||||
return i;
|
||||
}
|
||||
else if( hullcount == 1 )
|
||||
{
|
||||
if( PM_HullPointContents( hull, hull->firstclipnode, pos_l ) == CONTENTS_SOLID )
|
||||
return i;
|
||||
|
|
|
@ -42,15 +42,20 @@ typedef struct server_physics_api_s
|
|||
void ( *pfnLinkEdict) ( edict_t *ent, qboolean touch_triggers );
|
||||
double ( *pfnGetServerTime )( void ); // unclamped
|
||||
double ( *pfnGetFrameTime )( void ); // unclamped
|
||||
void* ( *pfnGetModel)( int modelindex );
|
||||
areanode_t* ( *pfnGetHeadnode)( void ); // BSP tree for all physic entities
|
||||
int ( *pfnServerState)( void );
|
||||
void ( *pfnHost_Error)( const char *error, ... ); // cause Host Error
|
||||
|
||||
void* ( *pfnGetModel )( int modelindex );
|
||||
areanode_t* ( *pfnGetHeadnode )( void ); // BSP tree for all physic entities
|
||||
int ( *pfnServerState )( void );
|
||||
void ( *pfnHost_Error )( const char *error, ... ); // cause Host Error
|
||||
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
|
||||
struct triangleapi_s *pTriAPI; // draw coliisions etc. Only for local system
|
||||
|
||||
// draw debug messages (must be called from DrawOrthoTriangles). Only for local system
|
||||
int ( *pfnDrawConsoleString )( int x, int y, char *string );
|
||||
void ( *pfnDrawSetTextColor )( float r, float g, float b );
|
||||
void ( *pfnDrawConsoleStringLen )( const char *string, int *length, int *height );
|
||||
void ( *Con_NPrintf )( int pos, char *fmt, ... );
|
||||
void ( *Con_NXPrintf )( struct con_nprint_s *info, char *fmt, ... );
|
||||
} server_physics_api_t;
|
||||
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
|
||||
|
||||
// physic callbacks
|
||||
typedef struct physics_interface_s
|
||||
|
@ -66,14 +71,21 @@ typedef struct physics_interface_s
|
|||
void ( *SV_UpdatePlayerBaseVelocity )( edict_t *ent );
|
||||
// The game .dll should return 1 if save game should be allowed
|
||||
int ( *SV_AllowSaveGame )( void );
|
||||
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
|
||||
// override trigger area checking and touching
|
||||
int ( *SV_TriggerTouch )( edict_t *pent, edict_t *trigger );
|
||||
// some engine features can be enabled only through this function
|
||||
unsigned int ( *SV_CheckFeatures )( void );
|
||||
// used for draw debug collisions for custom physic engine etc
|
||||
void ( *DrawDebugTriangles)( void );
|
||||
void ( *DrawDebugTriangles )( void );
|
||||
// used for draw debug overlay (textured)
|
||||
void ( *DrawNormalTriangles)( void );
|
||||
void ( *DrawNormalTriangles )( void );
|
||||
// used for draw debug messages (2d mode)
|
||||
void ( *DrawOrthoTriangles )( void );
|
||||
// tracing entities with SOLID_CUSTOM mode on a server (not used by pmove code)
|
||||
void ( *ClipMoveToEntity)( edict_t *ent, const float *start, float *mins, float *maxs, const float *end, trace_t *trace );
|
||||
// tracing entities with SOLID_CUSTOM mode on a server (only used by pmove code)
|
||||
void ( *ClipPMoveToEntity)( struct physent_s *pe, const float *start, float *mins, float *maxs, const float *end, struct pmtrace_s *tr );
|
||||
} physics_interface_t;
|
||||
|
||||
#endif//PHYSINT_H
|
|
@ -411,7 +411,6 @@ extern convar_t *sv_allow_upload;
|
|||
extern convar_t *sv_allow_download;
|
||||
extern convar_t *sv_allow_studio_attachment_angles;
|
||||
extern convar_t *sv_allow_rotate_pushables;
|
||||
extern convar_t *sv_fix_pushstep;
|
||||
extern convar_t *sv_clienttrace;
|
||||
extern convar_t *sv_send_resources;
|
||||
extern convar_t *sv_send_logos;
|
||||
|
@ -613,6 +612,7 @@ void SV_ClearWorld( void );
|
|||
void SV_UnlinkEdict( edict_t *ent );
|
||||
qboolean SV_HeadnodeVisible( mnode_t *node, byte *visbits, int *lastleaf );
|
||||
void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, trace_t *trace );
|
||||
void SV_CustomClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, trace_t *trace );
|
||||
trace_t SV_TraceHull( edict_t *ent, int hullNum, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end );
|
||||
trace_t SV_Move( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int type, edict_t *e );
|
||||
trace_t SV_MoveNoEnts( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int type, edict_t *e );
|
||||
|
|
|
@ -245,6 +245,32 @@ gotnewcl:
|
|||
svs.last_heartbeat = MAX_HEARTBEAT;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_DisconnectClient
|
||||
|
||||
Disconnect client callback
|
||||
==================
|
||||
*/
|
||||
void SV_DisconnectClient( edict_t *pClient )
|
||||
{
|
||||
if( !pClient ) return;
|
||||
|
||||
// don't send to other clients
|
||||
pClient->v.modelindex = 0;
|
||||
|
||||
if( pClient->pvPrivateData != NULL )
|
||||
{
|
||||
// NOTE: new interface can be missing
|
||||
if( svgame.dllFuncs2.pfnOnFreeEntPrivateData != NULL )
|
||||
svgame.dllFuncs2.pfnOnFreeEntPrivateData( pClient );
|
||||
|
||||
// clear any dlls data but keep engine data
|
||||
Mem_Free( pClient->pvPrivateData );
|
||||
pClient->pvPrivateData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_FakeConnect
|
||||
|
@ -380,20 +406,7 @@ void SV_DropClient( sv_client_t *drop )
|
|||
}
|
||||
|
||||
// let the game known about client state
|
||||
svgame.dllFuncs.pfnClientDisconnect( drop->edict );
|
||||
|
||||
// don't send to other clients
|
||||
drop->edict->v.modelindex = 0;
|
||||
if( drop->edict->pvPrivateData )
|
||||
{
|
||||
// NOTE: new interface can be missing
|
||||
if( svgame.dllFuncs2.pfnOnFreeEntPrivateData )
|
||||
svgame.dllFuncs2.pfnOnFreeEntPrivateData( drop->edict );
|
||||
|
||||
// clear any dlls data but keep engine data
|
||||
Mem_Free( drop->edict->pvPrivateData );
|
||||
drop->edict->pvPrivateData = NULL;
|
||||
}
|
||||
SV_DisconnectClient( drop->edict );
|
||||
|
||||
drop->fakeclient = false;
|
||||
drop->hltv_proxy = false;
|
||||
|
@ -2054,7 +2067,8 @@ static void SV_ParseClientMove( sv_client_t *cl, sizebuf_t *msg )
|
|||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( cmds[0].viewangles, player->v.v_angle );
|
||||
if( !player->v.fixangle )
|
||||
VectorCopy( cmds[0].viewangles, player->v.v_angle );
|
||||
}
|
||||
|
||||
player->v.button = cmds[0].buttons;
|
||||
|
|
|
@ -454,9 +454,26 @@ void SV_ChangeLevel_f( void )
|
|||
}
|
||||
}
|
||||
|
||||
// bad changelevel position invoke enables in one-way transtion
|
||||
if( sv.net_framenum < 15 )
|
||||
{
|
||||
if( sv_validate_changelevel->integer )
|
||||
{
|
||||
MsgDev( D_INFO, "SV_ChangeLevel: a infinite changelevel detected.\n" );
|
||||
MsgDev( D_INFO, "Changelevel will be disabled until a next save\\restore.\n" );
|
||||
return; // lock with svs.spawncount here
|
||||
}
|
||||
}
|
||||
|
||||
if( sv.state != ss_active )
|
||||
{
|
||||
MsgDev( D_INFO, "Only the server may changelevel\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
SCR_BeginLoadingPlaque( false );
|
||||
|
||||
if( sv.state != ss_active || sv.background )
|
||||
if( sv.background )
|
||||
{
|
||||
// just load map
|
||||
Cbuf_AddText( va( "map %s\n", mapname ));
|
||||
|
|
|
@ -1172,7 +1172,7 @@ void pfnChangeLevel( const char* s1, const char* s2 )
|
|||
if( svs.changelevel_next_time > host.realtime )
|
||||
return;
|
||||
|
||||
svs.changelevel_next_time = host.realtime + 0.5f; // rest 1 secs if failed
|
||||
svs.changelevel_next_time = host.realtime + 0.5f; // rest 0.5f secs if failed
|
||||
|
||||
// make sure we don't issue two changelevels
|
||||
if( svs.spawncount == last_spawncount )
|
||||
|
@ -2127,7 +2127,13 @@ static void pfnTraceModel( const float *v1, const float *v2, int hullNumber, edi
|
|||
mins = sv.worldmodel->hulls[hullNumber].clip_mins;
|
||||
maxs = sv.worldmodel->hulls[hullNumber].clip_maxs;
|
||||
|
||||
if( Mod_GetType( pent->v.modelindex ) == mod_brush )
|
||||
if( pent->v.solid == SOLID_CUSTOM )
|
||||
{
|
||||
// NOTE: always goes through custom clipping move
|
||||
// even if our callbacks is not initialized
|
||||
SV_CustomClipMoveToEntity( pent, v1, mins, maxs, v2, &trace );
|
||||
}
|
||||
else if( Mod_GetType( pent->v.modelindex ) == mod_brush )
|
||||
{
|
||||
int oldmovetype = pent->v.movetype;
|
||||
int oldsolid = pent->v.solid;
|
||||
|
@ -3602,7 +3608,8 @@ void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex,
|
|||
|
||||
if( SV_IsValidEdict( pInvoker ))
|
||||
{
|
||||
VectorCopy( pInvoker->v.origin, pvspoint );
|
||||
// add the view_ofs to avoid problems with crossed contents line
|
||||
VectorAdd( pInvoker->v.origin, pInvoker->v.view_ofs, pvspoint );
|
||||
args.entindex = invokerIndex = NUM_FOR_EDICT( pInvoker );
|
||||
|
||||
// g-cont. allow 'ducking' param for all entities
|
||||
|
|
|
@ -625,7 +625,6 @@ void SV_InitGame( void )
|
|||
svgame.globals->maxClients = sv_maxclients->integer;
|
||||
SV_UPDATE_BACKUP = ( svgame.globals->maxClients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
|
||||
|
||||
svs.spawncount = Com_RandomLong( 0, 65535 );
|
||||
svs.clients = Z_Malloc( sizeof( sv_client_t ) * sv_maxclients->integer );
|
||||
svs.num_client_entities = sv_maxclients->integer * SV_UPDATE_BACKUP * 64;
|
||||
svs.packet_entities = Z_Malloc( sizeof( entity_state_t ) * svs.num_client_entities );
|
||||
|
|
|
@ -64,7 +64,6 @@ convar_t *sv_send_resources;
|
|||
convar_t *sv_send_logos;
|
||||
convar_t *sv_sendvelocity;
|
||||
convar_t *sv_airmove;
|
||||
convar_t *sv_fix_pushstep;
|
||||
convar_t *sv_quakehulls;
|
||||
convar_t *mp_consistency;
|
||||
convar_t *serverinfo;
|
||||
|
@ -711,7 +710,6 @@ void SV_Init( void )
|
|||
sv_send_logos = Cvar_Get( "sv_send_logos", "1", 0, "send custom player decals to other clients" );
|
||||
sv_send_resources = Cvar_Get( "sv_send_resources", "1", 0, "send generic resources that specified in 'mapname.res'" );
|
||||
sv_sendvelocity = Cvar_Get( "sv_sendvelocity", "1", CVAR_ARCHIVE, "force to send velocity for event_t structure across network" );
|
||||
sv_fix_pushstep = Cvar_Get( "sv_fix_pushstep", "0", CVAR_ARCHIVE, "allow the 'func_pushable' push the clients which standing on when the entity is floating in water" );
|
||||
sv_quakehulls = Cvar_Get( "sv_quakehulls", "0", CVAR_ARCHIVE, "using quake style hull select instead of half-life style hull select" );
|
||||
mp_consistency = Cvar_Get( "mp_consistency", "1", CVAR_SERVERNOTIFY, "enbale consistency check in multiplayer" );
|
||||
clockwindow = Cvar_Get( "clockwindow", "0.5", 0, "timewindow to execute client moves" );
|
||||
|
@ -778,7 +776,7 @@ before Sys_Quit or Sys_Error
|
|||
void SV_Shutdown( qboolean reconnect )
|
||||
{
|
||||
// already freed
|
||||
if( !SV_Active()) return;
|
||||
if( !SV_Active( )) return;
|
||||
|
||||
if( host.type == HOST_DEDICATED ) MsgDev( D_INFO, "SV_Shutdown: %s\n", host.finalmsg );
|
||||
if( svs.clients ) SV_FinalMessage( host.finalmsg, reconnect );
|
||||
|
|
|
@ -110,7 +110,8 @@ void SV_WaterMove( edict_t *ent )
|
|||
return;
|
||||
}
|
||||
|
||||
if( ent->v.health <= 0.0f )
|
||||
// no watermove for monsters but pushables
|
||||
if(( ent->v.flags & FL_MONSTER ) && ent->v.health <= 0.0f )
|
||||
return;
|
||||
|
||||
drownlevel = (ent->v.deadflag == DEAD_NO) ? 3.0 : 1.0;
|
||||
|
|
|
@ -540,7 +540,7 @@ int SV_FlyMove( edict_t *ent, float time, trace_t *steptrace )
|
|||
|
||||
allFraction += trace.fraction;
|
||||
|
||||
if( trace.allsolid )
|
||||
if( trace.startsolid )
|
||||
{
|
||||
// entity is trapped in another solid
|
||||
VectorClear( ent->v.velocity );
|
||||
|
@ -663,7 +663,7 @@ void SV_AddGravity( edict_t *ent )
|
|||
else ent_gravity = 1.0f;
|
||||
|
||||
// add gravity incorrectly
|
||||
ent->v.velocity[2] -= (ent_gravity * sv_gravity->value * host.frametime );
|
||||
ent->v.velocity[2] -= ( ent_gravity * sv_gravity->value * host.frametime );
|
||||
ent->v.velocity[2] += ent->v.basevelocity[2] * host.frametime;
|
||||
ent->v.basevelocity[2] = 0.0f;
|
||||
|
||||
|
@ -731,10 +731,9 @@ Does not change the entities velocity at all
|
|||
*/
|
||||
trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int *blocked )
|
||||
{
|
||||
trace_t trace;
|
||||
sv_client_t *cl;
|
||||
int type;
|
||||
vec3_t end;
|
||||
trace_t trace;
|
||||
int type;
|
||||
vec3_t end;
|
||||
|
||||
VectorAdd( ent->v.origin, lpush, end );
|
||||
|
||||
|
@ -750,7 +749,7 @@ trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int
|
|||
{
|
||||
VectorCopy( trace.endpos, ent->v.origin );
|
||||
|
||||
if( apush[YAW] && ent->v.flags & FL_CLIENT && ( cl = SV_ClientFromEdict( ent, true )) != NULL )
|
||||
if( apush[YAW] && ( ent->v.flags & FL_CLIENT ))
|
||||
{
|
||||
ent->v.avelocity[1] += apush[1];
|
||||
ent->v.fixangle = 2;
|
||||
|
@ -803,17 +802,25 @@ allow entity to block pusher?
|
|||
*/
|
||||
static qboolean SV_CanBlock( edict_t *ent )
|
||||
{
|
||||
if( ent->v.solid == SOLID_NOT || ent->v.solid == SOLID_TRIGGER )
|
||||
return false;
|
||||
if( ent->v.mins[0] == ent->v.maxs[0] )
|
||||
return false;
|
||||
|
||||
// deadbody
|
||||
if( ent->v.solid == SOLID_NOT || ent->v.solid == SOLID_TRIGGER )
|
||||
{
|
||||
ent->v.mins[0] = ent->v.mins[1] = 0;
|
||||
ent->v.maxs[0] = ent->v.maxs[1] = 0;
|
||||
ent->v.maxs[2] = ent->v.mins[2];
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0 // deadbody
|
||||
if( ent->v.deadflag >= DEAD_DEAD )
|
||||
return false;
|
||||
|
||||
// point entities never block push
|
||||
if( VectorCompare( ent->v.mins, ent->v.maxs ))
|
||||
return false;
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1493,6 @@ This is also used for objects that have become still on the ground, but
|
|||
will fall if the floor is pulled out from under them.
|
||||
=============
|
||||
*/
|
||||
#if 1
|
||||
void SV_Physics_Step( edict_t *ent )
|
||||
{
|
||||
qboolean inwater;
|
||||
|
@ -1504,7 +1510,7 @@ void SV_Physics_Step( edict_t *ent )
|
|||
|
||||
if( ent->v.flags & FL_FLOAT && ent->v.waterlevel > 0 )
|
||||
{
|
||||
float buoyancy = SV_Submerged( ent ) * ent->v.skin * host.frametime;
|
||||
float buoyancy = SV_Submerged( ent ) * ent->v.skin * host.frametime;
|
||||
|
||||
SV_AddGravity( ent );
|
||||
ent->v.velocity[2] += buoyancy;
|
||||
|
@ -1535,9 +1541,7 @@ void SV_Physics_Step( edict_t *ent )
|
|||
|
||||
control = (speed < sv_stopspeed->value) ? sv_stopspeed->value : speed;
|
||||
newspeed = speed - (host.frametime * control * friction);
|
||||
|
||||
if( newspeed < 0 )
|
||||
newspeed = 0;
|
||||
if( newspeed < 0 ) newspeed = 0;
|
||||
newspeed /= speed;
|
||||
|
||||
vel[0] = vel[0] * newspeed;
|
||||
|
@ -1604,194 +1608,6 @@ void SV_Physics_Step( edict_t *ent )
|
|||
SV_CheckWaterTransition( ent );
|
||||
|
||||
}
|
||||
#else
|
||||
void SV_Physics_Step( edict_t *ent )
|
||||
{
|
||||
qboolean wasonground;
|
||||
qboolean wasinwater;
|
||||
qboolean inwater;
|
||||
qboolean isfalling = false;
|
||||
trace_t trace;
|
||||
|
||||
SV_CheckVelocity( ent );
|
||||
|
||||
wasonground = (ent->v.flags & FL_ONGROUND) ? true : false;
|
||||
wasinwater = (ent->v.flags & FL_INWATER) ? true : false;
|
||||
|
||||
// add gravity except:
|
||||
// flying monsters
|
||||
// swimming monsters who are in the water
|
||||
// pushables
|
||||
inwater = SV_CheckWater( ent );
|
||||
|
||||
if( ent->v.movetype == MOVETYPE_PUSHSTEP )
|
||||
{
|
||||
if( wasinwater && !inwater )
|
||||
ent->v.velocity[2] = 0.0f;
|
||||
|
||||
if( inwater && ( ent->v.flags & FL_FLOAT ))
|
||||
{
|
||||
vec3_t lmove;
|
||||
int e, block;
|
||||
edict_t *check;
|
||||
|
||||
ent->v.flags |= FL_INWATER;
|
||||
VectorClear( lmove );
|
||||
|
||||
// floating pushables
|
||||
if( ent->v.waterlevel >= 2 )
|
||||
{
|
||||
VectorScale( ent->v.velocity, 1.0f - (host.frametime * 0.5f), ent->v.velocity );
|
||||
ent->v.velocity[2] += (ent->v.skin * host.frametime );
|
||||
}
|
||||
else if( ent->v.waterlevel == 0 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->v.velocity[2] -= (ent->v.skin * host.frametime);
|
||||
}
|
||||
|
||||
if( sv_fix_pushstep->integer )
|
||||
{
|
||||
lmove[2] = (ent->v.skin * host.frametime);
|
||||
|
||||
// push the clients to avoid sticking in float items
|
||||
for( e = 1; e < svgame.globals->maxClients + 1; e++ )
|
||||
{
|
||||
check = EDICT_NUM( e );
|
||||
if( !SV_IsValidEdict( check )) continue;
|
||||
|
||||
if(( check->v.flags & FL_ONGROUND ) && check->v.groundentity == ent )
|
||||
{
|
||||
SV_PushEntity( check, lmove, vec3_origin, &block );
|
||||
check->v.groundentity = NULL;
|
||||
check->v.flags &= ~FL_ONGROUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( !wasonground )
|
||||
{
|
||||
ent->v.flags &= ~FL_INWATER;
|
||||
SV_AddGravity( ent );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// monster gravity
|
||||
if( !wasonground )
|
||||
{
|
||||
if(!( ent->v.flags & FL_FLY ))
|
||||
{
|
||||
if(!( ent->v.flags & FL_SWIM && ent->v.waterlevel > 0 ))
|
||||
{
|
||||
if( !inwater )
|
||||
{
|
||||
SV_AddHalfGravity( ent, host.frametime );
|
||||
isfalling = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !VectorIsNull( ent->v.velocity ) || !VectorIsNull( ent->v.basevelocity ))
|
||||
{
|
||||
vec3_t mins, maxs, point;
|
||||
float friction = sv_friction->value;
|
||||
int x, y;
|
||||
|
||||
friction *= ent->v.friction;
|
||||
ent->v.flags &= ~FL_ONGROUND;
|
||||
|
||||
// apply friction
|
||||
// let dead monsters who aren't completely onground slide
|
||||
if( wasonground )
|
||||
{
|
||||
float speed, newspeed;
|
||||
float *vel, control;
|
||||
|
||||
vel = ent->v.velocity;
|
||||
speed = sqrt( vel[0] * vel[0] + vel[1] * vel[1] );
|
||||
|
||||
// add ground speed
|
||||
if( ent->v.groundentity )
|
||||
{
|
||||
if( ent->v.groundentity->v.flags & FL_CONVEYOR )
|
||||
speed += ent->v.groundentity->v.speed;
|
||||
|
||||
}
|
||||
|
||||
if( speed )
|
||||
{
|
||||
control = speed < sv_stopspeed->value ? sv_stopspeed->value : speed;
|
||||
newspeed = speed - host.frametime * control * friction;
|
||||
|
||||
if( newspeed < 0.0f )
|
||||
newspeed = 0.0f;
|
||||
newspeed /= speed;
|
||||
|
||||
ent->v.velocity[0] *= newspeed;
|
||||
ent->v.velocity[1] *= newspeed;
|
||||
}
|
||||
}
|
||||
|
||||
VectorAdd( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
|
||||
SV_FlyMove( ent, host.frametime, NULL );
|
||||
VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
|
||||
|
||||
SV_CheckVelocity( ent );
|
||||
|
||||
// determine if it's on solid ground at all
|
||||
VectorAdd( ent->v.origin, ent->v.mins, mins );
|
||||
VectorAdd( ent->v.origin, ent->v.maxs, maxs );
|
||||
|
||||
point[2] = mins[2] - 1;
|
||||
for( x = 0; x <= 1; x++ )
|
||||
{
|
||||
if( ent->v.flags & FL_ONGROUND )
|
||||
break;
|
||||
|
||||
for( y = 0; y <= 1; y++ )
|
||||
{
|
||||
point[0] = x ? maxs[0] : mins[0];
|
||||
point[1] = y ? maxs[1] : mins[1];
|
||||
|
||||
trace = SV_Move( point, vec3_origin, vec3_origin, point, MOVE_NORMAL, ent );
|
||||
|
||||
if( trace.startsolid )
|
||||
{
|
||||
ent->v.flags |= FL_ONGROUND;
|
||||
ent->v.groundentity = trace.ent;
|
||||
ent->v.friction = 1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( svgame.globals->force_retouch != 0.0f )
|
||||
{
|
||||
trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent );
|
||||
if(( trace.fraction < 1.0f || trace.startsolid ) && SV_IsValidEdict( trace.ent ))
|
||||
SV_Impact( ent, trace.ent, &trace );
|
||||
}
|
||||
}
|
||||
|
||||
if(!( ent->v.flags & FL_ONGROUND ) && isfalling )
|
||||
{
|
||||
SV_AddHalfGravity( ent, host.frametime );
|
||||
}
|
||||
|
||||
if( !SV_RunThink( ent )) return;
|
||||
|
||||
SV_CheckWaterTransition( ent );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=============
|
||||
|
@ -1983,6 +1799,7 @@ void SV_DrawDebugTriangles( void )
|
|||
if( svgame.physFuncs.DrawDebugTriangles != NULL )
|
||||
{
|
||||
// debug draws only
|
||||
pglDisable( GL_BLEND );
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDisable( GL_TEXTURE_2D );
|
||||
|
||||
|
@ -1991,6 +1808,26 @@ void SV_DrawDebugTriangles( void )
|
|||
|
||||
pglEnable( GL_TEXTURE_2D );
|
||||
pglDepthMask( GL_TRUE );
|
||||
pglEnable( GL_BLEND );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_DrawOrthoTriangles
|
||||
|
||||
Called from renderer for debug purposes
|
||||
================
|
||||
*/
|
||||
void SV_DrawOrthoTriangles( void )
|
||||
{
|
||||
if( host.type != HOST_NORMAL )
|
||||
return;
|
||||
|
||||
if( svgame.physFuncs.DrawOrthoTriangles != NULL )
|
||||
{
|
||||
// draw solid overlay
|
||||
svgame.physFuncs.DrawOrthoTriangles ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2004,6 +1841,11 @@ static server_physics_api_t gPhysicsAPI =
|
|||
SV_ServerState,
|
||||
Host_Error,
|
||||
&gTriApi, // ouch!
|
||||
pfnDrawConsoleString,
|
||||
pfnDrawSetTextColor,
|
||||
pfnDrawConsoleStringLen,
|
||||
Con_NPrintf,
|
||||
Con_NXPrintf,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,6 +37,22 @@ void SV_ConvertPMTrace( trace_t *out, pmtrace_t *in, edict_t *ent )
|
|||
out->ent = ent;
|
||||
}
|
||||
|
||||
void SV_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr )
|
||||
{
|
||||
ASSERT( tr != NULL );
|
||||
|
||||
if( svgame.physFuncs.ClipPMoveToEntity != NULL )
|
||||
{
|
||||
// do custom sweep test
|
||||
svgame.physFuncs.ClipPMoveToEntity( pe, start, mins, maxs, end, tr );
|
||||
}
|
||||
else
|
||||
{
|
||||
// function is missed, so we didn't hit anything
|
||||
tr->allsolid = false;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed )
|
||||
{
|
||||
model_t *mod = Mod_Handle( ed->v.modelindex );
|
||||
|
@ -77,6 +93,12 @@ qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed )
|
|||
VectorCopy( ed->v.mins, pe->mins );
|
||||
VectorCopy( ed->v.maxs, pe->maxs );
|
||||
break;
|
||||
case SOLID_CUSTOM:
|
||||
pe->model = (mod->type == mod_brush) ? mod : NULL;
|
||||
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
|
||||
VectorCopy( ed->v.mins, pe->mins );
|
||||
VectorCopy( ed->v.maxs, pe->maxs );
|
||||
break;
|
||||
default:
|
||||
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
|
||||
VectorCopy( ed->v.mins, pe->mins );
|
||||
|
@ -192,7 +214,7 @@ void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3_t
|
|||
svgame.pmove->numvisent++;
|
||||
}
|
||||
|
||||
if( check->v.solid == SOLID_NOT && ( check->v.skin == 0 || check->v.modelindex == 0 ))
|
||||
if( check->v.solid == SOLID_NOT && ( check->v.skin == CONTENTS_NONE || check->v.modelindex == 0 ))
|
||||
continue;
|
||||
|
||||
// ignore monsterclip brushes
|
||||
|
@ -204,13 +226,17 @@ void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3_t
|
|||
if((( check->v.flags & FL_CLIENT ) && check->v.health <= 0 ) || check->v.deadflag == DEAD_DEAD )
|
||||
continue; // dead body
|
||||
|
||||
if( VectorIsNull( check->v.size )) continue;
|
||||
if( VectorIsNull( check->v.size ))
|
||||
continue;
|
||||
|
||||
VectorCopy( check->v.absmin, mins );
|
||||
VectorCopy( check->v.absmax, maxs );
|
||||
|
||||
if( check->v.flags & FL_CLIENT )
|
||||
SV_GetTrueMinMax( svs.currentPlayer, ( NUM_FOR_EDICT( check ) - 1), mins, maxs ); // try to get interpolated values
|
||||
{
|
||||
// trying to get interpolated values
|
||||
SV_GetTrueMinMax( svs.currentPlayer, ( NUM_FOR_EDICT( check ) - 1), mins, maxs );
|
||||
}
|
||||
|
||||
if( !BoundsIntersect( pmove_mins, pmove_maxs, mins, maxs ))
|
||||
continue;
|
||||
|
|
|
@ -2161,7 +2161,7 @@ void SV_SaveGame( const char *pName )
|
|||
for( n = 0; n < 999; n++ )
|
||||
{
|
||||
SV_SaveGetName( n, savename );
|
||||
if( !FS_FileExists( va( "save/%s.sav", savename ), false ))
|
||||
if( !FS_FileExists( va( "save/%s.sav", savename ), true ))
|
||||
break;
|
||||
}
|
||||
if( n == 1000 )
|
||||
|
@ -2213,7 +2213,7 @@ const char *SV_GetLatestSave( void )
|
|||
|
||||
for( i = 0; i < f->numfilenames; i++ )
|
||||
{
|
||||
ft = FS_FileTime( f->filenames[i], false );
|
||||
ft = FS_FileTime( f->filenames[i], true );
|
||||
|
||||
// found a match?
|
||||
if( ft > 0 )
|
||||
|
|
|
@ -485,7 +485,7 @@ void SV_TouchLinks( edict_t *ent, areanode_t *node )
|
|||
hull = SV_HullForBsp( touch, ent->v.mins, ent->v.maxs, offset );
|
||||
|
||||
// support for rotational triggers
|
||||
if( (mod->flags & MODEL_HAS_ORIGIN) && !VectorIsNull( touch->v.angles ))
|
||||
if(( mod->flags & MODEL_HAS_ORIGIN ) && !VectorIsNull( touch->v.angles ))
|
||||
{
|
||||
matrix4x4 matrix;
|
||||
Matrix4x4_CreateFromEntity( matrix, touch->v.angles, offset, 1.0f );
|
||||
|
@ -1071,6 +1071,33 @@ void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t
|
|||
trace->ent = ent;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_CustomClipMoveToEntity
|
||||
|
||||
A part of physics engine implementation
|
||||
or custom physics implementation
|
||||
==================
|
||||
*/
|
||||
void SV_CustomClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, trace_t *trace )
|
||||
{
|
||||
Q_memset( trace, 0, sizeof( trace_t ));
|
||||
VectorCopy( end, trace->endpos );
|
||||
trace->allsolid = true;
|
||||
trace->fraction = 1.0f;
|
||||
|
||||
if( svgame.physFuncs.ClipMoveToEntity != NULL )
|
||||
{
|
||||
// do custom sweep test
|
||||
svgame.physFuncs.ClipMoveToEntity( ent, start, mins, maxs, end, trace );
|
||||
}
|
||||
else
|
||||
{
|
||||
// function is missed, so we didn't hit anything
|
||||
trace->allsolid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
SV_ClipToLinks
|
||||
|
@ -1169,6 +1196,8 @@ static void SV_ClipToLinks( areanode_t *node, moveclip_t *clip )
|
|||
|
||||
if( touch->v.flags & FL_MONSTER )
|
||||
SV_ClipMoveToEntity( touch, clip->start, clip->mins2, clip->maxs2, clip->end, &trace );
|
||||
else if( touch->v.solid == SOLID_CUSTOM )
|
||||
SV_CustomClipMoveToEntity( touch, clip->start, clip->mins, clip->maxs, clip->end, &trace );
|
||||
else SV_ClipMoveToEntity( touch, clip->start, clip->mins, clip->maxs, clip->end, &trace );
|
||||
|
||||
clip->trace = World_CombineTraces( &clip->trace, &trace, touch );
|
||||
|
|
|
@ -266,6 +266,10 @@ void UI_DrawString( int x, int y, int w, int h, const char *string, const int co
|
|||
ch = *l++;
|
||||
ch &= 255;
|
||||
|
||||
// fix for letter ¸
|
||||
if( ch == '¸' ) ch = 'å';
|
||||
if( ch == '¨' ) ch = 'Å';
|
||||
|
||||
if( ch != ' ' )
|
||||
{
|
||||
if( shadow ) TextMessageDrawChar( xx + ofsX, yy + ofsY, charW, charH, ch, shadowModulate, uiStatic.hFont );
|
||||
|
|
|
@ -146,7 +146,8 @@ void UI_LoadBmpButtons( void )
|
|||
uiStatic.buttons_height = ( pInfoHdr->biBitCount == 4 ) ? 80 : 78; // bugstompers issues
|
||||
uiStatic.buttons_width = pInfoHdr->biWidth - 3; // make some offset
|
||||
|
||||
int cutted_img_sz = pInfoHdr->biWidth * uiStatic.buttons_height * pInfoHdr->biBitCount / 8;
|
||||
int stride = (pInfoHdr->biWidth * pInfoHdr->biBitCount / 8);
|
||||
int cutted_img_sz = ((stride + 3 ) & ~3) * uiStatic.buttons_height;
|
||||
int CuttedBmpSize = sizeof( bmphdr_t ) + pInfoHdr->biSize + pallete_sz + cutted_img_sz;
|
||||
byte *img_data = &bmp_buffer[bmp_len_holder-cutted_img_sz];
|
||||
|
||||
|
|
|
@ -41,8 +41,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define MAX_MODS 512 // engine limit
|
||||
|
||||
#define TYPE_LENGTH 16
|
||||
#define NAME_SPACE 4
|
||||
#define NAME_LENGTH 32+TYPE_LENGTH
|
||||
#define VER_LENGTH 10+NAME_LENGTH
|
||||
#define VER_LENGTH 6+NAME_LENGTH
|
||||
#define SIZE_LENGTH 10+VER_LENGTH
|
||||
|
||||
typedef struct
|
||||
|
@ -136,7 +137,14 @@ static void UI_CustomGame_GetModList( void )
|
|||
if( strlen( games[i]->type ))
|
||||
StringConcat( uiCustomGame.modsDescription[i], games[i]->type, TYPE_LENGTH );
|
||||
StringConcat( uiCustomGame.modsDescription[i], uiEmptyString, TYPE_LENGTH );
|
||||
StringConcat( uiCustomGame.modsDescription[i], games[i]->title, NAME_LENGTH );
|
||||
|
||||
if( ColorStrlen( games[i]->title ) > 31 ) // NAME_LENGTH
|
||||
{
|
||||
StringConcat( uiCustomGame.modsDescription[i], games[i]->title, ( NAME_LENGTH - NAME_SPACE ));
|
||||
StringConcat( uiCustomGame.modsDescription[i], "...", NAME_LENGTH );
|
||||
}
|
||||
else StringConcat( uiCustomGame.modsDescription[i], games[i]->title, NAME_LENGTH );
|
||||
|
||||
StringConcat( uiCustomGame.modsDescription[i], uiEmptyString, NAME_LENGTH );
|
||||
StringConcat( uiCustomGame.modsDescription[i], games[i]->version, VER_LENGTH );
|
||||
StringConcat( uiCustomGame.modsDescription[i], uiEmptyString, VER_LENGTH );
|
||||
|
|
|
@ -734,6 +734,9 @@ void UI_ScrollList_Draw( menuScrollList_s *sl )
|
|||
h = sl->generic.charHeight;
|
||||
y = sl->generic.y2 + sl->generic.charHeight;
|
||||
|
||||
// prevent the columns out of rectangle bounds
|
||||
PIC_EnableScissor( x, y, sl->generic.width - arrowWidth - uiStatic.outlineWidth, sl->generic.height );
|
||||
|
||||
for( i = sl->topItem; i < sl->topItem + sl->numRows; i++, y += sl->generic.charHeight )
|
||||
{
|
||||
if( !sl->itemNames[i] )
|
||||
|
@ -768,6 +771,8 @@ void UI_ScrollList_Draw( menuScrollList_s *sl )
|
|||
if( sl->generic.flags & QMF_FOCUSBEHIND )
|
||||
UI_DrawString( x, y, w, h, sl->itemNames[i], sl->generic.color, false, sl->generic.charWidth, sl->generic.charHeight, justify, shadow );
|
||||
}
|
||||
|
||||
PIC_DisableScissor();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2092,7 +2097,6 @@ const char *UI_PicButton_Key( menuPicButton_s *b, int key, int down )
|
|||
break;
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
if( !down ) return sound;
|
||||
if( b->generic.flags & QMF_MOUSEONLY )
|
||||
break;
|
||||
sound = uiSoundLaunch;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define PM_STUDIO_BOX 0x00000002 // Use boxes for non-complex studio models (even in traceline)
|
||||
#define PM_GLASS_IGNORE 0x00000004 // Ignore entities with non-normal rendermode
|
||||
#define PM_WORLD_ONLY 0x00000008 // Only trace against the world
|
||||
#define PM_CUSTOM_IGNORE 0x00000010 // Ignore entities with SOLID_CUSTOM mode
|
||||
|
||||
// Values for flags parameter of PM_TraceLine
|
||||
#define PM_TRACELINE_PHYSENTSONLY 0
|
||||
|
|
|
@ -1698,9 +1698,7 @@ int PM_CheckStuck (void)
|
|||
|
||||
PM_ResetStuckOffsets( pmove->player_index, pmove->server );
|
||||
|
||||
if (i >= 27)
|
||||
VectorCopy ( test, pmove->origin );
|
||||
|
||||
VectorCopy ( test, pmove->origin );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue