📄 g_weapon.pas
字号:
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 + -