#include "game.h"
/*****************************************************************************
 *****************************************************************************
 *						SHOTGUN, M16, HARPOON and ROCKET STUFF
 *****************************************************************************
 ****************************************************************************/

enum weapon_anim {W_AIM, W_DRAW, W_RECOIL, W_UNDRAW, W_UNAIM, W_RELOAD, W_UAIM, W_UUNAIM, W_URECOIL, W_SURF_UNDRAW};

#define HARPOON_DRAW_ANIM 1
#define ROCKET_DRAW_ANIM  0

#define PELLET_SCATTER  (20*ONE_DEGREE)        // Scatter of pellets
#define HARPOON_SPEED 150
#define ROCKET_SPEED  512

#if defined(PSX_VERSION) && defined(JAPAN)
#define PISTOL_DAMAGE	2		// Everyhing relates to pistol damage
#else
#define PISTOL_DAMAGE	1		// Everyhing relates to pistol damage
#endif

/******************************************************************************
 *						Draw ShotGun Meshes
 *****************************************************************************/
void	draw_shotgun_meshes( int weapon_type )
{
	int obj;

	obj = WeaponObject(weapon_type);
	lara.mesh_ptrs[HAND_R]  = meshes[objects[obj].mesh_index + HAND_R];
	lara.back_gun = 0;
}

/******************************************************************************
 *						UnDraw ShotGun Meshes
 *****************************************************************************/
void	undraw_shotgun_meshes( int weapon_type )
{
	int obj;

	obj = WeaponObject(weapon_type);
	lara.mesh_ptrs[HAND_R]  = meshes[objects[LARA].mesh_index + HAND_R];
	lara.back_gun = obj;
}

/******************************************************************************
 *						Make ShotGun ready
 *****************************************************************************/
void	ready_shotgun( int weapon_type )
{
	lara.gun_status = LG_READY;
	lara.left_arm.x_rot = lara.left_arm.y_rot = lara.left_arm.z_rot = 0;
	lara.right_arm.x_rot = lara.right_arm.y_rot = lara.right_arm.z_rot = 0;
	lara.left_arm.frame_number = lara.right_arm.frame_number = 0;
	lara.left_arm.lock = lara.right_arm.lock = 0;
	lara.target = NULL;
	lara.left_arm.frame_base = lara.right_arm.frame_base = objects[WeaponObject(weapon_type)].frame_base;
//	lara.torso_x_rot = lara.torso_y_rot = 0;
//	lara.head_x_rot = lara.head_y_rot = 0;
}

/*****************************************************************************
 *        Put Shotgun back in its Holster
 ****************************************************************************/
void	RifleHandler( int weapon_type )
{
	WEAPON_INFO	*winfo;

	winfo = &weapons[weapon_type];

	/* Get Target Information */
	if ( input&IN_ACTION )
		LaraTargetInfo( winfo );
	else
		lara.target = NULL;
	if ( lara.target==NULL )					// If No Targets are Locked
		LaraGetNewTarget( winfo );            	// attempt to find new target

	/* Aim Shotgun where-ever*/
	AimWeapon( winfo,&lara.left_arm );

	/* Make Lara look at Target */
	if ( lara.left_arm.lock )
	{
		lara.torso_y_rot = lara.left_arm.y_rot;
		lara.torso_x_rot = lara.left_arm.x_rot;
		lara.head_x_rot = lara.head_y_rot = 0;
	}

	/* Animate Shotgun */
	AnimateShotgun(weapon_type);

	// Make flash of light each time Lara fires her guns
	if (lara.right_arm.flash_gun)
	{
		if (weapon_type == LG_SHOTGUN || weapon_type == LG_M16)
		{
			TriggerDynamic(
				lara_item->pos.x_pos + (phd_sin(lara_item->pos.y_rot) >> (W2V_SHIFT-10)) + ((GetRandomControl()&255)-128),
				lara_item->pos.y_pos - WALL_L/2 + ((GetRandomControl()&127)-63),
				lara_item->pos.z_pos + (phd_cos(lara_item->pos.y_rot) >> (W2V_SHIFT-10)) + ((GetRandomControl()&255)-128),
				(weapon_type == LG_SHOTGUN) ? 12 : 11,
				(GetRandomControl()&7)+24,
				(GetRandomControl()&3)+16,
				GetRandomControl()&7
			);
		}
	}
}

/******************************************************************************
 *			Actually Fire ShotGun please
 *****************************************************************************/

void	FireShotgun( void )
{
	int			i,r,fired,x,y,z,lp;
	PHD_VECTOR pos;
	PHD_ANGLE	angles[2];
	PHD_ANGLE	dangles[2];

	angles[0] = lara.left_arm.y_rot + lara_item->pos.y_rot;
	angles[1] = lara.left_arm.x_rot;

	if (!lara.left_arm.lock)
	{
		angles[0] += lara.torso_y_rot;
	 	angles[1] += lara.torso_x_rot;
	}

	fired = 0;

	for ( i=0; i<SHOTGUN_AMMO_CLIP; i++ )
	{
		r = (int)((GetRandomControl()-16384)*PELLET_SCATTER)/65536;
		dangles[0] = angles[0] + r;
		r = (int)((GetRandomControl()-16384)*PELLET_SCATTER)/65536;
		dangles[1] = angles[1] + r;
		if ( FireWeapon( LG_SHOTGUN, lara.target, lara_item, dangles ) )
			fired=1;
	}

	if ( fired )
	{
		pos.x = 0;
		pos.y = SHOTGUN_YOFF;
		pos.z = SHOTGUN_ZOFF;
		GetLaraHandAbsPosition(&pos, 1);
		x = pos.x;
		y = pos.y;
		z = pos.z;
		pos.x = 0;
		pos.y = SHOTGUN_YOFF+1280;
		pos.z = SHOTGUN_ZOFF;
		GetLaraHandAbsPosition(&pos, 1);

		SmokeCountL = 32;
		SmokeWeapon = LG_SHOTGUN;
		for (lp=0;lp<7;lp++)
			TriggerGunSmoke(x, y, z, pos.x-x, pos.y-y, pos.z-z, 1, SmokeWeapon, 32);
		for (lp=0;lp<12;lp++)
			TriggerShotgunSparks(x, y, z, (pos.x-x)<<1, (pos.y-y)<<1, (pos.z-z)<<1);

		lara.right_arm.flash_gun = weapons[LG_SHOTGUN].flash_time;

		SoundEffect( weapons[LG_SHOTGUN].sample_num,&lara_item->pos,0 );
#if defined(GAMEDEBUG) && defined(PC_VERSION)
		level.ammo_used += 18;
#endif

		VIBRATE(0x1000, 0x1000, 2, 0x600, 5);

	}
}


void FireM16(int running)
{
	PHD_ANGLE angles[2];

	angles[0] = lara.left_arm.y_rot + lara_item->pos.y_rot;
	angles[1] = lara.left_arm.x_rot;

	if (!lara.left_arm.lock)
	{
		angles[0] += lara.torso_y_rot;
	 	angles[1] += lara.torso_x_rot;
	}

	// If running, reduce accuracy and damage
	if (running)
	{
		weapons[M16].shot_accuracy = ONE_DEGREE*12;
		weapons[M16].damage = 1;
	}
	else
	{
		weapons[M16].shot_accuracy = ONE_DEGREE*4;
		weapons[M16].damage = 3;
	}

	if (FireWeapon(LG_M16, lara.target, lara_item, angles))
	{
		SmokeCountL = 24;
		SmokeWeapon = LG_M16;
		TriggerGunShell(RIGHT_HAND,GUNSHELL,LG_M16);
		lara.right_arm.flash_gun = weapons[LG_M16].flash_time;

		VIBRATE(0x1000, 0x1000, 2, 0x1000, 2);

#if defined(GAMEDEBUG) && defined(PC_VERSION)
		level.ammo_used += 3; // this is what it is counted as, though may be wasted if running
#endif
	}
}


void FireHarpoon(void)
{
	sint16 item_number;
	ITEM_INFO *item;
	GAME_VECTOR pos;
	int distance;

	if (lara.harpoon.ammo <= 0)
		return;

	/* Create a harpoon object and launch it on its way */
	item_number = CreateItem();
	if (item_number != NO_ITEM)
	{
		item = &items[item_number];

		item->object_number = HARPOON_BOLT;
		item->room_number = lara_item->room_number;
		pos.x = -2;
		pos.y = 273 + 100;
		pos.z = 77;
		GetLaraJointAbsPosition((PHD_VECTOR *)&pos, 10);
		item->pos.x_pos = pos.x;
		item->pos.y_pos = pos.y;
		item->pos.z_pos = pos.z;

		InitialiseItem(item_number);

		/* Choose angle */
		if (lara.target)
		{
			find_target_point(lara.target, &pos);

			item->pos.y_rot = phd_atan(pos.z - item->pos.z_pos, pos.x - item->pos.x_pos);// + randomness
			distance = phd_sqrt(SQUARE(pos.z - item->pos.z_pos) + SQUARE(pos.x - item->pos.x_pos));
			item->pos.x_rot = -phd_atan(distance, pos.y - item->pos.y_pos); // + randomness
		}
		else
		{
			item->pos.x_rot = lara_item->pos.x_rot + lara.left_arm.x_rot;
			item->pos.y_rot = lara_item->pos.y_rot + lara.left_arm.y_rot;
		}
		item->pos.z_rot = 0;

		item->fallspeed = (sint16)(-HARPOON_SPEED * phd_sin(item->pos.x_rot) >> W2V_SHIFT);
		item->speed = (sint16)(HARPOON_SPEED * phd_cos(item->pos.x_rot) >> W2V_SHIFT);

		AddActiveItem(item_number);

		if (!savegame.bonus_flag)
			lara.harpoon.ammo--;
		savegame.ammo_used++;
	}
}


void ControlHarpoonBolt(sint16 item_number)
{
	ITEM_INFO *item, *target;
	FLOOR_INFO *floor;
	sint32 c, s, x, z, rx, rz, ox, oz, sx, sz, old_x, old_z;
	sint16 room_number, target_number;
	sint16 *bounds;

	item = &items[item_number];

	old_z = item->pos.z_pos;
	old_x = item->pos.x_pos;

	if (!(room[item->room_number].flags & UNDERWATER))
		item->fallspeed++;
	item->pos.y_pos += item->fallspeed;

	item->pos.z_pos += item->speed * phd_cos(item->pos.y_rot) >> W2V_SHIFT;
	item->pos.x_pos += item->speed * phd_sin(item->pos.y_rot) >> W2V_SHIFT;

	room_number = item->room_number;
	floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
	item->floor = GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos);

	if (item->room_number != room_number)
		ItemNewRoom(item_number, room_number);

	/* Has it hit a beastie? Check ones in same room as bolt TODO: should test surrounding rooms too? */
	for (target_number = room[item->room_number].item_number; target_number!=NO_ITEM; target_number=target->next_item)
	{
		target = &items[target_number];
		if (target == lara_item || !target->collidable)
			continue;

		if (target->object_number==SMASH_WINDOW || (target->status != INVISIBLE && objects[target->object_number].collision))
		{
			// check against bounds of target for collision
			bounds = GetBestFrame(target);
			if (item->pos.y_pos < target->pos.y_pos + bounds[2] || item->pos.y_pos > target->pos.y_pos + bounds[3])
				continue;

			// get vector from target to bolt and check against x,z bounds
			c = phd_cos(target->pos.y_rot);
			s = phd_sin(target->pos.y_rot);

			x = item->pos.x_pos - target->pos.x_pos;
			z = item->pos.z_pos - target->pos.z_pos;
			rx = (c*x - s*z) >> W2V_SHIFT;

			ox = old_x - target->pos.x_pos;
			oz = old_z - target->pos.z_pos;
			sx = (c*ox - s*oz) >> W2V_SHIFT;

			if ((rx < bounds[0] && sx < bounds[0]) || (rx > bounds[1] && sx > bounds[1]))
				continue;

			rz = (c*z + s*x) >> W2V_SHIFT;
			sz = (c*oz + s*ox) >> W2V_SHIFT;

			if ((rz < bounds[4] && sz < bounds[4]) || (rz > bounds[5] && sz > bounds[5]))
				continue;

			if (target->object_number==SMASH_WINDOW)
				SmashWindow(target_number);
			else
			{
				// centre of bolt is within bounds, and that's good enough for a hit as far as I'm concerned
				if (objects[target->object_number].intelligent)
				{
					DoLotsOfBlood(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, 0, 0, item->room_number, 5);

					HitTarget(target, NULL, weapons[LG_HARPOON].damage);
					/*
					target->hit_status = 1;
					target->hit_points -= weapons[LG_HARPOON].damage;
					if (target->hit_points <= 0)
						savegame.kills++;
					*/
					savegame.ammo_hit++;
				}
				KillItem(item_number);

				return;
			}
		}
	}

	/* Has it hit a wall or the floor? */
	if (item->pos.y_pos >= item->floor || item->pos.y_pos <= GetCeiling(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos))
	{
		KillItem(item_number);
		return;
	}

	/* Create bubbles in its wake if underwater */
	if (room[item->room_number].flags & UNDERWATER)
		CreateBubble(&item->pos, item->room_number);
}


void FireRocket(void)
{
	sint16 item_number,lp;
	ITEM_INFO *item;
	PHD_VECTOR pos;
	long	x,y,z;

	if (lara.rocket.ammo <= 0)
		return;

	/* Create a rocket object and launch it on its way */
	item_number = CreateItem();
	if (item_number != NO_ITEM)
	{
		item = &items[item_number];

		item->object_number = ROCKET;
		item->room_number = lara_item->room_number;
		pos.x = 0;
		pos.y = ROCKET_YOFF+96;
		pos.z = ROCKET_ZOFF;
		GetLaraHandAbsPosition(&pos, 1);
		item->pos.x_pos = x = pos.x;
		item->pos.y_pos = y = pos.y;
		item->pos.z_pos = z = pos.z;
		pos.x = 0;
		pos.y = ROCKET_YOFF+1024;
		pos.z = ROCKET_ZOFF;
		GetLaraHandAbsPosition(&pos, 1);

		SmokeCountL = 32;
		SmokeWeapon = LG_ROCKET;
		for (lp=0;lp<5;lp++)
			TriggerGunSmoke(x, y, z, pos.x-x, pos.y-y, pos.z-z, 1, LG_ROCKET, 32);

		InitialiseItem(item_number);

		item->pos.x_rot = lara_item->pos.x_rot + lara.left_arm.x_rot;
		item->pos.y_rot = lara_item->pos.y_rot + lara.left_arm.y_rot;
		item->pos.z_rot = 0;

		if (!lara.left_arm.lock)
		{
			item->pos.x_rot += lara.torso_x_rot;
	 		item->pos.y_rot += lara.torso_y_rot;
		}

//		item->pos.x_rot = lara_item->pos.x_rot + lara.left_arm.x_rot + lara.torso_x_rot;
//		item->pos.y_rot = lara_item->pos.y_rot + lara.left_arm.y_rot + lara.torso_y_rot;
//		item->pos.z_rot = 0;

		item->speed = ROCKET_SPEED>>5;
		item->fallspeed = 0;

		AddActiveItem(item_number);

		if (!savegame.bonus_flag)
			lara.rocket.ammo--;
		savegame.ammo_used++;

#if defined(PC_VERSION) && defined(GAMEDEBUG)
		level.ammo_used += 30;
#endif
	}
}

#define ROCKET_BLAST_RADIUS (WALL_L/2)

void ControlRocket(sint16 item_number)
{
	sint16 *bounds;
	FLOOR_INFO *floor;
	long	wx,wy,wz,xv,yv,zv;
	ITEM_INFO *item, *target;
	sint32 old_x, old_y, old_z;
	sint16 room_number, target_number;
	sint32 speed, c, s, x, z, rx, rz, ox, oz, sx, sz, explode, radius;

	item = &items[item_number];

	old_x = item->pos.x_pos;
	old_y = item->pos.y_pos;
	old_z = item->pos.z_pos;

	if (item->speed < ROCKET_SPEED)
		item->speed += (item->speed>>3)+2;
	item->shade = 0x2400;
	item->pos.z_rot+=(((item->speed>>2)+7)*ONE_DEGREE);

	phd_PushUnitMatrix();
	*(phd_mxptr+M03) = 0;
	*(phd_mxptr+M13) = 0;
	*(phd_mxptr+M23) = 0;
	phd_RotYXZ(item->pos.y_rot, item->pos.x_rot, item->pos.z_rot);
	phd_PushMatrix();
	phd_TranslateRel( 0, 0, -128);
	wx = (*(phd_mxptr+M03)>>W2V_SHIFT);
	wy = (*(phd_mxptr+M13)>>W2V_SHIFT);
	wz = (*(phd_mxptr+M23)>>W2V_SHIFT);
	phd_PopMatrix();
	phd_TranslateRel( 0, 0, -1024-(GetRandomControl()&511));
	xv = (*(phd_mxptr+M03)>>W2V_SHIFT);
	yv = (*(phd_mxptr+M13)>>W2V_SHIFT);
	zv = (*(phd_mxptr+M23)>>W2V_SHIFT);
	phd_PopMatrix();
	if (wibble & 4)
		TriggerRocketFlame(wx,wy,wz,xv-wx,yv-wy,zv-wz,item_number);
	TriggerRocketSmoke(wx+item->pos.x_pos, wy+item->pos.y_pos, wz+item->pos.z_pos, -1);
	TriggerDynamic(wx+item->pos.x_pos+(GetRandomControl()&15)-8, wy+item->pos.y_pos+(GetRandomControl()&15)-8, wz+item->pos.z_pos+(GetRandomControl()&15)-8,14,28+(GetRandomControl()&3),16+(GetRandomControl()&7),(GetRandomControl()&7));

//	if (item->speed-- < ROCKET_SPEED-10)
//		item->fallspeed++;
	speed = item->speed * phd_cos(item->pos.x_rot) >> W2V_SHIFT;
	item->pos.z_pos += speed * phd_cos(item->pos.y_rot) >> W2V_SHIFT;
	item->pos.x_pos += speed * phd_sin(item->pos.y_rot) >> W2V_SHIFT;
	item->pos.y_pos += item->fallspeed - (item->speed * phd_sin(item->pos.x_rot) >> W2V_SHIFT);

	room_number = item->room_number;
	floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
	item->floor = GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos);

	if (item->room_number != room_number)
		ItemNewRoom(item_number, room_number);

	/* Has it hit a wall or the floor? If so, explodes with blast radius */
	if (item->pos.y_pos >= item->floor || item->pos.y_pos <= GetCeiling(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos))
	{
		radius = ROCKET_BLAST_RADIUS;
		explode = 1;
	}
	else
		radius = explode = 0; // no radius, so must hit bad guy

	/* Has it hit a beastie? Check ones in same room as bolt TODO: should test surrounding rooms too? */
	for (target_number = room[item->room_number].item_number; target_number!=NO_ITEM; target_number=target->next_item)
	{
		target = &items[target_number];
		if (target == lara_item || !target->collidable)
			continue;

		if (target->object_number==SMASH_WINDOW ||
			(objects[target->object_number].intelligent && target->status != INVISIBLE && objects[target->object_number].collision))
		{
			// check against bounds of target for collision
			bounds = GetBestFrame(target);
			if (item->pos.y_pos+radius < target->pos.y_pos + bounds[2] || item->pos.y_pos-radius > target->pos.y_pos + bounds[3])
				continue;

			// get vector from target to bolt and check against x,z bounds
			c = phd_cos(target->pos.y_rot);
			s = phd_sin(target->pos.y_rot);

			x = item->pos.x_pos - target->pos.x_pos;
			z = item->pos.z_pos - target->pos.z_pos;
			rx = (c*x - s*z) >> W2V_SHIFT;

			ox = old_x - target->pos.x_pos;
			oz = old_z - target->pos.z_pos;
			sx = (c*ox - s*oz) >> W2V_SHIFT;

			if ((rx+radius < bounds[0] && sx+radius < bounds[0]) ||
				 (rx-radius > bounds[1] && sx-radius > bounds[1]))
				continue;

			rz = (c*z + s*x) >> W2V_SHIFT;
			sz = (c*oz + s*ox) >> W2V_SHIFT;

			if ((rz+radius < bounds[4] && sz+radius < bounds[4]) ||
				 (rz-radius > bounds[5] && sz-radius > bounds[5]))
				continue;

			if (target->object_number==SMASH_WINDOW)
				SmashWindow(target_number);
			else
			{
				// Kaboom! take that evil bad guy
//				HitTarget(target, NULL, weapons[LG_ROCKET].damage);
				HitTarget(target, NULL, 30*PISTOL_DAMAGE);

				savegame.ammo_hit++;
				explode = 1;

				// if dead, then blast them to bits
				if (target->hit_points <= 0)
				{
					savegame.kills++;
					CreatureDie(target_number, 1);
				}
			}
		}
	}

	if (explode)
	{
		TriggerExplosionSparks(old_x, old_y, old_z,3,-2);	// -2 = Set off a dynamic light controller.
		for (x=0;x<2;x++)
			TriggerExplosionSparks(old_x, old_y, old_z,3,-1);

	/* -------- determine how far Lara is away from the explosion */

#ifdef PSX_VERSION
		{
			long dist, x, y, z;

			x = old_x - lara_item->pos.x_pos;
			y = old_y - lara_item->pos.y_pos;
			z = old_z - lara_item->pos.z_pos;
			dist = SQUARE(x) + SQUARE(y) + SQUARE(z);

			if (dist < 0x1900000)
			{
				dist = 0xff00 - ((dist>>9) & 0xff00);
				RUMBLE(dist>>4, dist, 20, 0x100, 40);
			}
		}
#endif

/*		fx_number = CreateEffect(item->room_number);
		if (fx_number != NO_ITEM)
		{
			fx = &effects[fx_number];
			fx->pos.x_pos = old_x;
			fx->pos.y_pos = old_y;
			fx->pos.z_pos = old_z;
			fx->speed = 0;
			fx->frame_number = 0;
			fx->counter = 0;
			fx->object_number = EXPLOSION1;

		}*/
		SoundEffect(105, NULL, 0);
		KillItem(item_number);
	}
}


void draw_shotgun(int weapon_type)
{
	ITEM_INFO *item;

	if (lara.weapon_item == NO_ITEM)
	{
		lara.weapon_item = CreateItem();
		item = &items[lara.weapon_item];
		item->object_number = WeaponObject(weapon_type);
		if (weapon_type == LG_ROCKET)
			item->anim_number = objects[ROCKET_GUN].anim_index + ROCKET_DRAW_ANIM;
		else
			item->anim_number = objects[item->object_number].anim_index + HARPOON_DRAW_ANIM; // M16 too
		item->frame_number = anims[item->anim_number].frame_base;
		item->current_anim_state = item->goal_anim_state = W_DRAW;
		item->status = ACTIVE;
		item->room_number = NO_ROOM; // needed to stop KillItem() throwing a wobbly
		lara.left_arm.frame_base = lara.right_arm.frame_base = objects[item->object_number].frame_base;
	}
	else
		item = &items[lara.weapon_item];

	AnimateItem(item);

	if (item->current_anim_state == W_AIM || item->current_anim_state == W_UAIM)
		ready_shotgun(weapon_type);
	else if (item->frame_number - anims[item->anim_number].frame_base == 10)
		draw_shotgun_meshes(weapon_type);
	else if (lara.water_status == LARA_UNDERWATER)
		item->goal_anim_state = W_UAIM;

//	lara.left_arm.frame_number = lara.right_arm.frame_number = item->frame_number;

	lara.left_arm.frame_base = lara.right_arm.frame_base = anims[item->anim_number].frame_ptr;
	lara.left_arm.frame_number = lara.right_arm.frame_number = item->frame_number - anims[item->anim_number].frame_base;
	lara.left_arm.anim_number = lara.right_arm.anim_number = item->anim_number;
}


void undraw_shotgun(int weapon_type)
{
	ITEM_INFO *item;

	item = &items[lara.weapon_item];
	if (lara.water_status == LARA_SURFACE)
		item->goal_anim_state = W_SURF_UNDRAW;
	else
		item->goal_anim_state = W_UNDRAW;

	AnimateItem(item);

	if (item->status == DEACTIVATED)
	{
		lara.gun_status = LG_ARMLESS;
		lara.target = NULL;
		lara.left_arm.lock = lara.right_arm.lock = 0;
		KillItem(lara.weapon_item);
		lara.weapon_item = NO_ITEM;
		lara.left_arm.frame_number = lara.right_arm.frame_number = 0;
	}
	else if (item->current_anim_state == W_UNDRAW && item->frame_number - anims[item->anim_number].frame_base == 21)
		undraw_shotgun_meshes(weapon_type);

//	lara.left_arm.frame_number = lara.right_arm.frame_number = item->frame_number;

	lara.left_arm.frame_base = lara.right_arm.frame_base = anims[item->anim_number].frame_ptr;
	lara.left_arm.frame_number = lara.right_arm.frame_number = item->frame_number - anims[item->anim_number].frame_base;
	lara.left_arm.anim_number = lara.right_arm.anim_number = item->anim_number;
}


void AnimateShotgun(int weapon_type)
{
	/* Do readied state of harpoon. Needs to switch between underwater and above water aiming when
		Lara passes in and out of water with the harpoon out */
	ITEM_INFO *item;
	int running;
	static int m16_firing = 0, harpoon_fired = 0;

	if (SmokeCountL)
	{
  		PHD_VECTOR pos;

		if (SmokeWeapon == LG_ROCKET)
		{
			pos.x = 0;
			pos.y = ROCKET_YOFF;
			pos.z = ROCKET_ZOFF;
		}
		else if (SmokeWeapon == LG_SHOTGUN)
		{
			pos.x = -16;
			pos.y = SHOTGUN_YOFF;
			pos.z = SHOTGUN_ZOFF;
		}
		else if (SmokeWeapon == LG_M16)
		{
			pos.x = 0;
			pos.y = M16_YOFF;
			pos.z = M16_ZOFF;
		}
		GetLaraHandAbsPosition(&pos, 1);
		TriggerGunSmoke(pos.x, pos.y, pos.z, 0,0,0,0,SmokeWeapon, SmokeCountL);
	}

	item = &items[lara.weapon_item];
	if (weapon_type == LG_M16 && lara_item->speed != 0)
		running = 1;
	else
		running = 0;

	switch (item->current_anim_state)
	{
	case W_AIM:
		m16_firing = 0; // for M16 sounds

		if (harpoon_fired)
		{
			item->goal_anim_state = W_RELOAD;
			harpoon_fired = 0;
		}
		else if (lara.water_status == LARA_UNDERWATER || running)		// switch to underwater aim if Lara falls in
			item->goal_anim_state = W_UAIM;
		else if (((input & IN_ACTION) && !lara.target) || lara.left_arm.lock)
			item->goal_anim_state = W_RECOIL;
		else // loops on first frame if user not pressing fire and no lock
			item->goal_anim_state = W_UNAIM;
		break;

	case W_UAIM:
		m16_firing = 0;

		if (harpoon_fired)
		{
			item->goal_anim_state = W_RELOAD;
			harpoon_fired = 0;
		}
		else if (lara.water_status != LARA_UNDERWATER && !running)
			item->goal_anim_state = W_AIM;
		else if (((input & IN_ACTION) && !lara.target) || lara.left_arm.lock)
			item->goal_anim_state = W_URECOIL;
		else
			item->goal_anim_state = W_UUNAIM;
		break;

	case W_RECOIL:
		/* Fire on second frame */
		if (item->frame_number - anims[item->anim_number].frame_base == 0)
		{
			item->goal_anim_state = W_UNAIM;
			if (lara.water_status != LARA_UNDERWATER && !running && !harpoon_fired)
			{
				if ((input & IN_ACTION) && (!lara.target || lara.left_arm.lock))
				{
					if (weapon_type == LG_HARPOON)
					{
						FireHarpoon();
						if (!(lara.harpoon.ammo&3)) // reload every 4 bolts
							harpoon_fired = 1;
					}
					else if (weapon_type == LG_ROCKET)
					{
						FireRocket();
					}
					else if (weapon_type == LG_M16)
					{
						FireM16(0);
						SoundEffect(78, &lara_item->pos, 0);
						m16_firing = 1;
					}
					else
						FireShotgun();

					item->goal_anim_state = W_RECOIL;
				}
				else if (lara.left_arm.lock)
					item->goal_anim_state = W_AIM; // loop on first frame
			}

			if (item->goal_anim_state != W_RECOIL && m16_firing)
			{
				SoundEffect(104, &lara_item->pos, 0);
				m16_firing = 0;
			}
		}
		else if (m16_firing)
			SoundEffect(78, &lara_item->pos, 0);
		else if (weapon_type == LG_SHOTGUN && !(input & IN_ACTION) && !lara.left_arm.lock)
			item->goal_anim_state = W_UNAIM;

		if ((item->frame_number - anims[item->anim_number].frame_base) == 12 && weapon_type == LG_SHOTGUN)
			TriggerGunShell(RIGHT_HAND,SHOTGUNSHELL,LG_SHOTGUN);
		break;

	case W_URECOIL:
		/* Underwater for harpoon; running for M16 */
		if (item->frame_number - anims[item->anim_number].frame_base == 0)
		{
			item->goal_anim_state = W_UUNAIM;
			if ((lara.water_status == LARA_UNDERWATER || running) && !harpoon_fired)
			{
				if ((input & IN_ACTION) && (!lara.target || lara.left_arm.lock))
				{
					if (weapon_type == LG_HARPOON)
					{
						FireHarpoon();
						if (!(lara.harpoon.ammo&3))
							harpoon_fired = 1;
					}
					else
						FireM16(1);
					item->goal_anim_state = W_URECOIL;
				}
				else if (lara.left_arm.lock)
					item->goal_anim_state = W_UAIM; // loop on first frame
			}
		}
		if (weapon_type == LG_M16 && item->goal_anim_state == W_URECOIL)
			SoundEffect(78, &lara_item->pos, 0);
		break;
	}
	AnimateItem(item);

//	lara.left_arm.frame_number = lara.right_arm.frame_number = item->frame_number;


	lara.left_arm.frame_base = lara.right_arm.frame_base = anims[item->anim_number].frame_ptr;
	lara.left_arm.frame_number = lara.right_arm.frame_number = item->frame_number - anims[item->anim_number].frame_base;
	lara.left_arm.anim_number = lara.right_arm.anim_number = item->anim_number;
}
