Quake DeveLS - Flash Grenades Addon

Author: Paul Currie
Difficulty: Easy

Thanks to NightHawk's Flash Grenade I've had the priveledge of blasting opponents to pieces when they can't defend themselves, but I felt that something was missing. So I added an distance dependent non-linear intensity falloff (fancy words, huh? :) It basically means that the further off you are, the less blinded you are.

I also added that even if you threw the grenade you are not completely saved from the flash effects (but still considerably better off than the other victims). I also added that turning your back on the grenade doesn't make you immune to it (that's what my opponents were doing all the damn time). Turning you back on a flash grenade will save you from the worst effects, but the flash will still light up walls etc. quite a lot. These two factors make it quite easy to remove the most harmful effects of the flash greande (i.e. total blindness), but will partially blind your opponents a lot more often.

1. Adding the code

You will ofcource need NightHawk's Flash Grenade implemented and working before adding this.

All you need to do is open up g_weapon.c and find the Flash_Explode() function. Then just add the lines with the '+' in front of them, and remove/comment out the ones with '-'.

#define		FLASH_RADIUS		300
#define		BLIND_FLASH		10		// Time of blindness in FRAMES

void Flash_Explode (edict_t *ent)
        vec3_t	offset, v;
        edict_t	*target;
+       float Distance, BlindTimeAdd;
        // Move it off the ground so people are sure to see it
        VectorSet(offset, 0, 0, 10);
        VectorAdd(ent->s.origin, offset, ent->s.origin);
        if (ent->owner->client)
                PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);

        target = NULL;
        while ((target = findradius(target, ent->s.origin, FLASH_RADIUS)) != NULL) {
-               if (target == ent->owner)
-                       continue;       // You know when to close your eyes, don't you?
                if (!target->client)
                	continue;       // It's not a player
                if (!visible(ent, target))
                        continue;       // The grenade can't see it

+               // Find distance
+               VectorSubtract(ent->s.origin, target->s.origin, v);
+               Distance = VectorLength(v);
+               // Calculate blindness factor
+               if ( Distance < FLASH_RADIUS/10 )
+                       BlindTimeAdd = BLIND_FLASH; // Blind completely
+               else
+                       BlindTimeAdd = 1.5 * BLIND_FLASH * ( 1 / ( ( Distance - FLASH_RADIUS*2 ) / (FLASH_RADIUS*2) - 2 ) + 1 ); // Blind partially
+               if ( BlindTimeAdd < 0 )
+                       BlindTimeAdd = 0; // Do not blind at all.

+               // Not facing it, but still blinded a little
                if (!infront(target, ent))
+                       BlindTimeAdd *= .5;
-                       continue;
+               // You know when to close your eyes, don't you? Doesn't quite do the job. :)
+               if (target == ent->owner)
+               {
+                       target->client->blindTime += BlindTimeAdd * .3;
+                       target->client->blindBase = BLIND_FLASH;
+                       continue;
+               }

                // Increment the blindness counter
                target->client->blindTime += BlindTimeAdd * 1.5;
                target->client->blindBase = BLIND_FLASH;
                target->s.angles[YAW] = (rand() % 360); // Whee!

                // Let the player know what just happened
                // (It's just as well, he won't see the message immediately!)
                gi.cprintf(target, PRINT_HIGH, "You are blinded by a flash grenade!!!\n");

                // Let the owner of the grenade know it worked
                gi.cprintf(ent->owner, PRINT_HIGH, "%s is blinded by your flash grenade!\n", target->client->pers.netname);

        // Blow up the grenade

Feel free to experiment with the FLASH_RADIUS define. Some like powerful flashes while other prefer them smaller. With the range falloff it shouldn't make your friends object totally to a larger flash radius. Bear in mind though that the main loop for calculating the flash value will run through all objects within the range, so if things start going slow, decrease the radius. The two if-tests in the main loop (!target->client and !visible()) will remove the number of false hits, i.e. calculating flash for a non-player is just silly, but it still has to detect and run the (!visible()) test which could result in some serious vector calculus (i.e. floating-point heaven/hell depending on what kind of CPU you own :).

Tutorial by Paul Currie .

This site, and all content and graphics displayed on it,
are ©opyrighted to the Quake DeveLS team. All rights received.
Got a suggestion? Comment? Question? Hate mail? Send it to us!
Oh yeah, this site is best viewed in 16 Bit or higher, with the resolution on 800*600.
Thanks to Planet Quake for their great help and support with hosting.
Best viewed with Netscape 4