📄 g_weapon.pas
字号:
var
edict_t *bolt;
tr : trace_t;
begin
VectorNormalize (dir);
bolt := G_Spawn();
//only CFT
{$IFDEF CTF}
bolt.svflags := SVF_PROJECTILE; // special net code is used for projectiles
{$ELSE}
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.
{$ENDIF}
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) then
check_dodge (self, bolt.s.origin, dir, speed);
tr := gi.trace (self.s.origin, NULL, NULL, 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, NULL, NULL);
end;
end;//procedure (GAME <> CTF)
{*
=================
fire_grenade
=================
*}
// (GAME=CTF)
procedure static void Grenade_Explode (edict_t *ent);
var
origin : vec3_t;
mod_ : integer;
points : float;
v,
dir : vec3_t;
begin
if (ent.owner.client) then
PlayerNoise(ent.owner, ent.s.origin, PNOISE_IMPACT);
//FIXME: if we are onground then raise our Z just a bit since we are a point?
if (ent.enemy) 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 & 1)
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, (int)points, (int)points, DAMAGE_RADIUS, mod_);
end;
// if (ent.spawnflags & 2)
if ((ent.spawnflags AND 2) <> 0)
then mod_ := MOD_HELD_GRENADE
else
// if (ent.spawnflags & 1)
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)
then
if (ent.groundentity)
then gi.WriteByte (TE_GRENADE_EXPLOSION_WATER)
else gi.WriteByte (TE_ROCKET_EXPLOSION_WATER);
end
else
if (ent.groundentity)
then gi.WriteByte (TE_GRENADE_EXPLOSION)
else gi.WriteByte (TE_ROCKET_EXPLOSION);
end;
gi.WritePosition (origin);
gi.multicast (ent.s.origin, MULTICAST_PHS);
G_FreeEdict (ent);
end;//procedure (GAME=CTF)
// (GAME=CTF)
procedure static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
begin
if (other = ent.owner) then
Exit;
// if (surf && (surf.flags & SURF_SKY)) then
if (surf AND ((surf.flags AND SURF_SKY) <>0)) then
begin
G_FreeEdict (ent);
Exit;
end;
if (!other.takedamage) then
begin
// if (ent.spawnflags & 1)
if ((ent.spawnflags AND 1) <> 0)
then
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);
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 (GAME=CTF)
// (GAME=CTF)
procedure fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius);
var
edict_t *grenade;
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 (GAME=CTF)
// (GAME=CTF)
procedure fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean held);
var
edict_t *grenade;
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;//procedure (GAME=CTF)
{*
=================
fire_rocket
=================
*}
// (GAME=CTF)
procedure rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
var
origin : vec3_t;
n : integer;
begin
if (other = ent.owner) then
Exit;
// if (surf && (surf.flags & SURF_SKY)) then
if (surf AND ((surf.flags AND SURF_SKY) <> 0)) then
begin
G_FreeEdict (ent);
Exit;
end;
if (ent.owner.client) then
PlayerNoise(ent.owner, ent.s.origin, PNOISE_IMPACT);
// calculate position for the explosion entity
VectorMA (ent.s.origin, -0.02, ent.velocity, origin);
if (other.takedamage)
then T_Damage (other, ent, ent.owner, ent.velocity, ent.s.origin, plane.normal, ent.dmg, 0, 0, MOD_ROCKET)
else begin
// don't throw any debris in net games
if (!deathmatch.value AND !coop.value) then
// if ((surf) && !(surf.flags & (SURF_WARP|SURF_TRANS33|SURF_TRANS66|SURF_FLOWING))) then
if ( (surf) AND
(surf.flags AND (SURF_WARP OR SURF_TRANS33 OR SURF_TRANS66 OR SURF_FLOWING) = 0) ) then
begin
n := random(5);
// while(n--)
while n<>0 do
begin
ThrowDebris (ent, 'models/objects/debris2/tris.md2', 2, ent.s.origin);
Dec(n);
end;//while
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)
then gi.WriteByte (TE_ROCKET_EXPLOSION_WATER)
else gi.WriteByte (TE_ROCKET_EXPLOSION);
gi.WritePosition (origin);
gi.multicast (ent.s.origin, MULTICAST_PHS);
G_FreeEdict (ent);
end;//procedure (GAME=CTF)
// (GAME=CTF)
procedure fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
var
edict_t *rocket;
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) then
check_dodge (self, rocket.s.origin, dir, speed);
gi.linkentity (rocket);
end;//procedure (GAME=CTF)
{*
=================
fire_rail
=================
*}
// (GAME=CTF)
procedure fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
var
from,
end_ : vec3_t;
tr : trace_t;
edict_t *ignore;
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) do
begin
tr := gi.trace (from, NULL, NULL, end_, ignore, mask);
// if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA))
if ( (tr.contents AND (CONTENTS_SLIME OR CONTENTS_LAVA)) <> 0 )
then begin
// mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA);
mask := mask AND (NOT (CONTENTS_SLIME OR CONTENTS_LAVA));
water := true;
end
else begin
// if ((tr.ent.svflags & SVF_MONSTER) OR (tr.ent.client))
if ( ((tr.ent.svflags AND SVF_MONSTER) <> 0) OR tr.ent.client )
then ignore := tr.ent
else ignore := NULL;
if ((tr.ent <> self) AND (tr.ent.takedamage)) then
T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_RAILGUN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -