⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sv_init.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  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 + -