📄 sv_init.pas
字号:
end
else begin
strcpy(sv.configstrings[CS_AIRACCEL], '0' );
pm_airaccelerate := 0;
end; { if }
SZ_Init( sv.multicast, @sv.multicast_buf, sizeof(sv.multicast_buf) );
strcpy( sv.name, server );
// leave slots at start for clients only
for i := 0 to Trunc(maxclients.value - 1) do begin
// needs to reconnect
if ( svs.clients^[i].state > cs_connected ) then
svs.clients^[i].state := cs_connected;
svs.clients^[i].lastframe := -1;
end; { for }
sv.time := 1000;
strcpy( sv.name, server );
strcpy( sv.configstrings[CS_NAME], server );
if ( serverstate <> ss_game ) then
sv.models[1] := CM_LoadMap( '', False, checksum ) // no real map
else begin
Com_sprintf( sv.configstrings[CS_MODELS+1], sizeof(sv.configstrings[CS_MODELS+1]),
'maps/%s.bsp', [server] );
sv.models[1] := CM_LoadMap( sv.configstrings[CS_MODELS+1], False, checksum );
end; { if }
Com_sprintf( sv.configstrings[CS_MAPCHECKSUM], sizeof(sv.configstrings[CS_MAPCHECKSUM]),
'%i', [checksum] );
//
// clear physics interaction links
//
SV_ClearWorld();
for i := 1 to CM_NumInLineModels() - 1 do begin
Com_sprintf( sv.configstrings[CS_MODELS+1+i], sizeof(sv.configstrings[CS_MODELS+1+i]),
'*%i', [i] );
sv.models[i+1] := CM_InlineModel( sv.configstrings[CS_MODELS+1+i] );
end; { for }
//
// spawn the rest of the entities on the map
//
// precache and static commands can be issued during
// map initialization
sv.state := ss_loading;
Com_SetServerState( Integer(sv.state) );
// load and spawn all other entities
ge^.SpawnEntities( sv.name, CM_EntityString, spawnpoint );
// run two frames to allow everything to settle
ge^.RunFrame;
ge^.RunFrame;
// all precaches are complete
sv.state := serverstate;
Com_SetServerState( Integer(sv.state) );
// create a baseline for more efficient communications
SV_CreateBaseline;
// check for a savegame
SV_CheckForSavegame;
// set serverinfo variable
Cvar_FullSet( 'mapname', sv.name, CVAR_SERVERINFO or CVAR_NOSET );
Com_Printf( '-------------------------------------'#10 );
end;
{
==============
SV_InitGame
A brand new game has been started
==============
}
procedure SV_InitGame;
var
i: Integer;
ent: edict_p;
idmaster: array[0..32-1] of Char;
begin
if ( svs.initialized ) then begin
// Cause any connected clients to reconnect
SV_Shutdown( 'Server restarted'#10, True );
end
else begin
// Make sure the client is down
CL_Drop;
SCR_BeginLoadingPlaque;
end; { if }
// get any latched variable changes (maxclients, etc)
Cvar_GetLatchedVars;
svs.initialized := True;
if (Cvar_VariableValue('coop')<>0) and (Cvar_VariableValue('deathmatch')<>0) then begin
Com_Printf( 'Deathmatch and Coop both set, disabling Coop'#10 );
Cvar_FullSet( 'coop', '0', CVAR_SERVERINFO or CVAR_LATCH );
end; { if }
// dedicated servers are can't be single player and are usually DM
// so unless they explicity set coop, force it to deathmatch
if ( dedicated.value<>0 ) then begin
if not( Cvar_VariableValue('coop')<>0 ) then
Cvar_FullSet('deathmatch', '1', CVAR_SERVERINFO or CVAR_LATCH );
end; { if }
// init clients
if ( Cvar_VariableValue('deathmatch')<>0 ) then begin
if ( maxclients.value <= 1 ) then
Cvar_FullSet('maxclients', '8', CVAR_SERVERINFO or CVAR_LATCH )
else if ( maxclients.value > MAX_CLIENTS ) then
Cvar_FullSet('maxclients', va('%i', [MAX_CLIENTS]), CVAR_SERVERINFO or CVAR_LATCH);
end
else if ( Cvar_VariableValue('coop')<>0 ) then begin
if ( (maxclients.value <= 1) or (maxclients.value > 4) ) then
Cvar_FullSet('maxclients', '4', CVAR_SERVERINFO or CVAR_LATCH);
{$IFDEF COPYPROTECT}
if ( (not sv.attractloop) and (not dedicated.value<>0) ) then
Sys_CopyProtect;
{$ENDIF}
end
else begin // non-deathmatch, non-coop is one player
Cvar_FullSet('maxclients', '1', CVAR_SERVERINFO or CVAR_LATCH);
{$IFDEF COPYPROTECT}
if ( not sv.attractloop ) then
Sys_CopyProtect;
{$ENDIF}
end; { if }
svs.spawncount := rand();
svs.clients := Z_Malloc( sizeof(client_t) * Round(maxclients.value) );
svs.num_client_entities := Round(maxclients.value) * UPDATE_BACKUP * 64;
svs.client_entities := Z_Malloc( sizeof(entity_state_t) * svs.num_client_entities );
// init network stuff
NET_Config( (maxclients.value > 1) );
// heartbeats will always be sent to the id master
svs.last_heartbeat := -99999;
Com_sprintf(idmaster, sizeof(idmaster), '192.246.40.37:%d', [PORT_MASTER] );
NET_StringToAdr( idmaster, master_adr[0] );
// Init game
SV_InitGameProgs;
for i := 0 to Trunc(maxclients.value) - 1 do begin
ent := EDICT_NUM(i+1);
ent^.s.number := i+1;
svs.clients^[i].edict := ent;
FillChar (svs.clients^[i].lastcmd, sizeof(svs.clients^[i].lastcmd), 0);
end; { for }
end;
{
======================
SV_Map
the full syntax is:
map [*]<map>$<startspot>+<nextserver>
command from the console or progs.
Map can also be a.cin, .pcx, or .dm2 file
Nextserver is used to allow a cinematic to play, then proceed to
another level:
map tram.cin+jail_e3
======================
}
procedure SV_Map( attractloop: qboolean; levelstring: PChar; loadgame: qboolean);
var
level: array[0..MAX_QPATH-1] of Char;
ch: PChar;
l: Integer;
spawnpoint: array[0..MAX_QPATH-1] of Char;
begin
sv.loadgame := loadgame;
sv.attractloop := attractloop;
if ( (sv.state = ss_dead) and ( not sv.loadgame ) ) then
SV_InitGame; // the game is just starting
strcpy( level, levelstring );
// if there is a + in the map, set nextserver to the remainder
ch := strstr(level, '+');
if ( ch <> nil) then begin
ch^ := #0;
Cvar_Set('nextserver', va('gamemap "%s"', [ch+1]) )
end
else
Cvar_Set('nextserver', '');
// ZOID special hack for end game screen in coop mode
if ( Cvar_VariableValue('coop')<>0) and (not Q_stricmp(level, 'victory.pcx')<>0) then
Cvar_Set('nextserver', 'gamemap "*base1"');
// if there is a $, use the remainder as a spawnpoint
ch := strstr(level, '$');
if ( ch<>nil ) then begin
ch^ := #0;
strcpy( spawnpoint, ch+1 )
end
else
spawnpoint[0] := #0;
// skip the end-of-unit flag if necessary
if ( level[0] = '*' ) then
strcpy( level, level+1 );
l := strlen(level);
if (l > 4) and (strcmp(level+l-4, '.cin')=0) then begin
SCR_BeginLoadingPlaque; // for local system
SV_BroadcastCommand( 'changing'#10 , []);
SV_SpawnServer(level, spawnpoint, ss_cinematic, attractloop, loadgame);
end
else if (l > 4) and (strcmp(level+l-4, '.dm2')=0) then begin
SCR_BeginLoadingPlaque; // for local system
SV_BroadcastCommand( 'changing'#10, [] );
SV_SpawnServer(level, spawnpoint, ss_demo, attractloop, loadgame);
end
else if (l > 4) and (strcmp(level+l-4, '.pcx')=0) then begin
SCR_BeginLoadingPlaque; // for local system
SV_BroadcastCommand( 'changing'#10 , []);
SV_SpawnServer(level, spawnpoint, ss_pic, attractloop, loadgame);
end
else begin
SCR_BeginLoadingPlaque; // for local system
SV_BroadcastCommand( 'changing'#10, [] );
SV_SendClientMessages;
SV_SpawnServer(level, spawnpoint, ss_game, attractloop, loadgame);
Cbuf_CopyToDefer;
end; { if }
SV_BroadcastCommand( 'reconnect'#10, [] );
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -