
Quake DeveLS - Kamikaze Mode
Author: WonderSlug
Difficulty: Medium
Banzai??...As
in little trees??
Well in commemoration of
the Nagano Olympics Ive come up with a little Kamikaze Mode mod. (Well not
really im just writing this up while watching the opening of the games.. and
they kinda go good together)
Where the idea really came
from was, a friend I work with said it would be cool to have something like in
"Predator" where the alien activates the self destruct weapon and
blows the forest to bits. (Thank Hockenhiem for the idea.) In talking about it
we thought I would be a great team tactic in CTF. Imagine a heavily defended
base and just you and a bud attacking. You activate Kamikaze mode charge in and
blow the base clean (yourself as well but thats kinda the point) ...your bud
comes in right after the carnage, grabs the flag and takes it home for the
capture.
Well thats the theory as
least.
Code you
Kill Yourself By.
Ok lets start by creating
two files and adding them to the project...
kamikaze.h and kamikaze.c... first lets start with the header file..
Place this code in the
kamikaze.h file
/*
kamikaze.h
by....Wonderslug
*/
/* Amount of Damage caused */#define KAMIKAZE_DAMAGE 300
/* Radius of blast */
#define KAMIKAZE_DAMAGE_RADUIS 800 // Quake Units
/* Count down time */
#define KAMIKAZE_BLOW_TIME 50 // 1/10 secondsvoid Start_Kamikaze_Mode(edict_t *the_doomed_one); // setup and start self destruct modeqboolean Kamikaze_Active(edict_t *the_doomed_one);void Kamikaze_Explode(edict_t *the_doomed_one);void Kamikaze_Cancel(edict_t *the_spared_one);
This is just a couple of
defines that define how much damage and how far out the blast goes, as well as
the amount of time before the blast.
Ok now place the following
code in the kamikaze.c
/* kamikaze.c
All functions for independent kamikaze by....Wonderslug*/
#include "g_local.h"#include "kamikaze.h"/*
Function: Start_Kamikaze_Mode
Places the edict passed to it into Kamikaze Mode (probably best to pass a player to it) Warns everyone that so and so is a kamikaze...*/
void Start_Kamikaze_Mode(edict_t *the_doomed_one){ /* see if we are already in kamikaze mode*/
if (the_doomed_one->client->kamikaze_mode & 1) {
gi.cprintf(the_doomed_one, PRINT_MEDIUM, "Already in Kamikaze Mode!! Kiss you butt Goodbye!");return;
} /* dont run if in god mode */
if (the_doomed_one->flags & FL_GODMODE){ gi.cprintf(the_doomed_one, PRINT_MEDIUM, "Can't Kamikaze in God Mode, Whats the Point?"); return; } /* not in kamikaze mode yet */ the_doomed_one->client->kamikaze_mode = 1;/* Give us only so long */
the_doomed_one->client->kamikaze_timeleft = KAMIKAZE_BLOW_TIME; the_doomed_one->client->kamikaze_framenum = level.framenum + the_doomed_one->client->kamikaze_timeleft; /* Warn the World */ gi.bprintf (PRINT_MEDIUM,"%s is a Kamikaze - BANZAI!!\n", the_doomed_one->client->pers.netname); gi.sound( the_doomed_one, CHAN_WEAPON, gi.soundindex("makron/rail_up.wav"), 1, ATTN_NONE, 0 ); return;}
/*
Function: Kamikaze_Active
Are we in Kamikaze Mode? a helper function to see if we are running in Kamikaze Mode*/
qboolean Kamikaze_Active(edict_t *the_doomed_one){ return (the_doomed_one->client->kamikaze_mode);}
/*
Function: Kamikaze_Cancel
Canceled for Some Reason Call if Player is killed before time is up*/
void Kamikaze_Cancel(edict_t *the_spared_one){ /* not in kamikaze mode yet */ the_spared_one->client->kamikaze_mode = 0; /* Give us only so long */ the_spared_one->client->kamikaze_timeleft = 0; the_spared_one->client->kamikaze_framenum = 0; return;}
void Kamikaze_Explode(edict_t *the_doomed_one){ /* A whole Lotta Damage */ T_RadiusDamage (the_doomed_one, the_doomed_one, KAMIKAZE_DAMAGE, NULL, KAMIKAZE_DAMAGE_RADUIS); /* BANG ! and show the clients */ gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition(the_doomed_one -> s.origin); gi.multicast (the_doomed_one->s.origin, MULTICAST_PVS);}
This is all the major
functions for the kamikaze starting, canceling, seeing if we are in kamikaze
mode, and of course the end explosion.
Now we have to add in some
variables to be carried around by the client... so open up g_local.h and go to
line line 827. This is the gclient_t structure. Place the following code in
there.
Replace this
float respawn_time; // can respawn when time > this
} gclient_t;
With this
float respawn_time; // can respawn when time > this
/* WonderSlug --Added For Kamikaze Mode */int kamikaze_mode;
float kamikaze_framenum;
float kamikaze_timeleft;
/* WonderSlug End */} gclient_t;
These are just some
variables to carry information about when to blow up and if we are in the mode
to go boom as well.
Next open up g_cmds.c and
place this bit of code around line 636 in the ClientCommand function
Replace this
else if (Q_stricmp (cmd, "wave") == 0) Cmd_Wave_f (ent); else if (Q_stricmp (cmd, "gameversion") == 0)
With this
else if (Q_stricmp (cmd, "wave") == 0) Cmd_Wave_f (ent);/* WonderSlug -- Start Kamikaze Mode */
else if (Q_stricmp (cmd, "kamikaze") == 0) Start_Kamikaze_Mode(ent); /* WonderSlug End */ else if (Q_stricmp (cmd, "gameversion") == 0)
What this does is let us
bind a convenient key to the kamikaze command.
Now open up the file
p_client.c and at the very bottom of the ClientThink function place the
following code at line 1072
Replace this
client->weapon_thunk = true; Think_Weapon (ent); } }
With This...
client->weapon_thunk = true; Think_Weapon (ent); } } /* WonderSlug ----Code to go boom */ if ((ent->client->kamikaze_framenum <= level.framenum) && (ent->client->kamikaze_mode & 1))Kamikaze_Explode(ent);
/* WonderSlug End */
This is the code to blow up once we reach the timelimit.
Now still p_client.c go to
line 147 and place the following in the player_die function
Replace this
VectorClear (self->avelocity); self->takedamage = DAMAGE_YES;
With This...
/* WonderSlug */Kamikaze_Cancel(self); /* No Kamikaze Now!!*/
/* end wonderlsug */ VectorClear (self->avelocity); self->takedamage = DAMAGE_YES;
Now if we die while in
Kamikaze mode we dont blow up....gotta give the defenders a chance.
Now open the file p_hud.c
and on line 362 in the G_SetStats function place the following code. Replace
this
if (ent->client->quad_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad"); ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10; } else if (ent->client->invincible_framenum > level.framenum)
With This...
if (ent->client->quad_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad"); ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10; }/* WonderSlug Kamikaze */
else if (ent->client->kamikaze_framenum > level.framenum) {
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad"); ent->client->ps.stats[STAT_TIMER] = ent->client->kamikaze_timeleft/10; } /* WonderSlug End */ else if (ent->client->invincible_framenum > level.framenum)
What this does is add the
countdown on the screen just like the Quad damage... im fact we are using the
quad damage symbol because i could ot think of one for blowing yourself up.
Now still in p_hud.c go to
line 25 and add the following code into the MoveClientToIntermission function.
Replace this
// clean up powerup info ent->client->quad_framenum = 0;
With This...
// clean up powerup info/* Wonderslug Cancel Kamikaze if going to new level */
ent->client->kamikaze_framenum = 0; /* WonderSlug End */ ent->client->quad_framenum = 0;
This is just to clean up
the timing when moving to a new level.
Time so add some visible
effects...open up p_view.c and in the G_SetClientEffects function on line 763
add in the following code. Replace this
// show cheaters!!! if (ent->flags & FL_GODMODE) { ent->s.effects |= EF_COLOR_SHELL; ent->s.renderfx |= (RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE); }
With This...
// show cheaters!!! and Kamikazes!!! if ((ent->flags & FL_GODMODE) || (ent->client->kamikaze_mode & 1)) { ent->s.effects |= EF_COLOR_SHELL; ent->s.renderfx |= (RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE); }
Now the Kamikaze has a
nice white glow to others...The defenders need to know who there biggest threat
is..again it cant be one sided. Now if your using God mode on your multi player
server you deserve to be confused.
Still in p_view.c go to
line 424 in the SV_CalcBlend function and insert this code
Replace this
if (ent->client->quad_framenum > level.framenum) { remaining = ent->client->quad_framenum - level.framenum;if (remaining == 30) // beginning to fade
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (0, 0, 1, 0.08, ent->client->ps.blend); } else if (ent->client->invincible_framenum > level.framenum)
With This...
if (ent->client->quad_framenum > level.framenum) { remaining = ent->client->quad_framenum - level.framenum;if (remaining == 30) // beginning to fade
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4) ) SV_AddBlend (0, 0, 1, 0.08, ent->client->ps.blend); }/* Wonderslug make screen go colored */
else if (ent->client->kamikaze_framenum > level.framenum){remaining = ent->client->kamikaze_framenum - level.framenum;
ent->client->kamikaze_timeleft = remaining;
if (remaining == 30)
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect2.wav"), 1, ATTN_NORM, 0);if (remaining > 30 || (remaining & 4))
SV_AddBlend (0, 0, 1, 0.08, ent->client->ps.blend); } /* Wonderslug End */ else if (ent->client->invincible_framenum > level.framenum)
Now here we have the code
to make the screen go a little different color when we are in Kamikaze mode. It
also does the waring on the last couple of seconds.
All thats left now is to
go back and place
#include "kamikaze.h"
in all the
c files we have just messed with. You dont need to place it in the g_local.h.
These files are
Just place it up at the top along with the other includes.
You should now be ready to
Rock and Blow Up.. bind a key to the "cmd kamikaze" and your off to
die for the common goal...or if in deathmatch just to take out a lot of
people... I recommend using it close to at least one enemy..you still lose a frag
for nuking yourself...but if you take one along with you it balances out.
So Go forth....and Die for
the Greater Good!!!
BANZAI!!!! and avoid the
Salt!! -=WonderSlug
Tutorial by WonderSlug .
|
This site, and all
content and graphics displayed on it, |