📄 g_save.pas
字号:
with fields[42] do begin name:='mynoise2'; ofs:= FOFS_mynoise2; _type:= F_EDICT; flags:= FFL_NOSPAWN; end;
with fields[43] do begin name:='target_ent'; ofs:= FOFS_target_ent; _type:= F_EDICT; flags:= FFL_NOSPAWN; end;
with fields[44] do begin
name:='chain';
ofs:= FOFS_chain;
_type:= F_EDICT;
flags:= FFL_NOSPAWN;
end;
with fields[45] do begin
name:='prethink';
ofs:= FOFS_prethink;
_type:= F_FUNCTION;
flags:= FFL_NOSPAWN;
end;
with fields[46] do begin name:='think'; ofs:= FOFS_think; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[47] do begin name:='blocked'; ofs:= FOFS_blocked; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[48] do begin name:='touch'; ofs:= FOFS_touch; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[49] do begin name:='use'; ofs:= FOFS_use; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[50] do begin name:='pain'; ofs:= FOFS_pain; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[51] do begin name:='die'; ofs:= FOFS_die; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[52] do begin name:='stand'; ofs:= FOFS_monsterinfo_stand; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[53] do begin name:='idle'; ofs:= FOFS_monsterinfo_idle; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[54] do begin name:='search'; ofs:= FOFS_monsterinfo_search; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[55] do begin name:='walk'; ofs:= FOFS_monsterinfo_walk; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[56] do begin name:='run'; ofs:= FOFS_monsterinfo_run; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[57] do begin name:='dodge'; ofs:= FOFS_monsterinfo_dodge; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[58] do begin name:='attack'; ofs:= FOFS_monsterinfo_attack; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[59] do begin name:='melee'; ofs:= FOFS_monsterinfo_melee; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[60] do begin name:='sight'; ofs:= FOFS_monsterinfo_sight; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[61] do begin name:='checkattack'; ofs:= FOFS_monsterinfo_checkattack; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
with fields[62] do begin name:='currentmove'; ofs:= FOFS_monsterinfo_currentmove; _type:= F_MMOVE; flags:= FFL_NOSPAWN; end;
with fields[63] do begin name:='endfunc'; ofs:= FOFS_moveinfo_endfunc; _type:= F_FUNCTION; flags:= FFL_NOSPAWN; end;
// temp spawn vars -- only valid when the spawn function is called
with fields[64] do begin name:='lip'; ofs:= STOFS_lip; _type:= F_INT; flags:= FFL_SPAWNTEMP; end;
with fields[65] do begin name:='distance'; ofs:= STOFS_distance; _type:= F_INT; flags:= FFL_SPAWNTEMP; end;
with fields[66] do begin name:='height'; ofs:= STOFS_height; _type:= F_INT; flags:= FFL_SPAWNTEMP; end;
with fields[67] do begin name:='noise'; ofs:= STOFS_noise; _type:= F_LSTRING; flags:= FFL_SPAWNTEMP; end;
with fields[68] do begin name:='pausetime'; ofs:= STOFS_pausetime; _type:= F_FLOAT; flags:= FFL_SPAWNTEMP; end;
with fields[69] do begin name:='item'; ofs:= STOFS_item; _type:= F_LSTRING; flags:= FFL_SPAWNTEMP; end;
//need for item field in edict struct, FFL_SPAWNTEMP item will be skipped on saves
with fields[70] do begin name:='item'; ofs:= FOFS_item; _type:= F_ITEM; end;
with fields[71] do begin name:='gravity'; ofs:= STOFS_gravity; _type:= F_LSTRING; flags:= FFL_SPAWNTEMP; end;
with fields[72] do begin name:='sky'; ofs:= STOFS_sky; _type:= F_LSTRING; flags:= FFL_SPAWNTEMP; end;
with fields[73] do begin name:='skyrotate'; ofs:= STOFS_skyrotate; _type:= F_FLOAT; flags:= FFL_SPAWNTEMP; end;
with fields[74] do begin name:='skyaxis'; ofs:= STOFS_skyaxis; _type:= F_VECTOR; flags:= FFL_SPAWNTEMP; end;
with fields[75] do begin name:='minyaw'; ofs:= STOFS_minyaw; _type:= F_FLOAT; flags:= FFL_SPAWNTEMP; end;
with fields[76] do begin name:='maxyaw'; ofs:= STOFS_maxyaw; _type:= F_FLOAT; flags:= FFL_SPAWNTEMP; end;
with fields[77] do begin name:='minpitch'; ofs:= STOFS_minpitch; _type:= F_FLOAT; flags:= FFL_SPAWNTEMP; end;
with fields[78] do begin name:='maxpitch'; ofs:= STOFS_maxpitch; _type:= F_FLOAT; flags:= FFL_SPAWNTEMP; end;
with fields[79] do begin name:='nextmap'; ofs:= STOFS_nextmap; _type:= F_LSTRING; flags:= FFL_SPAWNTEMP; end;
with fields[80] do begin name:=Nil; ofs:= 0; _type:= fieldtype_t(0); flags:= 0; end;
end;
procedure SetLevelFields;
begin
with levelfields[0] do begin
name:='changemap'; ofs:= LLOFS_changemap; _type:= F_LSTRING;
end;
with levelfields[1] do begin
name:='sight_client'; ofs:= LLOFS_sight_client; _type:= F_EDICT;
end;
with levelfields[2] do begin
name:='sight_entity'; ofs:= LLOFS_sight_entity; _type:= F_EDICT;
end;
with levelfields[3] do begin
name:='sound_entity'; ofs:= LLOFS_sound_entity; _type:= F_EDICT;
end;
with levelfields[4] do begin
name:='sound2_entity'; ofs:= LLOFS_sound2_entity; _type:= F_EDICT;
end;
with levelfields[5] do begin
name:=Nil; ofs:= 0; _type:= F_INT;
end;
end;
procedure SetClientFields;
begin
with clientfields[0] do begin
name:='pers.weapon'; ofs:= CLOFS_pers_weapon; _type:= F_ITEM;
end;
with clientfields[1] do begin
name:='pers.lastweapon'; ofs:= CLOFS_pers_lastweapon; _type:= F_ITEM;
end;
with clientfields[2] do begin
name:='newweapon'; ofs:= CLOFS_newweapon; _type:= F_ITEM;
end;
with clientfields[3] do begin
name:=Nil; ofs:= 0; _type:= F_INT;
end;
end;
(*
============
InitGame
This will be called when the dll is first loaded, which
only happens when a new game is started or a save game
is loaded.
============
*)
procedure InitGame; cdecl;
begin
gi.dprintf('==== InitGame ===='#10);
gun_x := gi.cvar('gun_x', '0', 0);
gun_y := gi.cvar('gun_y', '0', 0);
gun_z := gi.cvar('gun_z', '0', 0);
//FIXME: sv_ prefix is wrong for these
sv_rollspeed := gi.cvar('sv_rollspeed', '200', 0);
sv_rollangle := gi.cvar('sv_rollangle', '2', 0);
sv_maxvelocity := gi.cvar('sv_maxvelocity', '2000', 0);
sv_gravity := gi.cvar('sv_gravity', '800', 0);
// noset vars
dedicated := gi.cvar('dedicated', '0', CVAR_NOSET);
// latched vars
sv_cheats := gi.cvar('cheats', '0', CVAR_SERVERINFO OR CVAR_LATCH);
gi.cvar('gamename', GAMEVERSION, CVAR_SERVERINFO OR CVAR_LATCH);
gi.cvar('gamedate', __DATE__ , CVAR_SERVERINFO OR CVAR_LATCH);
maxclients := gi.cvar('maxclients', '4', CVAR_SERVERINFO OR CVAR_LATCH);
maxspectators := gi.cvar('maxspectators', '4', CVAR_SERVERINFO);
deathmatch := gi.cvar('deathmatch', '0', CVAR_LATCH);
coop := gi.cvar('coop', '0', CVAR_LATCH);
skill := gi.cvar('skill', '1', CVAR_LATCH);
maxentities := gi.cvar('maxentities', '1024', CVAR_LATCH);
// change anytime vars
dmflags := gi.cvar('dmflags', '0', CVAR_SERVERINFO);
fraglimit := gi.cvar('fraglimit', '0', CVAR_SERVERINFO);
timelimit := gi.cvar('timelimit', '0', CVAR_SERVERINFO);
password := gi.cvar('password', '', CVAR_USERINFO);
spectator_password := gi.cvar('spectator_password', '', CVAR_USERINFO);
needpass := gi.cvar('needpass', '0', CVAR_SERVERINFO);
filterban := gi.cvar('filterban', '1', 0);
g_select_empty := gi.cvar ('g_select_empty', '0', CVAR_ARCHIVE);
run_pitch := gi.cvar('run_pitch', '0.002', 0);
run_roll := gi.cvar('run_roll', '0.005', 0);
bob_up := gi.cvar('bob_up', '0.005', 0);
bob_pitch := gi.cvar('bob_pitch', '0.002', 0);
bob_roll := gi.cvar('bob_roll', '0.002', 0);
// flood control
flood_msgs := gi.cvar('flood_msgs', '4', 0);
flood_persecond := gi.cvar('flood_persecond', '4', 0);
flood_waitdelay := gi.cvar('flood_waitdelay', '10', 0);
// dm map list
sv_maplist := gi.cvar('sv_maplist', '', 0);
// items
InitItems();
Com_sprintf(game.helpmessage1, sizeof(game.helpmessage1), '', ['']);
Com_sprintf(game.helpmessage2, sizeof(game.helpmessage2), '', ['']);
// initialize all entities for this game
game.maxentities := Trunc(maxentities.value); //CAK - Trunc ?
g_edicts := gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
globals.edicts := @g_edicts[0];
globals.max_edicts := game.maxentities;
// initialize all clients for this game
game.maxclients := Trunc(maxclients.value);
game.clients := gi.TagMalloc (game.maxclients * sizeof(gclient_a(game.clients)[0]), TAG_GAME);
globals.num_edicts := game.maxclients+1;
end;
//=========================================================
type
pedict_p = ^edict_p;
pgclient_p = ^gclient_p;
pgitem_p = ^gitem_p;
PPByte = ^PByte;
procedure WriteField1(Var f: File; field: field_p; base: PByte);
Var p: Pointer; len: Integer; index: Integer;
begin
if (field.flags AND FFL_SPAWNTEMP)>0 then
exit;
p := Pointer(LongInt(base) + field.ofs);
case field._type of
F_INT, F_FLOAT, F_ANGLEHACK, F_VECTOR, F_IGNORE: {do nothing};
F_LSTRING, F_GSTRING: begin
if PPChar(p)^<>Nil then
len := strlen(PPChar(p)^)+1
else
len := 0;
PInteger(p)^ := len;
end;
F_EDICT: begin
if pedict_p(p)^ = Nil then
index := -1
else
index := (LongInt(pedict_p(p)^) - LongInt(g_edicts)) div sizeof(edict_t);
PInteger(p)^ := index;
end;
F_CLIENT: begin
if pgclient_p(p)^ = Nil then
index := -1
else
index := (LongInt(pgclient_p(p)^) - LongInt(game.clients)) div sizeof(gclient_t);
PInteger(p)^ := index;
end;
F_ITEM: begin
if pedict_p(p)^ = Nil then
index := -1
else
index := (LongInt(pgitem_p(p)^) - LongInt(@itemlist)) div sizeof(gitem_t);
PInteger(p)^ := index;
end;
//relative to code segment
F_FUNCTION: begin
if PPByte(p)^ = Nil then
index := 0
else
index := LongInt(PPByte(p)^) - LongInt(PByte(@InitGame));
PInteger(p)^ := index;
end;
//relative to data segment
F_MMOVE: begin
if PPByte(p)^ = Nil then
index := 0
else
index := LongInt(PPByte(p)^) - LongInt(PByte(@mmove_reloc));
PInteger(p)^ := index;
end;
else
gi.error('WriteEdict: unknown field type');
end;
end;
procedure WriteField2(Var f: File; field: field_p; base: PByte);
Var len: Integer; p: Pointer;
begin
if (field.flags AND FFL_SPAWNTEMP)>0 then
exit;
p := Pointer(LongInt(base) + field.ofs);
case field._type of
F_LSTRING:
if PPChar(p)^ <> Nil then begin
len := strlen(PPChar(p)^) + 1;
BlockWrite(F, PPChar(p)^^, len);
end;
end;
end;
procedure ReadField(Var f: File; field: field_p; base: PByte);
Var p: Pointer; len: Integer; index: Integer;
begin
if (field.flags AND FFL_SPAWNTEMP)>0 then
exit;
p := Ptr(LongInt(base) + field.ofs);
case field._type of
F_INT, F_FLOAT, F_ANGLEHACK, F_VECTOR, F_IGNORE: {do nothing};
F_LSTRING: begin
len := PInteger(p)^;
if len = 0 then
PPChar(p)^ := Nil
else begin
PPChar(p)^ := gi.TagMalloc(len, TAG_LEVEL);
BlockRead(f, PPChar(p)^^, len);
end;
end;
F_EDICT: begin
index := PInteger(p)^;
if index = -1 then
pedict_p(p)^ := Nil
else
pedict_p(p)^ := @g_edicts[index];
end;
F_CLIENT: begin
index := PInteger(p)^;
if index = -1 then
pgclient_p(p)^ := Nil
else
pgclient_p(p)^ := @gclient_a(game.clients)[index];
end;
F_ITEM: begin
index := PInteger(p)^;
if index = -1 then
pgitem_p(p)^ := Nil
else
pgitem_p(p)^ := @itemlist[index];
end;
//relative to code segment
F_FUNCTION: begin
index := PInteger(p)^;
if index = 0 then
PPByte(p)^ := Nil
else
PPByte(p)^ := PByte(LongInt(@InitGame)+index);
end;
//relative to data segment
F_MMOVE: begin
index := PInteger(p)^;
if index = 0 then
PPByte(p)^ := Nil
else
PPByte(p)^ := PByte(LongInt(@mmove_reloc) + index);
end;
else
gi.error('ReadEdict: unknown field type');
end {case};
end {procedure};
//=========================================================
(*
==============
WriteClient
All pointer variables (except function pointers) must be handled specially.
==============
*)
procedure WriteClient(Var f: File; client: gclient_p);
Var field: field_p; temp: gclient_t;
begin
// all of the ints, floats, and vectors stay as they are
temp := client^;
// change the pointers to lengths or indexes
field:=@clientfields[0];
while field.name <> Nil do begin
WriteField1(f, field, PByte(@temp));
inc(field);
end;
// write the block
BlockWrite(f, temp, sizeof(temp));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -