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

📄 g_weapon.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
      end;
    end;
  end;

  T_RadiusDamage (ent, ent^.owner, ent^.radius_dmg, other, ent^.dmg_radius, MOD_R_SPLASH);

  gi.WriteByte (svc_temp_entity);
  if (ent^.waterlevel <> 0) then
    gi.WriteByte (integer(TE_ROCKET_EXPLOSION_WATER)) 
  else
    gi.WriteByte (integer(TE_ROCKET_EXPLOSION));  
  gi.WritePosition (origin);
  gi.multicast (@ent^.s.origin, MULTICAST_PHS);

  G_FreeEdict (ent);
end;

procedure fire_rocket (self : edict_p; const start, dir : vec3_t; damage, speed : integer; damage_radius : Single; radius_damage: Integer);
var
  rocket : edict_p;
begin
  rocket := G_Spawn();
  VectorCopy (start, rocket^.s.origin);
  VectorCopy (dir, rocket^.movedir);
  vectoangles (dir, rocket^.s.angles);
  VectorScale (dir, speed, rocket^.velocity);
  rocket^.movetype := MOVETYPE_FLYMISSILE;
  rocket^.clipmask := MASK_SHOT;
  rocket^.solid := SOLID_BBOX;
  rocket^.s.effects := rocket^.s.effects OR EF_ROCKET;
  VectorClear (rocket^.mins);
  VectorClear (rocket^.maxs);
  rocket^.s.modelindex := gi.modelindex ('models/objects/rocket/tris.md2');
  rocket^.owner := self;
  rocket^.touch := rocket_touch;
  rocket^.nextthink := level.time + 8000/speed;
  rocket^.think := G_FreeEdict;
  rocket^.dmg := damage;
  rocket^.radius_dmg := radius_damage;
  rocket^.dmg_radius := damage_radius;
  rocket^.s.sound := gi.soundindex ('weapons/rockfly.wav');
  rocket^.classname := 'rocket';

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

  gi.linkentity (rocket);
end;

{*
=================
fire_rail
=================
*}
procedure fire_rail (self : edict_p; var start, aimdir : vec3_t; damage, kick : integer);
var
  from,
  end_   : vec3_t;
  tr     : trace_t;
  ignore : edict_p;
  mask   : integer;
  water  : qboolean;
begin
  VectorMA (start, 8192, aimdir, end_);
  VectorCopy (start, from);
  ignore := self;
  water := false;
  mask := MASK_SHOT or CONTENTS_SLIME OR CONTENTS_LAVA;
  while (ignore <> Nil) do
  begin
    tr := gi.trace (@from, Nil, Nil, @end_, ignore, mask);

    if ( (tr.contents AND (CONTENTS_SLIME OR CONTENTS_LAVA)) <> 0 ) then
    begin
      mask := mask AND (NOT (CONTENTS_SLIME OR CONTENTS_LAVA));
      water := true;
    end
    else
    begin
      { Original Code Comment Below: }
      //ZOID--added so rail goes through SOLID_BBOX entities (gibs, etc)
      if ( ((edict_p(tr.ent)^.svflags AND SVF_MONSTER) <> 0) OR (edict_p(tr.ent)^.client <> Nil) OR (edict_p(tr.ent)^.solid = SOLID_BBOX)) then
        ignore := tr.ent
      else
        ignore := Nil;

      if ((tr.ent <> self) AND (edict_p(tr.ent)^.takedamage <> DAMAGE_NO)) then   
        T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_RAILGUN);
    end;

    VectorCopy (tr.endpos, from);
  end;

  { Original Code Comment Below: }
  // send gun puff / flash
  gi.WriteByte (svc_temp_entity);
  gi.WriteByte (integer(TE_RAILTRAIL));  
  gi.WritePosition (start);
  gi.WritePosition (tr.endpos);
  gi.multicast (@self^.s.origin, MULTICAST_PHS);
{ Original Code Comment Below: }
//  gi.multicast (start, MULTICAST_PHS);
  if (water) then
  begin
    gi.WriteByte (svc_temp_entity);
    gi.WriteByte (integer(TE_RAILTRAIL));  
    gi.WritePosition (start);
    gi.WritePosition (tr.endpos);
    gi.multicast (@tr.endpos, MULTICAST_PHS);
  end;

  if (self.client <> Nil) then
    PlayerNoise (self, tr.endpos, PNOISE_IMPACT);
end;

{*
=================
fire_bfg
=================
*}

procedure bfg_explode (self : edict_p); cdecl;
var
  ent    : edict_p;
  v      : vec3_t;
  points,
  dist   : Single;
label __Continue;
begin
  if (self^.s.frame = 0) then
  begin
    { Original Code Comment Below: }
    // the BFG effect
    ent := Nil; 
    ent := findradius(ent, self^.s.origin, self^.dmg_radius);
    while (ent <> Nil) do
    begin
      if (ent^.takedamage = DAMAGE_NO) then
        goto __Continue;
      if (ent = self^.owner) then
        goto __Continue;
      if (NOT CanDamage(ent, self)) then
        goto __Continue;
      if (NOT CanDamage(ent, self^.owner)) then
        goto __Continue;

      VectorAdd (ent^.mins, ent^.maxs, v);
      VectorMA (ent^.s.origin, 0.5, v, v);
      VectorSubtract (self^.s.origin, v, v);
      dist := VectorLength(v);
      points := self^.radius_dmg * (1.0 - sqrt(dist/self^.dmg_radius));
      if (ent = self^.owner) then
        points := points * 0.5;

      gi.WriteByte (svc_temp_entity);
      gi.WriteByte (integer(TE_BFG_EXPLOSION));
      gi.WritePosition (ent^.s.origin);
      gi.multicast (@ent^.s.origin, MULTICAST_PHS);
      T_Damage (ent, self, self^.owner, self^.velocity, ent^.s.origin, vec3_origin, trunc(points), 0, DAMAGE_ENERGY, MOD_BFG_EFFECT);

    __Continue:
      ent := findradius(ent, self^.s.origin, self^.dmg_radius);
    end;
  end;

  self^.nextthink := level.time + FRAMETIME;
  Inc(self^.s.frame);
  if (self^.s.frame = 5) then
    self^.think := G_FreeEdict;
end;

procedure bfg_touch (self, other : edict_p; plane : cplane_p; surf : csurface_p); cdecl;
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);


  // core explosion - prevents firing it into the wall/floor

  if (other^.takedamage <> DAMAGE_NO) then 
    T_Damage (other, self, self^.owner, self^.velocity, self^.s.origin, plane^.normal, 200, 0, 0, MOD_BFG_BLAST);
  T_RadiusDamage(self, self^.owner, 200, other, 100, MOD_BFG_BLAST);

  gi.sound (self, CHAN_VOICE, gi.soundindex ('weapons/bfg__x1b.wav'), 1, ATTN_NORM, 0);
  self^.solid := SOLID_NOT;
  self^.touch := Nil;
  VectorMA (self^.s.origin, -1 * FRAMETIME, self^.velocity, self^.s.origin);
  VectorClear (self^.velocity);
  self^.s.modelindex := gi.modelindex ('sprites/s_bfg3.sp2');
  self^.s.frame := 0;
  self^.s.sound := 0;
  self^.s.effects := self^.s.effects AND (NOT EF_ANIM_ALLFAST);
  self^.think := bfg_explode;
  self^.nextthink := level.time + FRAMETIME;
  self^.enemy := other;

  gi.WriteByte (svc_temp_entity);
  gi.WriteByte (integer(TE_BFG_BIGEXPLOSION)); 
  gi.WritePosition (self^.s.origin);
  gi.multicast (@self^.s.origin, MULTICAST_PVS);
end;

procedure bfg_think (self : edict_p); cdecl;
var
  ent,
  ignore : edict_p;
  point,
  dir,
  start,
  end_   : vec3_t;
  dmg    : integer;
  tr     : trace_t;
label __Continue;
begin
  if (deathmatch^.value <> 0) then
    dmg := 5
  else
    dmg := 10;

  ent := nil;
  ent := findradius(ent, self^.s.origin, 256);
  while (ent <> Nil) do
  begin
    if (ent = self) then
      goto __Continue;

    if (ent = self^.owner) then
      goto __Continue;

    if (ent^.takedamage = DAMAGE_NO) then
      goto __Continue;

    if ( ((ent^.svflags AND SVF_MONSTER) = 0) AND
         (ent^.client = Nil) AND
         (strcmp(ent^.classname, 'misc_explobox') <> 0) ) then
      goto __Continue;

    VectorMA (ent^.absmin, 0.5, ent^.size, point);

    VectorSubtract (point, self^.s.origin, dir);
    VectorNormalize (dir);

    ignore := self;
    VectorCopy (self^.s.origin, start);
    VectorMA (start, 2048, dir, end_);
    while True do
    begin
      tr := gi.trace (@start, Nil, Nil, @end_, ignore, CONTENTS_SOLID or CONTENTS_MONSTER or CONTENTS_DEADMONSTER);

      if (tr.ent = Nil) then
        Break;

      // hurt it if we can
      if ( (edict_p(tr.ent)^.takedamage <> DAMAGE_NO) AND
           ((edict_p(tr.ent)^.flags AND FL_IMMUNE_LASER) = 0) AND
           (tr.ent <> self^.owner) ) then
        T_Damage (tr.ent, self, self^.owner, dir, tr.endpos, vec3_origin, dmg, 1, DAMAGE_ENERGY, MOD_BFG_LASER);

      // if we hit something that's not a monster or player we're done
      if ( ((edict_p(tr.ent)^.svflags AND SVF_MONSTER) = 0) AND (edict_p(tr.ent)^.client = Nil) ) then
      begin
        gi.WriteByte (svc_temp_entity);
        gi.WriteByte (integer(TE_LASER_SPARKS));
        gi.WriteByte (4);
        gi.WritePosition (tr.endpos);
        gi.WriteDir (tr.plane.normal);
        gi.WriteByte (self^.s.skinnum);
        gi.multicast (@tr.endpos, MULTICAST_PVS);
        Break;
      end;

      ignore := tr.ent;
      VectorCopy (tr.endpos, start);
    end;
    gi.WriteByte (svc_temp_entity);
    gi.WriteByte (integer(TE_BFG_LASER));
    gi.WritePosition (self^.s.origin);
    gi.WritePosition (tr.endpos);
    gi.multicast (@self^.s.origin, MULTICAST_PHS);
    
  __Continue:
    ent := findradius(ent, self^.s.origin, 256);
  end;

  self^.nextthink := level.time + FRAMETIME;
end;

procedure fire_bfg (self : edict_p; const start, dir : vec3_t; damage, speed : integer; damage_radius : Single);
var
  bfg : edict_p;
begin
  bfg := G_Spawn();
  VectorCopy (start, bfg^.s.origin);
  VectorCopy (dir, bfg^.movedir);
  vectoangles (dir, bfg^.s.angles);
  VectorScale (dir, speed, bfg^.velocity);
  bfg^.movetype := MOVETYPE_FLYMISSILE;
  bfg^.clipmask := MASK_SHOT;
  bfg^.solid := SOLID_BBOX;
  bfg^.s.effects := bfg^.s.effects OR EF_BFG OR EF_ANIM_ALLFAST;
  VectorClear (bfg^.mins);
  VectorClear (bfg^.maxs);
  bfg^.s.modelindex := gi.modelindex ('sprites/s_bfg1.sp2');
  bfg^.owner := self;
  bfg^.touch := bfg_touch;
  bfg^.nextthink := level.time + 8000/speed;
  bfg^.think := G_FreeEdict;
  bfg^.radius_dmg := damage;
  bfg^.dmg_radius := damage_radius;
  bfg^.classname := 'bfg blast';
  bfg^.s.sound := gi.soundindex ('weapons/bfg__l1a.wav');

  bfg^.think := bfg_think;
  bfg^.nextthink := level.time + FRAMETIME;
  bfg^.teammaster := bfg;
  bfg^.teamchain := Nil;

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

  gi.linkentity (bfg);
end;

end.

⌨️ 快捷键说明

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