177 lines
5.0 KiB
C
177 lines
5.0 KiB
C
/*==============================================================================
|
|
The Weapons Factory -
|
|
Flash Grenade Functions
|
|
Original code by ??
|
|
Modified by Gregg Reno
|
|
==============================================================================*/
|
|
#include "g_local.h"
|
|
#define FLASH_RADIUS 300
|
|
#define BLIND_FLASH 50 // Time of blindness in FRAMES
|
|
|
|
|
|
void Flash_Explode (edict_t *ent)
|
|
{
|
|
vec3_t offset, v;
|
|
edict_t *target;
|
|
float Distance, BlindTimeAdd;
|
|
// vec3_t origin;
|
|
|
|
//safe_cprintf(ent->owner, PRINT_HIGH, "Flash goes BOOM!\n");
|
|
|
|
// 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
|
|
// if (!infront(target, ent))
|
|
// continue; // It's not facing it
|
|
|
|
//dont blind teammates
|
|
if (target->wf_team == ent->wf_team)
|
|
continue;
|
|
|
|
// 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;
|
|
// 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->blindTime = 300;
|
|
//
|
|
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!)
|
|
safe_cprintf(target, PRINT_HIGH, "You are blinded by a flash grenade!!!\n");
|
|
|
|
// Let the owner of the grenade know it worked
|
|
safe_cprintf(ent->owner, PRINT_HIGH, "%s is blinded by your flash grenade!\n",
|
|
target->client->pers.netname);
|
|
}
|
|
|
|
// Blow up the grenade
|
|
BecomeExplosion1(ent);
|
|
}
|
|
|
|
|
|
void Flash_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|
{
|
|
if (other == ent->owner)
|
|
return;
|
|
|
|
// Dont blow up if on same team
|
|
if (other->wf_team == ent->wf_team)
|
|
return;
|
|
|
|
// If it goes in to orbit, it's gone...
|
|
if (surf && (surf->flags & SURF_SKY))
|
|
{
|
|
G_FreeEdict (ent);
|
|
return;
|
|
}
|
|
|
|
// All this does is make the bouncing noises when it hits something...
|
|
if (!other->takedamage)
|
|
{
|
|
if (ent->spawnflags & 1)
|
|
{
|
|
if (random() > 0.5)
|
|
gi.sound (ent, CHAN_VOICE, gi.soundindex("weapons/hgrenb1a.wav"),
|
|
1, ATTN_NORM, 0);
|
|
else
|
|
gi.sound (ent, CHAN_VOICE, gi.soundindex("weapons/hgrenb2a.wav"),
|
|
1, ATTN_NORM, 0);
|
|
}
|
|
else
|
|
{
|
|
gi.sound (ent, CHAN_VOICE, gi.soundindex("weapons/grenlb1b.wav"),
|
|
1, ATTN_NORM, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// The ONLY DIFFERENCE between this and "Grenade_Touch"!!
|
|
Flash_Explode (ent);
|
|
}
|
|
|
|
|
|
|
|
void fire_flash (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius)
|
|
{
|
|
edict_t *grenade;
|
|
vec3_t dir;
|
|
vec3_t forward, right, up;
|
|
|
|
vectoangles (aimdir, dir);
|
|
AngleVectors (dir, forward, right, up);
|
|
|
|
grenade = G_Spawn();
|
|
grenade->wf_team = self->wf_team;
|
|
VectorCopy (start, grenade->s.origin);
|
|
VectorScale (aimdir, speed, grenade->velocity);
|
|
VectorMA (grenade->velocity, 200 + crandom() * 10.0, up, grenade->velocity);
|
|
VectorMA (grenade->velocity, crandom() * 10.0, right, grenade->velocity);
|
|
VectorSet (grenade->avelocity, 300, 300, 300);
|
|
grenade->movetype = MOVETYPE_BOUNCE;
|
|
grenade->clipmask = MASK_SHOT;
|
|
grenade->solid = SOLID_BBOX;
|
|
grenade->s.effects |= EF_GRENADE;
|
|
VectorClear (grenade->mins);
|
|
VectorClear (grenade->maxs);
|
|
// grenade->s.modelindex = gi.modelindex ("models/objects/grenade2/tris.md2");
|
|
grenade->s.modelindex = gi.modelindex (GRFLASH_MODEL);
|
|
grenade->s.skinnum = GRFLASH_SKIN;
|
|
grenade->owner = self;
|
|
grenade->touch = Flash_Touch;
|
|
grenade->think = Flash_Explode;
|
|
grenade->classname = "flash_grenade";
|
|
grenade->nextthink = level.time + timer;
|
|
grenade->dmg = damage;
|
|
grenade->dmg_radius = damage_radius;
|
|
grenade->classname = "grenade";
|
|
grenade->spawnflags = 1;
|
|
grenade->s.sound = gi.soundindex("weapons/hgrenc1b.wav");
|
|
|
|
//safe_cprintf(self, PRINT_HIGH, "FLASH!\n");
|
|
|
|
if (timer <= 0.0)
|
|
GenericGrenade_Explode (grenade);
|
|
else
|
|
{
|
|
gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/hgrent1a.wav"), 1, ATTN_NORM, 0);
|
|
gi.linkentity (grenade);
|
|
}
|
|
}
|