📄 sv_init.pas
字号:
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]);
{$IFDEF WIN32}
NET_StringToAdr(idmaster, master_adr[0]);
{$ELSE}
NET_StringToAdr(idmaster, @master_adr[0]);
{$ENDIF}
// 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.
d.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -