260 lines
6.3 KiB
C
260 lines
6.3 KiB
C
#include "g_local.h"
|
|
/*
|
|
==========================
|
|
Mega Chaingun
|
|
==========================
|
|
*/
|
|
/*
|
|
|
|
Gregg put this code in client think At the very end
|
|
if(ent->cantmove)
|
|
VectorCopy(ent->LockedPosition,ent->s.origin);
|
|
|
|
Alright also make this use shells
|
|
*/
|
|
void fire_ChainBlast(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread)
|
|
{
|
|
trace_t tr;
|
|
vec3_t dir;
|
|
vec3_t forward, right, up;
|
|
vec3_t end;
|
|
float r;
|
|
float ran;
|
|
float u;
|
|
float adjustedkick;
|
|
vec3_t water_start;
|
|
qboolean water = false;
|
|
int content_mask = MASK_SHOT | MASK_WATER;
|
|
vec3_t distance;
|
|
int dist;
|
|
|
|
tr = gi.trace (self->s.origin, NULL, NULL, start, self, MASK_SHOT);
|
|
if (!(tr.fraction < 1.0))
|
|
{
|
|
vectoangles (aimdir, dir);
|
|
AngleVectors (dir, forward, right, up);
|
|
|
|
r = crandom()*hspread;
|
|
u = crandom()*vspread;
|
|
VectorMA (start, 8192, forward, end);
|
|
VectorMA (end, r, right, end);
|
|
VectorMA (end, u, up, end);
|
|
|
|
if (gi.pointcontents (start) & MASK_WATER)
|
|
{
|
|
water = true;
|
|
VectorCopy (start, water_start);
|
|
content_mask &= ~MASK_WATER;
|
|
}
|
|
|
|
tr = gi.trace (start, NULL, NULL, end, self, content_mask);
|
|
}
|
|
|
|
// send gun puff / flash
|
|
if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
|
|
{
|
|
if (tr.fraction < 1.0)
|
|
{
|
|
if (tr.ent->takedamage)
|
|
{
|
|
//Push or kick is dependant on distance
|
|
distance[0] = tr.ent->s.origin[0] - self->s.origin[0];
|
|
distance[1] = tr.ent->s.origin[1] - self->s.origin[1];
|
|
distance[2] = tr.ent->s.origin[2] - self->s.origin[2];
|
|
dist=VectorLength(distance);
|
|
|
|
if (dist < 200)
|
|
adjustedkick = kick;
|
|
else if (dist < 350)
|
|
adjustedkick = 10;
|
|
else
|
|
adjustedkick = 5;
|
|
|
|
|
|
if (tr.ent->wf_team == self->wf_team)
|
|
T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, damage, DAMAGE_BULLET, MOD_MEGACHAINGUN);
|
|
else
|
|
T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, (int)adjustedkick, DAMAGE_BULLET, MOD_MEGACHAINGUN);
|
|
}
|
|
// else
|
|
// {
|
|
// if (strncmp (tr.surface->name, "sky", 3) != 0)
|
|
// {
|
|
// if (self->client)
|
|
// PlayerNoise(self, tr.endpos, PNOISE_IMPACT);
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
ran = random();
|
|
if(ran<0.1)//Well this is for shots that somehow misfire
|
|
{
|
|
gi.WriteByte (svc_temp_entity);
|
|
gi.WriteByte (TE_BUBBLETRAIL);
|
|
gi.WritePosition (start);
|
|
gi.WritePosition (tr.endpos);
|
|
gi.multicast (start, MULTICAST_PVS);
|
|
|
|
gi.WriteByte (svc_temp_entity);
|
|
gi.WriteByte (TE_GUNSHOT);
|
|
gi.WritePosition (tr.endpos);
|
|
gi.WriteDir (tr.plane.normal);
|
|
gi.multicast (tr.endpos, MULTICAST_PVS);
|
|
|
|
}
|
|
|
|
}
|
|
void MegaChaingun_Fire (edict_t *ent)
|
|
{
|
|
int i;
|
|
int shots;
|
|
vec3_t start;
|
|
vec3_t forward, right, up;
|
|
float r, u;
|
|
vec3_t offset;
|
|
int damage;
|
|
|
|
int kick = 20;
|
|
|
|
if (!ent->groundentity && !ent->cantmove)
|
|
{
|
|
ent->client->ps.gunframe = 32;
|
|
|
|
safe_cprintf (ent, PRINT_HIGH, "Must be on the ground to fire. \n");
|
|
ent->cantmove = 0;
|
|
ent->client->weapon_sound = 0;
|
|
return;
|
|
}
|
|
|
|
damage = wf_game.weapon_damage[WEAPON_MEGACHAINGUN];
|
|
|
|
if (ent->client->ps.gunframe == 5)
|
|
{
|
|
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);
|
|
VectorCopy(ent->s.origin,ent->LockedPosition);
|
|
ent->cantmove=1;
|
|
}
|
|
|
|
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK))
|
|
{
|
|
ent->client->ps.gunframe = 32;
|
|
ent->cantmove = 0;
|
|
ent->client->weapon_sound = 0;
|
|
return;
|
|
}
|
|
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTON_ATTACK)
|
|
&& ent->client->pers.inventory[ent->client->ammo_index])
|
|
{
|
|
ent->client->ps.gunframe = 15;
|
|
}
|
|
else
|
|
{
|
|
ent->client->ps.gunframe++;
|
|
}
|
|
|
|
if (ent->client->ps.gunframe == 22)
|
|
{
|
|
ent->client->weapon_sound = 0;
|
|
ent->cantmove = 0;
|
|
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnd1a.wav"), 1, ATTN_IDLE, 0);
|
|
}
|
|
else
|
|
{
|
|
ent->client->weapon_sound = gi.soundindex("weapons/chngnl1a.wav");
|
|
}
|
|
|
|
if (ent->client->ps.gunframe <= 9)
|
|
shots = 1;
|
|
else if (ent->client->ps.gunframe <= 14)
|
|
{
|
|
if (ent->client->buttons & BUTTON_ATTACK)
|
|
shots = 1;
|
|
else
|
|
shots = 1;
|
|
}
|
|
else
|
|
shots = 2;
|
|
|
|
if (ent->client->pers.inventory[ent->client->ammo_index] < shots)
|
|
shots = ent->client->pers.inventory[ent->client->ammo_index];
|
|
|
|
if (!shots)
|
|
{
|
|
if (level.time >= ent->pain_debounce_time)
|
|
{
|
|
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
|
|
ent->pain_debounce_time = level.time + 1;
|
|
}
|
|
NoAmmoWeaponChange (ent);
|
|
return;
|
|
}
|
|
|
|
if (is_quad)
|
|
{
|
|
damage *= 4;
|
|
kick *= 4;
|
|
}
|
|
|
|
for (i=0 ; i<3 ; i++)
|
|
{
|
|
ent->client->kick_origin[i] = crandom() * 0.35;
|
|
ent->client->kick_angles[i] = crandom() * 0.7;
|
|
}
|
|
|
|
for (i=0 ; i<shots ; i++)
|
|
{
|
|
// get start / end positions
|
|
AngleVectors (ent->client->v_angle, forward, right, up);
|
|
r = 7 + crandom()*4;
|
|
u = crandom()*4;
|
|
VectorSet(offset, 0, r, u + ent->viewheight-8);
|
|
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
|
|
//WF JR LAG fixing in case lag gets high
|
|
//Hopefully this will help during a fierce battle and the
|
|
//ping times rocket up
|
|
if (ent->client->ping >550)
|
|
{
|
|
fire_ChainBlast(ent, start, forward, damage*2, kick, 450, 450);
|
|
fire_ChainBlast(ent, start, forward, damage*2, kick, 450, 450);
|
|
}
|
|
else
|
|
{
|
|
fire_ChainBlast(ent, start, forward, damage, kick, 500, 500);
|
|
fire_ChainBlast(ent, start, forward, damage, kick, 500, 500);
|
|
fire_ChainBlast(ent, start, forward, damage, kick, 500, 500);
|
|
fire_ChainBlast(ent, start, forward, damage, kick, 500, 500);
|
|
}
|
|
//end lag
|
|
}
|
|
//WF
|
|
//Send a tracer bullet
|
|
//if ((shots == 3) && (random() < .16))
|
|
//{
|
|
// fire_blaster (ent, start, forward, 0, 1000, EF_HYPERBLASTER, true);
|
|
//}
|
|
//WF
|
|
// send muzzle flash
|
|
gi.WriteByte (svc_muzzleflash);
|
|
gi.WriteShort (ent-g_edicts);
|
|
gi.WriteByte ((MZ_CHAINGUN1 + shots - 1) | is_silenced);
|
|
gi.multicast (ent->s.origin, MULTICAST_PVS);
|
|
|
|
PlayerNoise(ent, start, PNOISE_WEAPON);
|
|
|
|
if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
|
|
{
|
|
// TeT we do fire four bullets per shot
|
|
//ent->client->pers.inventory[ent->client->ammo_index] -= (shots * 3);
|
|
ent->client->pers.inventory[ent->client->ammo_index] -= (int)(shots * 1.5);
|
|
}
|
|
}
|
|
|
|
|
|
void Weapon_MegaChaingun (edict_t *ent)
|
|
{
|
|
static int pause_frames[] = {38, 43, 51, 61, 0};
|
|
static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0};
|
|
|
|
Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, MegaChaingun_Fire);
|
|
} |