TUTORIAL 7 - Cloaking
by AssKicka
Teach those bots a lesson, Predator-style !
Let's add a nice cloaking feature that also decrements the players health while cloaked.
1. ADDING A NEW ENTITY FLAG.
First we are going to add a new entity flag called FL_CLOAK that we will use to activate and deactivate our cloaking. Open up g_local.h and add the code bellow after line 32.
#define FL_NO_HUMANS 0x00004000 // spawn point just for bots
#define FL_CLOAK 0x00010000 // health cloaking
2. CREATING A NEW CONSOLE COMMAND.
Open up g_cmds.c and add the code bellow after line 1022
/*
=================
Cmd_Cloak_f
=================
*/
void Cmd_Cloak_f( gentity_t *ent ) {
char *msg; // message to player
ent->flags ^= FL_CLOAK;
if (!(ent->flags & FL_CLOAK)) {
msg = "Cloaking OFF\n";
ent->client->ps.powerups[PW_INVIS] = level.time;
// Removes the invisible powerup from the player
}
else {
msg = "Cloaking ON\n";
ent->client->ps.powerups[PW_INVIS] = level.time + 1000000000;
// Gives the invisible powerup to the player
}
trap_SendServerCommand( ent-g_entities, va("print \"%s\"", msg));
}
All we did here is create a new function that is called when you use the /cloak command that we will be adding bellow. This function will change the current state of FL_CLOAK, activate/deactivate the invisible powerup and print a relative on/off message to the player.
What the hell is "level.time + 1000000000" ? What we are doing is making the invisible powerup last for 1666 minutes. We don't really need it to last that long because we will be decrementing the players health until it reaches 10 and then auto deactivating cloaking.
Now we must add the /cloak console command and get it to call the function we created. Goto line 1095 and add the code bellow
else if (Q_stricmp (cmd, "setviewpos") == 0)
Cmd_SetViewpos_f( ent );
else if (Q_stricmp (cmd, "cloak") == 0)
Cmd_Cloak_f( ent );
3. MAKING THE CLIENTS HEALTH DECREMENT WHILE CLOAKED.
We will now make the players health decrement every second while cloaking is enabled. open g_active.c and goto line 397 in ClientTimeActions. This function will be called once every second, making it perfect for our cloaking feautre. Modify the existing code
// count down health when over max
if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] ) {
ent->health--;
to match the following code :
if (!(ent->flags & FL_CLOAK)) {
// count down health when over max and not cloaked.
if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] ) {
ent->health--;
}
}
else {
// count down health when cloaked.
ent->health--;
if ( ent->health < 11) {
ent->flags ^= FL_CLOAK;
ent->client->ps.powerups[PW_INVIS] = level.time;
}
}
Lets look at what we have done. First we check if FL_CLOAK is enabled, if it is NOT we then check if the players health is MORE than 100 (STAT_MAX_HEALTH), If it IS we decrement the players health. If the player is cloaked the "else" section is executed, meaning the players health is decremented. The reason we do it this way is because we do not want the players health to decrement by 2 if he is cloaked and his health is above STAT_MAX_HEALTH. We have also forced cloaking off when the players health reaches 10.
4. DON'T DROP POWER-UPS WHILE CLOAKED.
The next step is to remove the cloak powerup just before the normal powerups are dropped when the player dies. We need to do this because if a player died while he was cloaked, the invisible powerup will pop up and the next player who picks it up will have unlimited invisibility, without his health decrementing (bit unfair don't you think).
Open g_combat.c and goto line 67, now add the code bellow :
if (self->flags & FL_CLOAK) {
// remove the invisible powerup if the player is cloaked.
self->client->ps.powerups[PW_INVIS] = level.time;
}
That's it, create your .qvm file and enjoy being the preditor !
|