
The Wall Piercing
Railgun!
No longer
will you be able to duck behind the thinnest chunk of Quake wall and be safe
from the high speed slugs spewd forth from the mighty railgun! A big
thanks goes to Mr. Grim.
This is originally his code. This tutorial will modify your railgun so
it can pass right through walls and hit players on the other side. It's
very easy, very quick, and VERY fun!
Add in the blue code and take out and pink code.
Let's get started. Open up
g_weapon.c and go down to your fire_rail function. Modify it so it looks
like this:
/*
=================
fire_rail
=================
*/
void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int
kick)
{
vec3_t from;
vec3_t end;
trace_t tr;
edict_t *ignore;
int
mask;
int n;
qboolean water;
VectorMA (start, 8192, aimdir, end);
VectorCopy (start, from);
ignore = self;
water = false;
mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA;
while (ignore)
{
tr = gi.trace (from, NULL, NULL,
end, ignore, mask);
if (tr.contents &
(CONTENTS_SLIME|CONTENTS_LAVA))
{
mask &=
~(CONTENTS_SLIME|CONTENTS_LAVA);
water =
true;
}
else
{
//ZOID--added so rail goes through SOLID_BBOX entities (gibs, etc)
if
((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client) ||
(tr.ent->solid == SOLID_BBOX))
ignore = tr.ent;
else
ignore = NULL;
if ((tr.ent
!= self) && (tr.ent->takedamage))
T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, self->dmg,
kick, 0, MOD_RAILGUN);
}
VectorCopy (tr.endpos, from);
}
// send gun puff / flash
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_RAILTRAIL);
gi.WritePosition (start);
gi.WritePosition (tr.endpos);
gi.multicast (self->s.origin, MULTICAST_PHS);
// gi.multicast (start, MULTICAST_PHS);
if (water)
{
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_RAILTRAIL);
gi.WritePosition (start);
gi.WritePosition (tr.endpos);
gi.multicast (tr.endpos,
MULTICAST_PHS);
}
if (self->client)
PlayerNoise(self, tr.endpos,
PNOISE_IMPACT);
// Take this point, and add 1, until we find an open place...
VectorMA (tr.endpos, 10, aimdir,
from);
n = 0;
while (n < 10)
{
if ((!(gi.pointcontents(from) &
CONTENTS_SOLID)) )
{
// Found a hole...fire again...
fire_rail (self, from, aimdir, damage, kick);
n = 10;
}
else
n++;
VectorMA (from, 10, aimdir, from);
}
}
That's it! Now at the
bottom it checks in increments of 10 Quake units from the end position of the
trace. If any of those checks are not in a solid, it calls on fire_rail
again! Very simple and easy. If you want it to go through thicker
or thinner walls you can change the while statement. Right now it checks
10 times in increments of 10 units so it can pass through 100 unit walls.
Hope ya like it!
Tutorial by Willi