diff --git a/change.log b/change.log index 4859345c..564deeeb 100644 --- a/change.log +++ b/change.log @@ -104,7 +104,7 @@ Sound: set s_cull to zero as default Input: fix problems with call WC_SYSMENU instead of user-defined command when ALT is pressed Console: add a new command that called "mapstats" and works like bspinfo.exe Physic: added new meta-type SOLID_CUSTOM that could be traced in game dlls with physic API -Pmove: get to work PM_CheckStuck on a servder-sdie +Pmove: get to work PM_CheckStuck on a server-side Server: added a new cvar that called a "sv_validate_changelevel" for skip any checks with changelevel problems Server: make check for recursive changelevel (and ignore it) Server: fix the problem with non-sended events when a player sight cross-line contents diff --git a/cl_dll/cl_dll.dsp b/cl_dll/cl_dll.dsp index fe9820a0..6864326b 100644 --- a/cl_dll/cl_dll.dsp +++ b/cl_dll/cl_dll.dsp @@ -155,7 +155,7 @@ SOURCE=.\hl\hl_weapons.cpp # End Source File # Begin Source File -SOURCE=..\dlls\wpn_shared\hl_wpn_glock.cpp +SOURCE=..\dlls\glock.cpp # End Source File # Begin Source File diff --git a/engine/client/cl_cmds.c b/engine/client/cl_cmds.c index ada2ff89..ccabb293 100644 --- a/engine/client/cl_cmds.c +++ b/engine/client/cl_cmds.c @@ -154,7 +154,7 @@ void CL_ScreenshotGetName( int lastnum, char *filename ) lastnum -= c * 10; d = lastnum; - Q_sprintf( filename, "scrshots/%s/shot%i%i%i%i.bmp", clgame.mapname, a, b, c, d ); + Q_sprintf( filename, "scrshots/%s_shot%i%i%i%i.bmp", clgame.mapname, a, b, c, d ); } /* diff --git a/engine/client/gl_backend.c b/engine/client/gl_backend.c index 547e7b33..bedd3190 100644 --- a/engine/client/gl_backend.c +++ b/engine/client/gl_backend.c @@ -84,7 +84,7 @@ void GL_BackendEndFrame( void ) break; case 4: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities", - r_numStatics, r_numEntities ); + r_numStatics, r_numEntities - r_numStatics ); break; case 5: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i tempents\n%3i viewbeams\n%3i particles", diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index 4212202d..a331064c 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -241,6 +241,8 @@ typedef struct uint c_particle_count; uint c_mirror_passes; + + uint c_client_ents; // entities that moved to client } ref_speeds_t; extern ref_speeds_t r_stats; @@ -253,8 +255,8 @@ extern mleaf_t *r_viewleaf, *r_oldviewleaf; extern mleaf_t *r_viewleaf2, *r_oldviewleaf2; extern dlight_t cl_dlights[MAX_DLIGHTS]; extern dlight_t cl_elights[MAX_ELIGHTS]; -#define r_numEntities (tr.num_solid_entities + tr.num_trans_entities + tr.num_child_entities) -#define r_numStatics (tr.num_static_entities) +#define r_numEntities (tr.num_solid_entities + tr.num_trans_entities + tr.num_child_entities + tr.num_static_entities) +#define r_numStatics (r_stats.c_client_ents) extern struct beam_s *cl_active_beams; extern struct beam_s *cl_free_beams; diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index d8d02616..25fefa48 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -20,6 +20,7 @@ GNU General Public License for more details. #include "library.h" #include "beamdef.h" #include "particledef.h" +#include "entity_types.h" #define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA ) @@ -418,6 +419,9 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int entityType ) clent->curstate.entityType = entityType; + if( entityType == ET_FRAGMENTED ) + r_stats.c_client_ents++; + if( R_FollowEntity( clent )) { // follow entity diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index ff47cb83..1ca585d1 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -1480,9 +1480,9 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo ) R_GetLightSpot( plight->lightspot ); // shadow stuff - plight->lightcolor[0] = ambient.r * (1.0f / 255.0f); - plight->lightcolor[1] = ambient.g * (1.0f / 255.0f); - plight->lightcolor[2] = ambient.b * (1.0f / 255.0f); + plight->lightcolor[0] = lightinfo->color[0] = ambient.r * (1.0f / 255.0f); + plight->lightcolor[1] = lightinfo->color[1] = ambient.g * (1.0f / 255.0f); + plight->lightcolor[2] = lightinfo->color[2] = ambient.b * (1.0f / 255.0f); VectorCopy( plight->lightcolor, lightinfo->color ); lightinfo->shadelight = (ambient.r + ambient.g + ambient.b) / 3; @@ -1640,13 +1640,19 @@ void R_StudioSetupLighting( alight_t *lightinfo ) studiolight_t *plight; int i; - if( !m_pStudioHeader ) return; + if( !m_pStudioHeader || !lightinfo ) + return; plight = &g_studiolight; for( i = 0; i < m_pStudioHeader->numbones; i++ ) Matrix3x4_VectorIRotate( g_lighttransform[i], lightinfo->plightvec, plight->blightvec[i] ); + // copy custom alight color in case of mod-maker changed it + plight->lightcolor[0] = lightinfo->color[0]; + plight->lightcolor[1] = lightinfo->color[1]; + plight->lightcolor[2] = lightinfo->color[2]; + R_StudioGetShadowImpactAndDir(); } diff --git a/engine/client/gl_warp.c b/engine/client/gl_warp.c index fdf34cb9..c5c48086 100644 --- a/engine/client/gl_warp.c +++ b/engine/client/gl_warp.c @@ -682,6 +682,7 @@ void R_DrawSkyChain( msurface_t *s ) { msurface_t *fa; + GL_SetRenderMode( kRenderNormal ); GL_Bind( GL_TEXTURE0, tr.solidskyTexture ); speedscale = cl.time * 8.0f; @@ -690,7 +691,7 @@ void R_DrawSkyChain( msurface_t *s ) for( fa = s; fa; fa = fa->texturechain ) EmitSkyPolys( fa ); - pglEnable( GL_BLEND ); + GL_SetRenderMode( kRenderTransTexture ); GL_Bind( GL_TEXTURE0, tr.alphaskyTexture ); speedscale = cl.time * 16.0f; @@ -713,6 +714,7 @@ will have them chained together. */ void EmitSkyLayers( msurface_t *fa ) { + GL_SetRenderMode( kRenderNormal ); GL_Bind( GL_TEXTURE0, tr.solidskyTexture ); speedscale = cl.time * 8.0f; @@ -720,7 +722,7 @@ void EmitSkyLayers( msurface_t *fa ) EmitSkyPolys( fa ); - pglEnable( GL_BLEND ); + GL_SetRenderMode( kRenderTransTexture ); GL_Bind( GL_TEXTURE0, tr.alphaskyTexture ); speedscale = cl.time * 16.0f; diff --git a/engine/common/build.c b/engine/common/build.c index d7d7dd90..a9633648 100644 --- a/engine/common/build.c +++ b/engine/common/build.c @@ -23,7 +23,7 @@ static char mond[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int Q_buildnum( void ) { // do not touch this! Only author of Xash3D can increase buildnumbers! -#if 0 +#if 1 int m = 0, d = 0, y = 0; static int b = 0; diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index d272c6dd..ff23eed2 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -64,7 +64,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) for( i = 0, nummaps = 0; i < t->numfilenames; i++ ) { char entfilename[CS_SIZE]; - int ver = -1, lumpofs = 0, lumplen = 0; + int ver = -1, mapver = -1, lumpofs = 0, lumplen = 0; const char *ext = FS_FileExtension( t->filenames[i] ); char *ents = NULL, *pfile; qboolean gearbox = false; @@ -132,6 +132,12 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) // get the message contents pfile = COM_ParseFile( pfile, message ); } + else if(!Q_strcmp( token, "mapversion" )) + { + // get the message contents + pfile = COM_ParseFile( pfile, token ); + mapver = Q_atoi( token ); + } } Mem_Free( ents ); } @@ -143,7 +149,8 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) switch( ver ) { case Q1BSP_VERSION: - Q_strncpy( buf, "Quake", sizeof( buf )); + if( mapver == 220 ) Q_strncpy( buf, "Half-Life Alpha", sizeof( buf )); + else Q_strncpy( buf, "Quake", sizeof( buf )); break; case HLBSP_VERSION: if( gearbox ) Q_strncpy( buf, "Blue-Shift", sizeof( buf )); @@ -154,6 +161,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) break; default: Q_strncpy( buf, "??", sizeof( buf )); break; } + Msg( "%16s (%s) ^3%s^7\n", matchbuf, buf, message ); nummaps++; } diff --git a/engine/common/console.c b/engine/common/console.c index e49ba516..ad9251d0 100644 --- a/engine/common/console.c +++ b/engine/common/console.c @@ -441,18 +441,18 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font ) if( font->valid ) return; // already loaded // loading conchars - font->hFontTexture = GL_LoadTexture( va( "fonts/font%i", fontNumber ), NULL, 0, TF_FONT|TF_NEAREST, NULL ); + font->hFontTexture = GL_LoadTexture( va( "fonts.wad/font%i", fontNumber ), NULL, 0, TF_FONT|TF_NEAREST, NULL ); R_GetTextureParms( &fontWidth, NULL, font->hFontTexture ); // setup creditsfont - if( FS_FileExists( va( "fonts/font%i.fnt", fontNumber ), false ) && fontWidth != 0 ) + if( FS_FileExists( va( "fonts.wad/font%i.fnt", fontNumber ), false ) && fontWidth != 0 ) { byte *buffer; size_t length; qfont_t *src; // half-life font with variable chars witdh - buffer = FS_LoadFile( va( "fonts/font%i", fontNumber ), &length, false ); + buffer = FS_LoadFile( va( "fonts.wad/font%i", fontNumber ), &length, false ); if( buffer && length >= sizeof( qfont_t )) { diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index a78d1a70..1ea90d37 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -873,7 +873,7 @@ int FS_CheckNastyPath( const char *path, qboolean isgamedir ) // Windows and UNIXes: don't allow absolute paths if( path[0] == '/' && !fs_ext_path ) return 2; // attempt to go outside the game directory - +#if 0 // all: don't allow . characters before the last slash (it should only be used in filenames, not path elements), // this catches all imaginable cases of ./, ../, .../, etc if( Q_strchr( path, '.' ) && !fs_ext_path ) @@ -881,7 +881,7 @@ int FS_CheckNastyPath( const char *path, qboolean isgamedir ) if( isgamedir ) return 2; // gamedir is entirely path elements, so simply forbid . entirely if( Q_strchr( path, '.' ) < Q_strrchr( path, '/' )) return 2; // possible attempt to go outside the game directory } - +#endif // all: forbid trailing slash on gamedir if( isgamedir && !fs_ext_path && path[Q_strlen( path )-1] == '/' ) return 2; @@ -890,7 +890,7 @@ int FS_CheckNastyPath( const char *path, qboolean isgamedir ) // after all these checks we're pretty sure it's a / separated filename // and won't do much if any harm - return false; + return 0; } /* @@ -1558,13 +1558,12 @@ void FS_Init( void ) for( i = 0; i < dirs.numstrings; i++ ) { - const char *ext = FS_FileExtension( dirs.strings[i] ); - - if( Q_stricmp( ext, "" ) || (!Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) + if( !FS_SysFolderExists( dirs.strings[i] ) || (!Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) continue; if( !SI.games[SI.numgames] ) SI.games[SI.numgames] = (gameinfo_t *)Mem_Alloc( fs_mempool, sizeof( gameinfo_t )); + if( FS_ParseGameInfo( dirs.strings[i], SI.games[SI.numgames] )) SI.numgames++; // added } diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index eef41a84..4d689cfd 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -59,7 +59,8 @@ typedef struct leaflist_s typedef struct { - int version; // map version + int version; // bsp version + int mapversion; // map version (an key-value in worldspawn settings) uint checksum; // current map checksum int load_sequence; // increace each map change vec3_t hull_sizes[MAX_MAP_HULLS]; // actual hull sizes diff --git a/engine/common/model.c b/engine/common/model.c index 89e32baa..14f1639b 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -2205,9 +2205,11 @@ static void Mod_LoadEntities( const dlump_t *l ) path += (end - path) + 1; // move pointer if( mod_numwads >= 128 ) break; // too many wads... } - return; // all done } + else if( !Q_stricmp( keyname, "mapversion" )) + world.mapversion = Q_atoi( token ); } + return; // all done } } @@ -2661,7 +2663,7 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load // swap all the lumps mod_base = (byte *)header; - loadmodel->mempool = Mem_AllocPool( va( "sv: ^2%s^7", loadmodel->name )); + loadmodel->mempool = Mem_AllocPool( va( "^2%s^7", loadmodel->name )); // load into heap if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && (header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 ) @@ -2677,6 +2679,10 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load Mod_LoadPlanes( &header->lumps[LUMP_PLANES] ); } + // Half-Life: alpha version has BSP version 29 and map version 220 + if( world.version <= 29 && world.mapversion == 220 ) + world.version = bmodel_version = HLBSP_VERSION; + Mod_LoadVertexes( &header->lumps[LUMP_VERTEXES] ); Mod_LoadEdges( &header->lumps[LUMP_EDGES] ); Mod_LoadSurfEdges( &header->lumps[LUMP_SURFEDGES] ); diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 529a24c8..c4bc310b 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -111,6 +111,7 @@ void SV_DirectConnect( netadr_t from ) { Netchan_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i.\n", PROTOCOL_VERSION ); MsgDev( D_ERROR, "SV_DirectConnect: rejected connect from version %i\n", version ); + Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" ); return; } @@ -130,6 +131,7 @@ void SV_DirectConnect( netadr_t from ) if( !NET_IsLocalAddress( from ) && ( host.realtime - cl->lastconnect ) < sv_reconnect_limit->value ) { MsgDev( D_INFO, "%s:reconnect rejected : too soon\n", NET_AdrToString( from )); + Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" ); return; } break; @@ -151,6 +153,7 @@ void SV_DirectConnect( netadr_t from ) if( i == MAX_CHALLENGES ) { Netchan_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address.\n" ); + Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" ); return; } @@ -194,6 +197,7 @@ void SV_DirectConnect( netadr_t from ) { Netchan_OutOfBandPrint( NS_SERVER, from, "print\nServer is full.\n" ); MsgDev( D_INFO, "SV_DirectConnect: rejected a connection.\n" ); + Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" ); return; } @@ -221,6 +225,10 @@ gotnewcl: newcl->userid = g_userid++; // create unique userid newcl->authentication_method = 2; + // initailize netchan here because SV_DropClient will clear network buffer + Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport ); + BF_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf + // get the game a chance to reject this connection or modify the userinfo if( !( SV_ClientConnect( ent, userinfo ))) { @@ -229,6 +237,7 @@ gotnewcl: else Netchan_OutOfBandPrint( NS_SERVER, from, "print\nConnection refused.\n" ); MsgDev( D_ERROR, "SV_DirectConnect: game rejected a connection.\n"); + Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" ); SV_DropClient( newcl ); return; } @@ -239,9 +248,6 @@ gotnewcl: // send the connect packet to the client Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect" ); - Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport ); - BF_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf - newcl->state = cs_connected; newcl->cl_updaterate = 0.05; // 20 fps as default newcl->lastmessage = host.realtime; @@ -269,6 +275,8 @@ void SV_DisconnectClient( edict_t *pClient ) { if( !pClient ) return; + svgame.dllFuncs.pfnClientDisconnect( pClient ); + // don't send to other clients pClient->v.modelindex = 0; diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 594da4aa..12311e6e 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -548,7 +548,7 @@ int SV_FlyMove( edict_t *ent, float time, trace_t *steptrace ) allFraction += trace.fraction; - if( trace.startsolid ) + if( trace.allsolid ) { // entity is trapped in another solid VectorClear( ent->v.velocity ); diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index 4003f064..d4ed032b 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -627,7 +627,7 @@ static void SV_SetupPMove( playermove_t *pmove, sv_client_t *cl, usercmd_t *ucmd VectorCopy( clent->v.velocity, pmove->velocity ); VectorCopy( clent->v.basevelocity, pmove->basevelocity ); VectorCopy( clent->v.view_ofs, pmove->view_ofs ); - VectorClear( pmove->movedir ); + VectorCopy( clent->v.movedir, pmove->movedir ); pmove->flDuckTime = clent->v.flDuckTime; pmove->bInDuck = clent->v.bInDuck; pmove->usehull = (clent->v.flags & FL_DUCKING) ? 1 : 0; // reset hull @@ -700,18 +700,21 @@ static void SV_FinishPMove( playermove_t *pmove, sv_client_t *cl ) VectorCopy( pmove->velocity, clent->v.velocity ); VectorCopy( pmove->basevelocity, clent->v.basevelocity ); VectorCopy( pmove->punchangle, clent->v.punchangle ); + VectorCopy( pmove->movedir, clent->v.movedir ); + clent->v.flTimeStepSound = pmove->flTimeStepSound; clent->v.flFallVelocity = pmove->flFallVelocity; - clent->v.oldbuttons = pmove->oldbuttons; + clent->v.oldbuttons = pmove->cmd.buttons; clent->v.waterlevel = pmove->waterlevel; clent->v.watertype = pmove->watertype; - clent->v.flTimeStepSound = pmove->flTimeStepSound; + clent->v.maxspeed = pmove->clientmaxspeed; clent->v.flDuckTime = pmove->flDuckTime; clent->v.flSwimTime = pmove->flSwimTime; clent->v.iStepLeft = pmove->iStepLeft; clent->v.movetype = pmove->movetype; clent->v.friction = pmove->friction; + clent->v.deadflag = pmove->deadflag; + clent->v.effects = pmove->effects; clent->v.bInDuck = pmove->bInDuck; - clent->v.gravity = pmove->gravity; clent->v.flags = pmove->flags; // copy back user variables diff --git a/mainui/menu_main.cpp b/mainui/menu_main.cpp index 50d477a2..1a4f8a41 100644 --- a/mainui/menu_main.cpp +++ b/mainui/menu_main.cpp @@ -108,7 +108,7 @@ static void UI_Background_Ownerdraw( void *self ) if (uiStatic.m_fHaveSteamBackground || uiStatic.m_fDisableLogo) return; // no logos for steam background - if( GetLogoLength() <= 0.1 || GetLogoWidth() <= 32 ) + if( GetLogoLength() <= 0.05f || GetLogoWidth() <= 32 ) return; // don't draw stub logo (GoldSrc rules) float logoWidth, logoHeight, logoPosY;