q2wf-portable/wf_flash.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);
}
}