ZYLON GAS GRENADES

 

 

philip
profile | email

posted 10-28-98 1:44 AM CT (US)
Title: ZYLON GAS GRENADES
Difficulty: Fair-to-Midland
By: Philip (aka Maj.Bitch)
Email: peblair@gv.net
Date: 10-27-98
Note: Give credit where credit is due.
======================================================

This is a heavy modification of a smoke grenade tutorial
originally posted by 'Decker' for which many thanks are
extended for his originality and inspiration.

ABOUT:

I had been thinking about modifying the grenade to make
it so that it emits some kind of toxic gas clouds which,
when inhaled (touched) by the player, their health units
decrease. Well, after a few hours of coding, here it is!

You now have a new weapon in your arsenal!

--------- Zylon Gas Grenades -------------

GREAT for setting off in narrow hallways or elevator
shafts that you want to fill with clouds of toxic gas
to kill all those bastards passing through!!

GREAT for flushing campers out of their cubby-hole
campsites and other hideaways!!

Cool effects too!!! Watch as toxic gas clouds
slowly bubble up toward the ceiling/sky.

HINT: Drop a few grenades down an elevator shaft and
stand back and watch the clouds come floating upward.

HINT. Drop some grenades into a pool of water and watch
as the clouds bubble off of the water surface and rise
into the air.

=========================================================
This weapon is called the Zylon Gas Grenade (zylon is a toxic
gas which had been used in gas chambers in past wars). The
player can toggle an aliased key (as discussed below) to
turn their regular grenades into zylon gas grenades. These
grenades don't explode like the standard issue Q2 grenades
do, but emit small clouds of toxic green gas (for those opengl
enabled) which float away from the grenades resting position
and eminate slowly upward. If any player (including yourself)
comes in contact with any of the floating green clouds and
inhales (touches) any of the zylon gas, then their health
units are accordingly deducted 20 units.. (You can change
this to make the clouds as toxic as you want!!) You can
even add a small explosion to the clouds touch function!!

The standard grenade function is still fully enabled and
quite functional. All the player has to do is to hit
their aliased 'zylon' key and all their grenades will
be converted to zylon gas grenades. When you want the
regular exploding grenades back again, just hit your
zylon key again and your back in action again..

Okay, let's get started..

=====================================================
Open you g_local.h file and let's put a few variables
in place.

At the bottom of your struct edict_s record add:

int Zylon_timer; // duration of Zylon gas clouds

At the bottom of your struct gclient_s record add:

int Zylon_grenade; // Zylon Gas Grenade 1=ON, 0=OFF

=====================================================
Add a MOD_ZYLON_GAS flag to your other MOD_ flags in
your g_local.h file. You'll have to fit it in there
as the next incremented flag variable as shown:

#define MOD_ROCKET_BOMBS 0x00000023
#define MOD_CLUSTER_BOMBS 0x00000024
#define MOD_RAILSTRIKE 0x00000025
#define MOD_BFG_NUKE 0x00000026
#define MOD_DECOY 0x00000027
#define MOD_ZYLON_GAS 0x00000028 // NEW FLAG HERE
#define MOD_FRIENDLY_FIRE 0x10000000 // DON'T CHANGE THIS ONE!!!!

=====================================================
Okay, now find your void ClientObituary() function
and let's add some obits to your gameplay..

---- right after these lines here --------
case MOD_TARGET_BLASTER:
message="got blasted";
break;

--------- add these lines --------------
case MOD_ZYLON_GAS:
message="was gassed";
break;
case MOD_BOMB:

=============
a bit farther on down in this same function...

---------- after these lines ---------
case MOD_TARGET_BLASTER:
message="got blasted";
break;

-------- add these lines here ----------
case MOD_ZYLON_GAS:
message="inhaled Zylon gas";
break;

=============
even farther down in this same function...

-------- after these lines here -------
case MOD_TELEFRAG:
message="tried to invade";
message2="'s personal space";
break;

------- add these lines here ----------
case MOD_ZYLON_GAS:
message="inhaled";
message2="'s zylon gas";
break;

Note: you can change the client obituaries to whatever
you feel is more suitable for your particular mod..

=====================================================

Okay. open up your g_cmds.c file and at the bottom
of ClientCommand() add the following lines as shown.

else if (Q_stricmp(cmd, "zylon") == 0 ) {
ent->client->Zylon_grenade=abs(ent->client->Zylon_grenade-1);
gi.centerprintf(ent,"ZYLON GAS GRENADES %s!\n",ent->client->Zylon_grenade<1?"DISABLED":_x0022_ENABLED_x0022__x0029__x003b_>
} // end else if

This will toggle the zylon gas grenades on/off with
a single hit of your aliased 'zylon' key.

=====================================================
Okay, now find your InitClientPersistant() function
and at the bottom of this fucntion add this variable
initialization:

client->Zylon_grenade = 0; // init as OFF

This will set the zylon grenades to OFF by default.
=====================================================
Create a new file called g_zylon.c and paste in all
of the following code from START to STOP:

Note: Be sure that the include statement matches your
particular setup!!

Remember, if my function calls don't match yours then
change mine..

Okay.. cut from here...

-------------- START CUTTING HERE ----------------

#include "xxxxxx.h"
#include "xxxxxx.h"

//======================================================
//============= ZYLON GAS GRENADES =====================
//======================================================

//======================================================
void Zylon_Touch(edict_t *Zylon, edict_t *target, cplane_t *plane, csurface_t *surf) {
vec3_t dir={0,0,0};

Zylon->enemy=target;

if (target->takedamage)
T_Damage(target, // entity which touched the gas cloud..
Zylon, // this entity
Zylon->owner, // the grenades owner..
dir, // not needed..
Zylon->s.origin,// location in world where touch occurred.
plane->normal, // not needed...
20, // deduct 20 health units per gas cloud touch!!
0, // no knockback force
0, // no damage radius
MOD_ZYLON_GAS );// for client obituaries..

G_FreeEdict(Zylon); // free up this cloud upon touch..
}

//======================================================
void Generate_Zylon_Gas(edict_t *ent, vec3_t last_angles) {
edict_t *Zylon;
int x,y;

Zylon = G_Spawn();

Zylon->classname = "Zylon";
Zylon->owner = ent; // owner is the grenade..
// player is grenade's owner!

VectorCopy (ent->s.origin, Zylon->s.origin);
x = (random()>0.5?-1:1);
y = (random()>0.5?-1:1);
Zylon->s.origin[0] += (random()*20+1)*x;
Zylon->s.origin[1] += (random()*20+1)*y;
Zylon->s.origin[2] += 8;
VectorCopy (ent->s.old_origin, Zylon->s.old_origin);
VectorClear(Zylon->s.angles);
Zylon->velocity[2] = (random()*40)+40;
Zylon->velocity[1] = ((int)((random()*40)+20+last_angles[1])%60)*y;
Zylon->velocity[0] = ((int)((random()*40)+20+last_angles[0])%60)*x;
VectorCopy(Zylon->velocity, last_angles);

Zylon->movetype = MOVETYPE_FLY; // clouds float gently around..

Zylon->solid = SOLID_BBOX; // enable touch detection..

Zylon->s.renderfx = RF_SHELL_GREEN; // gas clouds have green glow..
Zylon->s.effects = EF_COLOR_SHELL; // change this to see what you get!!

VectorSet(Zylon->mins, -10, -10, -10); // size of bbox for touch
VectorSet(Zylon->maxs, 10, 10, 10); // size of bbox for touch

Zylon->s.modelindex = gi.modelindex("sprites/s_explod.sp2");

Zylon->touch=Zylon_Touch; // Touch detection function.

Zylon->nextthink = level.time+10;
Zylon->think=G_FreeEdict; // kill gas cloud in 10 secs if not touched..

gi.linkentity (Zylon);
}

//======================================================
void Zylon_Grenade(edict_t *ent) {

Generate_Zylon_Gas(ent, ent->move_angles);

if (ent->Zylon_timer > level.time) {
ent->nextthink = level.time + 0.2;
ent->think = Zylon_Grenade;
return; }

G_FreeEdict(ent);
}

---------------STOP HERE ------------------

=====================================================

Open up your g_weapons.c file and paste in the following
at the top of the file..

void Zylon_Grenade(edict_t *ent);

Add this little helper function at the top of g_weapons.c

//======================================================
// True if Ent is valid, has client, and edict_t inuse.
//======================================================
qboolean G_EntExists(edict_t *ent) {
return ((ent) && (ent->client) && (ent->inuse));
}

Okay, now find your grenade_explode() function in this
same file and add this code to the top as shown:

-----------------------------------------------
void Grenade_Explode(edict_t *ent) {
.
.
.
// Zylon Grenades only if activated by real Player..
if (G_EntExists(ent->owner))
if (ent->owner->client->Zylon_grenade) {
ent->Zylon_timer = level.time+10+(random()*10);
Zylon_Grenade(ent);
return; }

=====================================================

Lastly, be sure to include the following in your
autoexec.cfg file as shown by example...

bind g "zylon"

This will turn the zylon gas grenades ON/OFF with a
single keystroke!

=====================================================

That's it!! Now, get out there and GAS ALL THOSE BASTARDS!!

regards,
philip
aka Maj.Bitch