kingpin-sdk/gamesrc/P_WEAPON.C
2000-03-27 00:00:00 +00:00

3235 lines
85 KiB
C

// g_weapon.c
#include "g_local.h"
#include "m_player.h"
static qboolean is_quad;
// RAFAEL
static qboolean is_quadfire;
static byte is_silenced;
void weapon_grenade_fire (edict_t *ent, qboolean held);
// RAFAEL
void weapon_trap_fire (edict_t *ent, qboolean held);
static void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result)
{
vec3_t _distance;
VectorCopy (distance, _distance);
if (client->pers.hand == LEFT_HANDED)
_distance[1] *= -1;
else if (client->pers.hand == CENTER_HANDED)
_distance[1] = 0;
G_ProjectSource (point, _distance, forward, right, result);
}
/*
===============
PlayerNoise
Each player can have two noise objects associated with it:
a personal noise (jumping, pain, weapon firing), and a weapon
target noise (bullet wall impacts)
Monsters that don't directly see the player can move
to a noise in hopes of seeing the player from there.
===============
*/
void PlayerNoise(edict_t *who, vec3_t where, int type)
{
if (deathmatch->value && type != PNOISE_WEAPON)
return;
VectorCopy( who->s.origin, who->noise_pos );
who->noise_time = level.time + 2;
who->noise_type = type;
VectorCopy( who->s.angles, who->noise_angles );
}
#define MAX_PISTOL_ROUNDS 10
#define MAX_TOMMYGUN_ROUNDS 50
#define MAX_SHOTGUN_ROUNDS 8
#define MAX_BARMACHINEGUN_ROUNDS 30
#define MAX_GRENADELAUNCHER_ROUNDS 3
#define MAX_ROCKETLAUNCHER_ROUNDS 5
#define MAX_FLAMEGUN_ROUNDS 50
// this is here so we can simplify the auto-reload code. it's in the same order as clip_t
int auto_rounds[] =
{
0,
MAX_PISTOL_ROUNDS,
MAX_SHOTGUN_ROUNDS,
MAX_TOMMYGUN_ROUNDS,
MAX_BARMACHINEGUN_ROUNDS,
MAX_GRENADELAUNCHER_ROUNDS,
MAX_ROCKETLAUNCHER_ROUNDS,
//MAX_FLAMEGUN_ROUNDS,
0
};
int QweryClipIndex (gitem_t *item);
void AutoLoadWeapon( gclient_t *client, gitem_t *weapon, gitem_t *ammo )
{
int clip_index;
int ammo_index;
if (((clip_index = QweryClipIndex( weapon )) != CLIP_NONE) && !(client->pers.weapon_clip[clip_index]))
{
ammo_index = ITEM_INDEX(ammo);
if (client->pers.inventory[ammo_index] >= auto_rounds[clip_index])
{
client->pers.weapon_clip[clip_index] = auto_rounds[clip_index];
client->pers.inventory[ammo_index] -= auto_rounds[clip_index];
}
else // not quite enough ammo, so just load all ammo
{
client->pers.weapon_clip[clip_index] = client->pers.inventory[ammo_index];
client->pers.inventory[ammo_index] = 0;
}
}
}
qboolean Pickup_Weapon (edict_t *ent, edict_t *other)
{
int index;
gitem_t *ammo;
int auto_reload=false;
index = ITEM_INDEX(ent->item);
if ( ( ((int)(dmflags->value) & DF_WEAPONS_STAY) || coop->value)
&& other->client->pers.inventory[index])
{
if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM) ) )
return false; // leave the weapon for others to pickup
}
// Ridah, start with gun loaded
if (!(other->client->pers.inventory[index]))
auto_reload = true;
//other->client->pers.inventory[index]++;
other->client->pers.inventory[index] = 1;
if (ent->item->ammo && !(ent->spawnflags & DROPPED_ITEM) )
{
// give them some ammo with it
ammo = FindItem (ent->item->ammo);
if ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value )
Add_Ammo (other, ammo, 1000);
else
Add_Ammo (other, ammo, ammo->quantity);
if (auto_reload)
AutoLoadWeapon( other->client, ent->item, ammo );
if (! (ent->spawnflags & DROPPED_PLAYER_ITEM) )
{
if (deathmatch->value)
{
if ((int)(dmflags->value) & DF_WEAPONS_STAY)
ent->flags |= FL_RESPAWN;
else
SetRespawn (ent, 30);
}
if (coop->value)
ent->flags |= FL_RESPAWN;
}
}
else if (!(strcmp (ent->classname, "weapon_crowbar")))
{
if (! (ent->spawnflags & DROPPED_PLAYER_ITEM) )
{
if (deathmatch->value)
{
if ((int)(dmflags->value) & DF_WEAPONS_STAY)
ent->flags |= FL_RESPAWN;
else
SetRespawn (ent, 30);
}
if (coop->value)
ent->flags |= FL_RESPAWN;
}
}
if (other->client->pers.weapon == FindItem ("SPistol"))
other->client->pers.silencer_shots = 20;
/*
if (other->client->pers.weapon != ent->item &&
(other->client->pers.inventory[index] == 1) &&
( !deathmatch->value || other->client->pers.weapon == FindItem("Pipe") ) )
other->client->newweapon = ent->item;
*/
if (deathmatch->value)
{
if (other->client->pers.weapon != ent->item && auto_reload && (other->client->pers.weapon == FindItem ("Pistol") || other->client->pers.weapon == FindItem ("Pipe") ))
other->client->newweapon = ent->item;
}
else
{
if (other->client->pers.weapon != ent->item && auto_reload)
other->client->newweapon = ent->item;
}
return true;
}
/*
Change Clip Index
*/
void ChangeClipIndex (edict_t *ent)
{
if (!strcmp(ent->client->pers.weapon->pickup_name, "Pipe"))
ent->client->clip_index = CLIP_NONE;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Crowbar"))
ent->client->clip_index = CLIP_NONE;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Pistol"))
ent->client->clip_index = CLIP_PISTOL;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "SPistol"))
ent->client->clip_index = CLIP_PISTOL;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Shotgun"))
ent->client->clip_index = CLIP_SHOTGUN;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Tommygun"))
ent->client->clip_index = CLIP_TOMMYGUN;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "FlameThrower"))
ent->client->clip_index = CLIP_FLAMEGUN;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Bazooka"))
ent->client->clip_index = CLIP_ROCKETS;
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Grenade Launcher"))
ent->client->clip_index = CLIP_GRENADES;
// JOSEPH 16-APR-99
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Heavy machinegun"))
ent->client->clip_index = CLIP_SLUGS;
// END JOSEPH
}
int QweryClipIndex (gitem_t *item)
{
if (!strcmp(item->pickup_name, "Pipe"))
return CLIP_NONE;
else if (!strcmp(item->pickup_name, "Crowbar"))
return CLIP_NONE;
else if (!strcmp(item->pickup_name, "Pistol"))
return CLIP_PISTOL;
else if (!strcmp(item->pickup_name, "SPistol"))
return CLIP_PISTOL;
else if (!strcmp(item->pickup_name, "Shotgun"))
return CLIP_SHOTGUN;
else if (!strcmp(item->pickup_name, "Tommygun"))
return CLIP_TOMMYGUN;
else if (!strcmp(item->pickup_name, "FlameThrower"))
return CLIP_FLAMEGUN;
else if (!strcmp(item->pickup_name, "Bazooka"))
return CLIP_ROCKETS;
else if (!strcmp(item->pickup_name, "Grenade Launcher"))
return CLIP_GRENADES;
// JOSEPH 16-APR-99
else if (!strcmp(item->pickup_name, "Heavy machinegun"))
return CLIP_SLUGS;
// END JOSEPH
return (0);
}
/*
===============
ChangeWeapon
The old weapon has been dropped all the way, so make the new one
current
===============
*/
void ChangeWeapon (edict_t *ent)
{
int i;
if (ent->client->grenade_time)
{
ent->client->grenade_time = level.time;
ent->client->weapon_sound = 0;
weapon_grenade_fire (ent, false);
ent->client->grenade_time = 0;
}
ent->client->pers.lastweapon = ent->client->pers.weapon;
ent->client->pers.weapon = ent->client->newweapon;
ent->client->newweapon = NULL;
ent->client->machinegun_shots = 0;
// set visible model
if (ent->s.modelindex == 255) {
if (ent->client->pers.weapon)
i = (((QweryClipIndex(ent->client->pers.weapon)+1) & 0xff) << 8);
else
i = 0;
ent->s.skinnum = (ent - g_edicts - 1) | i;
}
if (ent->client->pers.weapon && ent->client->pers.weapon->ammo)
ent->client->ammo_index = ITEM_INDEX(FindItem(ent->client->pers.weapon->ammo));
else
ent->client->ammo_index = 0;
if (!ent->client->pers.weapon)
{ // dead
ent->client->ps.gunindex = 0;
return;
}
ent->client->weaponstate = WEAPON_ACTIVATING;
ent->client->ps.gunframe = 0;
// ent->client->flashlight = false;
// RAFAEL 28-dec-98
ent->client->gun_noise = false;
if (ent->client->pers.weapon)
ChangeClipIndex (ent);
{
int i;
if (!strcmp (ent->client->pers.weapon->pickup_name , "SPistol"))
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
ent->client->ps.gunindex = gi.modelindex("models/weapons/silencer_mdx/magnum.mdx");
else
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
}
else if (!strcmp (ent->client->pers.weapon->pickup_name , "Pistol"))
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
ent->client->ps.gunindex = gi.modelindex("models/weapons/v_colt/magnum.mdx");
else
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
}
else if (!strcmp (ent->client->pers.weapon->pickup_name, "Shotgun"))
ent->client->ps.gunindex = gi.modelindex("models/weapons/shotgun/shotgun.mdx");
else if (!strcmp (ent->client->pers.weapon->pickup_name, "Heavy machinegun"))
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_COOLING_JACKET)
ent->client->ps.gunindex = gi.modelindex("models/weapons/v_hmgcool/hmgcool.mdx");
else
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
}
else
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
memset(&(ent->client->ps.model_parts[0]), 0, sizeof(model_part_t) * MAX_MODEL_PARTS);
ent->client->ps.num_parts = 0;
ent->client->ps.num_parts++;
// ent->client->ps.model_parts[PART_HEAD].modelindex = gi.modelindex(ent->client->pers.weapon->view_model);
ent->client->ps.model_parts[PART_HEAD].modelindex = ent->client->ps.gunindex;//gi.modelindex(ent->client->pers.weapon->view_model);
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_HEAD].skinnum[i] = 0; // will we have more than one skin???
// HACK, set arm model
if (!strcmp(ent->client->pers.weapon->pickup_name, "Shotgun"))
{
// Ridah, HACK: changed this to use PART_LEGS, since PART_BODY sometimes doesn't show up
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/shotgun/hand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
}
// JOSEPH 12-OCT-98
// JOSEPH 5-FEB-99-B
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Pipe"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/blakjak/hand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
}
// END JOSEPH
// JOSEPH 19-JAN-99
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Crowbar"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/crowbar/hand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
}
// END JOSEPH
else if (!strcmp(ent->client->pers.weapon->pickup_name, "FlameThrower"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/v_flamegun/hand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
}
// END JOSEPH
// JOSEPH 4-MAR-99
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Bazooka"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/v_rocket_launcher/hand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/v_rocket_launcher/shell_a.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
// note to self: not using this anymore
/*
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_GUN].modelindex = gi.modelindex("models/weapons/v_rocket_launcher/shell_b.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_GUN].skinnum[i] = 0; // will we have more than one skin???
*/
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_GUN2].modelindex = gi.modelindex("models/weapons/v_rocket_launcher/clip.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_GUN2].skinnum[i] = 0; // will we have more than one skin???
}
// END JOSEPH
else if (!strcmp (ent->client->pers.weapon->pickup_name , "SPistol"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/silencer_mdx/handl.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/silencer_mdx/handr.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_GUN].modelindex = gi.modelindex("models/weapons/silencer_mdx/clip.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_GUN].skinnum[i] = 0;
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
}
else if (!strcmp (ent->client->pers.weapon->pickup_name , "Pistol"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/v_colt/handl.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/v_colt/handr.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_GUN].modelindex = gi.modelindex("models/weapons/v_colt/clip.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_GUN].skinnum[i] = 0;
}
else if (!strcmp(ent->client->pers.weapon->pickup_name, "Tommygun"))
{
// Ridah, hacked this, we're still having disappearing hands after going from the Pistol ?!
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_CIGAR].modelindex = gi.modelindex("models/weapons/v_tomgun/lhand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_CIGAR].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/v_tomgun/rhand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
}
// JOSEPH 16-APR-99
else if (!strcmp (ent->client->pers.weapon->pickup_name , "Heavy machinegun"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/v_hmg/lhand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/v_hmg/clip.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
}
// END JOSEPH
else if (!strcmp (ent->client->pers.weapon->pickup_name , "Grenade Launcher"))
{
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_LEGS].modelindex = gi.modelindex("models/weapons/v_grenade_launcher/lhand.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_LEGS].skinnum[i] = 0; // will we have more than one skin???
ent->client->ps.num_parts++;
ent->client->ps.model_parts[PART_BODY].modelindex = gi.modelindex("models/weapons/v_grenade_launcher/clip.mdx");
for (i=0; i<MAX_MODELPART_OBJECTS; i++)
ent->client->ps.model_parts[PART_BODY].skinnum[i] = 0; // will we have more than one skin???
}
}
// ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
#if 0
ent->client->anim_priority = ANIM_PAIN;
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
int rnd;
rnd = rand()%3;
if (rnd==0)
{
ent->s.frame = FRAME_crouch_pain1_01;
ent->client->anim_end = FRAME_crouch_pain1_08;
}
else if (rnd==1)
{
ent->s.frame = FRAME_crouch_pain2_01;
ent->client->anim_end = FRAME_crouch_pain2_06;
}
else if (rnd==2)
{
ent->s.frame = FRAME_crouch_pain3_01;
ent->client->anim_end = FRAME_crouch_pain3_06;
}
}
else
{
int rnd;
/*
rnd = rand()%3;
if (rnd==0)
{
ent->s.frame = FRAME_pain1_01;
ent->client->anim_end = FRAME_pain1_05;
}
else if (rnd==1)
{
ent->s.frame = FRAME_pain2_01;
ent->client->anim_end = FRAME_pain2_05;
}
else if (rnd==2)
{
ent->s.frame = FRAME_pain3_01;
ent->client->anim_end = FRAME_pain3_05;
}
*/
rnd = rand()%6;
switch (rnd)
{
case 0:
ent->s.frame = FRAME_pain_Rarm_01;
ent->client->anim_end = FRAME_pain_Rarm_10;
break;
case 1:
ent->s.frame = FRAME_pain_Larm_01;
ent->client->anim_end = FRAME_pain_Larm_09;
break;
case 2:
ent->s.frame = FRAME_pain_chest_01;
ent->client->anim_end = FRAME_pain_chest_09;
break;
case 3:
ent->s.frame = FRAME_pain_head_01;
ent->client->anim_end = FRAME_pain_head_10;
break;
case 4:
ent->s.frame = FRAME_pain_Rleg_01;
ent->client->anim_end = FRAME_pain_Rleg_10;
break;
case 5:
ent->s.frame = FRAME_pain_Lleg_01;
ent->client->anim_end = FRAME_pain_Lleg_08;
break;
}
}
#endif
}
/*
=================
NoAmmoWeaponChange
=================
*/
void NoAmmoWeaponChange (edict_t *ent)
{
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("grenades"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("grenade launcher"))] )
{
ent->client->newweapon = FindItem ("grenade launcher");
return;
}
// JOSEPH 16-APR-99
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("308cal"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("heavy machinegun"))] )
{
ent->client->newweapon = FindItem ("heavy machinegun");
return;
}
// END JOSEPH
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("gas"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("flamethrower"))] )
{
ent->client->newweapon = FindItem ("flamethrower");
return;
}
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("rockets"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("bazooka"))] )
{
ent->client->newweapon = FindItem ("Bazooka");
return;
}
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("bullets"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("tommygun"))] )
{
ent->client->newweapon = FindItem ("tommygun");
return;
}
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("shells"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("shotgun"))] )
{
ent->client->newweapon = FindItem ("shotgun");
return;
}
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("bullets"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("pistol"))] )
{
ent->client->newweapon = FindItem ("pistol");
return;
}
// JOSEPH 5-FEB-99-B
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("crowbar"))])
ent->client->newweapon = FindItem ("Crowbar");
else
ent->client->newweapon = FindItem ("Pipe");
// END JOSEPH
}
/*
Think_FlashLight
*/
void Think_FlashLight (edict_t *ent)
{
trace_t tr;
vec3_t forward;
vec3_t end;
vec3_t mins, maxs;
edict_t *light;
vec3_t angles, origin;
if (ent->health < 1)
return;
if (ent->client->flashlight)
{
VectorCopy (ent->client->v_angle, angles);
VectorCopy (ent->s.origin, origin);
AngleVectors (angles, forward, NULL, NULL);
VectorCopy (origin, end);
VectorMA (end, 8194, forward, end);
VectorSet (mins, -8, -8, -8 );
VectorSet (maxs, 8, 8, 8);
tr = gi.trace (ent->s.origin, mins, maxs, end, ent, MASK_SHOT);
if (((tr.ent) && (tr.ent->s.renderfx2 & RF2_SURF_ALPHA)) || ((tr.contents & MASK_ALPHA)))
{
vec3_t start;
VectorCopy (tr.endpos, start);
VectorMA (start, 8, forward, start);
tr = gi.trace (start, mins, maxs, end, ent, MASK_SHOT);
}
light = G_Spawn();
VectorCopy (tr.endpos, light->s.origin);
light->s.renderfx |= RF_BEAM;
light->s.effects |= EF_FLASHLIGHT;
light->nextthink = level.time + 0.1;
light->think = G_FreeEdict;
gi.linkentity (light);
}
}
/*
=================
Think_Weapon
Called by ClientBeginServerFrame and ClientThink
=================
*/
void Think_Weapon (edict_t *ent)
{
// make sure flamethrower is disabled when it should be
ent->s.renderfx2 &= ~RF2_FLAMETHROWER;
// if just died, put the weapon away
if (ent->health < 1)
{
ent->client->newweapon = NULL;
ChangeWeapon (ent);
}
// JOSEPH 10-FEB-99
if (level.bar_lvl)
return;
// END JOSEPH
// Unholster a holstered gun if fired
if ((!ent->client->pers.weapon) && ent->client->pers.holsteredweapon && (((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK)))
{
ent->client->newweapon = ent->client->pers.holsteredweapon;
ChangeWeapon (ent);
ent->client->pers.holsteredweapon = 0;
}
else if (ent->client->pers.weapon && ent->client->pers.weapon->weaponthink)
{
is_quad = (ent->client->quad_framenum > level.framenum);
// RAFAEL
is_quadfire = (ent->client->quadfire_framenum > level.framenum);
//if (ent->client->pers.silencer_shots)
// is_silenced = MZ_SILENCED;
//else
is_silenced = 0;
ent->client->pers.weapon->weaponthink (ent);
}
}
/*
================
Use_Weapon
Make the weapon ready if there is ammo
================
*/
void Use_Weapon (edict_t *ent, gitem_t *item)
{
int ammo_index;
gitem_t *ammo_item;
int clip_index;
// see if we're already using it
if (item == ent->client->pers.weapon)
return;
if (item->ammo && !g_select_empty->value && !(item->flags & IT_AMMO))
{
ammo_item = FindItem(item->ammo);
ammo_index = ITEM_INDEX(ammo_item);
clip_index = QweryClipIndex (item);
if (!ent->client->pers.inventory[ammo_index] && !ent->client->pers.weapon_clip [clip_index])
{
gi.cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
return;
}
/*
if (ent->client->pers.inventory[ammo_index] < item->quantity)
{
gi.cprintf (ent, PRINT_HIGH, "Not enough %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
return;
}
*/
}
// change to this weapon when down
ent->client->newweapon = item;
}
// RAFAEL 14-APR-98
void Use_Weapon2 (edict_t *ent, gitem_t *item)
{
int ammo_index;
gitem_t *ammo_item;
int index;
int clip_index;
// JOSEPH 5-FEB-99-B
if (strcmp (item->pickup_name, "Pipe") == 0)
{
// Ridah, changed this so it defaults to Crowbar if we have it
if (ent->client->pers.weapon != FindItem ("Crowbar"))
{
item = FindItem ("Crowbar");
index = ITEM_INDEX (item);
if (!ent->client->pers.inventory[index])
{
item = FindItem ("Pipe");
}
}
}
// END JOSEPH
else if (strcmp (item->pickup_name, "Pistol") == 0)
{
if (item == ent->client->pers.weapon)
{
item = FindItem ("SPistol");
index = ITEM_INDEX (item);
if (!ent->client->pers.inventory[index])
{
item = FindItem ("Pistol");
}
}
}
// see if we're already using it
if (item == ent->client->pers.weapon)
return;
if (item->ammo)
{
ammo_item = FindItem(item->ammo);
ammo_index = ITEM_INDEX(ammo_item);
clip_index = QweryClipIndex (item);
if (!ent->client->pers.inventory[ammo_index] && !g_select_empty->value && !ent->client->pers.weapon_clip [clip_index])
{
gi.cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
return;
}
}
// change to this weapon when down
ent->client->newweapon = item;
}
// END 14-APR-98
/*
================
Drop_Weapon
================
*/
void Drop_Weapon (edict_t *ent, gitem_t *item)
{
int index;
if ((int)(dmflags->value) & DF_WEAPONS_STAY)
return;
index = ITEM_INDEX(item);
// see if we're already using it
if ( ((item == ent->client->pers.weapon) || (item == ent->client->newweapon))&& (ent->client->pers.inventory[index] == 1) )
{
gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
return;
}
Drop_Item (ent, item);
ent->client->pers.inventory[index]--;
}
/*
================
Weapon_Generic
A generic function to handle the basics of weapon thinking
================
*/
#define FRAME_FIRE_FIRST (FRAME_ACTIVATE_LAST + 1)
#define FRAME_IDLE_FIRST (FRAME_FIRE_LAST + 1)
#define FRAME_DEACTIVATE_FIRST (FRAME_IDLE_LAST + 1)
#define FRAME_OFFSET_FOR_SPISTOL 43
#define FRAME_OFFSET_FOR_SPISTOL_WITH_SILENCER 70
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
{
int n;
// RAFAEL 01-11-99
if (ent->client->weaponstate == WEAPON_RELOADING_SPISTOL)
{
if (ent->client->ps.gunframe == FRAME_OFFSET_FOR_SPISTOL)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = FRAME_IDLE_FIRST;
return;
}
ent->client->ps.gunframe++;
return;
}
if (ent->client->weaponstate == WEAPON_RELOADING)
{
if (ent->client->ps.gunframe == FRAME_FIRE_LAST)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = FRAME_IDLE_FIRST;
return;
}
ent->client->ps.gunframe++;
return;
}
if (ent->client->weaponstate == WEAPON_RELOAD_CYCLE)
{
/*
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = FRAME_IDLE_FIRST;
}
else
*/
{
ent->client->ps.gunframe++;
return;
}
}
if (ent->client->weaponstate == WEAPON_DROPPING)
{
if (ent->client->pers.weapon == FindItem("SPistol"))
{
if (ent->client->pers.silencer_shots && ent->client->ps.gunframe == FRAME_OFFSET_FOR_SPISTOL_WITH_SILENCER)
{
ChangeWeapon (ent);
return;
}
if (ent->client->ps.gunframe == FRAME_DEACTIVATE_LAST)
{
ChangeWeapon (ent);
return;
}
}
else
{
if (ent->client->ps.gunframe == FRAME_DEACTIVATE_LAST)
{
ChangeWeapon (ent);
return;
}
else if ((ent->client->weaponstate != WEAPON_FIRING) && (ent->client->ps.gunframe < FRAME_DEACTIVATE_FIRST))
{
ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;
return;
}
}
/*
else if ((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4)
{
ent->client->anim_priority = ANIM_REVERSE;
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
ent->s.frame = FRAME_crpain4+1;
ent->client->anim_end = FRAME_crpain1;
}
else
{
ent->s.frame = FRAME_pain304+1;
ent->client->anim_end = FRAME_pain301;
}
}
*/
ent->client->ps.gunframe++;
// Ridah, faster weapon changing in deathmatch
if (deathmatch->value && ent->client->ps.gunframe < FRAME_DEACTIVATE_LAST)
ent->client->ps.gunframe++;
return;
}
if (ent->client->weaponstate == WEAPON_ACTIVATING)
{
if (ent->client->ps.gunframe == FRAME_ACTIVATE_LAST)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = FRAME_IDLE_FIRST;
return;
}
ent->client->ps.gunframe++;
// Ridah, faster weapon changing in deathmatch
if (deathmatch->value && ent->client->ps.gunframe < FRAME_ACTIVATE_LAST)
ent->client->ps.gunframe++;
return;
}
if ((ent->client->newweapon) /*&& (ent->client->weaponstate != WEAPON_FIRING)*/)
{
ent->client->weaponstate = WEAPON_DROPPING;
ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;
/*
if ((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4)
{
ent->client->anim_priority = ANIM_REVERSE;
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
ent->s.frame = FRAME_crpain4+1;
ent->client->anim_end = FRAME_crpain1;
}
else
{
ent->s.frame = FRAME_pain304+1;
ent->client->anim_end = FRAME_pain301;
}
}
*/
return;
}
if (ent->client->weaponstate == WEAPON_READY)
{
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
{
ent->client->latched_buttons &= ~BUTTON_ATTACK;
if (ent->client->clip_index == CLIP_PISTOL && ent->client->pers.weapon_clip[ent->client->clip_index] >= 1)
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else if (ent->client->clip_index == CLIP_SHOTGUN && ent->client->pers.weapon_clip[ent->client->clip_index] >= 1)
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else if (ent->client->clip_index == CLIP_TOMMYGUN && ent->client->pers.weapon_clip[ent->client->clip_index] >=1)
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else if (ent->client->clip_index == CLIP_SLUGS && ent->client->pers.weapon_clip[ent->client->clip_index] >=1)
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else if (ent->client->clip_index == CLIP_GRENADES && ent->client->pers.weapon_clip[ent->client->clip_index] >=1)
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else if (ent->client->clip_index == CLIP_ROCKETS && ent->client->pers.weapon_clip[ent->client->clip_index] >=1)
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else if ((!ent->client->ammo_index) ||
( ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity))
{
ent->client->ps.gunframe = FRAME_FIRE_FIRST;
ent->client->weaponstate = WEAPON_FIRING;
}
else
{
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);
}
}
else
{
if (ent->client->ps.gunframe == FRAME_IDLE_LAST)
{
ent->client->ps.gunframe = FRAME_IDLE_FIRST;
return;
}
if (pause_frames)
{
for (n = 0; pause_frames[n]; n++)
{
if (ent->client->ps.gunframe == pause_frames[n])
{
if (rand()&15)
return;
}
}
}
ent->client->ps.gunframe++;
return;
}
}
if (ent->client->weaponstate == WEAPON_FIRING)
{
for (n = 0; fire_frames[n]; n++)
{
if (ent->client->ps.gunframe == fire_frames[n])
{
if (ent->client->quad_framenum > level.framenum)
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0);
/*
if (ent->client->anim_priority <= ANIM_JUMP
&& (!ent->groundentity || (!ent->client->anim_run && !ent->client->anim_slide)))
{
// start the animation
ent->client->anim_priority = ANIM_ATTACK;
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
if (ent->s.frame != FRAME_crch_shoot_01)
ent->s.frame = FRAME_crch_shoot_01-1;
ent->client->anim_end = FRAME_crch_shoot_05;
}
else
{
if (ent->s.frame != FRAME_shoot_01)
ent->s.frame = FRAME_shoot_01-1;
ent->client->anim_end = FRAME_shoot_04;
}
}
*/
fire (ent);
break;
}
}
if (!fire_frames[n])
ent->client->ps.gunframe++;
// JOSEPH 5-FEB-99-B
// Blackjack hack
if ((ent->client->ps.gunframe == 9) &&
(!((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK)) &&
(!strcmp(ent->client->pers.weapon->pickup_name, "Pipe")))
{
ent->client->ps.gunframe = FRAME_IDLE_FIRST+1;
ent->client->weaponstate = WEAPON_READY;
}
// END JOSEPH
// JOSEPH 19-JAN-99
// Crowbar hack
else if ((ent->client->ps.gunframe == 9) &&
(!((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK)) &&
(!strcmp(ent->client->pers.weapon->pickup_name, "Crowbar")))
{
ent->client->ps.gunframe = FRAME_IDLE_FIRST+1;
ent->client->weaponstate = WEAPON_READY;
}
// END JOSEPH
if (ent->client->ps.gunframe == FRAME_IDLE_FIRST+1)
ent->client->weaponstate = WEAPON_READY;
}
}
/*
======================================================================
GRENADE
======================================================================
*/
#define GRENADE_TIMER 3.0
#define GRENADE_MINSPEED 400
#define GRENADE_MAXSPEED 800
void weapon_grenade_fire (edict_t *ent, qboolean held)
{
vec3_t offset;
vec3_t forward, right;
vec3_t start;
int damage = 125;
float timer;
int speed;
float radius;
radius = damage+40;
if (is_quad)
damage *= 4;
VectorSet(offset, 8, 8, ent->viewheight-8);
AngleVectors (ent->client->v_angle, forward, right, NULL);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
timer = ent->client->grenade_time - level.time;
speed = GRENADE_MINSPEED + (GRENADE_TIMER - timer) * ((GRENADE_MAXSPEED - GRENADE_MINSPEED) / GRENADE_TIMER);
fire_grenade2 (ent, start, forward, damage, speed, timer, radius, held);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
ent->client->pers.inventory[ent->client->ammo_index]--;
ent->client->grenade_time = level.time + 1.0;
/*
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
{
ent->client->anim_priority = ANIM_ATTACK;
ent->s.frame = FRAME_crattak1-1;
ent->client->anim_end = FRAME_crattak3;
}
else
{
ent->client->anim_priority = ANIM_REVERSE;
ent->s.frame = FRAME_wave08;
ent->client->anim_end = FRAME_wave01;
}
*/
}
void Weapon_Grenade (edict_t *ent)
{
if ((ent->client->newweapon) && (ent->client->weaponstate == WEAPON_READY))
{
ChangeWeapon (ent);
return;
}
if (ent->client->weaponstate == WEAPON_ACTIVATING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 16;
return;
}
if (ent->client->weaponstate == WEAPON_READY)
{
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
{
ent->client->latched_buttons &= ~BUTTON_ATTACK;
if (ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->ps.gunframe = 1;
ent->client->weaponstate = WEAPON_FIRING;
ent->client->grenade_time = 0;
}
else
{
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 ((ent->client->ps.gunframe == 29) || (ent->client->ps.gunframe == 34) || (ent->client->ps.gunframe == 39) || (ent->client->ps.gunframe == 48))
{
if (rand()&15)
return;
}
if (++ent->client->ps.gunframe > 48)
ent->client->ps.gunframe = 16;
return;
}
if (ent->client->weaponstate == WEAPON_FIRING)
{
if (ent->client->ps.gunframe == 5)
gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/grenade_launcher/hgrena1b.wav"), 1, ATTN_NORM, 0);
if (ent->client->ps.gunframe == 11)
{
if (!ent->client->grenade_time)
{
ent->client->grenade_time = level.time + GRENADE_TIMER + 0.2;
ent->client->weapon_sound = gi.soundindex("weapons/grenade_launcher/hgrenc1b.wav");
}
// they waited too long, detonate it in their hand
if (!ent->client->grenade_blew_up && level.time >= ent->client->grenade_time)
{
ent->client->weapon_sound = 0;
weapon_grenade_fire (ent, true);
ent->client->grenade_blew_up = true;
}
if (ent->client->buttons & BUTTON_ATTACK)
return;
if (ent->client->grenade_blew_up)
{
if (level.time >= ent->client->grenade_time)
{
ent->client->ps.gunframe = 15;
ent->client->grenade_blew_up = false;
}
else
{
return;
}
}
}
if (ent->client->ps.gunframe == 12)
{
ent->client->weapon_sound = 0;
weapon_grenade_fire (ent, false);
}
if ((ent->client->ps.gunframe == 15) && (level.time < ent->client->grenade_time))
return;
ent->client->ps.gunframe++;
if (ent->client->ps.gunframe == 16)
{
ent->client->grenade_time = 0;
ent->client->weaponstate = WEAPON_READY;
}
}
}
// JOSEPH 18-DEC-98
void Think_Eject_Shell (edict_t *ent)
{
if (!ent->misstime--)
{
ent->nextthink = 0;
G_FreeEdict(ent);
}
else
{
if (ent->misstime <= 20)
{
if (ent->misstime == 20)
{
ent->s.renderfx2 |= RF2_PASSALPHA;
ent->s.effects = 1; // this is full alpha now
}
ent->s.effects += (255/20);
if (ent->s.effects > 255)
ent->s.effects = 255;
}
// ent->s.angles[0] += ent->avelocity[0];
ent->s.angles[1] += ent->avelocity[1];
// ent->s.angles[2] += ent->avelocity[2];
ent->nextthink = level.time + 0.1;
}
}
// END JOSEPH
// JOSEPH 7-JAN-99
void Eject_Shotgun_Shell (edict_t *ent)
{
edict_t *dropped = NULL;
vec3_t forward, right, up;
vec3_t offset;
if (!(ent->client))
return;
if (deathmatch->value)
return;
//gi.dprintf("angles = %s\n", vtos(ent->s.angles));
dropped = G_Spawn();
if (!dropped)
return;
dropped->s.modelindex = gi.modelindex("models/weapons/sshell_md2/tris.md2");
dropped->movetype = MOVETYPE_BOUNCE;
dropped->mins[0] = -4;
dropped->mins[1] = -4;
dropped->mins[2] = -2;
dropped->maxs[0] = 4;
dropped->maxs[1] = 4;
dropped->maxs[2] = 4;
AngleVectors (ent->client->v_angle, forward, right, up);
dropped->s.angles[YAW] = ent->client->v_angle[YAW];
VectorSet(offset, 0, 16, ent->viewheight -2 );
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, dropped->s.origin);
VectorScale (forward, 5 + ((rand()&15)-8), dropped->velocity);
VectorMA (dropped->velocity, 50 + (rand()&31), right, dropped->velocity);
dropped->velocity[2] = 150 + (rand()&31);
// Ridah, changed this so they don't stick in the ground so much
VectorSet(dropped->avelocity, 0/*((rand()&7)-4)*/, ((rand()&15)-8), ((rand()&7)-4));
dropped->think = Think_Eject_Shell;
dropped->misstime = 40;
dropped->nextthink = level.time + 0.1;
dropped->s.renderfx2 |= RF2_NOSHADOW;
gi.linkentity (dropped);
return;
}
// END JOSEPH
//======================================================================
// JOSEPH 12-OCT-98
void Blackjack_Hit (edict_t *ent, vec3_t vorigin, int damage)
{
vec3_t start;
vec3_t forward, right;
int kick = 2;
vec3_t offset;
if (is_quad)
damage *= 4;
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 0, 0, ent->viewheight);
VectorAdd (offset, vorigin, offset);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
if (fire_blackjack (ent, start, forward, damage, kick, MOD_BLACKJACK))
ent->client->ps.weapon_usage++;
if (ent->client->ps.weapon_usage > 20)
{
ent->client->ps.rdflags &= ~RDF_SKINPLUS;
ent->client->ps.rdflags |= RDF_SKINPLUSPLUS;
}
else if (ent->client->ps.weapon_usage > 10)
ent->client->ps.rdflags |= RDF_SKINPLUS;
// PlayerNoise(ent, start, PNOISE_WEAPON);
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_BLACKJACK_SWING);
gi.multicast (ent->s.origin, MULTICAST_PVS);
}
void Weapon_Blackjack_Hit (edict_t *ent)
{
int damage;
if (deathmatch->value)
damage = 10;
else
damage = 8;// - (int)(skill->value-1);
Blackjack_Hit (ent, vec3_origin, damage);
ent->client->ps.gunframe++;
}
void Weapon_Blackjack (edict_t *ent)
{
static int pause_frames[] = {0, 0};
static int fire_frames[] = {8, 11, 0};
if (ent->client->ps.gunframe < 5)
{
ent->client->ps.rdflags &= ~RDF_SKINPLUS;
ent->client->ps.rdflags &= ~RDF_SKINPLUSPLUS;
}
Weapon_Generic (ent, 5, 13, 31, 36, pause_frames, fire_frames, Weapon_Blackjack_Hit);
ent->client->ps.model_parts[PART_BODY].invisible_objects = 0;
}
// END JOSEPH
// JOSEPH 19-JAN-99
void Crowbar_Hit (edict_t *ent, vec3_t vorigin, int damage)
{
vec3_t start;
vec3_t forward, right;
int kick = 2;
vec3_t offset;
if (is_quad)
damage *= 4;
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 0, 0, ent->viewheight);
VectorAdd (offset, vorigin, offset);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
if (fire_crowbar (ent, start, forward, damage, kick, MOD_CROWBAR))
ent->client->ps.weapon_usage++;
if (ent->client->ps.weapon_usage > 20)
{
ent->client->ps.rdflags &= ~RDF_SKINPLUS;
ent->client->ps.rdflags |= RDF_SKINPLUSPLUS;
}
else if (ent->client->ps.weapon_usage > 10)
ent->client->ps.rdflags |= RDF_SKINPLUS;
// PlayerNoise(ent, start, PNOISE_WEAPON);
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_CROWBAR_SWING);
gi.multicast (ent->s.origin, MULTICAST_PVS);
}
void Weapon_Crowbar_Hit (edict_t *ent)
{
int damage;
if (deathmatch->value)
damage = 50; // This should be very powerful in deathmatch
else
damage = 12;// - (int)(skill->value-1);
Crowbar_Hit (ent, vec3_origin, damage);
ent->client->ps.gunframe++;
}
void Weapon_Crowbar (edict_t *ent)
{
static int pause_frames[] = {0, 0};
static int fire_frames[] = {8, 11, 0};
if (ent->client->ps.gunframe < 5)
{
ent->client->ps.rdflags &= ~RDF_SKINPLUS;
ent->client->ps.rdflags &= ~RDF_SKINPLUSPLUS;
}
Weapon_Generic (ent, 5, 13, 31, 36, pause_frames, fire_frames, Weapon_Crowbar_Hit);
ent->client->ps.model_parts[PART_BODY].invisible_objects = 0;
}
// END JOSEPH
// JOSEPH 7-JAN-99
void Eject_Pistol_Shell (edict_t *ent)
{
edict_t *dropped = NULL;
vec3_t forward, right, up;
vec3_t offset;
if (!(ent->client))
return;
if (deathmatch->value)
return;
//gi.dprintf("angles = %s\n", vtos(ent->s.angles));
dropped = G_Spawn();
if (!dropped)
return;
dropped->s.modelindex = gi.modelindex("models/weapons/shell_md2/tris.md2");
dropped->movetype = MOVETYPE_BOUNCE;
dropped->mins[0] = -4;
dropped->mins[1] = -4;
dropped->mins[2] = -2;
dropped->maxs[0] = 4;
dropped->maxs[1] = 4;
dropped->maxs[2] = 4;
AngleVectors (ent->client->v_angle, forward, right, up);
dropped->s.angles[YAW] = ent->client->v_angle[YAW];
VectorSet(offset, 0, 16, ent->viewheight -2 );
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, dropped->s.origin);
VectorScale (forward, 5 + ((rand()&15)-8), dropped->velocity);
VectorMA (dropped->velocity, 50 + (rand()&31), right, dropped->velocity);
dropped->velocity[2] = 150 + (rand()&31);
// Ridah, changed this so they don't stick in the ground so much
VectorSet(dropped->avelocity, 0/*((rand()&7)-4)*/, ((rand()&15)-8), ((rand()&7)-4));
dropped->think = Think_Eject_Shell;
dropped->misstime = 40;
dropped->nextthink = level.time + 0.1;
dropped->s.renderfx2 |= RF2_NOSHADOW;
gi.linkentity (dropped);
return;
}
// JOSEPH 7-JAN-99
void Eject_Tommy_Shell (edict_t *ent)
{
edict_t *dropped = NULL;
vec3_t forward, right, up;
vec3_t offset;
if (!(ent->client))
return;
if (deathmatch->value)
return;
//gi.dprintf("angles = %s\n", vtos(ent->s.angles));
dropped = G_Spawn();
if (!dropped)
return;
dropped->s.modelindex = gi.modelindex("models/weapons/shell_md2/tris.md2");
dropped->movetype = MOVETYPE_BOUNCE;
dropped->mins[0] = -4;
dropped->mins[1] = -4;
dropped->mins[2] = -2;
dropped->maxs[0] = 4;
dropped->maxs[1] = 4;
dropped->maxs[2] = 4;
AngleVectors (ent->client->v_angle, forward, right, up);
dropped->s.angles[YAW] = ent->client->v_angle[YAW];
VectorSet(offset, 0, 16, ent->viewheight -2 );
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, dropped->s.origin);
VectorScale (forward, 5 + ((rand()&15)-8), dropped->velocity);
VectorMA (dropped->velocity, 50 + (rand()&31), right, dropped->velocity);
dropped->velocity[2] = 150 + (rand()&31);
// Ridah, changed this so they don't stick in the ground so much
VectorSet(dropped->avelocity, 0/*((rand()&7)-4)*/, ((rand()&15)-8), ((rand()&7)-4));
dropped->think = Think_Eject_Shell;
dropped->misstime = 40;
dropped->nextthink = level.time + 0.1;
dropped->s.renderfx2 |= RF2_NOSHADOW;
gi.linkentity (dropped);
return;
}
// END JOSEPH
// WEAPON PISTOL
void Pistol_Fire (edict_t *ent, vec3_t vorigin, int damage)
{
vec3_t start;
vec3_t forward, right;
int kick = 2;
vec3_t offset;
if (is_quad)
damage *= 4;
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 0, 0, ent->viewheight);
VectorAdd (offset, vorigin, offset);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
VectorScale (forward, -2, ent->client->kick_origin);
ent->client->kick_angles[0] = -4;
fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_PISTOL);
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
{
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_PISTOL_DAMAGE_MOD | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
}
else
{
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_PISTOL | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
}
PlayerNoise(ent, start, PNOISE_WEAPON);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
{
ent->client->pers.weapon_clip[ent->client->clip_index]--;
}
ent->client->gun_noise = true;
}
void Weapon_Pistol_Fire (edict_t *ent)
{
int damage;
int rounds;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 29;
}
return;
}
if (deathmatch->value)
damage = 15;
else
damage = 10;
if (ent->client->ps.gunframe == 6)
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_ROF)
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
{
damage *= 2;
}
ent->client->ps.gunframe = 8;
}
else
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
{
damage *= 2;
}
ent->client->ps.gunframe++;
}
Pistol_Fire (ent, vec3_origin, damage);
Eject_Pistol_Shell(ent);
}
else if (ent->client->ps.gunframe == 10)
{
if (!ent->client->pers.weapon_clip[ent->client->clip_index])
{
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_PISTOL_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_PISTOL_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
ent->client->ps.gunframe++;
if (ent->client->pers.pistol_mods & WEAPON_MOD_RELOAD)
;//gi.dprintf ("need fast reload sound\n");
else
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/pistol/clip_out.wav"), 1, ATTN_NORM, 0);
if (! ent->client->pers.weapon_clip[ent->client->clip_index])
{
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);
}
}
else
ent->client->ps.gunframe = 29;
}
}
void Weapon_Pistol (edict_t *ent)
{
int rounds;
//static int pause_frames[] = {46, 0, 0};
static int pause_frames[] = {0, 0, 0};
static int fire_frames[] = {6, 10, 0};
if (ent->client->reload_weapon)
{
if (ent->client->ps.gunframe >= 28 && ent->client->ps.gunframe <= 44)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_PISTOL_ROUNDS)
{
ent->client->ps.gunframe = 10;
ent->client->weaponstate = WEAPON_RELOADING;
ent->client->pers.inventory[ent->client->ammo_index] += ent->client->pers.weapon_clip[ent->client->clip_index];
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_PISTOL_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_PISTOL_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
}
ent->client->reload_weapon = false;
}
else
ent->client->reload_weapon = false;
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->pers.inventory[ent->client->ammo_index])
{
if (ent->client->ps.gunframe >= 28 && ent->client->ps.gunframe <= 44)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 10;
ent->client->weaponstate = WEAPON_RELOADING;
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_PISTOL_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_PISTOL_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
}
}
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
ent->client->ps.gunindex = gi.modelindex("models/weapons/v_colt/magnum.mdx");
Weapon_Generic (ent, 5, 28, 44, 49, pause_frames, fire_frames, Weapon_Pistol_Fire);
if (ent->client->pers.pistol_mods & WEAPON_MOD_RELOAD)
{
if (ent->client->ps.gunframe == 21)
ent->client->ps.gunframe = 26;
}
if (ent->client->ps.gunframe >= 10 && ent->client->ps.gunframe <= 28)
{
ent->client->ps.model_parts[PART_BODY].invisible_objects = 0;
}
else
ent->client->ps.model_parts[PART_BODY].invisible_objects = (1<<0 | 1<<1);
if (ent->client->ps.gunframe == 1)
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/pistol/holster.wav"), 1, ATTN_NORM, 0);
if (ent->client->ps.gunframe == 11)
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/pistol/clip_out.wav"), 1, ATTN_NORM, 0);
if (ent->client->ps.gunframe == 18)
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/pistol/clip_in.wav"), 1, ATTN_NORM, 0);
if (ent->client->ps.gunframe >= 10 && ent->client->ps.gunframe <= 24)
{
ent->client->ps.model_parts[PART_GUN].invisible_objects = 0;
}
else
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
}
void SPistol_Fire (edict_t *ent, vec3_t vorigin, int damage)
{
vec3_t start;
vec3_t forward, right;
int kick = 2;
vec3_t offset;
// is_silenced = MZ_SILENCED;
if (is_quad)
damage *= 4;
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 0, 0, ent->viewheight);
VectorAdd (offset, vorigin, offset);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
VectorScale (forward, -2, ent->client->kick_origin);
ent->client->kick_angles[0] = -4;
fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_SILENCER);
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_SPISTOL | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
ent->client->pers.weapon_clip[ent->client->clip_index]--;
if (!ent->client->pers.weapon_clip[ent->client->clip_index] && !ent->client->pers.inventory[ ent->client->ammo_index])
{
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);
}
Eject_Pistol_Shell(ent);
ent->client->gun_noise = false;
}
void Weapon_SPistol_Fire (edict_t *ent)
{
int damage;
int rounds;
if (ent->waterlevel >= 2)
{
//gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 50;
}
return;
}
if (deathmatch->value)
damage = 15;
else
damage = 10;
if (ent->client->ps.gunframe == 21)
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_ROF)
{
ent->client->ps.gunframe = 23;
}
else
{
ent->client->ps.gunframe++;
}
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
{
damage *= 2;
}
SPistol_Fire (ent, vec3_origin, damage);
Eject_Pistol_Shell(ent);
ent->client->pers.silencer_shots--;
if (!ent->client->pers.silencer_shots)
ent->client->ps.gunframe = 43;
}
else if (ent->client->ps.gunframe == 25)
{
if (!ent->client->pers.weapon_clip[ent->client->clip_index])
{
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_PISTOL_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_PISTOL_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
ent->client->ps.gunframe++;
if (ent->client->pers.pistol_mods & WEAPON_MOD_RELOAD)
;//gi.dprintf ("need fast reload sound\n");
else
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/pistol/clip_out.wav"), 1, ATTN_NORM, 0);
if (! ent->client->pers.weapon_clip[ent->client->clip_index])
{
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);
}
}
else
ent->client->ps.gunframe = 50;
}
else if (ent->client->ps.gunframe == 44)
{
if (!(ent->client->pers.silencer_shots))
ent->client->ps.gunframe++;
else
ent->client->ps.gunframe = 50;
}
}
void Weapon_SPistol (edict_t *ent)
{
static int pause_frames[] = {0, 0, 0};
static int fire_frames[] = {21, 25, 44, 0};
int rounds;
// gi.dprintf ("silencer shots left: %d\n", ent->client->pers.silencer_shots);
if (ent->client->ps.gunframe < 22)
{
ent->client->ps.model_parts[PART_BODY].invisible_objects = 0;
}
else if (ent->client->weaponstate == WEAPON_RELOADING_SPISTOL && ent->client->ps.gunframe < 40)
{
if (ent->client->ps.gunframe < 39)
ent->client->ps.model_parts[PART_GUN].invisible_objects = 0;
else
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
ent->client->ps.model_parts[PART_BODY].invisible_objects = 0;
}
else if (ent->client->pers.holsteredweapon)
{
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
ent->client->ps.model_parts[PART_BODY].invisible_objects = (1<<0 | 1<<1);
}
else
{
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
ent->client->ps.model_parts[PART_BODY].invisible_objects = (1<<0 | 1<<1);
}
if (ent->client->ps.gunframe == 49)
{
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("bullets"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("pistol"))] )
{
ent->client->newweapon = FindItem ("pistol");
}
else
NoAmmoWeaponChange (ent);
ent->client->ps.gunframe = 71;
ent->client->weaponstate = WEAPON_DROPPING;
{
gitem_t *it;
int index;
it = FindItem ("SPistol");
index = ITEM_INDEX (it);
ent->client->pers.inventory[index] = 0;
}
}
else if (ent->client->reload_weapon)
{
if (ent->client->ps.gunframe >= 50 && ent->client->ps.gunframe <= 65)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_PISTOL_ROUNDS)
{
ent->client->ps.gunframe = 25;
ent->client->weaponstate = WEAPON_RELOADING_SPISTOL;
ent->client->pers.inventory[ent->client->ammo_index] += ent->client->pers.weapon_clip[ent->client->clip_index];
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_PISTOL_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_PISTOL_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
}
ent->client->reload_weapon = false;
}
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->pers.inventory[ent->client->ammo_index])
{
if (ent->client->ps.gunframe >= 50 && ent->client->ps.gunframe <= 65)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 25;
ent->client->weaponstate = WEAPON_RELOADING_SPISTOL;
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_PISTOL_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_PISTOL_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
}
}
if (ent->client->pers.pistol_mods & WEAPON_MOD_DAMAGE)
ent->client->ps.gunindex = gi.modelindex("models/weapons/silencer_mdx/magnum.mdx");
Weapon_Generic (ent, 20, 49, 65, 75, pause_frames, fire_frames, Weapon_SPistol_Fire);
if (ent->client->ps.gunframe == 1)
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/pistol/silencerattatch.wav"), 1, ATTN_NORM, 0);
}
// JOSEPH 26-AUG-98
/*
======================================================================
TOMMYGUN
======================================================================
*/
void Tommygun_Fire (edict_t *ent)
{
int i;
vec3_t start;
//vec3_t fireorigin;
vec3_t forward, right;
vec3_t angles;
int damage = 8;
int kick = 2;
vec3_t offset;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 30;
}
return;
}
// First shot
if (!(ent->client->buttons & BUTTON_ATTACK))
{
// ent->client->machinegun_shots = 0;
ent->client->ps.gunframe = 30;
return;
}
if (deathmatch->value)
damage *= 1.75;
if (ent->client->pers.inventory[ent->client->ammo_index] == 0 && ent->client->pers.weapon_clip[ent->client->clip_index] == 0)
return;
if (ent->client->ps.gunframe == 5)
ent->client->ps.gunframe = 4;
else
ent->client->ps.gunframe = 5;
if (is_quad)
{
damage *= 4;
kick *= 4;
}
// Tommy is too powerful in real-mode
if (dm_realmode->value)
damage /= 2;
// Bounce
for (i=1 ; i<3 ; i++)
{
ent->client->kick_origin[i] = crandom() * 0.22;
ent->client->kick_angles[i] = crandom() * 0.6;
}
ent->client->kick_origin[0] = crandom() * 0.22;
// ent->client->kick_angles[0] = ent->client->machinegun_shots * -.5;
// get start / end positions
VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
AngleVectors (angles, forward, right, NULL);
VectorSet(offset, 0, 0, ent->viewheight-1);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_MACHINEGUN);
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_MACHINEGUN | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
PlayerNoise(ent, start, PNOISE_WEAPON);
// Disable for unlimited ammo
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
{
ent->client->pers.weapon_clip [ent->client->clip_index]--;
if (!(ent->client->pers.inventory[ent->client->ammo_index]) && !ent->client->pers.weapon_clip [ent->client->clip_index])
{
NoAmmoWeaponChange (ent);
ent->client->ps.gunframe = 30;
}
else if (!ent->client->pers.weapon_clip [ent->client->clip_index])
{
ent->client->reload_weapon = true;
ent->client->ps.gunframe = 30;
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/machinegun/machgcock.wav"), 1, ATTN_NORM, 0);
}
}
if (!deathmatch->value) // uses up bandwidth
Eject_Tommy_Shell(ent);
ent->client->gun_noise = true;
}
void Weapon_Tommygun (edict_t *ent)
{
int rounds;
static int pause_frames[] = {44, 0, 0};
static int fire_frames[] = {4, 5, 0};
if (ent->client->pers.inventory[ent->client->ammo_index] == 0 && ent->client->pers.weapon_clip[ent->client->clip_index] == 0
&& ent->client->weaponstate != WEAPON_DROPPING)
{
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);
}
else if (ent->client->reload_weapon)
{
if (ent->client->ps.gunframe >= 30 && ent->client->ps.gunframe <= 40)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_TOMMYGUN_ROUNDS)
{
ent->client->ps.gunframe = 6;
ent->client->weaponstate = WEAPON_RELOADING;
ent->client->pers.inventory[ent->client->ammo_index] += ent->client->pers.weapon_clip[ent->client->clip_index];
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_TOMMYGUN_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_TOMMYGUN_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/machinegun/machgcock.wav"), 1, ATTN_NORM, 0);
}
ent->client->reload_weapon = false;
}
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->pers.inventory[ent->client->ammo_index])
{
if (ent->client->ps.gunframe >= 30 && ent->client->ps.gunframe <= 40)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 6;
ent->client->weaponstate = WEAPON_RELOADING;
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_TOMMYGUN_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_TOMMYGUN_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/machinegun/machgcock.wav"), 1, ATTN_NORM, 0);
}
}
Weapon_Generic (ent, 3, 29, 40, 46, pause_frames, fire_frames, Tommygun_Fire);
}
// END JOSEPH
/*
======================================================================
FLAMETHROWER
======================================================================
*/
void FlameThrower_Fire (edict_t *ent)
{
vec3_t start;
vec3_t forward, right;
vec3_t angles;
int damage = 2;
int kick = 0;
static int flamesnd = 0;
// vec3_t offset;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 14;
ent->s.renderfx2 &= ~RF2_FLAMETHROWER;
}
return;
}
if (deathmatch->value && rand()%2)
damage = 1;
if (ent->health <= 0)
return;
if (!(ent->client->buttons & BUTTON_ATTACK))
{
// ent->client->machinegun_shots = 0;
ent->client->ps.gunframe = 14;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/flame_thrower/flameend.wav"), 1, ATTN_NORM, 0);
flamesnd = 0;
ent->s.renderfx2 &= ~RF2_FLAMETHROWER;
return;
}
ent->client->ps.gunframe ++ ;
if (ent->client->ps.gunframe == 14)
ent->client->ps.gunframe = 6;
if (ent->client->pers.inventory[ent->client->ammo_index] < 1)
{
ent->client->ps.gunframe = 6;
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);
ent->s.renderfx2 &= ~RF2_FLAMETHROWER;
return;
}
if (is_quad)
{
damage *= 4;
kick *= 4;
}
// get start / end positions
VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
AngleVectors (angles, forward, right, NULL);
VectorCopy( ent->s.origin, start );
fire_flamethrower (ent, start, forward, damage, kick, MOD_FLAMETHROWER);
PlayerNoise(ent, start, PNOISE_WEAPON);
ent->s.renderfx2 |= RF2_FLAMETHROWER;
flamesnd++;
if (flamesnd > 2)
flamesnd = 0;
if (flamesnd == 1)
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/flame_thrower/flame2.wav"), 1, ATTN_NORM, 0);
else if (flamesnd == 2)
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/flame_thrower/flame3.wav"), 1, ATTN_NORM, 0);
else
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/flame_thrower/flame1.wav"), 1, ATTN_NORM, 0);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
{
if ((ent->client->pers.inventory[ent->client->ammo_index] -= 2) < 0)
ent->client->pers.inventory[ent->client->ammo_index] = 0;
}
// RAFAEL 28-dec-98
ent->client->gun_noise = true;
}
void Weapon_FlameThrower (edict_t *ent)
{
static int pause_frames[] = {18, 24, 0};
static int fire_frames[] = {6, 7, 8, 9, 10, 11, 12, 13};
Weapon_Generic (ent, 5, 13, 25, 31, pause_frames, fire_frames, FlameThrower_Fire);
}
/*
SHOTGUN
*/
void shotgun_fire (edict_t *ent)
{
vec3_t start;
vec3_t forward, right;
vec3_t offset;
int damage = 8;
int kick = 50;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 33;
}
return;
}
if (deathmatch->value)
damage *= 2;
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 0, 0, ent->viewheight-2);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
if (deathmatch->value)
{
fire_shotgun (ent, start, forward, damage, kick, 500, 500, DEFAULT_SAWED_SHOTGUN_COUNT, MOD_SHOTGUN);
}
else
{
fire_shotgun (ent, start, forward, damage, kick, 500, 500, DEFAULT_SAWED_SHOTGUN_COUNT , MOD_SHOTGUN);
}
VectorScale (forward, -2, ent->client->kick_origin);
// send muzzle flash
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_SHOTGUN | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
ent->client->ps.gunframe++;
PlayerNoise(ent, start, PNOISE_WEAPON);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
ent->client->pers.weapon_clip[ent->client->clip_index]--;
Eject_Shotgun_Shell(ent);
ent->client->gun_noise = true;
}
void Weapon_Shotgun_Fire (edict_t *ent)
{
if (ent->client->ps.gunframe == 6)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index])
shotgun_fire (ent);
else
{
ent->client->ps.gunframe = 17;
ent->client->reload_weapon = true;
ent->client->weaponstate = WEAPON_RELOAD_CYCLE;
}
}
else if (ent->client->ps.gunframe == 16)
{
if (!ent->client->pers.weapon_clip[ent->client->clip_index])
{
if (ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->ps.gunframe ++;
ent->client->reload_weapon = true;
ent->client->weaponstate = WEAPON_RELOAD_CYCLE;
}
else
{
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);
}
}
else
{
ent->client->ps.gunframe = 33;
}
}
}
void Weapon_Shotgun (edict_t *ent)
{
static int pause_frames[] = {0, 0};
static int fire_frames[] = {6, 16, 0};
static int kick_frames[] = {-12, -9, -6, -4, -1};
if ((ent->client->ps.gunframe >= 6) & (ent->client->ps.gunframe <= 9))
{
ent->client->kick_angles[0] = kick_frames[ent->client->ps.gunframe-6];
}
if (ent->client->ps.gunframe == 7)
ent->client->ps.rdflags |= RDF_NOLERP;
else
ent->client->ps.rdflags &= ~RDF_NOLERP;
if (ent->client->reload_weapon)
{
if (ent->client->buttons & BUTTON_ATTACK && ent->client->pers.weapon_clip[ent->client->clip_index] >= 1 && ent->client->weaponstate != WEAPON_FIRING)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 33;
ent->client->weaponstate = WEAPON_READY;
}
else if (ent->client->newweapon)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 33;
ent->client->weaponstate = WEAPON_DROPPING;
}
else
{
if (ent->client->ps.gunframe == 29)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_SHOTGUN_ROUNDS)
{
if (ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->pers.inventory[ent->client->ammo_index]--;
ent->client->pers.weapon_clip[ent->client->clip_index]++;
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_SHOTGUN_ROUNDS)
ent->client->ps.gunframe = 21;
else
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 29;
ent->client->weaponstate = WEAPON_RELOADING;
}
}
else
{
ent->client->reload_weapon = false;
ent->client->weaponstate = WEAPON_RELOADING;
}
}
else
{
ent->client->reload_weapon = false;
ent->client->weaponstate = WEAPON_RELOADING;
}
}
else if (ent->client->ps.gunframe >= 33 && ent->client->ps.gunframe <= 40)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_SHOTGUN_ROUNDS &&
ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->weaponstate = WEAPON_RELOAD_CYCLE;
ent->client->ps.gunframe = 17;
}
}
}
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->weaponstate != WEAPON_DROPPING
&& !ent->client->buttons & BUTTON_ATTACK)
{
ent->client->reload_weapon = true;
ent->client->weaponstate = WEAPON_RELOAD_CYCLE;
ent->client->ps.gunframe = 17;
if (!ent->client->pers.inventory[ent->client->ammo_index])
{
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);
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 33;
ent->client->weaponstate = WEAPON_READY;
}
}
if (ent->client->ps.gunframe == 21)
{
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/shotgun/shotgload.wav"), 1, ATTN_NORM, 0);
}
Weapon_Generic (ent, 5, 32, 40, 45, pause_frames, fire_frames, Weapon_Shotgun_Fire);
/*
if (ent->client->ps.gunframe == 1)
{
ent->client->ps.model_parts[PART_HEAD].invisible_objects = 0;
ent->client->ps.model_parts[PART_BODY].invisible_objects = 0;
ent->client->ps.model_parts[PART_LEGS].invisible_objects = 0;
}
*/
}
/*
BAR .308
*/
void weapon_barmachinegun_fire (edict_t *ent)
{
vec3_t start;
vec3_t forward, right;
vec3_t offset;
int damage;
int kick;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 43;
}
return;
}
if (deathmatch->value)
{
// tone down if too much in deathmatch
damage = 50;
kick = 50;
}
else
{
damage = 25;
kick = 50;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorScale (forward, -3, ent->client->kick_origin);
ent->client->kick_angles[0] = -3;
VectorSet(offset, 0, 0, ent->viewheight-1);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
fire_bullet (ent, start, forward, damage, kick, 0, 0, MOD_BARMACHINEGUN);
// send muzzle flash
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
if (ent->client->ps.gunframe == 5)
gi.WriteByte (MZ_BARMACHINEGUN | is_silenced);
else
gi.WriteByte (MZ_BARMACHINEGUN2 | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
PlayerNoise(ent, start, PNOISE_WEAPON);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
{
ent->client->pers.weapon_clip [ent->client->clip_index]--;
if (!(ent->client->pers.inventory[ent->client->ammo_index]) && !ent->client->pers.weapon_clip [ent->client->clip_index])
{
NoAmmoWeaponChange (ent);
ent->client->ps.gunframe = 43;
}
else if (ent->client->pers.inventory[ent->client->ammo_index] && !(ent->client->pers.weapon_clip [ent->client->clip_index]))
{
ent->client->reload_weapon = true;
ent->client->ps.gunframe = 43;
}
}
Eject_Tommy_Shell(ent);
ent->client->gun_noise = true;
}
void barmachinegun_fire (edict_t *ent)
{
if ((ent->client->ps.gunframe == 19)/* && !(ent->client->buttons & BUTTON_ATTACK)*/)
{
ent->client->ps.gunframe = 43;
return;
}
else if (ent->client->ps.gunframe == 12)
{
if (ent->client->pers.pistol_mods & WEAPON_MOD_COOLING_JACKET)
{
ent->client->ps.gunframe = 43;
}
}
else if (ent->client->ps.gunframe == 5
|| ent->client->ps.gunframe == 7
|| ent->client->ps.gunframe == 9)
{
weapon_barmachinegun_fire (ent);
if (ent->client->pers.pistol_mods & WEAPON_MOD_COOLING_JACKET)
{
ent->client->pers.hmg_shots --;
if (!ent->client->pers.hmg_shots)
{
ent->client->pers.pistol_mods &= ~WEAPON_MOD_COOLING_JACKET;
ent->client->newweapon = ent->client->pers.weapon;
if (ent->client->pers.inventory[ent->client->ammo_index] || ent->client->pers.weapon_clip[ent->client->clip_index])
ChangeWeapon (ent);
else
NoAmmoWeaponChange (ent);
}
}
}
ent->client->ps.gunframe++;
}
#define MAX_BARGUN_ROUNDS 30
void Weapon_Barmachinegun (edict_t *ent)
{
static int pause_frames[] = {0, 0};
static int fire_frames[] = {5, 6, 7, 8, 9, 12, 19, 0};
int rounds;
if (ent->client->pers.inventory[ent->client->ammo_index] == 0 && ent->client->pers.weapon_clip[ent->client->clip_index] == 0
&& ent->client->weaponstate != WEAPON_DROPPING)
{
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);
}
else if (ent->client->reload_weapon)
{
if (ent->client->ps.gunframe >= 43 && ent->client->ps.gunframe <= 53)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_BARGUN_ROUNDS)
{
ent->client->ps.gunframe = 20;
ent->client->weaponstate = WEAPON_RELOADING;
ent->client->pers.inventory[ent->client->ammo_index] += ent->client->pers.weapon_clip[ent->client->clip_index];
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_BARGUN_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_BARGUN_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/hmg/hmgcock.wav"), 1, ATTN_NORM, 0);
}
ent->client->reload_weapon = false;
}
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->pers.inventory[ent->client->ammo_index])
{
if (ent->client->ps.gunframe >= 43 && ent->client->ps.gunframe <= 53)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 20;
ent->client->weaponstate = WEAPON_RELOADING;
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_BARGUN_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_BARGUN_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/hmg/hmgcock.wav"), 1, ATTN_NORM, 0);
}
}
Weapon_Generic (ent, 4, 42, 53, 59, pause_frames, fire_frames, barmachinegun_fire);
// gi.dprintf ("Frame: %d\n", ent->client->ps.gunframe);
}
/*
======================================================================
GRENADE LAUNCHER
======================================================================
*/
void Eject_Grenade_Shell (edict_t *ent)
{
edict_t *dropped = NULL;
vec3_t forward, right, up;
vec3_t offset;
if (!(ent->client))
return;
if (deathmatch->value)
return;
//gi.dprintf("angles = %s\n", vtos(ent->s.angles));
dropped = G_Spawn();
if (!dropped)
return;
dropped->s.modelindex = gi.modelindex("models/weapons/grenade_shell/tris.md2");
dropped->movetype = MOVETYPE_BOUNCE;
dropped->mins[0] = -4;
dropped->mins[1] = -4;
dropped->mins[2] = -2;
dropped->maxs[0] = 4;
dropped->maxs[1] = 4;
dropped->maxs[2] = 4;
AngleVectors (ent->client->v_angle, forward, right, up);
dropped->s.angles[YAW] = ent->client->v_angle[YAW];
VectorSet(offset, 0, 16, ent->viewheight -2 );
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, dropped->s.origin);
VectorScale (forward, 5 + ((rand()&15)-8), dropped->velocity);
VectorMA (dropped->velocity, 50 + (rand()&31), right, dropped->velocity);
dropped->velocity[2] = 150 + (rand()&31);
// Ridah, changed this so they don't stick in the ground so much
VectorSet(dropped->avelocity, 0/*((rand()&7)-4)*/, ((rand()&15)-8), ((rand()&7)-4));
dropped->think = Think_Eject_Shell;
dropped->misstime = 40;
dropped->nextthink = level.time + 0.1;
dropped->s.renderfx2 |= RF2_NOSHADOW;
gi.linkentity (dropped);
return;
}
void weapon_grenadelauncher_fire (edict_t *ent)
{
vec3_t offset;
vec3_t forward, right;
vec3_t start;
int damage = 120;
float radius;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 33;
}
return;
}
damage *= 2; // 240 points of damage
radius = damage*2; // 480 units radius
radius *= 0.75;
VectorSet(offset, 16, 8, ent->viewheight-8);
AngleVectors (ent->client->v_angle, forward, right, NULL);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
VectorScale (forward, -2, ent->client->kick_origin);
ent->client->kick_angles[0] = -1;
fire_grenade (ent, start, forward, damage, 750, 2.0, radius);
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_GRENADE | is_silenced);
gi.multicast (ent->s.origin, MULTICAST_PVS);
ent->client->ps.gunframe++;
PlayerNoise(ent, start, PNOISE_WEAPON);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
{
ent->client->pers.weapon_clip[ent->client->clip_index]--;
if (!(ent->client->pers.inventory[ent->client->ammo_index]) && !ent->client->pers.weapon_clip [ent->client->clip_index])
{
NoAmmoWeaponChange (ent);
ent->client->ps.gunframe = 33;
}
}
Eject_Grenade_Shell(ent);
ent->client->gun_noise = true;
}
void Weapon_GrenadeLauncher_Fire (edict_t *ent)
{
if (ent->client->ps.gunframe == 5)
weapon_grenadelauncher_fire (ent);
else if (ent->client->ps.gunframe == 16)
{
if ((ent->client->pers.inventory[ent->client->ammo_index]) && !ent->client->pers.weapon_clip [ent->client->clip_index])
{
ent->client->reload_weapon = true;
}
ent->client->ps.gunframe = 33;
}
}
#define MAX_GRENADE_ROUNDS 3
void Weapon_GrenadeLauncher (edict_t *ent)
{
static int pause_frames[] = {0, 0};
static int fire_frames[] = {5, 16, 0};
int rounds;
if (ent->client->pers.inventory[ent->client->ammo_index] == 0 && ent->client->pers.weapon_clip[ent->client->clip_index] == 0
&& ent->client->weaponstate != WEAPON_DROPPING)
{
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);
}
else if (ent->client->reload_weapon)
{
if (ent->client->ps.gunframe >= 33 && ent->client->ps.gunframe <= 40)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_GRENADE_ROUNDS)
{
ent->client->ps.gunframe = 17;
ent->client->weaponstate = WEAPON_RELOADING;
ent->client->pers.inventory[ent->client->ammo_index] += ent->client->pers.weapon_clip[ent->client->clip_index];
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_GRENADE_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_GRENADE_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/grenade_launcher/reload.wav"), 1, ATTN_NORM, 0);
}
ent->client->reload_weapon = false;
}
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->pers.inventory[ent->client->ammo_index])
{
if (ent->client->ps.gunframe >= 33 && ent->client->ps.gunframe <= 40)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 17;
ent->client->weaponstate = WEAPON_RELOADING;
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_GRENADE_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_GRENADE_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/grenade_launcher/reload.wav"), 1, ATTN_NORM, 0);
}
}
Weapon_Generic (ent, 4, 32, 40, 45, pause_frames, fire_frames, Weapon_GrenadeLauncher_Fire);
if (ent->client->ps.gunframe >= 17 && ent->client->ps.gunframe <= 32)
{
ent->client->ps.model_parts[PART_GUN].invisible_objects = 0;
}
else
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
if (ent->client->ps.gunframe >= 9 && ent->client->ps.gunframe <= 16)
ent->client->ps.rdflags |= RDF_NOLERP;
else
ent->client->ps.rdflags &= ~RDF_NOLERP;
}
// rocket launcher
void weapon_rocketlauncher_fire (edict_t *ent)
{
vec3_t offset, start;
vec3_t forward, right;
int damage;
float damage_radius;
int radius_damage;
if (ent->waterlevel >= 2)
{
// gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
if (ent->client->weaponstate == WEAPON_FIRING)
{
ent->client->weaponstate = WEAPON_READY;
ent->client->ps.gunframe = 30;
}
return;
}
damage = 100 + (int)(random() * 20.0);
radius_damage = 120;
damage_radius = 180; // 256;
if (is_quad)
{
damage *= 4;
radius_damage *= 4;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorScale (forward, -2, ent->client->kick_origin);
ent->client->kick_angles[0] = -4;
VectorSet(offset, 8, 8, ent->viewheight-8);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
fire_rocket (ent, start, forward, damage, 900, 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++;
PlayerNoise(ent, start, PNOISE_WEAPON);
if (! ( (int)dmflags->value & DF_INFINITE_AMMO && deathmatch->value ) )
{
ent->client->pers.weapon_clip[ent->client->clip_index]--;
if (!(ent->client->pers.inventory[ent->client->ammo_index]) && !ent->client->pers.weapon_clip [ent->client->clip_index])
{
NoAmmoWeaponChange (ent);
ent->client->ps.gunframe = 30;
}
}
ent->client->gun_noise = true;
}
void Weapon_RocketLauncher_Fire (edict_t *ent)
{
if (ent->client->ps.gunframe == 6)
weapon_rocketlauncher_fire (ent);
else if (ent->client->ps.gunframe == 13)
{
if ((ent->client->pers.inventory[ent->client->ammo_index]) && !ent->client->pers.weapon_clip [ent->client->clip_index])
{
ent->client->reload_weapon = true;
}
ent->client->ps.gunframe = 30;
}
}
#define MAX_ROCKET_ROUNDS 5
void Weapon_RocketLauncher (edict_t *ent)
{
static int pause_frames[] = {0, 0};
static int fire_frames[] = {6, 13, 0};
int rounds;
if (ent->client->pers.inventory[ent->client->ammo_index] == 0 && ent->client->pers.weapon_clip[ent->client->clip_index] == 0
&& ent->client->weaponstate != WEAPON_DROPPING)
{
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);
}
else if (ent->client->reload_weapon)
{
if (ent->client->ps.gunframe >= 30 && ent->client->ps.gunframe <= 41)
{
if (ent->client->pers.weapon_clip[ent->client->clip_index] < MAX_ROCKET_ROUNDS)
{
ent->client->ps.gunframe = 14;
ent->client->weaponstate = WEAPON_RELOADING;
ent->client->pers.inventory[ent->client->ammo_index] += ent->client->pers.weapon_clip[ent->client->clip_index];
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_ROCKET_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_ROCKET_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/rocket_launcher/reload.wav"), 1, ATTN_NORM, 0);
}
ent->client->reload_weapon = false;
}
}
else if (!ent->client->pers.weapon_clip[ent->client->clip_index] && ent->client->pers.inventory[ent->client->ammo_index])
{
if (ent->client->ps.gunframe >= 30 && ent->client->ps.gunframe <= 41)
{
ent->client->reload_weapon = false;
ent->client->ps.gunframe = 14;
ent->client->weaponstate = WEAPON_RELOADING;
if (ent->client->pers.inventory[ent->client->ammo_index] < MAX_ROCKET_ROUNDS)
{
rounds = ent->client->pers.inventory[ent->client->ammo_index];
}
else
rounds = MAX_ROCKET_ROUNDS;
ent->client->pers.weapon_clip[ent->client->clip_index] = rounds;
ent->client->pers.inventory[ent->client->ammo_index] -= rounds;
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/rocket_launcher/reload.wav"), 1, ATTN_NORM, 0);
}
}
Weapon_Generic (ent, 5, 29, 41, 47, pause_frames, fire_frames, Weapon_RocketLauncher_Fire);
/*
if (ent->client->ps.gunframe >= 14 && ent->client->ps.gunframe <= 29)
{
ent->client->ps.model_parts[PART_GUN].invisible_objects = 0;
}
else
ent->client->ps.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
*/
// gi.dprintf ("frame: %d\n", ent->client->ps.gunframe);
}