|
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
|