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

📄 g_weapon.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
//This is "COMMON" file for \GAME\g_weapon.pas & \CTF\g_weapon.pas
{$DEFINE CTF}
{ $IFDEF CTF}
{ $ELSE}
{ $ENDIF}


// PLEASE, don't modify this file
// 80% complete

{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): g_weapon.c                                                        }
{                                                                            }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru            }
{ Initial conversion on : 24-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 :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ 1) ???../g_local.inc                                                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{                                                                            }
{----------------------------------------------------------------------------}

unit g_weapon;

interface

//...

implementation

uses g_local, q_shared, game;


{*
=================
check_dodge

This is a support routine used when a client is firing
a non-instant attack weapon.  It checks to see if a
monster's dodge function should be called.
=================
*}
// (GAME=CTF)
//procedure static void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed);
procedure check_dodge (self : edict_p; start, dir : vec3_t; speed : integer);
var
  end_,
  v    : vec3_t;
  tr   : trace_t;
  eta  : float;

begin
  // easy mode only ducks one quarter the time
  if (skill.value = 0) then
    if (random > 0.25) then
      Exit;

  VectorMA (start, 8192, dir, end_);
(*Y  tr := gi.trace (start, Nil, NULL, end_, self, MASK_SHOT);
  if ( (tr.ent <> Nil) AND ((tr.ent.svflags AND SVF_MONSTER) <> 0) AND
       (tr.ent.health > 0) AND Assigned(tr.ent.monsterinfo.dodge) AND infront(tr.ent, self) ) then
*)  begin
    VectorSubtract (tr.endpos, start, v);
    eta := (VectorLength(v) - tr.ent.maxs[0]) / speed;
    tr.ent.monsterinfo.dodge (tr.ent, self, eta);
  end;
end;//procedure (GAME=CTF)


{*
=================
fire_hit

Used for all impact (hit/punch/slash) attacks
=================
*}
// (GAME=CTF)
//function fire_hit (edict_t *self, vec3_t aim, int damage, int kick) : qboolean;
function fire_hit (self : edict_t; aim : vec3_t; damage, kick : integer) : qboolean;
var
  tr        : trace_t;
  forward_,
  right, up,
  v,
  point,
  dir       : vec3_t;
  range     : float;
begin
  //see if enemy is in range
  VectorSubtract (self.enemy.s.origin, self.s.origin, dir);
  range := VectorLength(dir);
  if (range > aim[0]) then
  begin
    Result := false;
    Exit;
  end;

  if (aim[1] > self.mins[0]) AND (aim[1] < self.maxs[0])
  then begin
    // the hit is straight on so back the range up to the edge of their bbox
    range := range -self.enemy.maxs[0];
  end
  else begin
    // this is a side hit so adjust the "right" value out to the edge of their bbox
    if (aim[1] < 0)
    then aim[1] := self.enemy.mins[0]
    else aim[1] := self.enemy.maxs[0];
  end;

  VectorMA (self.s.origin, range, dir, point);

//Y  tr := gi.trace (self.s.origin, NULL, NULL, point, self, MASK_SHOT);
  if (tr.fraction < 1) then
  begin
//Y    if (!tr.ent.takedamage) then
    begin
      Result := false;
      Exit;
    end;
    // if it will hit any client/monster then hit the one we wanted to hit
//    if ((tr.ent.svflags & SVF_MONSTER) or (tr.ent.client)) then
    if ( ((tr.ent.svflags AND SVF_MONSTER) <> 0) OR (tr.ent.client <> Nil) ) then
      tr.ent := self.enemy;
  end;

  AngleVectors(self.s.angles, @forward_, @right, @up);
  VectorMA (self.s.origin, range, forward_, point);
  VectorMA (point, aim[1], right, point);
  VectorMA (point, aim[2], up, point);
  VectorSubtract (point, self.enemy.s.origin, dir);

  // do the damage
//Y  T_Damage (tr.ent, self, self, dir, point, vec3_origin, damage, kick/2, DAMAGE_NO_KNOCKBACK, MOD_HIT);

//  if (!(tr.ent.svflags & SVF_MONSTER) and (!tr.ent.client)) then
//Y  if ( ((tr.ent.svflags AND SVF_MONSTER) = 0) AND (!tr.ent.client) ) then
  begin
    Result := false;
    Exit;
  end;

  // do our special form of knockback here
  VectorMA (self.enemy.absmin, 0.5, self.enemy.size, v);
  VectorSubtract (v, point, v);
  VectorNormalize (v);
  VectorMA (self.enemy.velocity, kick, v, self.enemy.velocity);
  if (self.enemy.velocity[2] > 0) then
    self.enemy.groundentity := Nil;
  Result := true;
end;//function (GAME=CTF)

{*
=================
fire_lead

This is an internal support routine used for bullet/pellet based weapons.
=================
*}
// (GAME=CTF)
//procedure static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int te_impact, int hspread, int vspread, int mod);
procedure fire_lead (self : edict_p; start, aimdir : vec3_t; damage, kick, te_impact, hspread, vspread, mod_ : integer);
var
  tr           : trace_t;
  dir,
  forward_,
  right, up,
  end_,
  water_start,
  pos          : vec3_t;
  r, u         : float;
  water        : qboolean;
  color,
  content_mask : integer;
begin
{	qboolean	water = false;
	int			content_mask = MASK_SHOT | MASK_WATER;}
  water := false;
  content_mask := MASK_SHOT OR MASK_WATER;

(*Y  tr := gi.trace (self.s.origin, NULL, NULL, start, self, MASK_SHOT);
  if (!(tr.fraction < 1.0)) then*)
  begin
//Y      vectoangles (aimdir, dir);
      AngleVectors (dir, @forward_, @right, @up);

      r := crandom()*hspread;
      u := crandom()*vspread;
      VectorMA (start, 8192, forward_, end_);
      VectorMA (end_, r, right, end_);
      VectorMA (end_, u, up, end_);

//      if (gi.pointcontents (start) & MASK_WATER) then
//Y      if (gi.pointcontents (start) AND MASK_WATER) <> 0 then
      begin
        water := true;
        VectorCopy (start, water_start);
//        content_mask &= ~MASK_WATER;
        content_mask := content_mask AND (NOT MASK_WATER);
      end;

//Y      tr := gi.trace (start, NULL, NULL, end, self, content_mask);

      // see if we hit water
//      if (tr.contents & MASK_WATER) then
      if (tr.contents AND MASK_WATER) <> 0 then
      begin
        water := true;
        VectorCopy (tr.endpos, water_start);

//Y        if (!VectorCompare (start, tr.endpos)) then
        begin
//          if (tr.contents & CONTENTS_WATER)
          if (tr.contents AND CONTENTS_WATER) <> 0
          then begin
(*Y            if (strcmp(tr.surface.name, '*brwater') = 0)
            then color := SPLASH_BROWN_WATER
            else color := SPLASH_BLUE_WATER;*)
          end
          else
            if (tr.contents AND CONTENTS_SLIME) <> 0
            then color := SPLASH_SLIME
            else
              if (tr.contents AND CONTENTS_LAVA) <> 0
              then color := SPLASH_LAVA
              else color := SPLASH_UNKNOWN;

          if (color <> SPLASH_UNKNOWN) then
          begin
(*            gi.WriteByte (svc_temp_entity);
            gi.WriteByte (TE_SPLASH);
            gi.WriteByte (8);
            gi.WritePosition (tr.endpos);
            gi.WriteDir (tr.plane.normal);
            gi.WriteByte (color);
            gi.multicast (tr.endpos, MULTICAST_PVS);*)
          end;

          // change bullet's course when it enters water
          VectorSubtract (end_, start, dir);
//Y          vectoangles (dir, dir);
          AngleVectors (dir, @forward_, @right, @up);
          r := crandom()*hspread*2;
          u := crandom()*vspread*2;
          VectorMA (water_start, 8192, forward_, end_);
          VectorMA (end_, r, right, end_);
          VectorMA (end_, u, up, end_);
        end;//if

        // re-trace ignoring water this time
//Y        tr := gi.trace (water_start, NULL, NULL, end, self, MASK_SHOT);
      end;//if
  end;//if

  // send gun puff / flash
//  if (!((tr.surface) and (tr.surface.flags & SURF_SKY))) then
  if NOT ( (tr.surface<>Nil) AND ((tr.surface.flags AND SURF_SKY) <> 0) ) then
  begin
    if (tr.fraction < 1.0) then
(*Y      if (tr.ent.takedamage)
      then T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_BULLET, mod_)
      else
        if (strncmp (tr.surface.name, 'sky', 3) <> 0) then
        begin
          gi.WriteByte (svc_temp_entity);
          gi.WriteByte (te_impact);
          gi.WritePosition (tr.endpos);
          gi.WriteDir (tr.plane.normal);
          gi.multicast (tr.endpos, MULTICAST_PVS);

          if (self.client) then
            PlayerNoise (self, tr.endpos, PNOISE_IMPACT);
        end;*)
  end;//if

  // if went through water, determine where the end and make a bubble trail
  if (water) then
  begin
    VectorSubtract (tr.endpos, water_start, dir);
    VectorNormalize (dir);
    VectorMA (tr.endpos, -2, dir, pos);
//    if (gi.pointcontents (pos) & MASK_WATER)
(*Y    if ((gi.pointcontents (pos) AND MASK_WATER) <> 0)
    then VectorCopy (pos, tr.endpos)
    else tr := gi.trace (pos, NULL, NULL, water_start, tr.ent, MASK_WATER);*)

    VectorAdd (water_start, tr.endpos, pos);
    VectorScale (pos, 0.5, pos);

(*Y    gi.WriteByte (svc_temp_entity);
    gi.WriteByte (TE_BUBBLETRAIL);
    gi.WritePosition (water_start);
    gi.WritePosition (tr.endpos);
    gi.multicast (pos, MULTICAST_PVS);*)
  end;
end;//procedure (GAME=CTF)


{*
=================
fire_bullet

Fires a single round.  Used for machinegun and chaingun.  Would be fine for
pistols, rifles, etc....
=================
*}
// (GAME=CTF)
//procedure fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod);
procedure fire_bullet (self : edict_p; start, aimdir : vec3_t; damage, kick, hspread, vspread, mod_ : integer);
begin
//Y  fire_lead (self, start, aimdir, damage, kick, TE_GUNSHOT, hspread, vspread, mod_);
end;//procedure (GAME=CTF)


{*
=================
fire_shotgun

Shoots shotgun pellets.  Used by shotgun and super shotgun.
=================
*}
// (GAME=CTF)

⌨️ 快捷键说明

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