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