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

📄 g_save.pas

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