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

📄 g_spawn.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//100%
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): g_spawn.c - nil system driver to aid porting efforts              }
{                                                                            }
{ Initial conversion by : Mani (mani246yahoo.com)                            }
{ Initial conversion on : 30-Apr-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 :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ 1) g_local.h                                                               }
{ 2)                                                                         }
{ 3)                                                                         }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{                                                                            }
{----------------------------------------------------------------------------}
unit g_spawn;

interface


uses
  g_local,
  g_items,
  q_shared,
  g_save,
  g_func,
  g_misc,
  g_trigger,
  CPas,
  DelphiTypes,
  m_insane,
  m_berserk,
  m_gladiator,
  m_gunner,
  m_infantry,
  m_soldier,
  m_tank,
  m_medic,
  m_flipper,
  m_chick,
  m_parasite,
  m_flyer,
  p_client,
  m_actor,
  m_brain,
  m_float,
  m_hover,
  m_mutant,
  m_supertank,
  m_boss2,
  m_boss3,
  m_boss31,
  g_turret,
  g_main,
  g_target;

type
  spawn_t = record
    name: pchar;
    spawn: procedure(ent: edict_p); cdecl;
  end;
  spawn_p = ^spawn_t;

procedure SP_worldspawn(ent: edict_p); cdecl;
procedure ED_CallSpawn(ent: edict_p); cdecl;
procedure SpawnEntities(mapname: pchar;  entities: pchar;  spawnpoint: pchar); cdecl;

var
  spawns: array [0..108] of spawn_t =
( (name:'item_health'; spawn:SP_item_health),
  (name:'item_health_small'; spawn:SP_item_health_small),
  (name:'item_health_large'; spawn:SP_item_health_large),
  (name:'item_health_mega'; spawn:SP_item_health_mega),

  (name:'info_player_start'; spawn:SP_info_player_start),
  (name:'info_player_deathmatch'; spawn:SP_info_player_deathmatch),
  (name:'info_player_coop'; spawn:SP_info_player_coop),
  (name:'info_player_intermission'; spawn:SP_info_player_intermission),

  (name:'func_plat'; spawn:SP_func_plat),
  (name:'func_button'; spawn:SP_func_button),
  (name:'func_door'; spawn:SP_func_door),
  (name:'func_door_secret'; spawn:SP_func_door_secret),
  (name:'func_door_rotating'; spawn:SP_func_door_rotating),
  (name:'func_rotating'; spawn:SP_func_rotating),
  (name:'func_train'; spawn:SP_func_train),
  (name:'func_water'; spawn:SP_func_water),
  (name:'func_conveyor'; spawn:SP_func_conveyor),
  (name:'func_areaportal'; spawn:SP_func_areaportal),
  (name:'func_clock'; spawn:SP_func_clock),
  (name:'func_wall'; spawn:SP_func_wall),
  (name:'func_object'; spawn:SP_func_object),
  (name:'func_timer'; spawn:SP_func_timer),
  (name:'func_explosive'; spawn:SP_func_explosive),
  (name:'func_killbox'; spawn:SP_func_killbox),

  (name:'trigger_always'; spawn:SP_trigger_always),
  (name:'trigger_once'; spawn:SP_trigger_once),
  (name:'trigger_multiple'; spawn:SP_trigger_multiple),
  (name:'trigger_relay'; spawn:SP_trigger_relay),
  (name:'trigger_push'; spawn:SP_trigger_push),
  (name:'trigger_hurt'; spawn:SP_trigger_hurt),
  (name:'trigger_key'; spawn:SP_trigger_key),
  (name:'trigger_counter'; spawn:SP_trigger_counter),
  (name:'trigger_elevator'; spawn:SP_trigger_elevator),
  (name:'trigger_gravity'; spawn:SP_trigger_gravity),
  (name:'trigger_monsterjump'; spawn:SP_trigger_monsterjump),

  (name:'target_temp_entity'; spawn:SP_target_temp_entity),
  (name:'target_speaker'; spawn:SP_target_speaker),
  (name:'target_explosion'; spawn:SP_target_explosion),
  (name:'target_changelevel'; spawn:SP_target_changelevel),
  (name:'target_secret'; spawn:SP_target_secret),
  (name:'target_goal'; spawn:SP_target_goal),
  (name:'target_splash'; spawn:SP_target_splash),
  (name:'target_spawner'; spawn:SP_target_spawner),
  (name:'target_blaster'; spawn:SP_target_blaster),
  (name:'target_crosslevel_trigger'; spawn:SP_target_crosslevel_trigger),
  (name:'target_crosslevel_target'; spawn:SP_target_crosslevel_target),
  (name:'target_laser'; spawn:SP_target_laser),
  (name:'target_help'; spawn:SP_target_help),
  (name:'target_actor'; spawn:SP_target_actor),
  (name:'target_lightramp'; spawn:SP_target_lightramp),
  (name:'target_earthquake'; spawn:SP_target_earthquake),
  (name:'target_character'; spawn:SP_target_character),
  (name:'target_string'; spawn:SP_target_string),

  (name:'worldspawn'; spawn:SP_worldspawn),
  (name:'viewthing'; spawn:SP_viewthing),

  (name:'light'; spawn:SP_light),
  (name:'light_mine1'; spawn:SP_light_mine1),
  (name:'light_mine2'; spawn:SP_light_mine2),
  (name:'info_null'; spawn:SP_info_null),
  (name:'func_group'; spawn:SP_info_null),
  (name:'info_notnull'; spawn:SP_info_notnull),
  (name:'path_corner'; spawn:SP_path_corner),
  (name:'point_combat'; spawn:SP_point_combat),

  (name:'misc_explobox'; spawn:SP_misc_explobox),
  (name:'misc_banner'; spawn:SP_misc_banner),
  (name:'misc_satellite_dish'; spawn:SP_misc_satellite_dish),
  (name:'misc_actor'; spawn:SP_misc_actor),
  (name:'misc_gib_arm'; spawn:SP_misc_gib_arm),
  (name:'misc_gib_leg'; spawn:SP_misc_gib_leg),
  (name:'misc_gib_head'; spawn:SP_misc_gib_head),
  (name:'misc_insane'; spawn:SP_misc_insane),
  (name:'misc_deadsoldier'; spawn:SP_misc_deadsoldier),
  (name:'misc_viper'; spawn:SP_misc_viper),
  (name:'misc_viper_bomb'; spawn:SP_misc_viper_bomb),
  (name:'misc_bigviper'; spawn:SP_misc_bigviper),
  (name:'misc_strogg_ship'; spawn:SP_misc_strogg_ship),
  (name:'misc_teleporter'; spawn:SP_misc_teleporter),
  (name:'misc_teleporter_dest'; spawn:SP_misc_teleporter_dest),
  (name:'misc_blackhole'; spawn:SP_misc_blackhole),
  (name:'misc_eastertank'; spawn:SP_misc_eastertank),
  (name:'misc_easterchick'; spawn:SP_misc_easterchick),
  (name:'misc_easterchick2'; spawn:SP_misc_easterchick2),

  (name:'monster_berserk'; spawn:SP_monster_berserk),
  (name:'monster_gladiator'; spawn:SP_monster_gladiator),
  (name:'monster_gunner'; spawn:SP_monster_gunner),
  (name:'monster_infantry'; spawn:SP_monster_infantry),
  (name:'monster_soldier_light'; spawn:SP_monster_soldier_light),
  (name:'monster_soldier'; spawn:SP_monster_soldier),
  (name:'monster_soldier_ss'; spawn:SP_monster_soldier_ss),
  (name:'monster_tank'; spawn:SP_monster_tank),
  (name:'monster_tank_commander'; spawn:SP_monster_tank),
  (name:'monster_medic'; spawn:SP_monster_medic),
  (name:'monster_flipper'; spawn:SP_monster_flipper),
  (name:'monster_chick'; spawn:SP_monster_chick),
  (name:'monster_parasite'; spawn:SP_monster_parasite),
  (name:'monster_flyer'; spawn:SP_monster_flyer),
  (name:'monster_brain'; spawn:SP_monster_brain),
  (name:'monster_floater'; spawn:SP_monster_floater),
  (name:'monster_hover'; spawn:SP_monster_hover),
  (name:'monster_mutant'; spawn:SP_monster_mutant),
  (name:'monster_supertank'; spawn:SP_monster_supertank),
  (name:'monster_boss2'; spawn:SP_monster_boss2),
  (name:'monster_boss3_stand'; spawn:SP_monster_boss3_stand),
  (name:'monster_jorg'; spawn:SP_monster_jorg),
  (name:'monster_commander_body'; spawn:SP_monster_commander_body),

  (name:'turret_breach'; spawn:SP_turret_breach),
  (name:'turret_base'; spawn:SP_turret_base),
  (name:'turret_driver'; spawn:SP_turret_driver),
  (Name:nil; spawn:nil));



implementation



uses
  g_utils,
  p_trail,
  g_local_add,
  game_add,
  SysUtils;


(*
===============
ED_CallSpawn

Finds the spawn function for the entity and calls it
===============
*)
procedure ED_CallSpawn(ent: edict_p);
var
  s: spawn_p;
  item: gitem_p;
  i: integer;
label
  continue_;
begin
  if (ent^.classname = nil) then
  begin
    gi.dprintf('ED_CallSpawn: NULL classname'#10);
    Exit;
  end;

  // check item spawn functions
  i:=0;
  item:= @itemlist;
  while i < game.num_items do
  begin
    if item^.classname = nil then
      goto continue_;

    if StrComp(item^.classname, ent^.classname) = 0 then
    begin
      // found it
      SpawnItem(ent, item);
      Exit;
    end;
  continue_:
    inc(i);
    inc(item);
  end;

  // check normal spawn functions
  s := @spawns;
  while s^.name <> nil do
  begin
    if StrComp(s^.name, ent^.classname) = 0 then
    begin
      // found it
      s^.spawn(ent);
      Exit;
    end;
    Inc(s);
  end;
  gi.dprintf('%s doesn''t have a spawn function'#10, ent^.classname);
end;

(*
=============
ED_NewString
=============
*)
function ED_NewString(string_: pchar): pchar;
var
  newb, new_p: pchar;
  I, L: integer;
begin
  L := StrLen(string_) + 1;
  newb := gi.TagMalloc(L, TAG_LEVEL);
  new_p := newb;

  i := 0;
  while i < (L - 1) do
  begin
    if (string_[I] = '\'{#92}) and (I < L - 1) then
    begin
      Inc(I);
      if string_[I] = 'n' then
      begin
        new_p^ := #10;
        Inc(new_p);
      end
      else
      begin
        new_p^ := '\'{#92};
        Inc(new_p);
      end;
    end
    else
    begin
      new_p^ := string_[I];
      Inc(new_p);
    end;
    Inc(i);
  end;

  Result := newb;
end;


(*
===============
ED_ParseField

Takes a key/value pair and sets the binary values
in an edict
===============
*)    
procedure ED_ParseField(key: pchar;  value: pchar;  ent: edict_p);
var
  f: field_p;
  b: pbyte;
  v: single;
  vec: vec3_t;
begin
  f := @fields;
  while f^.name <> nil do
  begin
    if ((f^.flags and FFL_NOSPAWN) = 0) and (Q_stricmp(f^.name, key) = 0) then
    begin
      // found it
      if (f^.flags and FFL_SPAWNTEMP) <> 0 then
        b := PByte(@st)
      else
        b := PByte(ent);

      case f^._type of
        F_LSTRING:  begin
          PPChar(Integer(b) + f^.ofs)^ := ED_NewString(value);
        end;
        F_VECTOR:  begin
          sscanf(value, '%f %f %f', [@vec[0], @vec[1], @vec[2]]);
          PSingleArray(Integer(b) + f^.ofs)[0] := vec[0];
          PSingleArray(Integer(b) + f^.ofs)[1] := vec[1];
          PSingleArray(Integer(b) + f^.ofs)[2] := vec[2];
        end;
        F_INT:  begin
          PInteger(Integer(b) + f^.ofs)^ := atoi(value);
        end;
        F_FLOAT:  begin
          PSingle(Integer(b) + f^.ofs)^ := atof(value);
        end;
        F_ANGLEHACK:  begin
          v := atof(value);
          PSingleArray(Integer(b) + f^.ofs)[0] := 0;
          PSingleArray(Integer(b) + f^.ofs)[1] := v;
          PSingleArray(Integer(b) + f^.ofs)[2] := 0;
        end;
        F_IGNORE: ;
      end;
      Exit;
    end;
    Inc(f);
  end;
  gi.dprintf('%s is not a field'#10, key);
end;

(*
====================
ED_ParseEdict

Parses an edict out of the given string, returning the new position
ed should be a properly initialized empty edict.
====================
*)    
function ED_ParseEdict(data: pchar;  ent: edict_p): pchar;
var
  init: QBoolean;
  keyname: array [0..(256 - 1)] of Char;
  com_token: PChar;
begin
  init := false;
  FillChar(st, SizeOf(st),0);

  (* go through all the dictionary pairs*)
  while True do
  begin
    (* parse key*)
    com_token := COM_Parse(data);
    if com_token[0] = '}' then
      Break;
    if data = nil then
      gi.error('ED_ParseEntity: EOF without closing brace');

    strncpy(keyname, com_token, SizeOf(keyname)-1);

    // parse value
    com_token := COM_Parse(data);
    if data = nil then
      gi.error('ED_ParseEntity: EOF without closing brace');

    if com_token[0] = '}' then
      gi.error('ED_ParseEntity: closing brace without data');

    init := true;

    (* keynames with a leading underscore are used for utility comments,*)
    (* and are immediately discarded by quake*)
    if keyname[0] = '_' then
      Continue;
      
    ED_ParseField(keyname, com_token, ent);
  end;
  
  if not init then
    FillChar(ent, SizeOf(ent^), 0);   { <<-- Perhaps SizeOf(edict_t) }

  Result := data;
end;


(*
================
G_FindTeams

Chain together all entities with a matching team field.

All but the first will have the FL_TEAMSLAVE flag set.
All but the last will have the teamchain field set to the next one
================
*)
procedure G_FindTeams();
var
  e, e2, chain: edict_p;
  i, j, c, c2: integer;
label
  Continue_, Continue_J;
begin
  c := 0;
  c2 := 0;
  e:= @g_edicts^[1];
  for i := 1 to globals.num_edicts-1 do
  begin
    if not e^.inuse then
      goto Continue_;
    if e^.team = nil then
      goto Continue_;
    if (e^.flags and FL_TEAMSLAVE) <> 0 then
      goto Continue_;

    chain := e;
    e^.teammaster := e;
    inc(c);
    inc(c2);
    e2 := edict_p(Cardinal(e) + 1 * SizeOf(edict_t));
    for j:= i + 1 to globals.num_edicts-1 do
    begin
      if not e2^.inuse then
        goto Continue_J;
      if e2^.team = nil then
        goto Continue_J;
      if (e2^.flags and FL_TEAMSLAVE) <> 0 then
        goto Continue_J;

      if strcmp(e^.team, e2^.team) = 0 then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -