📄 sv_init.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): sv_init.c }
{ }
{ Initial conversion by : dhouse (david@dahsoftware.com) }
{ Initial conversion on : 013-Jan-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ Copyright (C) 1997-2001 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 }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. }
{ }
{ See the GNU General Public License for more details. }
{ }
{----------------------------------------------------------------------------}
{ Updated on : }
{ Updated by : }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{----------------------------------------------------------------------------}
// 25.07.2002 Juha: Proof-readed this unit
unit sv_init;
interface
uses
q_shared,
q_shared_add,
GameUnit,
server;
procedure SV_InitGame; cdecl;
procedure SV_Map(attractloop: qboolean; levelstring: PChar; loadgame: qboolean); cdecl;
function SV_ModelIndex(name: PChar): Integer; cdecl;
function SV_SoundIndex(name: PChar): Integer; cdecl;
function SV_ImageIndex(name: PChar): Integer; cdecl;
var
svs: server_static_t; // persistant server info
sv: server_t; // local server
implementation
uses
SysUtils,
Common,
Cpas,
CVar,
CModel,
PMoveUnit,
Files,
Cmd,
cl_main,
cl_scrn,
{$IFDEF WIN32}
net_wins,
{$ELSE}
net_udp,
{$ENDIF}
sv_ccmds,
sv_game,
sv_world,
sv_main,
sv_send;
{
================
SV_FindIndex
================
}
function SV_FindIndex(name: PChar; start, max: Integer; create: qboolean): Integer;
var
i: Integer;
begin
if (name = nil) or (name[0] = #0) then
begin
Result := 0;
Exit;
end; { if }
i := 1;
while (i < max) and (sv.configstrings[start + i][0] <> #0) do
begin
if strcmp(sv.configstrings[start + i], name) = 0 then
begin
Result := i;
Exit;
end; { if }
Inc(i);
end; { for }
if (not create) then
begin
Result := 0;
Exit;
end; { if }
if (i = max) then
Com_Error(ERR_DROP, '*Index: overflow');
strncpy(sv.configstrings[start + i], name, sizeof(sv.configstrings[i]));
if (sv.state <> ss_loading) then
begin
// Send the update to everyone
SZ_Clear(sv.multicast);
MSG_WriteChar(sv.multicast, Integer(svc_configstring));
MSG_WriteShort(sv.multicast, start + i);
MSG_WriteString(sv.multicast, name);
SV_Multicast(@vec3_origin, MULTICAST_ALL_R);
end; { if }
Result := i;
end;
function SV_ModelIndex(name: pchar): Integer;
begin
Result := SV_FindIndex(name, CS_MODELS, MAX_MODELS, True);
end;
function SV_SoundIndex(name: pchar): Integer;
begin
Result := SV_FindIndex(name, CS_SOUNDS, MAX_SOUNDS, True);
end;
function SV_ImageIndex(name: pchar): Integer;
begin
Result := SV_FindIndex(name, CS_IMAGES, MAX_IMAGES, True);
end;
{
================
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
================
}
procedure SV_CreateBaseline;
var
svent: edict_p;
entnum: Integer;
begin
for entnum := 1 to (ge.num_edicts - 1) do
begin
svent := EDICT_NUM(entnum);
if (not svent^.inuse) then
Continue;
if ((not svent^.s.modelindex <> 0) and (not svent^.s.sound <> 0) and (not svent^.s.effects <> 0)) then
Continue;
svent^.s.number := entnum;
//
// take current state as baseline
//
VectorCopy(svent^.s.origin, svent^.s.old_origin);
sv.baselines[entnum] := svent^.s;
end; { for }
end;
{
=================
SV_CheckForSavegame
=================
}
procedure SV_CheckForSavegame;
var
name: array[0..MAX_OSPATH - 1] of Char;
f: integer;
i: Integer;
previousState: server_state_t;
begin
if (sv_noreload^.value <> 0) then
Exit;
if (Cvar_VariableValue('deathmatch') <> 0) then
Exit;
Com_sprintf(name, sizeof(name), '%s/save/current/%s.sav', [FS_Gamedir(), sv.name]);
f := FileOpen(name, fmOpenRead);
if f = -1 then
Exit; // no savegame
FileClose(f);
SV_ClearWorld;
// get configstrings and areaportals
SV_ReadLevelFile;
if (not sv.loadgame) then
begin
// coming back to a level after being in a different
// level, so run it for ten seconds
// rlava2 was sending too many lightstyles, and overflowing the
// reliable data. temporarily changing the server state to loading
// prevents these from being passed down.
previousState := sv.state;
sv.state := ss_loading;
for i := 0 to 100 - 1 do
ge^.RunFrame;
sv.state := previousState;
end; { if }
end;
{
================
SV_SpawnServer
Change the server to a new map, taking all connected
clients along with it.
================
}
procedure SV_SpawnServer(server, spawnpoint: PChar; serverstate: server_state_t; attractloop, loadgame: qboolean);
var
i: Integer;
checksum: Cardinal;
begin
if (attractloop) then
Cvar_Set('paused', '0');
Com_Printf('------- Server Initialization -------'#10);
Com_DPrintf('SpawnServer: %s'#10, [server]);
if (sv.demofile > 0) then
begin
FileClose(sv.demofile);
sv.demofile := 0;
end;
Inc(svs.spawncount); // any partially connected client will be restarted
sv.state := ss_dead;
Com_SetServerState(Integer(sv.state));
// wipe the entire per-level structure
FillChar(sv, sizeof(sv), 0);
svs.realtime := 0;
sv.loadgame := loadgame;
sv.attractloop := attractloop;
// save name for levels that don't set message
strcpy(sv.configstrings[CS_NAME], server);
if (Cvar_VariableValue('deathmatch') <> 0) then
begin
Com_sprintf(sv.configstrings[CS_AIRACCEL], MAX_QPATH, '%g', [sv_airaccelerate^.value]);
pm_airaccelerate := sv_airaccelerate^.value;
end
else
begin
strcpy(sv.configstrings[CS_AIRACCEL], '0');
pm_airaccelerate := 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -