212 lines
6.3 KiB
C
212 lines
6.3 KiB
C
|
#include "g_local.h"
|
||
|
void stick(edict_t *projectile, edict_t *object);
|
||
|
/*Shelton: Enemy disguised spies are purposely not safe from fire damage. Flare ammo cost
|
||
|
not changed, but should be, also, flare limit not invoked, but should be discussed (Im thinking
|
||
|
3 or 4). Flares last roughly 5 seconds from fire time to burnout. */
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
Flare Gun
|
||
|
================
|
||
|
*/
|
||
|
|
||
|
void flare2_explode (edict_t *ent)
|
||
|
{
|
||
|
G_FreeEdict (ent);
|
||
|
//Shelton: remove flare entity, no explosion, just burn out.
|
||
|
}
|
||
|
|
||
|
void flaregun2_sticky_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||
|
{
|
||
|
//Shelton: Sticky code taken from Snipers Flare.
|
||
|
|
||
|
if (other == ent->owner)
|
||
|
return;
|
||
|
|
||
|
if (other->wf_team == ent->wf_team)
|
||
|
return;
|
||
|
|
||
|
if (surf && (surf->flags & SURF_SKY))
|
||
|
{
|
||
|
G_FreeEdict (ent);
|
||
|
return;
|
||
|
}
|
||
|
//Shelton: Flare set to bounce off of owner & team. Remove if hits sky.
|
||
|
|
||
|
stick(ent, other);
|
||
|
//Shelton: otherwise stick it.
|
||
|
|
||
|
ent->s.effects |= EF_TELEPORTER;
|
||
|
|
||
|
if (other->takedamage)
|
||
|
{
|
||
|
burn_person(other, ent->owner, 10, MOD_FLAREGUN);
|
||
|
ent->think = flare2_explode;
|
||
|
}
|
||
|
/*Shelton: Direct hit on enemy, light em up. Flare continues to be stuck in victim
|
||
|
until nextthink occurs. During that time, other enemies may be burned too */
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
//Shelton: stick to wall, play sound.. etc.
|
||
|
}
|
||
|
|
||
|
static void mod_Flare2Think(edict_t *ent)
|
||
|
{
|
||
|
edict_t *blip = NULL;
|
||
|
|
||
|
if(ent->delay < level.time)
|
||
|
{
|
||
|
ent->think = flare2_explode;
|
||
|
}
|
||
|
//Shelton: flare timeout occurs, destroy flare.
|
||
|
while ((blip = findradius(blip, ent->s.origin, 100)) != NULL)
|
||
|
{
|
||
|
if (!(blip->svflags & SVF_MONSTER) && !blip->client)
|
||
|
continue;
|
||
|
if (!visible(ent, blip))
|
||
|
continue;
|
||
|
if (blip->health <= 0)
|
||
|
continue;
|
||
|
if (!blip->takedamage)
|
||
|
continue;
|
||
|
if (blip->wf_team != ent->wf_team)
|
||
|
burn_person(blip, ent->owner, 3, MOD_FLAREGUN);
|
||
|
continue;
|
||
|
if (blip->wf_team == ent->wf_team)
|
||
|
continue;
|
||
|
break;
|
||
|
}
|
||
|
//Shelton: blip for enemies to burn in radius, ignore team. Burn spies.
|
||
|
|
||
|
ent->nextthink = level.time + .1;
|
||
|
}
|
||
|
|
||
|
void fire_burningflare2(edict_t *self, vec3_t start, vec3_t dir, vec3_t los, int damage, int speed,
|
||
|
float damage_radius, int radius_damage)
|
||
|
{
|
||
|
edict_t *rocket;
|
||
|
|
||
|
rocket = G_Spawn();
|
||
|
|
||
|
VectorCopy (los, rocket->pos1); /*Added: Save the line of sight of the center rocket. This is
|
||
|
the axis around which the other two rockets rotate*/
|
||
|
VectorCopy (start, rocket->pos2); /*Added: Save the start position of the rocket (Not sure if
|
||
|
this is necessary. This info might already be somewhere else)?*/
|
||
|
|
||
|
VectorCopy (start, rocket->s.origin);
|
||
|
VectorCopy (dir, rocket->movedir);
|
||
|
vectoangles (dir, rocket->s.angles);
|
||
|
VectorScale (dir, speed, rocket->velocity);
|
||
|
rocket->movetype = MOVETYPE_TOSS;
|
||
|
rocket->clipmask = MASK_SHOT;
|
||
|
rocket->solid = SOLID_BBOX;
|
||
|
rocket->s.effects |= EF_ROCKET;
|
||
|
VectorClear (rocket->mins);
|
||
|
VectorClear (rocket->maxs);
|
||
|
rocket->s.modelindex = gi.modelindex ("models/objects/flarep/tris.md2");
|
||
|
rocket->owner = self;
|
||
|
rocket->touch = flaregun2_sticky_touch;
|
||
|
rocket->gravity = .4;
|
||
|
rocket->nextthink = level.time + 3;
|
||
|
rocket->think = mod_Flare2Think;
|
||
|
rocket->dmg = 0;
|
||
|
rocket->delay = level.time + 5;
|
||
|
rocket->radius_dmg = 0;
|
||
|
rocket->dmg_radius = 0;
|
||
|
rocket->s.sound = gi.soundindex ("weapons/rockfly.wav");
|
||
|
rocket->wf_team = self->wf_team;
|
||
|
if (self->client)
|
||
|
check_dodge (self, rocket->s.origin, dir, speed);
|
||
|
|
||
|
gi.linkentity (rocket);
|
||
|
}
|
||
|
|
||
|
/*Shelton: rocket settings slighly altered. Old flare firing method changed to straight shot.
|
||
|
However, it's current trajectory is a bit off, and I don't know how to fix that */
|
||
|
|
||
|
void Weapon_FlareGun2_Fire (edict_t *ent)
|
||
|
{
|
||
|
vec3_t offset, start;
|
||
|
vec3_t forward, right;
|
||
|
vec3_t traj_angle, lineofsight; /*Added: Trajectory angle of rocket and line of sight for the center rocket*/
|
||
|
int startspeed; /*Added: Start speed of the rockets*/
|
||
|
|
||
|
int damage;
|
||
|
float damage_radius;
|
||
|
int radius_damage;
|
||
|
|
||
|
startspeed = wf_game.weapon_speed[WEAPON_FLAREGUN];
|
||
|
|
||
|
damage = 0;
|
||
|
radius_damage = 0;
|
||
|
damage_radius = 0;
|
||
|
|
||
|
//Shelton: removed direct damage. All damage comes from burn_person().
|
||
|
AngleVectors (ent->client->v_angle, forward, right, NULL);
|
||
|
VectorScale (forward, 0, ent->client->kick_origin);
|
||
|
ent->client->kick_angles[0] = -1;
|
||
|
|
||
|
/*Added: Start of modified launcher code*/
|
||
|
VectorCopy(forward, lineofsight); /*our line of sight is the same as our forward view vector*/
|
||
|
VectorCopy(ent->client->v_angle, traj_angle); /*get the trajectory angles for later modification*/
|
||
|
/*This is the original launch code*/
|
||
|
VectorSet(offset, 8, 8, ent->viewheight-8);
|
||
|
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
|
||
|
/*Added: Now, modify the trajectory of the second rocket to 5 degrees off of the center axis*/
|
||
|
traj_angle[1] = ent->client->v_angle[1]+5;
|
||
|
AngleVectors (traj_angle, forward, right, NULL);
|
||
|
|
||
|
VectorSet(offset, 8, 8, ent->viewheight-8);
|
||
|
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
|
||
|
fire_burningflare2 (ent, start, forward, lineofsight, damage, startspeed, damage_radius, radius_damage);
|
||
|
|
||
|
// send muzzle flash
|
||
|
gi.WriteByte (svc_muzzleflash);
|
||
|
gi.WriteShort (ent-g_edicts);
|
||
|
gi.WriteByte (MZ_ROCKET | is_silenced);
|
||
|
gi.multicast (ent->s.origin, MULTICAST_PVS);
|
||
|
|
||
|
ent->client->ps.gunframe++;
|
||
|
// ### Hentai ### BEGIN
|
||
|
/*
|
||
|
ent->client->anim_priority = ANIM_ATTACK;
|
||
|
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||
|
{
|
||
|
ent->s.frame = FRAME_crattak1 - 1;
|
||
|
ent->client->anim_end = FRAME_crattak9;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ent->s.frame = FRAME_attack1 - 1;
|
||
|
ent->client->anim_end = FRAME_attack8;
|
||
|
}
|
||
|
|
||
|
// ### Hentai ### END
|
||
|
*/
|
||
|
PlayerNoise(ent, start, PNOISE_WEAPON);
|
||
|
|
||
|
//Reduce ammo
|
||
|
if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
|
||
|
ent->client->pers.inventory[ent->client->ammo_index] -= 6;
|
||
|
}
|
||
|
void Weapon_FlareGun2 (edict_t *ent)
|
||
|
{
|
||
|
static int pause_frames[] = {9,32, 0};
|
||
|
static int fire_frames[] = {9, 0};
|
||
|
|
||
|
Weapon_Generic (ent,5, 9, 31, 36, pause_frames, fire_frames, Weapon_FlareGun2_Fire);
|
||
|
}
|