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

📄 g_weapon.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
Fires a single round.  Used for machinegun and chaingun.  Would be fine for
pistols, rifles, etc....
=================
*}
procedure fire_bullet (self : edict_p; var start, aimdir : vec3_t; damage, kick, hspread, vspread, mod_ : integer);
begin
  fire_lead(self, start, aimdir, damage, kick, byte(TE_GUNSHOT), hspread, vspread, mod_);
end;


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

Shoots shotgun pellets.  Used by shotgun and super shotgun.
=================
*}
procedure fire_shotgun (self : edict_p; var start, aimdir : vec3_t; damage, kick, hspread, vspread, count, mod_ : integer);
var
  i : integer;
begin
  for i:= 0 to (count - 1) do
    fire_lead (self, start, aimdir, damage, kick, byte(TE_SHOTGUN), hspread, vspread, mod_);
end;


{*
=================
fire_blaster

Fires a single blaster bolt.  Used by the blaster and hyper blaster.
=================
*}
procedure blaster_touch (self, other : edict_p; plane : cplane_p; surf : csurface_p); cdecl;
var
  mod_ : integer;
begin
  if (other = self^.owner) then
    Exit;

  if ((surf <> Nil) AND ((surf^.flags AND SURF_SKY) <> 0)) then
  begin
    G_FreeEdict(self);
    Exit;
  end;

  if (self^.owner^.client <> Nil) then
    PlayerNoise (self^.owner, self^.s.origin, PNOISE_IMPACT);

  if (other^.takedamage <> DAMAGE_NO) then 
  begin
    if ((self^.spawnflags AND 1) <> 0) then
      mod_ := MOD_HYPERBLASTER
    else
      mod_ := MOD_BLASTER;
    T_Damage (other, self, self^.owner, self^.velocity, self^.s.origin, plane^.normal, self^.dmg, 1, DAMAGE_ENERGY, mod_);
  end
  else
  begin
    gi.WriteByte (svc_temp_entity);
    gi.WriteByte (integer(TE_BLASTER)); 
    gi.WritePosition (self^.s.origin);
    if (plane = Nil) then
      gi.WriteDir (vec3_origin)
    else
      gi.WriteDir (plane^.normal);
    gi.multicast (@self^.s.origin, MULTICAST_PVS);
  end;

  G_FreeEdict (self);
end;

procedure fire_blaster (self : edict_p; var start, dir : vec3_t; damage, speed, effect : integer; hyper : qboolean);
var
  bolt : edict_p;
  tr : trace_t;
begin
  VectorNormalize (dir);

  bolt := G_Spawn();

  bolt^.svflags := SVF_DEADMONSTER;
  // yes, I know it looks weird that projectiles are deadmonsters
  // what this means is that when prediction is used against the object
  // (blaster/hyperblaster shots), the player won't be solid clipped against
  // the object.  Right now trying to run into a firing hyperblaster
  // is very jerky since you are predicted 'against' the shots.

  VectorCopy (start, bolt^.s.origin);
  VectorCopy (start, bolt^.s.old_origin);
  vectoangles (dir, bolt^.s.angles);
  VectorScale (dir, speed, bolt^.velocity);
  bolt^.movetype := MOVETYPE_FLYMISSILE;
  bolt^.clipmask := MASK_SHOT;
  bolt^.solid := SOLID_BBOX;
  bolt^.s.effects := bolt^.s.effects OR effect;
  VectorClear (bolt^.mins);
  VectorClear (bolt^.maxs);
  bolt^.s.modelindex := gi.modelindex ('models/objects/laser/tris.md2');
  bolt^.s.sound := gi.soundindex ('misc/lasfly.wav');
  bolt^.owner := self;
  bolt^.touch := blaster_touch;
  bolt^.nextthink := level.time + 2;
  bolt^.think := G_FreeEdict;
  bolt^.dmg := damage;
  bolt^.classname := 'bolt';
  if (hyper) then
    bolt^.spawnflags := 1;
  gi.linkentity (bolt);

  if (self^.client <> Nil) then
    check_dodge (self, bolt^.s.origin, dir, speed);

  tr := gi.trace (@self^.s.origin, Nil, Nil, @bolt^.s.origin, bolt, MASK_SHOT);
  if (tr.fraction < 1.0) then
  begin
    VectorMA (bolt^.s.origin, -10, dir, bolt^.s.origin);
    bolt^.touch (bolt, tr.ent, Nil, Nil);
  end;
end;


{*
=================
fire_grenade
=================
*}
procedure Grenade_Explode (ent : edict_p); cdecl;
var
  origin : vec3_t;
  mod_   : integer;
  points : Single;
  v,
  dir    : vec3_t;
begin
  if (ent^.owner^.client <> Nil) then
    PlayerNoise (ent^.owner, ent^.s.origin, PNOISE_IMPACT);

  { Original Code Comment Below: }
  //FIXME: if we are onground then raise our Z just a bit since we are a point?
  if (ent^.enemy <> Nil) then
  begin
    VectorAdd (ent^.enemy^.mins, ent^.enemy^.maxs, v);
    VectorMA (ent^.enemy^.s.origin, 0.5, v, v);
    VectorSubtract (ent^.s.origin, v, v);
    points := ent^.dmg - 0.5 * VectorLength (v);
    VectorSubtract (ent^.enemy^.s.origin, ent^.s.origin, dir);
    if ((ent^.spawnflags AND 1) <> 0) then
      mod_ := MOD_HANDGRENADE
    else
      mod_ := MOD_GRENADE;
    T_Damage (ent^.enemy, ent, ent^.owner, dir, ent^.s.origin, vec3_origin, trunc(points), trunc(points), DAMAGE_RADIUS, mod_);
  end;

  if ((ent^.spawnflags AND 2) <> 0) then
    mod_ := MOD_HELD_GRENADE
  else if ((ent.spawnflags AND 1) <> 0) then
    mod_ := MOD_HG_SPLASH
  else
    mod_ := MOD_G_SPLASH;
  T_RadiusDamage(ent, ent^.owner, ent^.dmg, ent^.enemy, ent^.dmg_radius, mod_);

  VectorMA (ent^.s.origin, -0.02, ent^.velocity, origin);
  gi.WriteByte (svc_temp_entity);
  if (ent^.waterlevel <> 0) then
  begin
    if (ent^.groundentity <> Nil) then
      gi.WriteByte (integer(TE_GRENADE_EXPLOSION_WATER))  
    else
      gi.WriteByte (integer(TE_ROCKET_EXPLOSION_WATER));  
  end
  else
  begin
    if (ent^.groundentity <> nil) then
      gi.WriteByte (integer(TE_GRENADE_EXPLOSION)) 
    else
      gi.WriteByte (integer(TE_ROCKET_EXPLOSION)); 
  end;
  gi.WritePosition (origin);
  gi.multicast (@ent^.s.origin, MULTICAST_PHS);

  G_FreeEdict (ent);
end;

procedure Grenade_Touch (ent, other : edict_p; plane : cplane_p; surf : csurface_p); cdecl;
begin
  if (other = ent^.owner) then
    Exit;

  if ((surf <> Nil) AND ((surf^.flags AND SURF_SKY) <> 0)) then
  begin
    G_FreeEdict (ent);
    Exit;
  end;

  if (other^.takedamage = DAMAGE_NO) then
  begin
    if ((ent^.spawnflags AND 1) <> 0) then
    begin
      if (_random() > 0.5) then
        gi.sound (ent, CHAN_VOICE, gi.soundindex ('weapons/hgrenb1a.wav'), 1, ATTN_NORM, 0)
      else
        gi.sound (ent, CHAN_VOICE, gi.soundindex ('weapons/hgrenb2a.wav'), 1, ATTN_NORM, 0)
    end else
      gi.sound (ent, CHAN_VOICE, gi.soundindex ('weapons/grenlb1b.wav'), 1, ATTN_NORM, 0);

    Exit;
  end;

  ent^.enemy := other;
  Grenade_Explode (ent);
end;

procedure fire_grenade (self : edict_p; const start, aimdir : vec3_t; damage, speed : integer; timer, damage_radius : Single);
var
  grenade : edict_p;
  dir,
  forward_, right, up : vec3_t;
begin
  vectoangles (aimdir, dir);
  AngleVectors (dir, @forward_, @right, @up);

  grenade := G_Spawn();
  VectorCopy (start, grenade^.s.origin);
  VectorScale (aimdir, speed, grenade^.velocity);
  VectorMA (grenade^.velocity, 200 + crandom() * 10.0, up, grenade^.velocity);
  VectorMA (grenade^.velocity, crandom() * 10.0, right, grenade^.velocity);
  VectorSet (grenade^.avelocity, 300, 300, 300);
  grenade^.movetype := MOVETYPE_BOUNCE;
  grenade^.clipmask := MASK_SHOT;
  grenade^.solid := SOLID_BBOX;
  grenade^.s.effects := grenade^.s.effects OR EF_GRENADE;
  VectorClear (grenade^.mins);
  VectorClear (grenade^.maxs);
  grenade^.s.modelindex := gi.modelindex ('models/objects/grenade/tris.md2');
  grenade^.owner := self;
  grenade^.touch := Grenade_Touch;
  grenade^.nextthink := level.time + timer;
  grenade^.think := Grenade_Explode;
  grenade^.dmg := damage;
  grenade^.dmg_radius := damage_radius;
  grenade^.classname := 'grenade';

  gi.linkentity (grenade);
end;

procedure fire_grenade2 (self : edict_p; const start, aimdir : vec3_t; damage, speed : integer; timer, damage_radius : Single; held : qboolean);
var
  grenade : edict_p;
  dir,
  forward_, right, up : vec3_t;
begin
  vectoangles (aimdir, dir);
  AngleVectors (dir, @forward_, @right, @up);

  grenade := G_Spawn();
  VectorCopy (start, grenade^.s.origin);
  VectorScale (aimdir, speed, grenade^.velocity);
  VectorMA (grenade^.velocity, 200 + crandom() * 10.0, up, grenade^.velocity);
  VectorMA (grenade^.velocity, crandom() * 10.0, right, grenade^.velocity);
  VectorSet (grenade^.avelocity, 300, 300, 300);
  grenade^.movetype := MOVETYPE_BOUNCE;
  grenade^.clipmask := MASK_SHOT;
  grenade^.solid := SOLID_BBOX;
  grenade^.s.effects := grenade^.s.effects OR EF_GRENADE;
  VectorClear (grenade^.mins);
  VectorClear (grenade^.maxs);
  grenade^.s.modelindex := gi.modelindex ('models/objects/grenade2/tris.md2');
  grenade^.owner := self;
  grenade^.touch := Grenade_Touch;
  grenade^.nextthink := level.time + timer;
  grenade^.think := Grenade_Explode;
  grenade^.dmg := damage;
  grenade^.dmg_radius := damage_radius;
  grenade^.classname := 'hgrenade';
  if (held) then
    grenade^.spawnflags := 3
  else
    grenade^.spawnflags := 1;
  grenade^.s.sound := gi.soundindex('weapons/hgrenc1b.wav');

  if (timer <= 0.0) then
    Grenade_Explode (grenade)
  else
  begin
    gi.sound (self, CHAN_WEAPON, gi.soundindex ('weapons/hgrent1a.wav'), 1, ATTN_NORM, 0);
    gi.linkentity (grenade);
  end;
end;

{*
=================
fire_rocket
=================
*}
procedure rocket_touch (ent, other : edict_p; plane : cplane_p; surf : csurface_p); cdecl;
var
  origin : vec3_t;
  n      : integer;
begin
  if (other = ent^.owner) then
    Exit;

  if ((surf <> Nil) AND ((surf^.flags AND SURF_SKY) <> 0)) then
  begin
    G_FreeEdict (ent);
    Exit;
  end;

  if (ent^.owner^.client <> Nil) then
    PlayerNoise (ent^.owner, ent^.s.origin, PNOISE_IMPACT);

  { Original Code Comment Below: }
  // calculate position for the explosion entity
  VectorMA (ent^.s.origin, -0.02, ent^.velocity, origin);

  if (other^.takedamage <> DAMAGE_NO) then  
    T_Damage (other, ent, ent^.owner, ent^.velocity, ent^.s.origin, plane^.normal, ent^.dmg, 0, 0, MOD_ROCKET)
  else
  begin
    { Original Code Comment Below: }
    // don't throw any debris in net games
    if (deathmatch^.value = 0) AND (coop^.value = 0) then
    begin
      if ((surf <> Nil) AND (surf^.flags AND (SURF_WARP OR SURF_TRANS33 OR SURF_TRANS66 OR SURF_FLOWING) = 0)) then
      begin
        n := rand() mod 5;

        while (n <> 0) do
          try
            ThrowDebris (ent, 'models/objects/debris2/tris.md2', 2, ent^.s.origin);
          finally
            Dec(n);
          end;

⌨️ 快捷键说明

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