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

📄 g_monster.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//100%
{$ALIGN ON}{$MINENUMSIZE 4}
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): game\g_monster.c                                                  }
{                                                                            }
{ Initial conversion by : Clairebear ()                                      }
{ Initial conversion on : 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 : 12-July-2002                                                  }
{ Updated by : Scott Price (scott.price@totalise.co.uk)                      }
{ Updated on : 25-Sep-2002                                                   }
{ Updated by : Fabrizio Rossini                                              }
{ Updated on : 14-May-2003                                                   }
{ Updated by : Scott Price (scott.price@totalise.co.uk)                      }
{                                                                            }
{----------------------------------------------------------------------------}
{ Original Conversion Header Comments:                                       }
{ Comments                                                                   }
{ All original comments retained                                             }
{                                                                            }
{ procedure M_FliesOn (self pedict_t);                                       }
{ There's a string with a forward slash in it. Looks like a file name but    }
{ I havent changed the / to a \.                                             }
{ Removed "Static" declarations for some of the functions but left the       }
{ commented out original header for these in case it makes a difference      }
{                                                                            }
{ LOGIC PRECEDENCE WORRIES                                                   }
{ m_dropToFloor function                                                     }
{ if (trace.fraction == 1 || trace.allsolid)                                 }
{ procedure M_MoveFrame (self : pedict_t);                                   }
{ if (self->s.frame < move->firstframe || self->s.frame > move->lastframe)   }
{ NOTES:                                                                     }
{ ======                                                                     }
{ - function/procedures had been organised nicely in alphabetical.  This is  }
{   a bit of a pain when trying to compare to the original and debug the     }
{   code. Have re-arranged in the order of the .c source file.  Once         }
{   debugged it can be rearranged again in a nice alphabetical order.        }
{ - Have continued the conversion to completion.                             }
{ - Some routine declarations in the Interface have been left-out at present.}
{   Determine which are Static implementations and which are visible.        }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{----------------------------------------------------------------------------}
unit g_monster;


interface


uses
  q_shared,
  q_shared_add,
  g_local,
  g_local_add;


procedure monster_fire_bullet(self: edict_p; var start, dir: vec3_t; damage, kick,
  hspread, vspread, flashtype: Integer);
procedure monster_fire_shotgun(self: edict_p; var start, aimdir: vec3_t; damage,
  kick, hspread, vspread, count, flashtype: Integer);
procedure monster_fire_blaster(self: edict_p; var start, dir: vec3_t; damage, speed,
  flashtype, effect: Integer);
procedure monster_fire_grenade(self: edict_p; const start, aimdir: vec3_t; damage,
  speed, flashtype: Integer);
procedure monster_fire_rocket(self: edict_p; const start, dir: vec3_t; damage,
  speed, flashtype: Integer);
procedure monster_fire_railgun(self: edict_p; var start, aimdir: vec3_t; damage,
  kick, flashtype: Integer);
procedure monster_fire_bfg(self: edict_p; const start, aimdir: vec3_t; damage, speed,
  kick: Integer; damage_radius: single; flashtype: Integer);

procedure M_FlyCheck(self: edict_p);
procedure AttackFinished(self: edict_p; time: single);
procedure M_CheckGround(ent: edict_p);
procedure M_CatagorizePosition(ent: edict_p);
procedure M_WorldEffects(ent: edict_p);
procedure M_droptofloor(ent: edict_p); cdecl;
procedure M_SetEffects(ent: edict_p);
procedure M_MoveFrame(self: edict_p);

procedure monster_think(self: edict_p); cdecl;
procedure monster_use(self, other, activator: edict_p); cdecl;
procedure monster_triggered_spawn(self: edict_p); cdecl;
procedure monster_triggered_spawn_use(self, other, activator: edict_p); cdecl;
procedure monster_triggered_start(self: edict_p); cdecl;

procedure monster_death_use(self: edict_p);

function monster_start(self: edict_p): qboolean; { ???:  This is declared with no body?  Strange }

procedure monster_start_go(self: edict_p); cdecl;
procedure walkmonster_start_go(self: edict_p); cdecl;
procedure walkmonster_start(self: edict_p);
procedure flymonster_start_go(self: edict_p); cdecl;
procedure flymonster_start(self: edict_p);
procedure swimmonster_start_go(self: edict_p); cdecl;
procedure swimmonster_start(self: edict_p);

implementation

uses
  g_weapon,
  gameunit,
  game_add,
  g_main,
  g_combat,
  g_ai,
  g_utils,
  g_save,
  Cpas,
  m_move,
  g_items;

//
// monster weapons
//

//FIXME mosnters should call these with a totally accurate direction
// and we can mess it up based on skill.  Spread should be for normal
// and we can tighten or loosen based on skill.  We could muck with
// the damages too, but I'm not sure that's such a good idea.
procedure monster_fire_bullet(self: edict_p; var start, dir: vec3_t; damage, kick,
  hspread, vspread, flashtype: Integer);
begin
  fire_bullet(self, start, dir, damage, kick, hspread, vspread, MOD_UNKNOWN);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;

procedure monster_fire_shotgun(self: edict_p; var start, aimdir: vec3_t; damage,
  kick, hspread, vspread, count, flashtype: Integer);
begin
  fire_shotgun(self, start, aimdir, damage, kick, hspread, vspread, count, MOD_UNKNOWN);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;

procedure monster_fire_blaster(self: edict_p; var start, dir: vec3_t; damage, speed,
  flashtype, effect: Integer);
begin
  fire_blaster(self, start, dir, damage, speed, effect, false);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;

procedure monster_fire_grenade(self: edict_p; const start, aimdir: vec3_t; damage,
  speed, flashtype: Integer);
begin
  fire_grenade(self, start, aimdir, damage, speed, 2.5, damage+40);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;

procedure monster_fire_rocket(self: edict_p; const start, dir: vec3_t; damage,
  speed, flashtype: Integer);
begin
  fire_rocket(self, start, dir, damage, speed, damage+20, damage);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;

procedure monster_fire_railgun(self: edict_p; var start, aimdir: vec3_t; damage,
  kick, flashtype: Integer);
begin
  fire_rail(self, start, aimdir, damage, kick);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;

procedure monster_fire_bfg(self: edict_p; const start, aimdir: vec3_t; damage, speed,
  kick: Integer; damage_radius: single; flashtype: Integer);
begin
  fire_bfg(self, start, aimdir, damage, speed, damage_radius);

  gi.WriteByte(svc_muzzleflash2);
  gi.WriteShort((Cardinal(self) - Cardinal(g_edicts)) div sizeof(edict_t));
  gi.WriteByte(flashtype);
  gi.multicast(@start, MULTICAST_PVS);
end;


//
// Monster utility functions
//
procedure M_FliesOff(self: edict_p); cdecl;
begin
  self^.s.effects := self^.s.effects and (not EF_FLIES);
  self^.s.sound := 0;
end;

procedure M_FliesOn(self: edict_p); cdecl;
begin
  if (self^.waterlevel <> 0) then
    Exit;
  self^.s.effects := self^.s.effects or EF_FLIES;
  self^.s.sound := gi.soundindex('infantry/inflies1.wav');
  self^.think := M_FliesOff;
  self^.nextthink := level.time + 60;
end;


procedure M_FlyCheck(self: edict_p);
begin
  if (self^.waterlevel <> 0) then
    Exit;

  if _random() > 0.5 then
    Exit;

  self^.think := M_FliesOn;
  self^.nextthink := level.time + 5 + 10 * _random();
end;

procedure AttackFinished(self: edict_p; time: single);
begin
  self^.monsterinfo.attack_finished := level.time + time;
end;

procedure M_CheckGround (ent : edict_p);
var
  point: vec3_t;
  trace: trace_t;
begin
  if (ent^.flags and (FL_SWIM or FL_FLY)) <> 0 then
    Exit;

  if (ent^.velocity[2] > 100) then
  begin
    Ent^.groundentity := Nil;
    Exit;
  end;

  // if the hull point one-quarter unit down is solid the entity is on ground
  point[0] := ent^.s.origin[0];
  point[1] := ent^.s.origin[1];
  point[2] := ent^.s.origin[2] - 0.25;

  trace := gi.trace(@ent^.s.origin, @ent^.mins, @ent^.maxs, @point, ent, MASK_MONSTERSOLID);

  // check steepness
  if (trace.plane.normal[2] < 0.7) and (not trace.startsolid) then
  begin
    ent^.groundentity := Nil;
    Exit;
  end;

  //	ent->groundentity = trace.ent;
  //	ent->groundentity_linkcount = trace.ent->linkcount;
  //	if (!trace.startsolid && !trace.allsolid)
  //		VectorCopy (trace.endpos, ent->s.origin);

  if (not trace.startsolid) and (not trace.allsolid) then
  begin
    VectorCopy(trace.endpos, ent^.s.origin);
    ent^.groundentity := trace.ent;
    ent^.groundentity_linkcount := edict_p(trace.ent)^.linkcount;
    ent^.velocity[2] := 0;
  end;
end;

procedure M_CatagorizePosition (ent : edict_p);
var
  point: vec3_t;
  cont: integer;
begin
  //
  // get waterlevel
  //
  point[0] := ent^.s.origin[0];
  point[1] := ent^.s.origin[1];
  point[2] := ent^.s.origin[2] + ent^.mins[2] + 1;
  cont := gi.pointcontents(point);

  if ((cont and MASK_WATER) = 0) then
  begin
    ent^.waterlevel := 0;
    ent^.watertype := 0;
    Exit;
  end;

  ent^.watertype := cont;
  ent^.waterlevel := 1;
  point[2] := point[2] + 26;
  cont := gi.pointcontents(point);
  if ((cont and MASK_WATER) = 0) then
    Exit;

  ent^.waterlevel := 2;
  point[2] := point[2] + 22;
  cont := gi.pointcontents(point);
  if (Cont and MASK_WATER) <> 0 then
    ent^.waterlevel := 3;
end;

procedure M_WorldEffects (ent : edict_p);
var
  dmg: integer;
begin
  if (ent^.health > 0) then
  begin
    if (ent^.flags and FL_SWIM) = 0 then
    begin
      if (ent^.waterlevel < 3) then
      begin
        ent^.air_finished := level.time + 12
      end
      else if (ent^.air_finished < level.time) then
      begin// drown!
        if (ent^.pain_debounce_time < level.time) then
        begin
          dmg := 2 + 2 * floor(level.time - ent^.air_finished);
          if (dmg > 15) then
            dmg := 15;
          T_Damage(ent, world, world, vec3_origin, ent^.s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
          ent^.pain_debounce_time := level.time + 1;
        end;
      end;
    end
    else
    begin
      if (ent^.waterlevel > 0) then
      begin
        ent^.air_finished := level.time + 9;
      end
      else if (ent^.air_finished < level.time) then
      begin	// suffocate!
        if (ent^.pain_debounce_time < level.time) then
        begin
          dmg := 2 + 2 * floor(level.time - ent^.air_finished);
          if (dmg > 15) then
            dmg := 15;
          T_Damage(ent, world, world, vec3_origin, ent^.s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
          ent^.pain_debounce_time := level.time + 1;
        end;
      end;
    end;
  end;

  if (ent^.waterlevel = 0) then
  begin
    if (ent^.flags and FL_INWATER) <> 0 then
    begin
      gi.sound(ent, CHAN_BODY, gi.soundindex('player/watr_out.wav'), 1, ATTN_NORM, 0);
      ent^.flags := ent^.flags AND (NOT FL_INWATER);
    end;

    Exit;
  end;

  if ((ent^.watertype and CONTENTS_LAVA) <> 0) and ((ent^.flags and FL_IMMUNE_LAVA) = 0) then
  begin
    if (ent^.damage_debounce_time < level.time) then
    begin
      ent^.damage_debounce_time := level.time + 0.2;
      T_Damage(ent, world, world, vec3_origin, ent^.s.origin, vec3_origin, 10 * ent^.waterlevel, 0, 0, MOD_LAVA);
    end;
  end;
  if ((ent^.watertype and CONTENTS_SLIME) <> 0) and ((ent^.flags and FL_IMMUNE_SLIME) = 0) then
  begin
    if (ent^.damage_debounce_time < level.time) then
    begin
      ent^.damage_debounce_time := level.time + 1;
      T_Damage(ent, world, world, vec3_origin, ent^.s.origin, vec3_origin, 4 * ent^.waterlevel, 0, 0, MOD_SLIME);
    end;
  end;

  if (ent^.flags and FL_INWATER) = 0 then
  begin
    if (ent^.svflags and SVF_DEADMONSTER) = 0 then
    begin
      if ((ent^.watertype and CONTENTS_LAVA) <> 0) then
      begin
        if (_random() <= 0.5) then
          gi.sound(ent, CHAN_BODY, gi.soundindex('player/lava1.wav'), 1, ATTN_NORM, 0)
        else
          gi.sound(ent, CHAN_BODY, gi.soundindex('player/lava2.wav'), 1, ATTN_NORM, 0);
      end
      else if (ent^.watertype and CONTENTS_SLIME) <> 0 then
        gi.sound(ent, CHAN_BODY, gi.soundindex('player/watr_in.wav'), 1, ATTN_NORM, 0)
      else if (ent^.watertype and CONTENTS_WATER) <> 0 then
        gi.sound(ent, CHAN_BODY, gi.soundindex('player/watr_in.wav'), 1, ATTN_NORM, 0);
    end;

    ent^.flags := ent^.flags or FL_INWATER;
    ent^.damage_debounce_time := 0;
  end;
end;

procedure M_droptofloor(ent: edict_p);
var
  end_: vec3_t;
  trace: trace_t;
begin

⌨️ 快捷键说明

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