2004-08-23 00:15:46 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2005-07-03 15:16:20 +00:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
2004-08-23 00:15:46 +00:00
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# include "qwsvdef.h"
2004-11-29 01:21:00 +00:00
# ifndef CLIENTONLY
2004-08-23 00:15:46 +00:00
extern int total_loading_size , current_loading_size , loading_stage ;
char * T_GetString ( int num ) ;
2005-03-20 02:57:11 +00:00
# define Q2EDICT_NUM(i) (q2edict_t*)((char *)ge->edicts+(i)*ge->edict_size)
2004-08-23 00:15:46 +00:00
server_static_t svs ; // persistant server info
server_t sv ; // local server
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
entity_state_t * sv_staticentities ;
int sv_max_staticentities ;
2004-08-23 00:15:46 +00:00
char localmodels [ MAX_MODELS ] [ 5 ] ; // inline model names for precache
char localinfo [ MAX_LOCALINFO_STRING + 1 ] ; // local game info
extern cvar_t skill , sv_loadentfiles ;
extern cvar_t sv_cheats ;
2004-11-17 17:49:18 +00:00
extern cvar_t sv_bigcoords ;
2005-03-20 02:57:11 +00:00
extern cvar_t sv_gamespeed ;
extern cvar_t sv_csqcdebug ;
2009-05-24 10:11:17 +00:00
extern cvar_t sv_csqc_progname ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
extern cvar_t sv_calcphs ;
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = =
SV_ModelIndex
= = = = = = = = = = = = = = = =
*/
int SV_ModelIndex ( char * name )
{
int i ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
if ( ! name | | ! name [ 0 ] )
return 0 ;
2006-02-17 02:51:59 +00:00
for ( i = 1 ; i < MAX_MODELS & & sv . strings . model_precache [ i ] ; i + + )
if ( ! strcmp ( sv . strings . model_precache [ i ] , name ) )
2004-08-23 00:15:46 +00:00
return i ;
2006-02-17 02:51:59 +00:00
if ( i = = MAX_MODELS | | ! sv . strings . model_precache [ i ] )
2004-09-04 17:56:53 +00:00
{
2011-12-05 15:23:40 +00:00
if ( i ! = MAX_MODELS )
2004-09-04 17:56:53 +00:00
{
2011-12-05 15:23:40 +00:00
# ifdef VM_Q1
if ( svs . gametype = = GT_Q1QVM )
sv . strings . model_precache [ i ] = name ;
else
# endif
sv . strings . model_precache [ i ] = PR_AddString ( svprogfuncs , name , 0 ) ;
2004-09-04 17:56:53 +00:00
if ( ! strcmp ( name + strlen ( name ) - 4 , " .bsp " ) )
2009-11-07 13:29:15 +00:00
sv . models [ i ] = Mod_FindName ( sv . strings . model_precache [ i ] ) ;
2011-12-05 15:23:40 +00:00
Con_DPrintf ( " WARNING: SV_ModelIndex: model %s not precached \n " , name ) ;
if ( sv . state ! = ss_loading )
{
MSG_WriteByte ( & sv . reliable_datagram , svcfte_precache ) ;
MSG_WriteShort ( & sv . reliable_datagram , i ) ;
MSG_WriteString ( & sv . reliable_datagram , sv . strings . model_precache [ i ] ) ;
# ifdef NQPROT
MSG_WriteByte ( & sv . nqreliable_datagram , svcdp_precache ) ;
MSG_WriteShort ( & sv . nqreliable_datagram , i ) ;
MSG_WriteString ( & sv . nqreliable_datagram , sv . strings . model_precache [ i ] ) ;
# endif
}
2004-09-04 17:56:53 +00:00
}
}
2004-08-23 00:15:46 +00:00
return i ;
}
2004-11-19 17:45:22 +00:00
int SV_SafeModelIndex ( char * name )
{
int i ;
2005-07-03 15:16:20 +00:00
2004-11-19 17:45:22 +00:00
if ( ! name | | ! name [ 0 ] )
return 0 ;
2006-02-17 02:51:59 +00:00
for ( i = 1 ; i < MAX_MODELS & & sv . strings . model_precache [ i ] ; i + + )
if ( ! strcmp ( sv . strings . model_precache [ i ] , name ) )
2004-11-19 17:45:22 +00:00
return i ;
2006-02-17 02:51:59 +00:00
if ( i = = MAX_MODELS | | ! sv . strings . model_precache [ i ] )
2004-11-19 17:45:22 +00:00
{
return 0 ;
}
return i ;
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = =
SV_FlushSignon
Moves to the next signon buffer if needed
= = = = = = = = = = = = = = = =
*/
void SV_FlushSignon ( void )
{
if ( sv . signon . cursize < sv . signon . maxsize - 512 )
return ;
if ( sv . num_signon_buffers = = MAX_SIGNON_BUFFERS - 1 )
SV_Error ( " sv.num_signon_buffers == MAX_SIGNON_BUFFERS-1 " ) ;
sv . signon_buffer_size [ sv . num_signon_buffers - 1 ] = sv . signon . cursize ;
sv . signon . data = sv . signon_buffers [ sv . num_signon_buffers ] ;
sv . num_signon_buffers + + ;
sv . signon . cursize = 0 ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . signon . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
}
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
2004-08-23 00:15:46 +00:00
void SV_FlushDemoSignon ( void )
{
if ( sv . demosignon . cursize < sv . demosignon . maxsize - 512 )
return ;
if ( sv . num_demosignon_buffers = = MAX_SIGNON_BUFFERS - 1 )
SV_Error ( " sv.num_demosignon_buffers == MAX_SIGNON_BUFFERS-1 " ) ;
sv . demosignon_buffer_size [ sv . num_demosignon_buffers - 1 ] = sv . demosignon . cursize ;
sv . demosignon . data = sv . demosignon_buffers [ sv . num_demosignon_buffers ] ;
sv . num_demosignon_buffers + + ;
sv . demosignon . cursize = 0 ;
}
2009-11-07 13:29:15 +00:00
# endif
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = =
SV_CreateBaseline
Entity baselines are used to compress the update messages
to the clients - - only the fields that differ from the
baseline will be transmitted
= = = = = = = = = = = = = = = =
*/
/*void SV_CreateBaseline (void)
{
int i ;
edict_t * svent ;
2005-07-03 15:16:20 +00:00
int entnum ;
2004-08-23 00:15:46 +00:00
for ( entnum = 0 ; entnum < sv . num_edicts ; entnum + + )
{
svent = EDICT_NUM ( entnum ) ;
if ( svent - > free )
continue ;
// create baselines for all player slots,
// and any other edict that has a visible model
2005-03-28 00:11:59 +00:00
if ( entnum > MAX_CLIENTS & & ! svent - > v - > modelindex )
2004-08-23 00:15:46 +00:00
continue ;
//
// create entity baseline
//
2005-03-28 00:11:59 +00:00
VectorCopy ( svent - > v - > origin , svent - > baseline . origin ) ;
VectorCopy ( svent - > v - > angles , svent - > baseline . angles ) ;
svent - > baseline . frame = svent - > v - > frame ;
svent - > baseline . skinnum = svent - > v - > skin ;
2004-08-23 00:15:46 +00:00
if ( entnum > 0 & & entnum < = MAX_CLIENTS )
{
svent - > baseline . colormap = entnum ;
svent - > baseline . modelindex = SV_ModelIndex ( " progs/player.mdl " ) & 255 ;
}
else
{
svent - > baseline . colormap = 0 ;
svent - > baseline . modelindex =
2005-03-28 00:11:59 +00:00
SV_ModelIndex ( PR_GetString ( svent - > v - > model ) ) & 255 ;
2004-08-23 00:15:46 +00:00
}
# ifdef PEXT_SCALE
svent - > baseline . scale = 1 ;
# endif
# ifdef PEXT_TRANS
svent - > baseline . trans = 1 ;
# endif
//
// flush the signon message out to a seperate buffer if
// nearly full
//
SV_FlushSignon ( ) ;
//
// add to the message
//
2005-07-03 15:16:20 +00:00
MSG_WriteByte ( & sv . signon , svc_spawnbaseline ) ;
2004-08-23 00:15:46 +00:00
MSG_WriteShort ( & sv . signon , entnum ) ;
MSG_WriteByte ( & sv . signon , svent - > baseline . modelindex ) ;
MSG_WriteByte ( & sv . signon , svent - > baseline . frame ) ;
MSG_WriteByte ( & sv . signon , svent - > baseline . colormap ) ;
MSG_WriteByte ( & sv . signon , svent - > baseline . skinnum ) ;
for ( i = 0 ; i < 3 ; i + + )
{
MSG_WriteCoord ( & sv . signon , svent - > baseline . origin [ i ] ) ;
MSG_WriteAngle ( & sv . signon , svent - > baseline . angles [ i ] ) ;
}
}
}
*/
2006-02-27 00:42:25 +00:00
2012-02-14 15:50:34 +00:00
void SV_Snapshot_BuildStateQ1 ( entity_state_t * state , edict_t * ent , client_t * client ) ;
2006-02-27 00:42:25 +00:00
2004-08-23 00:15:46 +00:00
void SVNQ_CreateBaseline ( void )
{
edict_t * svent ;
2005-07-03 15:16:20 +00:00
int entnum ;
2012-02-12 05:18:31 +00:00
extern entity_state_t nullentitystate ;
2004-11-19 17:45:22 +00:00
int playermodel = SV_SafeModelIndex ( " progs/player.mdl " ) ;
2005-07-03 15:16:20 +00:00
2009-11-04 21:16:50 +00:00
for ( entnum = 0 ; entnum < sv . world . num_edicts ; entnum + + )
2004-08-23 00:15:46 +00:00
{
svent = EDICT_NUM ( svprogfuncs , entnum ) ;
2012-02-12 05:18:31 +00:00
memcpy ( & svent - > baseline , & nullentitystate , sizeof ( entity_state_t ) ) ;
2004-08-23 00:15:46 +00:00
svent - > baseline . number = entnum ;
if ( svent - > isfree )
continue ;
// create baselines for all player slots,
// and any other edict that has a visible model
2005-03-28 00:11:59 +00:00
if ( entnum > sv . allocated_client_slots & & ! svent - > v - > modelindex )
2004-08-23 00:15:46 +00:00
continue ;
//
// create entity baseline
//
2012-02-14 15:50:34 +00:00
SV_Snapshot_BuildStateQ1 ( & svent - > baseline , svent , NULL ) ;
2006-02-27 00:42:25 +00:00
2004-08-23 00:15:46 +00:00
if ( entnum > 0 & & entnum < = sv . allocated_client_slots )
{
if ( entnum > 0 & & entnum < = 16 )
svent - > baseline . colormap = entnum ;
else
svent - > baseline . colormap = 0 ; //this would crash NQ.
2004-11-19 17:45:22 +00:00
2012-02-14 15:50:34 +00:00
if ( ! svent - > baseline . solid )
svent - > baseline . solid = ( 2 | ( 3 < < 5 ) | ( 4 < < 10 ) ) ;
if ( ! svent - > baseline . modelindex )
svent - > baseline . modelindex = playermodel ;
2004-08-23 00:15:46 +00:00
}
svent - > baseline . modelindex & = 255 ;
}
}
/*
= = = = = = = = = = = = = = = =
SV_SaveSpawnparms
2005-07-03 15:16:20 +00:00
Grabs the current state of the progs serverinfo flags
2004-08-23 00:15:46 +00:00
and each client for saving across the
transition to another level
= = = = = = = = = = = = = = = =
*/
void SV_SaveSpawnparms ( qboolean dontsave )
{
int i , j ;
if ( ! sv . state )
return ; // no progs loaded yet
if ( ! svprogfuncs )
return ;
// serverflags is the only game related thing maintained
svs . serverflags = pr_global_struct - > serverflags ;
2011-04-25 03:25:22 +00:00
for ( i = 0 , host_client = svs . clients ; i < sv . allocated_client_slots ; i + + , host_client + + )
2004-08-23 00:15:46 +00:00
{
if ( host_client - > state ! = cs_spawned )
continue ;
if ( dontsave ) //level restart requires that stats can be reset
continue ;
// call the progs to get default spawn parms for the new client
2011-05-20 04:10:46 +00:00
if ( PR_FindGlobal ( svprogfuncs , " ClientReEnter " , 0 , NULL ) )
2004-08-23 00:15:46 +00:00
{ //oooh, evil.
char buffer [ 65536 ] ;
int bufsize = sizeof ( buffer ) ;
char * buf ;
for ( j = 0 ; j < NUM_SPAWN_PARMS ; j + + )
host_client - > spawn_parms [ j ] = 0 ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
buf = svprogfuncs - > saveent ( svprogfuncs , buffer , & bufsize , host_client - > edict ) ;
if ( host_client - > spawninfo )
Z_Free ( host_client - > spawninfo ) ;
host_client - > spawninfo = Z_Malloc ( bufsize + 1 ) ;
memcpy ( host_client - > spawninfo , buf , bufsize ) ;
host_client - > spawninfotime = sv . time ;
}
2007-09-02 19:55:17 +00:00
# ifdef VM_Q1
else if ( svs . gametype = = GT_Q1QVM )
{
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , host_client - > edict ) ;
Q1QVM_SetChangeParms ( ) ;
for ( j = 0 ; j < NUM_SPAWN_PARMS ; j + + )
{
2011-10-27 16:16:29 +00:00
if ( pr_global_ptrs - > spawnparamglobals [ j ] )
host_client - > spawn_parms [ j ] = * pr_global_ptrs - > spawnparamglobals [ j ] ;
2007-09-02 19:55:17 +00:00
else
host_client - > spawn_parms [ j ] = 0 ;
}
}
# endif
2011-10-27 16:16:29 +00:00
else if ( pr_global_ptrs - > SetChangeParms )
2004-08-23 00:15:46 +00:00
{
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , host_client - > edict ) ;
PR_ExecuteProgram ( svprogfuncs , pr_global_struct - > SetChangeParms ) ;
for ( j = 0 ; j < NUM_SPAWN_PARMS ; j + + )
2005-06-22 17:10:13 +00:00
{
2011-10-27 16:16:29 +00:00
if ( pr_global_ptrs - > spawnparamglobals [ j ] )
host_client - > spawn_parms [ j ] = * pr_global_ptrs - > spawnparamglobals [ j ] ;
2005-07-03 15:16:20 +00:00
else
2005-06-22 17:10:13 +00:00
host_client - > spawn_parms [ j ] = 0 ;
}
2004-08-23 00:15:46 +00:00
}
# ifdef SVRANKING
if ( host_client - > rankid )
{
rankstats_t rs ;
if ( Rank_GetPlayerStats ( host_client - > rankid , & rs ) )
{
rs . timeonserver + = realtime - host_client - > stats_started ;
host_client - > stats_started = realtime ;
rs . kills + = host_client - > kills ;
rs . deaths + = host_client - > deaths ;
host_client - > kills = 0 ;
host_client - > deaths = 0 ;
for ( j = 0 ; j < NUM_SPAWN_PARMS ; j + + )
2005-06-22 17:10:13 +00:00
{
2011-10-27 16:16:29 +00:00
if ( pr_global_ptrs - > spawnparamglobals [ j ] )
rs . parm [ j ] = * pr_global_ptrs - > spawnparamglobals [ j ] ;
2005-06-22 17:10:13 +00:00
else
rs . parm [ j ] = 0 ;
}
2004-08-23 00:15:46 +00:00
Rank_SetPlayerStats ( host_client - > rankid , & rs ) ;
}
}
# endif
}
}
/*
= = = = = = = = = = = = = = = =
SV_CalcPHS
Expands the PVS and calculates the PHS
( Potentially Hearable Set )
= = = = = = = = = = = = = = = =
*/
void SV_CalcPHS ( void )
{
int rowbytes , rowwords ;
int i , j , k , l , index , num ;
int bitbyte ;
unsigned * dest , * src ;
2009-06-21 17:45:33 +00:00
qbyte * scan , * lf ;
2004-08-23 00:15:46 +00:00
int count , vcount ;
2009-11-04 21:16:50 +00:00
if ( sv . world . worldmodel - > fromgame = = fg_quake2 | | sv . world . worldmodel - > fromgame = = fg_quake3 )
2004-08-23 00:15:46 +00:00
{
//PHS calcs are pointless with Q2 bsps
return ;
}
2009-11-04 21:16:50 +00:00
num = sv . world . worldmodel - > numleafs ;
2004-08-23 00:15:46 +00:00
rowwords = ( num + 31 ) > > 5 ;
rowbytes = rowwords * 4 ;
2012-02-27 12:23:15 +00:00
if ( ! sv_calcphs . ival | | ( sv_calcphs . ival = = 2 & & ( rowbytes * num > = 0x100000 | | ( ! deathmatch . ival & & ! coop . ival ) ) ) )
{
sv . pvs = Hunk_AllocName ( rowbytes * num , " pvs vis " ) ;
scan = sv . pvs ;
for ( i = 0 ; i < num ; i + + , scan + = rowbytes )
{
lf = sv . world . worldmodel - > funcs . LeafPVS ( sv . world . worldmodel , i , scan , rowbytes ) ;
if ( lf ! = scan )
memcpy ( scan , lf , rowbytes ) ;
}
Con_DPrintf ( " Skipping PHS \n " ) ;
sv . phs = NULL ;
return ;
}
2010-07-25 15:07:19 +00:00
2004-08-23 00:15:46 +00:00
sv . pvs = Hunk_AllocName ( rowbytes * num , " phs vis " ) ;
scan = sv . pvs ;
vcount = 0 ;
for ( i = 0 ; i < num ; i + + , scan + = rowbytes )
{
2009-11-04 21:16:50 +00:00
lf = sv . world . worldmodel - > funcs . LeafPVS ( sv . world . worldmodel , i , scan , rowbytes ) ;
2009-06-21 17:45:33 +00:00
if ( lf ! = scan )
memcpy ( scan , lf , rowbytes ) ;
2004-08-23 00:15:46 +00:00
if ( i = = 0 )
continue ;
for ( j = 0 ; j < num ; j + + )
{
if ( scan [ j > > 3 ] & ( 1 < < ( j & 7 ) ) )
{
vcount + + ;
}
}
}
2012-02-27 12:23:15 +00:00
if ( developer . value )
Con_TPrintf ( STL_BUILDINGPHS ) ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
2010-07-25 15:07:19 +00:00
/*this routine takes an exponential amount of time, so cache it if its too big*/
if ( rowbytes * num > = 0x100000 )
{
sv . phs = COM_LoadHunkFile ( va ( " maps/%s.phs " , sv . name ) ) ;
if ( sv . phs & & com_filesize = = rowbytes * num + 8 & & ( ( unsigned * ) sv . phs ) [ 0 ] = = * ( unsigned * ) " QPHS " & & ( ( unsigned * ) sv . phs ) [ 1 ] = = * ( unsigned * ) " \1 \0 \0 \0 " )
{
sv . phs + = 8 ;
Con_DPrintf ( " Loaded cached PHS \n " ) ;
return ;
}
else
Con_DPrintf ( " Stale cached PHS \n " ) ;
}
2004-08-23 00:15:46 +00:00
sv . phs = Hunk_AllocName ( rowbytes * num , " phs hear " ) ;
count = 0 ;
scan = sv . pvs ;
dest = ( unsigned * ) sv . phs ;
for ( i = 0 ; i < num ; i + + , dest + = rowwords , scan + = rowbytes )
{
memcpy ( dest , scan , rowbytes ) ;
for ( j = 0 ; j < rowbytes ; j + + )
{
bitbyte = scan [ j ] ;
if ( ! bitbyte )
continue ;
for ( k = 0 ; k < 8 ; k + + )
{
if ( ! ( bitbyte & ( 1 < < k ) ) )
continue ;
// or this pvs row into the phs
// +1 because pvs is 1 based
index = ( ( j < < 3 ) + k + 1 ) ;
if ( index > = num )
continue ;
src = ( unsigned * ) sv . pvs + index * rowwords ;
for ( l = 0 ; l < rowwords ; l + + )
dest [ l ] | = src [ l ] ;
}
}
if ( i = = 0 )
continue ;
for ( j = 0 ; j < num ; j + + )
if ( ( ( qbyte * ) dest ) [ j > > 3 ] & ( 1 < < ( j & 7 ) ) )
count + + ;
}
2010-07-25 15:07:19 +00:00
if ( rowbytes * num > = 0x100000 )
{
vfsfile_t * f = FS_OpenVFS ( va ( " maps/%s.phs " , sv . name ) , " wb " , FS_GAMEONLY ) ;
if ( f )
{
VFS_WRITE ( f , " QPHS \1 \0 \0 \0 " , 8 ) ;
VFS_WRITE ( f , sv . phs , rowbytes * num ) ;
VFS_CLOSE ( f ) ;
Con_Printf ( " Written PHS cache (%u bytes) \n " , rowbytes * num ) ;
}
}
2004-08-23 00:15:46 +00:00
if ( num )
2004-10-18 10:49:19 +00:00
if ( developer . value )
Con_TPrintf ( STL_PHSINFO , vcount / num , count / num , num ) ;
2004-08-23 00:15:46 +00:00
}
unsigned SV_CheckModel ( char * mdl )
{
qbyte stackbuf [ 1024 ] ; // avoid dirtying the cache heap
qbyte * buf ;
unsigned short crc ;
// int len;
buf = ( qbyte * ) COM_LoadStackFile ( mdl , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf )
return 0 ;
2005-09-08 22:52:46 +00:00
crc = QCRC_Block ( buf , com_filesize ) ;
2004-08-23 00:15:46 +00:00
// for (len = com_filesize; len; len--, buf++)
// CRC_ProcessByte(&crc, *buf);
return crc ;
}
void SV_UnspawnServer ( void ) //terminate the running server.
{
int i ;
if ( sv . state )
{
Con_TPrintf ( STL_SERVERUNSPAWNED ) ;
SV_FinalMessage ( " Server unspawned \n " ) ;
2011-08-16 04:12:15 +00:00
if ( sv . mvdrecording )
SV_MVDStop ( 0 , false ) ;
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < sv . allocated_client_slots ; i + + )
{
if ( svs . clients [ i ] . state )
SV_DropClient ( svs . clients + i ) ;
}
2011-12-23 03:12:29 +00:00
PR_Deinit ( ) ;
2005-03-18 06:13:11 +00:00
# ifdef Q2SERVER
SVQ2_ShutdownGameProgs ( ) ;
2009-03-03 01:52:30 +00:00
# endif
# ifdef HLSERVER
SVHL_ShutdownGame ( ) ;
2005-03-18 06:13:11 +00:00
# endif
2009-11-04 21:16:50 +00:00
sv . world . worldmodel = NULL ;
2004-08-23 00:15:46 +00:00
sv . state = ss_dead ;
* sv . name = ' \0 ' ;
}
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
2010-07-12 22:46:37 +00:00
if ( svs . clients [ i ] . frameunion . frames )
Z_Free ( svs . clients [ i ] . frameunion . frames ) ;
svs . clients [ i ] . frameunion . frames = NULL ;
2004-08-23 00:15:46 +00:00
svs . clients [ i ] . state = 0 ;
2005-05-19 02:53:03 +00:00
* svs . clients [ i ] . namebuf = ' \0 ' ;
svs . clients [ i ] . name = NULL ;
2004-08-23 00:15:46 +00:00
}
2012-02-12 05:18:31 +00:00
SV_FlushLevelCache ( ) ;
2004-08-23 00:15:46 +00:00
NET_CloseServer ( ) ;
}
/*
= = = = = = = = = = = = = = = =
SV_SpawnServer
Change the server to a new map , taking all connected
clients along with it .
This is only called from the SV_Map_f ( ) function .
= = = = = = = = = = = = = = = =
*/
void SV_SpawnServer ( char * server , char * startspot , qboolean noents , qboolean usecinematic )
{
func_t f ;
char * file ;
2005-05-15 18:49:04 +00:00
gametype_e newgametype ;
2005-03-07 08:58:26 +00:00
2004-08-23 00:15:46 +00:00
edict_t * ent ;
# ifdef Q2SERVER
q2edict_t * q2ent ;
# endif
2005-09-14 04:39:36 +00:00
int i , j ;
2004-08-23 00:15:46 +00:00
int spawnflagmask ;
2010-08-14 03:17:33 +00:00
extern int sv_allow_cheats ;
2004-08-23 00:15:46 +00:00
# ifndef SERVERONLY
2010-02-06 01:25:04 +00:00
if ( ! isDedicated & & qrenderer = = QR_NONE )
2004-08-23 00:15:46 +00:00
{
2004-09-20 23:25:38 +00:00
R_RestartRenderer_f ( ) ;
2007-05-25 22:16:29 +00:00
2010-02-06 01:25:04 +00:00
if ( qrenderer = = QR_NONE )
2007-05-25 22:16:29 +00:00
{
Sys_Error ( " No renderer set when map restarted \n " ) ;
return ;
}
2004-08-23 00:15:46 +00:00
}
# endif
Con_DPrintf ( " SpawnServer: %s \n " , server ) ;
svs . spawncount + + ; // any partially connected client will be
// restarted
# ifndef SERVERONLY
total_loading_size = 100 ;
current_loading_size = 0 ;
2009-04-06 00:34:32 +00:00
SCR_SetLoadingStage ( LS_SERVER ) ;
2006-09-17 00:59:22 +00:00
// SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
NET_InitServer ( ) ;
sv . state = ss_dead ;
if ( sv . gamedirchanged )
{
sv . gamedirchanged = false ;
# ifndef SERVERONLY
Wads_Flush ( ) ; //server code is responsable for flushing old state
# endif
2005-11-03 23:40:51 +00:00
# ifdef SVRANKING
2004-08-23 00:15:46 +00:00
Rank_Flush ( ) ;
2005-11-03 23:40:51 +00:00
# endif
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
2005-05-26 12:55:34 +00:00
if ( svs . clients [ i ] . state & & ISQWCLIENT ( & svs . clients [ i ] ) )
2004-08-23 00:15:46 +00:00
ReloadRanking ( & svs . clients [ i ] , svs . clients [ i ] . name ) ;
if ( svs . clients [ i ] . spawninfo ) //don't remember this stuff.
Z_Free ( svs . clients [ i ] . spawninfo ) ;
svs . clients [ i ] . spawninfo = NULL ;
}
T_FreeStrings ( ) ;
}
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
if ( sv_bigcoords . value )
{
svs . netprim . coordsize = 4 ;
svs . netprim . anglesize = 2 ;
}
else
{
svs . netprim . coordsize = 2 ;
svs . netprim . anglesize = 1 ;
}
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
svs . clients [ i ] . datagram . prim = svs . netprim ;
svs . clients [ i ] . netchan . message . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
svs . clients [ i ] . nextservertimeupdate = 0 ;
if ( ! svs . clients [ i ] . state ) //bots with the net_preparse module.
svs . clients [ i ] . userinfo [ 0 ] = ' \0 ' ; //clear the userinfo to clear the name
2004-11-17 17:49:18 +00:00
if ( svs . clients [ i ] . netchan . remote_address . type = = NA_LOOPBACK )
{ //forget this client's message buffers, so that any shared client/server network state persists (eg: float coords)
svs . clients [ i ] . num_backbuf = 0 ;
svs . clients [ i ] . datagram . cursize = 0 ;
}
2005-08-03 23:14:59 +00:00
svs . clients [ i ] . csqcactive = false ;
2004-08-23 00:15:46 +00:00
}
VoteFlushAll ( ) ;
# ifndef SERVERONLY
cl . worldmodel = NULL ;
2006-01-28 19:04:13 +00:00
r_worldentity . model = NULL ;
if ( 0 )
cls . state = ca_connected ;
2011-10-27 16:16:29 +00:00
if ( R_PreNewMap )
R_PreNewMap ( ) ;
# ifdef VM_CG
CG_Stop ( ) ;
# endif
2004-08-23 00:15:46 +00:00
# endif
2005-09-08 22:52:46 +00:00
# ifdef Q3SERVER
2005-10-05 02:26:54 +00:00
if ( svs . gametype = = GT_QUAKE3 )
2005-09-08 22:52:46 +00:00
SVQ3_ShutdownGame ( ) ; //botlib kinda mandates this. :(
# endif
2004-08-23 00:15:46 +00:00
Mod_ClearAll ( ) ;
Hunk_FreeToLowMark ( host_hunklevel ) ;
2005-05-19 02:53:03 +00:00
if ( svs . gametype = = GT_PROGS )
2004-08-23 00:15:46 +00:00
{
2005-05-19 02:53:03 +00:00
for ( i = 0 ; i < MAX_LIGHTSTYLES ; i + + )
{
2006-02-17 02:51:59 +00:00
if ( sv . strings . lightstyles [ i ] )
Z_Free ( sv . strings . lightstyles [ i ] ) ;
sv . strings . lightstyles [ i ] = NULL ;
2006-03-06 01:41:09 +00:00
sv . strings . lightstylecolours [ i ] = 7 ;
2005-05-19 02:53:03 +00:00
}
2004-08-23 00:15:46 +00:00
}
2009-11-12 08:53:10 +00:00
# ifdef USEODE
2011-09-03 03:49:43 +00:00
World_ODE_End ( & sv . world ) ;
2009-11-12 08:53:10 +00:00
# endif
2004-08-23 00:15:46 +00:00
// wipe the entire per-level structure
memset ( & sv , 0 , sizeof ( sv ) ) ;
sv . datagram . maxsize = sizeof ( sv . datagram_buf ) ;
sv . datagram . data = sv . datagram_buf ;
sv . datagram . allowoverflow = true ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . datagram . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
sv . reliable_datagram . maxsize = sizeof ( sv . reliable_datagram_buf ) ;
sv . reliable_datagram . data = sv . reliable_datagram_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . reliable_datagram . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
sv . multicast . maxsize = sizeof ( sv . multicast_buf ) ;
sv . multicast . data = sv . multicast_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . multicast . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
# ifdef NQPROT
sv . nqdatagram . maxsize = sizeof ( sv . nqdatagram_buf ) ;
sv . nqdatagram . data = sv . nqdatagram_buf ;
sv . nqdatagram . allowoverflow = true ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . nqdatagram . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
sv . nqreliable_datagram . maxsize = sizeof ( sv . nqreliable_datagram_buf ) ;
sv . nqreliable_datagram . data = sv . nqreliable_datagram_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . nqreliable_datagram . prim = svs . netprim ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
sv . nqmulticast . maxsize = sizeof ( sv . nqmulticast_buf ) ;
sv . nqmulticast . data = sv . nqmulticast_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . nqmulticast . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
# endif
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
# ifdef Q2SERVER
2004-08-23 00:15:46 +00:00
sv . q2datagram . maxsize = sizeof ( sv . q2datagram_buf ) ;
sv . q2datagram . data = sv . q2datagram_buf ;
sv . q2datagram . allowoverflow = true ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . q2datagram . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
sv . q2reliable_datagram . maxsize = sizeof ( sv . q2reliable_datagram_buf ) ;
sv . q2reliable_datagram . data = sv . q2reliable_datagram_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . q2reliable_datagram . prim = svs . netprim ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
sv . q2multicast . maxsize = sizeof ( sv . q2multicast_buf ) ;
sv . q2multicast . data = sv . q2multicast_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . q2multicast . prim = svs . netprim ;
# endif
2004-08-23 00:15:46 +00:00
sv . master . maxsize = sizeof ( sv . master_buf ) ;
sv . master . data = sv . master_buf ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . master . prim = msg_nullnetprim ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
sv . signon . maxsize = sizeof ( sv . signon_buffers [ 0 ] ) ;
sv . signon . data = sv . signon_buffers [ 0 ] ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
sv . signon . prim = svs . netprim ;
2004-08-23 00:15:46 +00:00
sv . num_signon_buffers = 1 ;
2011-12-05 15:23:40 +00:00
FS_ReferenceControl ( 1 , 1 ) ;
2004-08-23 00:15:46 +00:00
strcpy ( sv . name , server ) ;
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2012-05-09 15:30:53 +00:00
SCR_SetLoadingFile ( " map " ) ;
# else
# define SCR_SetLoadingFile(s)
2004-08-23 00:15:46 +00:00
# endif
Cvar_ApplyLatches ( CVAR_LATCH ) ;
2005-08-07 18:08:13 +00:00
//work out the gamespeed
//reset the server time.
2012-02-12 05:18:31 +00:00
sv . time = 0.01 ; //some progs don't like time starting at 0.
2004-08-23 00:15:46 +00:00
//cos of spawn funcs like self.nextthink = time...
2010-07-25 15:07:19 +00:00
//NQ uses 1, QW uses 0. Awkward.
2005-08-07 18:08:13 +00:00
sv . starttime = Sys_DoubleTime ( ) ;
2004-08-23 00:15:46 +00:00
COM_FlushTempoaryPacks ( ) ;
2010-08-14 03:17:33 +00:00
if ( sv_cheats . ival )
2006-03-11 03:12:10 +00:00
{
sv_allow_cheats = true ;
Info_SetValueForStarKey ( svs . info , " *cheats " , " ON " , MAX_SERVERINFO_STRING ) ;
}
else
{
2010-08-14 03:17:33 +00:00
sv_allow_cheats = 2 ;
2006-03-11 03:12:10 +00:00
Info_SetValueForStarKey ( svs . info , " *cheats " , " " , MAX_SERVERINFO_STRING ) ;
}
2006-03-11 04:39:16 +00:00
# ifndef SERVERONLY
2010-08-14 03:17:33 +00:00
//This fixes a bug where the server advertises cheats, the internal client connects, and doesn't think cheats are allowed.
//this applies to a few other things too, but cheats is the only special one (because of the *)
2006-03-11 03:12:10 +00:00
Q_strncpyz ( cl . serverinfo , svs . info , sizeof ( cl . serverinfo ) ) ;
CL_CheckServerInfo ( ) ;
2010-12-05 02:46:07 +00:00
Cvar_ForceCallback ( Cvar_FindVar ( " r_particlesdesc " ) ) ;
2006-03-11 03:12:10 +00:00
# endif
2004-08-23 00:15:46 +00:00
if ( usecinematic )
{
strcpy ( sv . name , server ) ;
2004-09-15 03:08:38 +00:00
strcpy ( sv . modelname , " " ) ;
2004-08-23 00:15:46 +00:00
}
else
{
2011-05-20 04:10:46 +00:00
char * exts [ ] = { " maps/%s.bsp " , " maps/%s.cm " , " maps/%s.hmp " , NULL } ;
2004-08-23 00:15:46 +00:00
strcpy ( sv . name , server ) ;
2011-07-22 15:11:35 +00:00
Q_snprintfz ( sv . modelname , sizeof ( sv . modelname ) , exts [ 0 ] , server ) ;
2011-02-25 04:22:14 +00:00
if ( ! COM_FCheckExists ( sv . modelname ) )
2011-05-20 04:10:46 +00:00
{
if ( COM_FCheckExists ( va ( exts [ 1 ] , server ) ) )
2011-07-22 15:11:35 +00:00
Q_snprintfz ( sv . modelname , sizeof ( sv . modelname ) , exts [ 1 ] , server ) ;
2011-05-20 04:10:46 +00:00
else if ( COM_FCheckExists ( va ( exts [ 2 ] , server ) ) )
2011-07-22 15:11:35 +00:00
Q_snprintfz ( sv . modelname , sizeof ( sv . modelname ) , exts [ 2 ] , server ) ;
2011-05-20 04:10:46 +00:00
}
2004-08-23 00:15:46 +00:00
}
sv . state = ss_loading ;
2009-11-04 21:16:50 +00:00
sv . world . worldmodel = Mod_ForName ( sv . modelname , true ) ;
if ( ! sv . world . worldmodel | | sv . world . worldmodel - > needload )
2007-05-25 22:16:29 +00:00
Sys_Error ( " %s is missing or corrupt \n " , sv . modelname ) ;
2009-11-04 21:16:50 +00:00
if ( sv . world . worldmodel - > type ! = mod_brush & & sv . world . worldmodel - > type ! = mod_heightmap )
2005-08-26 22:56:51 +00:00
Sys_Error ( " %s is not a bsp model \n " , sv . modelname ) ;
2004-08-23 00:15:46 +00:00
sv . state = ss_dead ;
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
// SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2012-05-09 15:30:53 +00:00
SCR_SetLoadingFile ( " phs " ) ;
2004-08-23 00:15:46 +00:00
# endif
SV_CalcPHS ( ) ;
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2012-05-09 15:30:53 +00:00
SCR_SetLoadingFile ( " gamecode " ) ;
2004-08-23 00:15:46 +00:00
# endif
2009-11-04 21:16:50 +00:00
if ( sv . world . worldmodel - > fromgame = = fg_doom )
2004-11-17 17:49:18 +00:00
Info_SetValueForStarKey ( svs . info , " *bspversion " , " 1 " , MAX_SERVERINFO_STRING ) ;
2009-11-04 21:16:50 +00:00
else if ( sv . world . worldmodel - > fromgame = = fg_halflife )
2004-08-23 00:15:46 +00:00
Info_SetValueForStarKey ( svs . info , " *bspversion " , " 30 " , MAX_SERVERINFO_STRING ) ;
2009-11-04 21:16:50 +00:00
else if ( sv . world . worldmodel - > fromgame = = fg_quake2 )
2004-08-23 00:15:46 +00:00
Info_SetValueForStarKey ( svs . info , " *bspversion " , " 38 " , MAX_SERVERINFO_STRING ) ;
2009-11-04 21:16:50 +00:00
else if ( sv . world . worldmodel - > fromgame = = fg_quake3 )
2004-08-23 00:15:46 +00:00
Info_SetValueForStarKey ( svs . info , " *bspversion " , " 46 " , MAX_SERVERINFO_STRING ) ;
else
Info_SetValueForStarKey ( svs . info , " *bspversion " , " " , MAX_SERVERINFO_STRING ) ;
if ( startspot )
Info_SetValueForStarKey ( svs . info , " *startspot " , startspot , MAX_SERVERINFO_STRING ) ;
else
Info_SetValueForStarKey ( svs . info , " *startspot " , " " , MAX_SERVERINFO_STRING ) ;
//
2009-11-12 08:53:10 +00:00
// init physics interaction links
2004-08-23 00:15:46 +00:00
//
2009-11-04 21:16:50 +00:00
World_ClearWorld ( & sv . world ) ;
2004-08-23 00:15:46 +00:00
2005-03-10 03:55:18 +00:00
//do we allow csprogs?
# ifdef PEXT_CSQC
2009-05-24 10:11:17 +00:00
if ( * sv_csqc_progname . string )
file = COM_LoadTempFile ( sv_csqc_progname . string ) ;
else
file = NULL ;
2005-03-10 03:55:18 +00:00
if ( file )
{
char text [ 64 ] ;
2008-05-25 22:23:43 +00:00
sv . csqcchecksum = Com_BlockChecksum ( file , com_filesize ) ;
sprintf ( text , " 0x%x " , sv . csqcchecksum ) ;
2005-03-10 03:55:18 +00:00
Info_SetValueForStarKey ( svs . info , " *csprogs " , text , MAX_SERVERINFO_STRING ) ;
2009-05-24 10:11:17 +00:00
sprintf ( text , " 0x%x " , com_filesize ) ;
Info_SetValueForStarKey ( svs . info , " *csprogssize " , text , MAX_SERVERINFO_STRING ) ;
if ( strcmp ( sv_csqc_progname . string , " csprogs.dat " ) )
Info_SetValueForStarKey ( svs . info , " *csprogsname " , sv_csqc_progname . string , MAX_SERVERINFO_STRING ) ;
else
Info_SetValueForStarKey ( svs . info , " *csprogsname " , " " , MAX_SERVERINFO_STRING ) ;
2005-03-10 03:55:18 +00:00
}
else
2008-05-25 22:23:43 +00:00
{
sv . csqcchecksum = 0 ;
2005-03-10 03:55:18 +00:00
Info_SetValueForStarKey ( svs . info , " *csprogs " , " " , MAX_SERVERINFO_STRING ) ;
2009-05-24 10:11:17 +00:00
Info_SetValueForStarKey ( svs . info , " *csprogssize " , " " , MAX_SERVERINFO_STRING ) ;
Info_SetValueForStarKey ( svs . info , " *csprogsname " , " " , MAX_SERVERINFO_STRING ) ;
2008-05-25 22:23:43 +00:00
}
2005-03-20 02:57:11 +00:00
sv . csqcdebug = sv_csqcdebug . value ;
if ( sv . csqcdebug )
Info_SetValueForStarKey ( svs . info , " *csqcdebug " , " 1 " , MAX_SERVERINFO_STRING ) ;
else
Info_RemoveKey ( svs . info , " *csqcdebug " ) ;
2005-03-10 03:55:18 +00:00
# endif
2005-03-20 02:57:11 +00:00
2007-09-02 19:55:17 +00:00
if ( svs . gametype = = GT_PROGS )
2004-08-23 00:15:46 +00:00
{
2007-09-02 19:55:17 +00:00
if ( svprogfuncs ) //we don't want the q1 stuff anymore.
{
CloseProgs ( svprogfuncs ) ;
2009-11-04 21:16:50 +00:00
sv . world . progs = svprogfuncs = NULL ;
2007-09-02 19:55:17 +00:00
}
2004-08-23 00:15:46 +00:00
}
2005-03-07 08:58:26 +00:00
sv . state = ss_loading ;
2005-05-15 18:49:04 +00:00
newgametype = svs . gametype ;
2009-03-03 01:52:30 +00:00
# ifdef HLSERVER
if ( SVHL_InitGame ( ) )
newgametype = GT_HALFLIFE ;
else
# endif
2005-03-07 08:58:26 +00:00
# ifdef Q3SERVER
if ( SVQ3_InitGame ( ) )
2005-05-15 18:49:04 +00:00
newgametype = GT_QUAKE3 ;
2005-03-07 08:58:26 +00:00
else
# endif
2004-08-23 00:15:46 +00:00
# ifdef Q2SERVER
2011-10-27 16:16:29 +00:00
if ( ( sv . world . worldmodel - > fromgame = = fg_quake2 | | sv . world . worldmodel - > fromgame = = fg_quake3 ) & & ! * pr_ssqc_progs . string & & SVQ2_InitGameProgs ( ) ) //these are the rules for running a q2 server
2005-05-15 18:49:04 +00:00
newgametype = GT_QUAKE2 ; //we loaded the dll
2004-08-23 00:15:46 +00:00
else
2007-09-02 19:55:17 +00:00
# endif
# ifdef VM_Q1
if ( PR_LoadQ1QVM ( ) )
newgametype = GT_Q1QVM ;
else
2004-08-23 00:15:46 +00:00
# endif
{
2005-05-15 18:49:04 +00:00
newgametype = GT_PROGS ; //let's just hope this loads.
2005-03-07 08:58:26 +00:00
Q_InitProgs ( ) ;
}
2004-08-23 00:15:46 +00:00
2005-03-07 08:58:26 +00:00
// if ((sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //full q2 dll decision in one if statement
2005-05-15 18:49:04 +00:00
if ( newgametype ! = svs . gametype )
2005-03-07 08:58:26 +00:00
{
2009-03-03 01:52:30 +00:00
# ifdef HLSERVER
2011-04-20 03:34:32 +00:00
if ( newgametype ! = GT_HALFLIFE )
SVHL_ShutdownGame ( ) ;
2009-03-03 01:52:30 +00:00
# endif
2005-05-15 18:49:04 +00:00
# ifdef Q3SERVER
2011-04-20 03:34:32 +00:00
if ( newgametype ! = GT_QUAKE3 )
SVQ3_ShutdownGame ( ) ;
2005-05-15 18:49:04 +00:00
# endif
# ifdef Q2SERVER
2011-04-20 03:34:32 +00:00
if ( newgametype ! = GT_QUAKE2 ) //we don't want the q2 stuff anymore.
SVQ2_ShutdownGameProgs ( ) ;
2005-05-15 18:49:04 +00:00
# endif
2007-09-02 19:55:17 +00:00
# ifdef VM_Q1
2011-04-20 03:34:32 +00:00
if ( newgametype ! = GT_Q1QVM )
Q1QVM_Shutdown ( ) ;
2007-09-02 19:55:17 +00:00
# endif
2005-05-15 18:49:04 +00:00
2011-04-20 03:34:32 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + ) //server type changed, so we need to drop all clients. :(
{
if ( svs . clients [ i ] . state )
SV_DropClient ( & svs . clients [ i ] ) ;
svs . clients [ i ] . namebuf [ 0 ] = ' \0 ' ; //kill all bots
}
}
svs . gametype = newgametype ;
2004-08-23 00:15:46 +00:00
2009-11-07 13:29:15 +00:00
sv . models [ 1 ] = sv . world . worldmodel ;
2007-09-03 22:37:13 +00:00
# ifdef VM_Q1
if ( svs . gametype = = GT_Q1QVM )
{
strcpy ( sv . strings . sound_precache [ 0 ] , " " ) ;
sv . strings . model_precache [ 0 ] = " " ;
sv . strings . model_precache [ 1 ] = sv . modelname ; //the qvm doesn't have access to this array
2009-11-04 21:16:50 +00:00
for ( i = 1 ; i < sv . world . worldmodel - > numsubmodels ; i + + )
2007-09-03 22:37:13 +00:00
{
sv . strings . model_precache [ 1 + i ] = localmodels [ i ] ;
2009-11-07 13:29:15 +00:00
sv . models [ i + 1 ] = Mod_ForName ( localmodels [ i ] , false ) ;
2007-09-03 22:37:13 +00:00
}
//check player/eyes models for hacks
sv . model_player_checksum = SV_CheckModel ( " progs/player.mdl " ) ;
sv . eyes_player_checksum = SV_CheckModel ( " progs/eyes.mdl " ) ;
}
else
# endif
if ( svs . gametype = = GT_PROGS )
2005-03-20 02:57:11 +00:00
{
2006-02-17 02:51:59 +00:00
strcpy ( sv . strings . sound_precache [ 0 ] , " " ) ;
sv . strings . model_precache [ 0 ] = " " ;
2005-03-20 02:57:11 +00:00
2006-02-17 02:51:59 +00:00
sv . strings . model_precache [ 1 ] = PR_AddString ( svprogfuncs , sv . modelname , 0 ) ;
2009-11-04 21:16:50 +00:00
for ( i = 1 ; i < sv . world . worldmodel - > numsubmodels ; i + + )
2005-03-20 02:57:11 +00:00
{
2006-02-17 02:51:59 +00:00
sv . strings . model_precache [ 1 + i ] = PR_AddString ( svprogfuncs , localmodels [ i ] , 0 ) ;
2009-11-07 13:29:15 +00:00
sv . models [ i + 1 ] = Mod_ForName ( localmodels [ i ] , false ) ;
2005-03-20 02:57:11 +00:00
}
//check player/eyes models for hacks
sv . model_player_checksum = SV_CheckModel ( " progs/player.mdl " ) ;
sv . eyes_player_checksum = SV_CheckModel ( " progs/eyes.mdl " ) ;
}
2005-07-03 15:16:20 +00:00
# ifdef Q2SERVER
2005-03-20 02:57:11 +00:00
else if ( svs . gametype = = GT_QUAKE2 )
{
2006-04-08 05:43:53 +00:00
extern int map_checksum ;
extern cvar_t sv_airaccelerate ;
2006-02-17 02:51:59 +00:00
memset ( sv . strings . configstring , 0 , sizeof ( sv . strings . configstring ) ) ;
2006-04-08 05:43:53 +00:00
if ( deathmatch . value )
sprintf ( sv . strings . configstring [ Q2CS_AIRACCEL ] , " %g " , sv_airaccelerate . value ) ;
else
strcpy ( sv . strings . configstring [ Q2CS_AIRACCEL ] , " 0 " ) ;
// init map checksum config string but only for Q2/Q3 maps
2009-11-04 21:16:50 +00:00
if ( sv . world . worldmodel - > fromgame = = fg_quake2 | | sv . world . worldmodel - > fromgame = = fg_quake3 )
2006-04-08 05:43:53 +00:00
sprintf ( sv . strings . configstring [ Q2CS_MAPCHECKSUM ] , " %i " , map_checksum ) ;
else
strcpy ( sv . strings . configstring [ Q2CS_MAPCHECKSUM ] , " 0 " ) ;
2006-02-17 02:51:59 +00:00
strcpy ( sv . strings . configstring [ Q2CS_MODELS + 1 ] , sv . modelname ) ;
2009-11-04 21:16:50 +00:00
for ( i = 1 ; i < sv . world . worldmodel - > numsubmodels ; i + + )
2005-03-20 02:57:11 +00:00
{
2006-02-17 02:51:59 +00:00
strcpy ( sv . strings . configstring [ Q2CS_MODELS + 1 + i ] , localmodels [ i ] ) ;
2009-11-07 13:29:15 +00:00
sv . models [ i + 1 ] = Mod_ForName ( localmodels [ i ] , false ) ;
2005-03-20 02:57:11 +00:00
}
}
2005-07-03 15:16:20 +00:00
# endif
2005-03-20 02:57:11 +00:00
2004-08-23 00:15:46 +00:00
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2012-05-09 15:30:53 +00:00
SCR_SetLoadingFile ( " clients " ) ;
2004-08-23 00:15:46 +00:00
# endif
2005-05-17 02:36:54 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
2012-02-12 05:18:31 +00:00
svs . clients [ i ] . edict = NULL ;
2005-05-17 02:36:54 +00:00
svs . clients [ i ] . name = svs . clients [ i ] . namebuf ;
svs . clients [ i ] . team = svs . clients [ i ] . teambuf ;
}
2005-03-07 08:58:26 +00:00
switch ( svs . gametype )
2004-08-23 00:15:46 +00:00
{
2007-08-07 19:16:32 +00:00
case GT_MAX :
break ;
2007-09-02 19:55:17 +00:00
case GT_Q1QVM :
2005-03-07 08:58:26 +00:00
case GT_PROGS :
2004-08-23 00:15:46 +00:00
ent = EDICT_NUM ( svprogfuncs , 0 ) ;
ent - > isfree = false ;
2005-07-03 15:16:20 +00:00
2010-08-16 02:03:02 +00:00
# ifndef SERVERONLY
2010-08-14 03:17:33 +00:00
/*force coop 1 if splitscreen and not deathmatch*/
{
extern cvar_t cl_splitscreen ;
if ( cl_splitscreen . value & & ! deathmatch . value & & ! coop . value )
Cvar_Set ( & coop , " 1 " ) ;
}
2010-08-16 02:03:02 +00:00
# endif
2010-08-14 03:17:33 +00:00
/*only make one slot for single-player*/
if ( ! isDedicated & & ! deathmatch . value & & ! coop . value )
sv . allocated_client_slots = 1 ;
else
sv . allocated_client_slots = MAX_CLIENTS ;
2004-08-23 00:15:46 +00:00
// leave slots at start for clients only
2010-08-14 03:17:33 +00:00
for ( i = 0 ; i < sv . allocated_client_slots ; i + + )
2004-08-23 00:15:46 +00:00
{
svs . clients [ i ] . viewent = 0 ;
ent = ED_Alloc ( svprogfuncs ) ; //EDICT_NUM(i+1);
svs . clients [ i ] . edict = ent ;
ent - > isfree = false ;
//ZOID - make sure we update frags right
svs . clients [ i ] . old_frags = 0 ;
if ( ! svs . clients [ i ] . state & & svs . clients [ i ] . name [ 0 ] ) //this is a bot.
svs . clients [ i ] . name [ 0 ] = ' \0 ' ; //make it go away
2005-02-28 07:16:19 +00:00
2007-09-03 22:37:13 +00:00
# ifdef VM_Q1
if ( svs . gametype = = GT_Q1QVM )
{ //we'll fix it up later anyway
svs . clients [ i ] . name = svs . clients [ i ] . namebuf ;
svs . clients [ i ] . team = svs . clients [ i ] . teambuf ;
}
else
# endif
{
svs . clients [ i ] . name = PR_AddString ( svprogfuncs , svs . clients [ i ] . namebuf , sizeof ( svs . clients [ i ] . namebuf ) ) ;
svs . clients [ i ] . team = PR_AddString ( svprogfuncs , svs . clients [ i ] . teambuf , sizeof ( svs . clients [ i ] . teambuf ) ) ;
}
2005-05-17 02:36:54 +00:00
2005-02-28 07:16:19 +00:00
# ifdef PEXT_CSQC
memset ( svs . clients [ i ] . csqcentsequence , 0 , sizeof ( svs . clients [ i ] . csqcentsequence ) ) ;
memset ( svs . clients [ i ] . csqcentversions , 0 , sizeof ( svs . clients [ i ] . csqcentversions ) ) ;
# endif
2004-08-23 00:15:46 +00:00
}
2010-08-14 03:17:33 +00:00
for ( ; i < MAX_CLIENTS ; i + + )
{
if ( svs . clients [ i ] . state )
SV_DropClient ( & svs . clients [ i ] ) ;
svs . clients [ i ] . namebuf [ 0 ] = ' \0 ' ; //kill all bots
}
2005-02-28 07:16:19 +00:00
# ifdef PEXT_CSQC
for ( i = 0 ; i < MAX_EDICTS ; i + + )
sv . csqcentversion [ i ] = 1 ; //force all csqc edicts to start off as version 1
# endif
2005-03-07 08:58:26 +00:00
break ;
case GT_QUAKE2 :
2007-08-07 19:16:32 +00:00
# ifdef Q2SERVER
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
q2ent = Q2EDICT_NUM ( i + 1 ) ;
q2ent - > s . number = i + 1 ;
svs . clients [ i ] . q2edict = q2ent ;
}
2011-04-20 03:34:32 +00:00
sv . allocated_client_slots = svq2_maxclients ;
2005-08-07 18:08:13 +00:00
# endif
2007-08-07 19:16:32 +00:00
break ;
2005-08-07 18:08:13 +00:00
case GT_QUAKE3 :
2007-08-07 19:16:32 +00:00
# ifdef Q3SERVER
2005-08-07 18:08:13 +00:00
sv . allocated_client_slots = 32 ;
2009-03-03 01:52:30 +00:00
# endif
break ;
case GT_HALFLIFE :
# ifdef HLSERVER
SVHL_SetupGame ( ) ;
2004-08-23 00:15:46 +00:00
# endif
2007-08-07 19:16:32 +00:00
break ;
2005-03-07 08:58:26 +00:00
}
2004-08-23 00:15:46 +00:00
2005-05-17 02:36:54 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
Q_strncpyz ( svs . clients [ i ] . name , Info_ValueForKey ( svs . clients [ i ] . userinfo , " name " ) , sizeof ( svs . clients [ i ] . namebuf ) ) ;
Q_strncpyz ( svs . clients [ i ] . team , Info_ValueForKey ( svs . clients [ i ] . userinfo , " team " ) , sizeof ( svs . clients [ i ] . teambuf ) ) ;
}
2004-08-23 00:15:46 +00:00
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
//
// spawn the rest of the entities on the map
2005-07-03 15:16:20 +00:00
//
2004-08-23 00:15:46 +00:00
// precache and static commands can be issued during
// map initialization
sv . state = ss_loading ;
if ( svprogfuncs )
{
2007-09-02 19:55:17 +00:00
//world entity is hackily spawned
2004-08-23 00:15:46 +00:00
extern cvar_t coop , pr_imitatemvdsv ;
eval_t * eval ;
ent = EDICT_NUM ( svprogfuncs , 0 ) ;
ent - > isfree = false ;
2007-09-03 22:37:13 +00:00
# ifdef VM_Q1
if ( svs . gametype ! = GT_Q1QVM ) //we cannot do this with qvm
# endif
2009-11-04 21:16:50 +00:00
ent - > v - > model = PR_NewString ( svprogfuncs , sv . world . worldmodel - > name , 0 ) ;
2005-03-28 00:11:59 +00:00
ent - > v - > modelindex = 1 ; // world model
ent - > v - > solid = SOLID_BSP ;
ent - > v - > movetype = MOVETYPE_PUSH ;
2004-08-23 00:15:46 +00:00
if ( progstype = = PROG_QW & & pr_imitatemvdsv . value > 0 )
{
2007-09-03 22:37:13 +00:00
# ifdef VM_Q1
if ( svs . gametype ! = GT_Q1QVM ) //we cannot do this with qvm
# endif
{
ent - > v - > targetname = PR_NewString ( svprogfuncs , " mvdsv " , 0 ) ;
2011-03-30 15:17:55 +00:00
ent - > v - > netname = PR_NewString ( svprogfuncs , version_string ( ) , 0 ) ;
2007-09-03 22:37:13 +00:00
}
2005-03-28 00:11:59 +00:00
ent - > v - > impulse = 0 ; //QWE_VERNUM;
ent - > v - > items = 103 ;
2004-08-23 00:15:46 +00:00
}
2007-09-03 22:37:13 +00:00
# ifdef VM_Q1
if ( svs . gametype ! = GT_Q1QVM ) //we cannot do this with qvm
# endif
2007-09-13 15:32:23 +00:00
pr_global_struct - > mapname = PR_NewString ( svprogfuncs , sv . name , 0 ) ;
2004-08-23 00:15:46 +00:00
// serverflags are for cross level information (sigils)
pr_global_struct - > serverflags = svs . serverflags ;
pr_global_struct - > time = 0.1 ; //HACK!!!! A few QuakeC mods expect time to be non-zero in spawn funcs - like prydon gate...
if ( progstype = = PROG_H2 )
{
2006-03-23 19:22:12 +00:00
cvar_t * cv ;
2004-08-23 00:15:46 +00:00
if ( coop . value )
{
2011-05-20 04:10:46 +00:00
eval = PR_FindGlobal ( svprogfuncs , " coop " , 0 , NULL ) ;
2004-08-23 00:15:46 +00:00
if ( eval ) eval - > _float = coop . value ;
}
else
{
2011-05-20 04:10:46 +00:00
eval = PR_FindGlobal ( svprogfuncs , " deathmatch " , 0 , NULL ) ;
2004-08-23 00:15:46 +00:00
if ( eval ) eval - > _float = deathmatch . value ;
}
2006-03-23 19:22:12 +00:00
cv = Cvar_Get ( " randomclass " , " 0 " , CVAR_LATCH , " Hexen2 " ) ;
2011-05-20 04:10:46 +00:00
eval = PR_FindGlobal ( svprogfuncs , " randomclass " , 0 , NULL ) ;
2006-03-23 19:22:12 +00:00
if ( eval & & cv ) eval - > _float = cv - > value ;
2004-08-23 00:15:46 +00:00
2006-03-23 19:22:12 +00:00
cv = Cvar_Get ( " cl_playerclass " , " 1 " , CVAR_USERINFO | CVAR_ARCHIVE , " Hexen2 " ) ;
2011-05-20 04:10:46 +00:00
eval = PR_FindGlobal ( svprogfuncs , " cl_playerclass " , 0 , NULL ) ;
2006-03-23 19:22:12 +00:00
if ( eval & & cv ) eval - > _float = cv - > value ;
2004-08-23 00:15:46 +00:00
}
else
{
2011-10-27 16:16:29 +00:00
if ( pr_global_ptrs - > coop & & coop . value )
2004-08-23 00:15:46 +00:00
pr_global_struct - > coop = coop . value ;
2011-10-27 16:16:29 +00:00
else if ( pr_global_ptrs - > deathmatch )
2004-08-23 00:15:46 +00:00
pr_global_struct - > deathmatch = deathmatch . value ;
}
2005-05-17 02:36:54 +00:00
2011-07-10 21:32:51 +00:00
if ( svs . gametype ! = GT_Q1QVM ) //we cannot do this with qvm
2004-08-23 00:15:46 +00:00
{
2011-07-10 21:32:51 +00:00
for ( i = 0 ; i < svs . numprogs ; i + + ) //do this AFTER precaches have been played with...
2004-08-23 00:15:46 +00:00
{
2011-07-10 21:32:51 +00:00
f = PR_FindFunction ( svprogfuncs , " initents " , svs . progsnum [ i ] ) ;
if ( f )
{
PR_ExecuteProgram ( svprogfuncs , f ) ;
}
2004-08-23 00:15:46 +00:00
}
}
2011-09-03 03:49:43 +00:00
if ( progstype = = PROG_QW )
// run the frame start qc function to let progs check cvars
SV_ProgStartFrame ( ) ; //prydon gate seems to fail because of this allowance
2004-08-23 00:15:46 +00:00
}
// load and spawn all other entities
2012-05-09 15:30:53 +00:00
SCR_SetLoadingFile ( " entities " ) ;
2004-08-23 00:15:46 +00:00
if ( progstype = = PROG_H2 )
{
extern cvar_t coop ;
spawnflagmask = 0 ;
if ( deathmatch . value )
spawnflagmask | = SPAWNFLAG_NOT_H2DEATHMATCH ;
else if ( coop . value )
spawnflagmask | = SPAWNFLAG_NOT_H2COOP ;
else
2010-08-28 17:14:38 +00:00
{
cvar_t * cl_playerclass = Cvar_Get ( " cl_playerclass " , " 0 " , CVAR_USERINFO , 0 ) ;
2004-08-23 00:15:46 +00:00
spawnflagmask | = SPAWNFLAG_NOT_H2SINGLE ;
2010-08-28 17:14:38 +00:00
if ( cl_playerclass & & cl_playerclass - > ival = = 1 )
spawnflagmask | = SPAWNFLAG_NOT_H2PALADIN ;
else if ( cl_playerclass & & cl_playerclass - > ival = = 2 )
spawnflagmask | = SPAWNFLAG_NOT_H2CLERIC ;
else if ( cl_playerclass & & cl_playerclass - > ival = = 3 )
spawnflagmask | = SPAWNFLAG_NOT_H2NECROMANCER ;
else if ( cl_playerclass & & cl_playerclass - > ival = = 4 )
spawnflagmask | = SPAWNFLAG_NOT_H2THEIF ;
else if ( cl_playerclass & & cl_playerclass - > ival = = 5 )
spawnflagmask | = SPAWNFLAG_NOT_H2NECROMANCER ; /*yes, I know.,. makes no sense*/
}
2004-08-23 00:15:46 +00:00
if ( skill . value < 0.5 )
spawnflagmask | = SPAWNFLAG_NOT_H2EASY ;
else if ( skill . value > 1.5 )
spawnflagmask | = SPAWNFLAG_NOT_H2HARD ;
else
spawnflagmask | = SPAWNFLAG_NOT_H2MEDIUM ;
2006-03-23 19:22:12 +00:00
//don't filter based on player class. we're lame and don't have any real concept of player classes.
2004-08-23 00:15:46 +00:00
}
else if ( ! deathmatch . value ) //decide if we are to inhibit single player game ents instead
{
spawnflagmask = SPAWNFLAG_NOT_DEATHMATCH ;
if ( skill . value < 0.5 )
spawnflagmask = SPAWNFLAG_NOT_EASY ;
else if ( skill . value > 1.5 )
spawnflagmask = SPAWNFLAG_NOT_HARD ;
else
spawnflagmask = SPAWNFLAG_NOT_MEDIUM ;
}
else
spawnflagmask = SPAWNFLAG_NOT_DEATHMATCH ;
//do this and get the precaches/start up the game
if ( sv_loadentfiles . value )
2009-11-04 21:16:50 +00:00
file = FS_LoadMallocFile ( va ( " maps/%s.ent " , server ) ) ;
2004-08-23 00:15:46 +00:00
else
file = NULL ;
if ( file )
{
char crc [ 12 ] ;
2005-09-08 22:52:46 +00:00
sprintf ( crc , " %i " , QCRC_Block ( file , com_filesize ) ) ;
2004-08-23 00:15:46 +00:00
Info_SetValueForStarKey ( svs . info , " *entfile " , crc , MAX_SERVERINFO_STRING ) ;
2005-03-07 08:58:26 +00:00
switch ( svs . gametype )
{
2007-08-07 19:16:32 +00:00
case GT_MAX :
break ;
2007-09-02 19:55:17 +00:00
case GT_Q1QVM :
2005-03-07 08:58:26 +00:00
case GT_PROGS :
2009-11-04 21:16:50 +00:00
sv . world . edict_size = PR_LoadEnts ( svprogfuncs , file , spawnflagmask ) ;
2005-03-07 08:58:26 +00:00
break ;
case GT_QUAKE2 :
2007-08-07 19:16:32 +00:00
# ifdef Q2SERVER
2004-08-23 00:15:46 +00:00
ge - > SpawnEntities ( sv . name , file , startspot ? startspot : " " ) ;
# endif
2007-08-07 19:16:32 +00:00
break ;
case GT_QUAKE3 :
break ;
2009-03-03 01:52:30 +00:00
case GT_HALFLIFE :
# ifdef HLSERVER
SVHL_SpawnEntities ( file ) ;
# endif
break ;
2005-03-07 08:58:26 +00:00
}
2004-08-23 00:15:46 +00:00
BZ_Free ( file ) ;
}
else
{
Info_SetValueForStarKey ( svs . info , " *entfile " , " " , MAX_SERVERINFO_STRING ) ;
2005-03-07 08:58:26 +00:00
switch ( svs . gametype )
{
2007-08-07 19:16:32 +00:00
case GT_MAX :
break ;
2007-09-02 19:55:17 +00:00
case GT_Q1QVM :
2005-03-07 08:58:26 +00:00
case GT_PROGS :
2009-11-04 21:16:50 +00:00
sv . world . edict_size = PR_LoadEnts ( svprogfuncs , sv . world . worldmodel - > entities , spawnflagmask ) ;
2005-03-07 08:58:26 +00:00
break ;
case GT_QUAKE2 :
2007-08-07 19:16:32 +00:00
# ifdef Q2SERVER
2009-11-04 21:16:50 +00:00
ge - > SpawnEntities ( sv . name , sv . world . worldmodel - > entities , startspot ? startspot : " " ) ;
2004-08-23 00:15:46 +00:00
# endif
2007-08-07 19:16:32 +00:00
break ;
case GT_QUAKE3 :
break ;
2009-03-03 01:52:30 +00:00
case GT_HALFLIFE :
# ifdef HLSERVER
2009-11-04 21:16:50 +00:00
SVHL_SpawnEntities ( sv . world . worldmodel - > entities ) ;
2009-03-03 01:52:30 +00:00
# endif
break ;
2005-03-07 08:58:26 +00:00
}
2004-08-23 00:15:46 +00:00
}
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
Q_strncpyz ( sv . mapname , sv . name , sizeof ( sv . mapname ) ) ;
if ( svprogfuncs )
{
eval_t * val ;
ent = EDICT_NUM ( svprogfuncs , 0 ) ;
2005-03-28 00:11:59 +00:00
ent - > v - > angles [ 0 ] = ent - > v - > angles [ 1 ] = ent - > v - > angles [ 2 ] = 0 ;
2004-08-23 00:15:46 +00:00
val = svprogfuncs - > GetEdictFieldValue ( svprogfuncs , ent , " message " , NULL ) ;
if ( val )
{
if ( progstype = = PROG_H2 )
2006-05-18 02:24:38 +00:00
snprintf ( sv . mapname , sizeof ( sv . mapname ) , " %s " , T_GetString ( val - > _float - 1 ) ) ;
2004-08-23 00:15:46 +00:00
else
2006-05-18 02:24:38 +00:00
snprintf ( sv . mapname , sizeof ( sv . mapname ) , " %s " , PR_GetString ( svprogfuncs , val - > string ) ) ;
2004-08-23 00:15:46 +00:00
}
2007-09-02 19:55:17 +00:00
else
snprintf ( sv . mapname , sizeof ( sv . mapname ) , " %s " , sv . name ) ;
2005-08-26 22:56:51 +00:00
if ( Cvar_Get ( " sv_readonlyworld " , " 1 " , 0 , " DP compatability " ) - > value )
ent - > readonly = true ; //lock it down!
2004-08-23 00:15:46 +00:00
2005-05-19 02:53:03 +00:00
// look up some model indexes for specialized message compression
SV_FindModelNumbers ( ) ;
}
2004-08-23 00:15:46 +00:00
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
// run two frames to allow everything to settle
realtime + = 0.1 ;
SV_Physics ( ) ;
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
realtime + = 0.1 ;
sv . time + = 0.1 ;
2005-08-07 18:08:13 +00:00
sv . starttime - = 0.1 ;
2004-08-23 00:15:46 +00:00
SV_Physics ( ) ;
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
// save movement vars
SV_SetMoveVars ( ) ;
// create a baseline for more efficient communications
// SV_CreateBaseline ();
2005-05-19 02:53:03 +00:00
if ( svprogfuncs )
SVNQ_CreateBaseline ( ) ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
# ifdef Q2SERVER
SVQ2_BuildBaselines ( ) ;
# endif
2004-08-23 00:15:46 +00:00
sv . signon_buffer_size [ sv . num_signon_buffers - 1 ] = sv . signon . cursize ;
2004-09-04 17:56:53 +00:00
// all spawning is completed, any further precache statements
// or prog writes to the signon message are errors
if ( usecinematic )
sv . state = ss_cinematic ;
else
sv . state = ss_active ;
2004-08-23 00:15:46 +00:00
SV_GibFilterInit ( ) ;
SV_FilterImpulseInit ( ) ;
Info_SetValueForKey ( svs . info , " map " , sv . name , MAX_SERVERINFO_STRING ) ;
2012-01-17 07:57:46 +00:00
if ( sv . allocated_client_slots ! = 1 )
Con_TPrintf ( STL_SERVERSPAWNED ) ; //misc filenotfounds can be misleading.
2004-08-23 00:15:46 +00:00
if ( ! startspot )
{
SV_FlushLevelCache ( ) ; //to make sure it's caught
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
{
if ( svs . clients [ i ] . spawninfo )
Z_Free ( svs . clients [ i ] . spawninfo ) ;
svs . clients [ i ] . spawninfo = NULL ;
}
}
if ( svprogfuncs & & startspot )
{
eval_t * eval ;
2011-05-20 04:10:46 +00:00
eval = PR_FindGlobal ( svprogfuncs , " startspot " , 0 , NULL ) ;
2005-05-17 02:36:54 +00:00
if ( eval ) eval - > string = PR_NewString ( svprogfuncs , startspot , 0 ) ;
2004-08-23 00:15:46 +00:00
}
if ( Cmd_AliasExist ( " f_svnewmap " , RESTRICT_LOCAL ) )
Cbuf_AddText ( " f_svnewmap \n " , RESTRICT_LOCAL ) ;
# ifndef SERVERONLY
current_loading_size + = 10 ;
2006-09-17 00:59:22 +00:00
//SCR_BeginLoadingPlaque();
SCR_ImageName ( server ) ;
2004-08-23 00:15:46 +00:00
# endif
2005-08-26 22:56:51 +00:00
2010-08-16 02:03:02 +00:00
/*DP_BOTCLIENT bots should move over to the new map too*/
2007-09-02 19:55:17 +00:00
if ( svs . gametype = = GT_PROGS | | svs . gametype = = GT_Q1QVM )
2005-08-26 22:56:51 +00:00
{
2005-09-14 04:39:36 +00:00
for ( i = 0 ; i < sv . allocated_client_slots ; i + + )
2005-08-26 22:56:51 +00:00
{
host_client = & svs . clients [ i ] ;
if ( host_client - > state = = cs_connected & & host_client - > protocol = = SCP_BAD )
{
sv_player = host_client - > edict ;
SV_ExtractFromUserinfo ( host_client ) ;
// copy spawn parms out of the client_t
2005-09-14 04:39:36 +00:00
for ( j = 0 ; j < NUM_SPAWN_PARMS ; j + + )
2005-08-26 22:56:51 +00:00
{
2011-10-27 16:16:29 +00:00
if ( pr_global_ptrs - > spawnparamglobals [ j ] )
* pr_global_ptrs - > spawnparamglobals [ j ] = host_client - > spawn_parms [ j ] ;
2005-08-26 22:56:51 +00:00
}
2005-10-07 16:27:20 +00:00
SV_SetUpClientEdict ( host_client , sv_player ) ;
2007-09-02 19:55:17 +00:00
sv_player - > xv - > clientcolors = atoi ( Info_ValueForKey ( host_client - > userinfo , " topcolor " ) ) * 16 + atoi ( Info_ValueForKey ( host_client - > userinfo , " bottomcolor " ) ) ;
2005-09-14 04:39:36 +00:00
2005-08-26 22:56:51 +00:00
// call the spawn function
2009-11-04 21:16:50 +00:00
pr_global_struct - > time = sv . world . physicstime ;
2005-08-26 22:56:51 +00:00
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , sv_player ) ;
PR_ExecuteProgram ( svprogfuncs , pr_global_struct - > ClientConnect ) ;
// actually spawn the player
2009-11-04 21:16:50 +00:00
pr_global_struct - > time = sv . world . physicstime ;
2005-08-26 22:56:51 +00:00
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , sv_player ) ;
PR_ExecuteProgram ( svprogfuncs , pr_global_struct - > PutClientInServer ) ;
2012-01-17 07:57:46 +00:00
sv . spawned_client_slots + + ;
2005-08-26 22:56:51 +00:00
// send notification to all clients
host_client - > sendinfo = true ;
host_client - > state = cs_spawned ;
SV_UpdateToReliableMessages ( ) ; //so that we don't flood too much with 31 bots and one player.
}
}
}
2006-11-03 15:53:04 +00:00
2011-12-05 15:23:40 +00:00
FS_ReferenceControl ( 0 , 0 ) ;
2006-11-03 15:53:04 +00:00
SV_MVD_SendInitialGamestate ( NULL ) ;
2004-08-23 00:15:46 +00:00
}
2004-11-29 01:21:00 +00:00
# endif
2010-02-06 01:25:04 +00:00