Exploding Nails

InsideQC tutorials kleskby 0 714
Author: Triften Chmil
Source: https://www.insideqc.com/qctut/qctut-11.shtml

Introduction This tutorial will tell you how to change the regular wussy nailgun into a weapon of mass destruction. Instead of regular nails, you will have time-delay explosive nails (a la Ghost in the Shell). 1.5 seconds after the last one hits, everyone with a nail sticking out of the will go critical and make a BIG mess.

Step 1

First, open weapons.qc and go down to launch_spike. It'll look like this:

/*
===============
launch_spike

Used for both the player and the ogre (From QTest? Now, that's a bit outdated, eh?)
===============
*/

Above this we will create a new function, W_FireDarts. We have to create a new function or else the scraggs will be certain death. Just cut and paste this or whatever:

void(float ox) W_FireDarts =// the ox makes the nails come out of each barrel
{
    local vector dir;
    local entity dart; //our dart entity

    if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
    {
        W_FireSuperSpikes (); //fire spikes and not darts if you are using the super nailgun
        return;
    }

    self.punchangle_x = -4;//the kickback

    self.currentammo = self.ammo_nails = self.ammo_nails - 1;
    sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
    self.attack_finished = time + 0.2;
    dir = aim (self, 1000);
    dart = spawn ();//creat the dart
    dart.owner = self;//you are the owner
    dart.movetype = MOVETYPE_FLYMISSILE;//It doesn't bounce
    dart.solid = SOLID_BBOX;//it doesn't share space with other items

    dart.angles = vectoangles(dir);

    dart.touch = dart_touch;//when touched call dart_touch
    dart.classname = "spike";
    dart.think = SUB_Remove;   //After 6 seconds of uneventful flight,
    dart.nextthink = time + 6; //remove the dart
    setmodel (dart, "progs/spike.mdl");
    setsize (dart, VEC_ORIGIN, VEC_ORIGIN);
    setorigin (dart, self.origin + '0 0 16' + v_right*ox);

    dart.velocity = dir * 700; //the dart's speed
};

Step 2

Above this we will have to define the various touch and think functions Here goes:

void() dart_touch =
{
local float rand;
        if (other == self.owner)
                return; //If it hits you, do nothing

        if (other.solid == SOLID_TRIGGER)
                return; // trigger field, do nothing

        if (pointcontents(self.origin) == CONTENT_SKY)
        {
                remove(self);
                return;
        }

// hit something that bleeds
        if (other.takedamage)
        {
                spawn_touchblood (4);
                T_Damage (other, self, self.owner, 4); //Low damage
                self.velocity = (self.velocity * 0);    //Set's the spike up so it sticks
                self.avelocity = VEC_ORIGIN;            //to an enemy
                self.enemy = other;
                dart_wait = time + 1.5; //the time delay for detonation
                self.think = dart_stick;        //In a tenth second
                self.nextthink = (time + 0.10); //go to dart_stick
                self.touch = dart_fuse;         //now when touched call dart_fuse

        }
        else //otherwise the dart hits a wall...
        {
                WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
                WriteByte (MSG_BROADCAST, TE_SPIKE);
                WriteCoord (MSG_BROADCAST, self.origin_x);
                WriteCoord (MSG_BROADCAST, self.origin_y);
                WriteCoord (MSG_BROADCAST, self.origin_z);
                remove(self);
        }
};

Above this we define dart_fuse and dart_stick

void() dart_fuse = //this is our touch function
{
        if (time > dart_wait) //if touching something and 1.5 seconds pass, then..
        {
//              T_RadiusDamage (self, self.owner, 120, world); //You can chose to do radius dmg
                T_Damage (other, other, self.owner, 400);      //or dmg only to the poor sap with
                WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);     //the dart.
                WriteByte (MSG_BROADCAST, TE_EXPLOSION);       //Then the dart becomes an explosion
                WriteCoord (MSG_BROADCAST, self.origin_x);
                WriteCoord (MSG_BROADCAST, self.origin_y);
                WriteCoord (MSG_BROADCAST, self.origin_z);
                BecomeExplosion ();
                remove(self);  //The dart exploded, therefore we remove it
        }
};
void() dart_stick = //our think function
{
        if ( ((self.enemy != world) && (self.enemy.health > 1)) ) //if the dart is on a live enemy then..
        {
                self.origin = self.enemy.origin; //it stays on the enemy and
                if ( (self.velocity == VEC_ORIGIN) ) //moves with the enemy
                {
                        self.avelocity = VEC_ORIGIN;
              }
        }
        else //if the enemy dies then..
        {
                WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); //explode harmlessly
                WriteByte (MSG_BROADCAST, TE_EXPLOSION);   //or you could make it do damage,
                WriteCoord (MSG_BROADCAST, self.origin_x); //doesn't matter.
                WriteCoord (MSG_BROADCAST, self.origin_y);
                WriteCoord (MSG_BROADCAST, self.origin_z);
                BecomeExplosion ();
        }
   self.nextthink = (time + 0.10);      //after another .1 sec check this function again
};

Step 3

Finally we mention functions ahead of time to define later and add one thing to player.qc. Add this above dart_fuse:

void() s_explode1;
void() BecomeExplosion;
float dart_wait;
void() W_FireSuperSpikes;

Open player.qc and find this:

void() player_nail1   =[$nailatt1, player_nail2  ]
{
    self.effects = self.effects | EF_MUZZLEFLASH;

    if (!self.button0)
        {player_run ();return;}
    self.weaponframe = self.weaponframe + 1;
    if (self.weaponframe == 9)
        self.weaponframe = 1;
    SuperDamageSound();
    W_FireSpikes (4);
    self.attack_finished = time + 0.2;
};
void() player_nail2   =[$nailatt2, player_nail1  ]
{
    self.effects = self.effects | EF_MUZZLEFLASH;

    if (!self.button0)
        {player_run ();return;}
    self.weaponframe = self.weaponframe + 1;
    if (self.weaponframe == 9)
        self.weaponframe = 1;
    SuperDamageSound();
    W_FireSpikes (-4);
    self.attack_finished = time + 0.2;
};

Change both of the W_FireSpikes to W_FireDarts. Leave the 4 and -4 alone.

Step 4

Compile and run in with guns a-blazin'!



Tags: tutorial, quakec, qc, insideqc, weapon

Comments


captcha


No comments yet. Be the first!
Owned by kleskby#1837
Close

You have no new notifications.

SHOUTBOX
Open chat to load…
Log in to chat