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