
/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#include "game.h"

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#define CAM_A_HANG 	0
#define CAM_E_HANG 	-60*ONE_DEGREE

#define DAMAGE_START  140
#define DAMAGE_LENGTH 14

#define MAX_HEAD_ROTATION 	(44*ONE_DEGREE)		// Look Around Limits
#define MAX_HEAD_TILT	  	(22*ONE_DEGREE)
#define MIN_HEAD_TILT 	  	(-35*ONE_DEGREE)
#define HEAD_TURN 		  	(2*ONE_DEGREE)

#define SLOPE_DIF  			60					// Maximum slope that can be vaulted etc..

#define BAD_JUMP_CEILING	((STEP_L*3)/4)		// 3/4  of a Step

#define LARA_DEF_ADD_EDGE	(5*ONE_DEGREE)

#ifdef PC_VERSION
//#define PC_JOYSTICK
#endif

/*---------------------------------------------------------------------------
 * Externals
\*--------------------------------------------------------------------------*/

extern char	*clmb_txt[];

#ifdef PSX_VERSION
extern sint32 LaraLookX;
extern sint32 LaraLookY;
#endif

/*---------------------------------------------------------------------------
 * Globals
\*--------------------------------------------------------------------------*/

LARA_INFO lara;
ITEM_INFO *lara_item;

int health_bar_timer=0;

/*---------------------------------------------------------------------------
 * Locals
\*--------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
 * Macros
\*--------------------------------------------------------------------------*/

#define FASTFALL_FRICTION	item->speed = (item->speed*95)/100

/*---------------------------------------------------------------------------
 * Local Functions
\*--------------------------------------------------------------------------*/

/*****************************************************************************
 *			Can Lara Hang at Current Position
 *				Returns 1 if lara still hanging
 ****************************************************************************/
static int TestWall(ITEM_INFO *item, sint32 front, sint32 right, sint32 down)
{
	int			x,y,z;
	int			h,c;
	FLOOR_INFO	*floor;
	sint16		room_num;
	PHD_ANGLE	angle;

	x = item->pos.x_pos;
	y = item->pos.y_pos + down;
	z = item->pos.z_pos;
	room_num = item->room_number;

	angle = (uint16)(item->pos.y_rot+0x2000)/0x4000;
	switch ( angle )
	{
		case NORTH:
			x-=right;
		break;

		case WEST:
			z+=right;
		break;

		case SOUTH:
			x+=right;
		break;

		case EAST:
			z-=right;
		break;
	}

	floor = GetFloor( x,y,z, &room_num );

	switch ( angle )
	{
		case NORTH:
			z+=front;
		break;

		case WEST:
			x-=front;
		break;

		case SOUTH:
			z-=front;
		break;

		case EAST:
			x+=front;
		break;
	}

	floor = GetFloor( x,y,z, &room_num );

	h = GetHeight( floor,x,y,z );
	c = GetCeiling( floor,x,y,z );
	if ( h!=NO_HEIGHT )
	{
		if ( (h-y)>0 && (c-y)<0 )
		{
			return(0); // No wall there
		}
		return(2);
	}
	return(1);			// Wall there!
}

/*******************************************************************************
 *			Handle When Lara Has Fallen Certain Distance
 ******************************************************************************/
static int LaraLandedBad(ITEM_INFO *item, COLL_INFO *coll)
{
	int landspeed, oy;
	FLOOR_INFO *floor;
	sint16 room_number;

	room_number = item->room_number;

	floor = GetFloor( item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
	oy = item->pos.y_pos;
	item->floor = item->pos.y_pos = GetHeight(floor, item->pos.x_pos, item->pos.y_pos-LARA_HITE, item->pos.z_pos );
	TestTriggers(trigger_index, 0);
	item->pos.y_pos = oy;
	landspeed = item->fallspeed - DAMAGE_START;
	if ( landspeed<=0 )
		return(0);
	else if ( landspeed>DAMAGE_LENGTH )
		item->hit_points = -1;
	else
		item->hit_points -= (landspeed*landspeed*LARA_HITPOINTS)/(DAMAGE_LENGTH*DAMAGE_LENGTH);
	if ( item->hit_points<=0 )
		return(1);
	return(0);
}

static int LaraDeflectEdgeDuck(ITEM_INFO *item, COLL_INFO *coll)
{
	if ((coll->coll_type == COLL_FRONT)
	||  (coll->coll_type == COLL_TOPFRONT))
	{
		ShiftItem(item, coll);
		item->speed = 0;
		item->gravity_status = 0;
		return 1;
	}

	else if (coll->coll_type == COLL_LEFT)
	{
		ShiftItem(item, coll);
		item->pos.y_rot += LARA_DEF_ADD_EDGE;
	}

	else if (coll->coll_type == COLL_RIGHT)
	{
		ShiftItem(item, coll);
		item->pos.y_rot -= LARA_DEF_ADD_EDGE;
	}

	return 0;
}

/*---------------------------------------------------------------------------
 * Public Functions
\*--------------------------------------------------------------------------*/

/****************************************************************************
* LaraAboveWater
*
* SYNOPSIS
*	void LaraAboveWater(ITEM_INFO *item, COLL_INFO *coll)
*
* PURPOSE
*	Standard Lara controller
*
* INPUTS
*	item		=
*	coll		=
*
* RETURN
*	Nothing
*/
void	LaraAboveWater(ITEM_INFO *item, COLL_INFO *coll)
{
/* -------- initialise collision defaults */

	coll->old.x = item->pos.x_pos;
	coll->old.y = item->pos.y_pos;
	coll->old.z = item->pos.z_pos;
	coll->old_anim_state = item->current_anim_state;
	coll->old_anim_number = item->anim_number;
	coll->old_frame_number = item->frame_number;
	coll->radius = LARA_RAD;
	coll->trigger = NULL;
	coll->lava_is_pit = 0;
	coll->slopes_are_walls = 0;
	coll->slopes_are_pits = 0;
	coll->enable_spaz = 1;
	coll->enable_baddie_push = 1;

/* -------- determine duck or roll */

#if 0
	if ((input & IN_DUCK)
	&& ((item->current_anim_state != AS_STOP)
	&&  (item->current_anim_state != AS_DUCK)
	&&  (item->current_anim_state != AS_DUCKROLL)))
		input = (input & ~IN_DUCK) | IN_ROLL;
#endif

/* -------- process look */

	if ((input & IN_LOOK) && !lara.extra_anim && lara.look)
		LookLeftRight();
	else
		ResetLook();

	lara.look = 1;

/* -------- process skidoo/boat */

	if (lara.skidoo != NO_ITEM)
	{
		if (items[lara.skidoo].object_number == SKIDOO) // may be a boat, not a skidoo!
		{
			if (SkidooControl())
				return;
		}
		else
		{
			LaraGun();
			return; // boat control is done in BoatControl
		}
	}

/* -------- update animation */

	if (lara.extra_anim)
		(*extra_control_routines[item->current_anim_state])(item, coll);
	else
		(*lara_control_routines[item->current_anim_state])(item, coll);		// Get Input regardless of Collisions etc..


	if ( item->pos.z_rot>=-LARA_LEAN_UNDO && item->pos.z_rot<=LARA_LEAN_UNDO )	// Undo Any Leaning
		item->pos.z_rot = 0;                                                    // on corners
	else if ( item->pos.z_rot<-LARA_LEAN_UNDO )
		item->pos.z_rot += LARA_LEAN_UNDO;
	else
		item->pos.z_rot -= LARA_LEAN_UNDO;


	if ( lara.turn_rate>=-LARA_TURN_UNDO && lara.turn_rate<=LARA_TURN_UNDO )	// Undo Turning Rate
		lara.turn_rate = 0;														// Uses fairly Quick rate
	else if ( lara.turn_rate<-LARA_TURN_UNDO )                                  // else get feeling of
		lara.turn_rate += LARA_TURN_UNDO;                                       // Unresponsiveness and Lag
	else
		lara.turn_rate -= LARA_TURN_UNDO;
	item->pos.y_rot += lara.turn_rate;                              			// Add On Turning Rate

	AnimateLara(item);															// Move Lara and animate...


	if (!lara.extra_anim)
	{
		LaraBaddieCollision( item,coll );											// Do any Baddie collisions...
		if (lara.skidoo == NO_ITEM) // 13/8/97: get out if Lara has found vehicle (in case normal collision overrides)
			(*lara_collision_routines[item->current_anim_state])( item,coll );			// Now Handle Any Collision Issues..
	}

	UpdateLaraRoom(item, -LARA_HITE/2);

	LaraGun();

	TestTriggers(coll->trigger, 0);
}


//--------------------------- DUCK ------------------------------------------

void	lara_as_duck(ITEM_INFO *item, COLL_INFO *coll)
{
	camera.target_elevation = -20*ONE_DEGREE;

	if (!(input & IN_DUCK))
	{
		item->goal_anim_state = AS_STOP;
		return;
	}

	if (input & IN_LOOK)
		LookUpDown();

	else	if (input & IN_FORWARD)
	{
		item->current_anim_state = AS_DUCKROLL;
		item->goal_anim_state = AS_DUCKROLL;
		item->anim_number =  DUCKROLL_A;
		item->frame_number = DUCKROLL_F;
		return;
	}
}

/* -------- forward roll from duck */

void	lara_as_duckroll( ITEM_INFO *item, COLL_INFO *coll )
{
	camera.target_elevation = -20*ONE_DEGREE;
	item->goal_anim_state = AS_DUCK;
}

void	lara_col_duck( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;
	lara.move_angle = item->pos.y_rot;
	coll->radius = LARA_RAD*2;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo(item, coll);

	if (LaraHitCeiling(item, coll))
		return;

	ShiftItem(item, coll);
	item->pos.y_pos += coll->mid_floor;
}

void	lara_col_duckroll(ITEM_INFO *item, COLL_INFO *coll)
{
	item->gravity_status = item->fallspeed = 0;
	lara.move_angle = item->pos.y_rot;
	coll->radius = LARA_RAD*2;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -(STEP_L-1);	// STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_walls = 1;
	coll->slopes_are_pits = 1;
	GetLaraCollisionInfo(item, coll);

	if (LaraHitCeiling(item, coll))
		return;

	if (LaraDeflectEdgeDuck(item, coll))
	{
		item->pos.z_rot = 0;

		if (item->frame_number < (DUCKROLL_F+2))
		{
			item->current_anim_state = AS_DUCK;
			item->goal_anim_state = AS_DUCK;
			item->anim_number = coll->old_anim_number;
			item->frame_number = coll->old_frame_number;
//			item->anim_number =  DUCKBREATHE_A;
//			item->frame_number = DUCKBREATHE_F;
		}

		return;
	}

	if (LaraFallen(item, coll))
		return;

	if (TestLaraSlide(item, coll))
		return;

	ShiftItem(item, coll);
	item->pos.y_pos += coll->mid_floor;
}

void LookUpDown(void)
{
	/* Look up/down and cancel up/down keys so don't have any other effects */
	camera.type = LOOK_CAMERA;

#ifdef ANALOG_CONTROL
	if (input & (IN_LOOKLEFT|IN_LOOKRIGHT|IN_LOOKFORWARD|IN_LOOKBACK))
		lara.head_x_rot = LaraLookX;
	else
#endif
	{
		if (input & IN_FORWARD)
		{
			input -= IN_FORWARD;
			if (lara.head_x_rot > MIN_HEAD_TILT)
				lara.head_x_rot -= HEAD_TURN;
		}
		else if (input & IN_BACK)
		{
			input -= IN_BACK;
			if (lara.head_x_rot < MAX_HEAD_TILT)
				lara.head_x_rot += HEAD_TURN;
		}
	}

	/* Twist torso if Lara's hands are not busy */
	if (lara.gun_status != LG_HANDSBUSY)
		lara.torso_x_rot = lara.head_x_rot;
}

void LookLeftRight(void)
{
	camera.type = LOOK_CAMERA;

#ifdef ANALOG_CONTROL
	if (input & (IN_LOOKLEFT|IN_LOOKRIGHT|IN_LOOKFORWARD|IN_LOOKBACK))
		lara.head_y_rot = LaraLookY;
	else
#endif
	{
		if (input & IN_LEFT)
		{
			input -= IN_LEFT;
			if (lara.head_y_rot > -MAX_HEAD_ROTATION)
				lara.head_y_rot -= HEAD_TURN;
		}
		else if (input & IN_RIGHT)
		{
			input -= IN_RIGHT;
			if (lara.head_y_rot < MAX_HEAD_ROTATION)
				lara.head_y_rot += HEAD_TURN;
		}
	}

	/* Twist torso if Lara's hands are not busy */
	if (lara.gun_status != LG_HANDSBUSY && lara.skidoo==NO_ITEM)
		lara.torso_y_rot = lara.head_y_rot;
}

void ResetLook(void)
{
	/* If looking at a target LOOK_CAMERA will be on when IN_LOOK is not pressed */
	if (camera.type == LOOK_CAMERA)
		return;

	/* If not in Look mode and got no target then reset Torso and Head Rots */
	if ( lara.head_x_rot > -HEAD_TURN && lara.head_x_rot < HEAD_TURN )
		lara.head_x_rot = 0;
	else
		lara.head_x_rot -= lara.head_x_rot/8;
	lara.torso_x_rot = lara.head_x_rot;

	if ( lara.head_y_rot > -HEAD_TURN && lara.head_y_rot < HEAD_TURN )
		lara.head_y_rot = 0;
	else
		lara.head_y_rot -= lara.head_y_rot/8;
	lara.torso_y_rot = lara.head_y_rot;
}

/******************************************************************************
 ******************************************************************************
 *					Lara control Routines Are Here
 *			these Request Different Anim States according to input..
 ******************************************************************************
 *****************************************************************************/

//-------------------------------------- WALK ---------------------------------

void	lara_as_walk( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->hit_points<=0 ) 					// Time To Die!!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}

#ifdef ANALOG_CONTROL
	if (input & IN_LOOK)
		LookUpDown();
#endif

#ifdef PC_JOYSTICK
	lara.turn_rate = LARA_FAST_TURN * joy_x >> 4;
#endif
	if ( input&IN_LEFT )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate -= LARA_TURN_RATE;
#endif
		if ( lara.turn_rate < -LARA_SLOW_TURN )
			lara.turn_rate = -LARA_SLOW_TURN;
	}
	else if ( input&IN_RIGHT )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate += LARA_TURN_RATE;
#endif
		if ( lara.turn_rate > LARA_SLOW_TURN )
			lara.turn_rate = LARA_SLOW_TURN;
	}
	if ( input & IN_FORWARD )
	{
		if (lara.water_status==LARA_WADE)
		{
			item->goal_anim_state = AS_WADE;
		}
		else
		{
			if (!( input&IN_SLOW ))
				item->goal_anim_state = AS_RUN;
			else
				item->goal_anim_state = AS_WALK;
		}
	}
	else
		item->goal_anim_state = AS_STOP;
}

//--------------------------------------- DASH ------------------------------

void	lara_as_dash(ITEM_INFO *item, COLL_INFO *coll)
{
	static int jump_ok = 1;

	if ( item->hit_points<=0 ) 					// Time To Die!!!
	{
		item->goal_anim_state = AS_DEATH;
		return;
	}

	if (input & IN_ROLL)
	{
		item->anim_number =  ROLL_A;
		item->frame_number = ROLL_F;
		item->current_anim_state = AS_ROLL;
		item->goal_anim_state = AS_STOP;
		return;
	}


#ifdef ANALOG_CONTROL
	if (input & IN_LOOK)
		LookUpDown();
#endif

#ifdef PC_JOYSTICK
	lara.turn_rate = LARA_FAST_TURN * joy_x >> 4;
#endif
	if ( input&IN_LEFT )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_FAST_TURN )
			lara.turn_rate = -LARA_FAST_TURN;
#endif
		item->pos.z_rot -= LARA_LEAN_RATE;
		if ( item->pos.z_rot< - LARA_LEAN_MAX )
			item->pos.z_rot = -LARA_LEAN_MAX;
	}
	else if ( input&IN_RIGHT )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_FAST_TURN )
			lara.turn_rate = LARA_FAST_TURN;
#endif
		item->pos.z_rot += LARA_LEAN_RATE;
		if ( item->pos.z_rot > LARA_LEAN_MAX )
			item->pos.z_rot = LARA_LEAN_MAX;
	}

	/* Gav: jump lock during stop2run anim (anim 6) */
   if (item->anim_number == 6)
		jump_ok = 0;
	else if (item->anim_number == 0)
	{
		// If proper run anim, wait till frame 4 before removing jump lock
		if (item->frame_number == 4)
			jump_ok = 1;
	}
	else // if any other anim, reset jump lock (if it is engaged; could happen if player stopped during stop2run anim)
		jump_ok = 1;

	if ( input&IN_JUMP && jump_ok && !item->gravity_status )
		item->goal_anim_state = AS_FORWARDJUMP;
	else if (input & IN_FORWARD )
	{
		if (lara.water_status==LARA_WADE)
		{
			item->goal_anim_state = AS_WADE;
		}
		else
		{
			if ( input&IN_SLOW )
				item->goal_anim_state = AS_WALK;
			else
				item->goal_anim_state = AS_RUN;
		}
	}
	else
		item->goal_anim_state = AS_STOP;
}



//---------------------------------------  RUN  -------------------------------

void	lara_as_run( ITEM_INFO *item, COLL_INFO *coll )
{
	static int jump_ok = 1;

	if ( item->hit_points<=0 ) 					// Time To Die!!!
	{
		item->goal_anim_state = AS_DEATH;
		return;
	}

	if (input & IN_DUCK)
	{
		item->anim_number = DASH_A;
		item->frame_number = DASH_F;
		item->current_anim_state = AS_DASH;
		item->goal_anim_state = AS_DASH;
		return;
	}

	if (input & IN_ROLL)
	{
		item->anim_number =  ROLL_A;
		item->frame_number = ROLL_F;
		item->current_anim_state = AS_ROLL;
		item->goal_anim_state = AS_STOP;
		return;
	}


#ifdef ANALOG_CONTROL
	if (input & IN_LOOK)
		LookUpDown();
#endif

#ifdef PC_JOYSTICK
	lara.turn_rate = LARA_FAST_TURN * joy_x >> 4;
#endif
	if ( input&IN_LEFT )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_FAST_TURN )
			lara.turn_rate = -LARA_FAST_TURN;
#endif
		item->pos.z_rot -= LARA_LEAN_RATE;
		if ( item->pos.z_rot< - LARA_LEAN_MAX )
			item->pos.z_rot = -LARA_LEAN_MAX;
	}
	else if ( input&IN_RIGHT )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_FAST_TURN )
			lara.turn_rate = LARA_FAST_TURN;
#endif
		item->pos.z_rot += LARA_LEAN_RATE;
		if ( item->pos.z_rot > LARA_LEAN_MAX )
			item->pos.z_rot = LARA_LEAN_MAX;
	}

	/* Gav: jump lock during stop2run anim (anim 6) */
   if (item->anim_number == 6)
		jump_ok = 0;
	else if (item->anim_number == 0)
	{
		// If proper run anim, wait till frame 4 before removing jump lock
		if (item->frame_number == 4)
			jump_ok = 1;
	}
	else // if any other anim, reset jump lock (if it is engaged; could happen if player stopped during stop2run anim)
		jump_ok = 1;

	if ( input&IN_JUMP && jump_ok && !item->gravity_status )
		item->goal_anim_state = AS_FORWARDJUMP;
	else if (input & IN_FORWARD )
	{
		if (lara.water_status==LARA_WADE)
		{
			item->goal_anim_state = AS_WADE;
		}
		else
		{
			if ( input&IN_SLOW )
				item->goal_anim_state = AS_WALK;
			else
				item->goal_anim_state = AS_RUN;
		}
	}
	else
		item->goal_anim_state = AS_STOP;
}


//----------------------------------------- STOP ------------------------------

#define POSE_START	(30*4)

void	lara_as_stop( ITEM_INFO *item, COLL_INFO *coll )
{
#ifdef ANALOG_CONTROL
	static char wait=0;
#endif

	if (item->hit_points <= 0)	// Time To Die !!!
	{
		item->goal_anim_state = AS_DEATH;
		return;
	}

	if ( input&IN_ROLL && lara.water_status!=LARA_WADE)							// Allow immediate entry
	{                                               // into Forward Roll
		item->anim_number =  ROLL_A;
		item->frame_number = ROLL_F;
		item->current_anim_state = AS_ROLL;
		item->goal_anim_state = AS_STOP;
		return;
	}

	if ((input & IN_DUCK)
	&&  (lara.gun_status == LG_ARMLESS)
	&&  (lara.water_status != LARA_WADE))
	{
		item->goal_anim_state = AS_DUCK;
		return;
	}

	item->goal_anim_state = AS_STOP;

	/* If using Look Key enable Lara to Look around */
	if (input & IN_LOOK)
		LookUpDown();

#ifdef ANALOG_CONTROL
	if (input & (IN_FORWARD|IN_BACK|IN_LEFT|IN_RIGHT|IN_STEPL|IN_STEPR))
	{
		if (input & IN_SLOW)
		{
			if (wait < 2)
			{
				wait++;
				return;
			}
		}
	}
	else
		wait = 0;
#endif

	if (input & IN_STEPL)
		item->goal_anim_state = AS_STEPLEFT;

	else if (input & IN_STEPR)
		item->goal_anim_state = AS_STEPRIGHT;

	else if (input & IN_LEFT)                           	// Do Turning...
		item->goal_anim_state = AS_TURN_L;

	else if (input & IN_RIGHT)
		item->goal_anim_state = AS_TURN_R;


	if ( lara.water_status==LARA_WADE )
	{
		if ( input&IN_JUMP )
			item->goal_anim_state = AS_COMPRESS;

		if ( input&IN_FORWARD )
		{
			if ( input&IN_SLOW )
				lara_as_wade( item,coll );
			else
				lara_as_walk( item,coll );
		}
		else if ( input&IN_BACK )
			lara_as_back( item,coll );
	}
	else
	{
		if (input & IN_JUMP)		// If user wants to move
			item->goal_anim_state = AS_COMPRESS;

		else if (input & IN_FORWARD)
		{
			if (input & IN_SLOW)
				lara_as_walk(item, coll);
			else
				lara_as_run(item, coll);
		}

		else if (input & IN_BACK)
		{
			if (input & IN_SLOW)
				lara_as_back(item, coll);
			else
				item->goal_anim_state = AS_FASTBACK;
		}
	}
}


//--------------------------- FORWARDJUMP --------------------------------------

void	lara_as_forwardjump( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->goal_anim_state==AS_SWANDIVE || item->goal_anim_state==AS_REACH )
		item->goal_anim_state = AS_FORWARDJUMP;
	if ( item->goal_anim_state!=AS_DEATH && item->goal_anim_state!=AS_STOP && item->goal_anim_state!=AS_RUN )
	{
		if ( (input&IN_ACTION) && lara.gun_status==LG_ARMLESS)
			item->goal_anim_state = AS_REACH;
		if ((input&IN_ROLL) || (input&IN_BACK))
			item->goal_anim_state = AS_TWIST;
		if ( (input&IN_SLOW) && lara.gun_status==LG_ARMLESS)
			item->goal_anim_state = AS_SWANDIVE;
		if (item->fallspeed > LARA_FASTFALL_SPEED)		// Fastfall has highest Priority
			item->goal_anim_state = AS_FASTFALL;        // for State changes
	}

	if ( input&IN_LEFT )							// TURN While Jumping..
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_JUMP_TURN )
			lara.turn_rate = -LARA_JUMP_TURN;
	}
	else if ( input&IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_JUMP_TURN )
			lara.turn_rate = LARA_JUMP_TURN;
	}
}

//------------------------------- POSE ----------------------------------------

void	lara_as_pose( ITEM_INFO *item, COLL_INFO *coll )
{
}

//------------------------------- FASTBACK ------------------------------------

void	lara_as_fastback( ITEM_INFO *item, COLL_INFO *coll )
{
	item->goal_anim_state = AS_STOP;
	if ( input&IN_LEFT )
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_MED_TURN )
			lara.turn_rate = -LARA_MED_TURN;
	}
	else if ( input&IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_MED_TURN )
			lara.turn_rate = LARA_MED_TURN;
	}
}

//-------------------------------- TURN R -------------------------------------

void	lara_as_turn_r( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->hit_points<=0 )						// Time To Die !!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
#ifdef PC_JOYSTICK
	lara.turn_rate = joy_x * LARA_FAST_TURN >> 4;
#else
	lara.turn_rate += LARA_TURN_RATE;
#endif
	if ( lara.gun_status==LG_READY)
		item->goal_anim_state = AS_FASTTURN;
	else if ( lara.turn_rate > LARA_SLOW_TURN )
	{
		if ( !(input&IN_SLOW) )
			item->goal_anim_state = AS_FASTTURN;
		else
			lara.turn_rate = LARA_SLOW_TURN;
	}
	if ( input&IN_FORWARD )
	{
		if (lara.water_status==LARA_WADE)
		{
			item->goal_anim_state = AS_WADE;
		}
		else
		{
			if ( input&IN_SLOW )
				item->goal_anim_state = AS_WALK;
			else
				item->goal_anim_state = AS_RUN;
		}
	}
	else if ( !( input&IN_RIGHT ) )
		item->goal_anim_state = AS_STOP;
}

//-------------------------------- TURN L -------------------------------------

void	lara_as_turn_l( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->hit_points<=0 )						// Time To Die !!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
#ifdef PC_JOYSTICK
	lara.turn_rate = joy_x * LARA_FAST_TURN >> 4;
#else
	lara.turn_rate -= LARA_TURN_RATE;
#endif
	if ( lara.gun_status==LG_READY )
		item->goal_anim_state = AS_FASTTURN;
	else if ( lara.turn_rate < -LARA_SLOW_TURN )
	{
		if ( !(input&IN_SLOW) )
			item->goal_anim_state = AS_FASTTURN;
		else
			lara.turn_rate = -LARA_SLOW_TURN;
	}
	if ( input&IN_FORWARD )
	{
		if (lara.water_status==LARA_WADE)
		{
			item->goal_anim_state = AS_WADE;
		}
		else
		{
			if ( input&IN_SLOW )
				item->goal_anim_state = AS_WALK;
			else
				item->goal_anim_state = AS_RUN;
		}
	}
	else if ( !( input&IN_LEFT ) )
		item->goal_anim_state = AS_STOP;
}

//------------------------------ DEATH ----------------------------------------
void	lara_as_death( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
//	camera.target_angle = 60*ONE_DEGREE;
//	camera.target_elevation = -45*ONE_DEGREE;
}

//---------------------------- FASTFALL ---------------------------------------

void	lara_as_fastfall( ITEM_INFO *item, COLL_INFO *coll )
{
	FASTFALL_FRICTION;
	if ( item->fallspeed==DAMAGE_START+DAMAGE_LENGTH )		//Kick off FALL_TO_DEATH sound effect
		SoundEffect( 30, &item->pos, 0 );
}

//----------------------------- HANG ------------------------------------------

void	lara_as_hang( ITEM_INFO *item, COLL_INFO *coll )
{
	if (input & IN_LOOK)
		LookUpDown();

	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = CAM_A_HANG;
	camera.target_elevation = CAM_E_HANG;
	if ( input&IN_LEFT || input&IN_STEPL )
		item->goal_anim_state = AS_HANGLEFT;
	else if ( input&IN_RIGHT || input&IN_STEPR )
		item->goal_anim_state = AS_HANGRIGHT;
}

//----------------------------- REACH -----------------------------------------
void	lara_as_reach( ITEM_INFO *item, COLL_INFO *coll )
{
	camera.target_angle = 85*ONE_DEGREE;
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
}

//----------------------------- SPLAT -----------------------------------------

void	lara_as_splat( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
}


//----------------------------------- LAND ------------------------------------

void	lara_as_land( ITEM_INFO *item, COLL_INFO *coll )
{
}

//-------------------------------- COMPRESS -----------------------------------

void	lara_as_compress( ITEM_INFO *item, COLL_INFO *coll )
{
	if (lara.water_status != LARA_WADE)
	{
		if ( (input&IN_FORWARD) && LaraFloorFront(item,item->pos.y_rot, 256)>=-STEPUP_HEIGHT )	// If Wall Directly In front
		{		                                                                           		// then dont go to jump in
			item->goal_anim_state = AS_FORWARDJUMP;                                 			// that direction
			lara.move_angle = item->pos.y_rot;
		}
		else if ( (input&IN_LEFT) && LaraFloorFront(item, (sint16)(item->pos.y_rot-16384), 256)>=-STEPUP_HEIGHT )
		{
			item->goal_anim_state = AS_LEFTJUMP;
			lara.move_angle = item->pos.y_rot-16384;
		}
		else if ( (input&IN_RIGHT) && LaraFloorFront(item, (sint16)(item->pos.y_rot+16384), 256)>=-STEPUP_HEIGHT )
		{
			item->goal_anim_state = AS_RIGHTJUMP;
			lara.move_angle = item->pos.y_rot+16384;
		}
		else if ( (input&IN_BACK) && LaraFloorFront(item, (sint16)(item->pos.y_rot-32768), 256)>=-STEPUP_HEIGHT )
		{
			item->goal_anim_state = AS_BACKJUMP;
			lara.move_angle = item->pos.y_rot-32768;
		}
	}
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
}

//------------------------------------- BACK ----------------------------------

void	lara_as_back( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->hit_points<=0 )						// Time To Die !!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
	if ( !(input&IN_BACK) || (!(input&IN_SLOW) && lara.water_status!=LARA_WADE) )		// if release SLOW or BACK
		item->goal_anim_state = AS_STOP;            // go back to STOP
	else
		item->goal_anim_state = AS_BACK;
	if ( input&IN_LEFT )
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_SLOW_TURN )
			lara.turn_rate = -LARA_SLOW_TURN;
	}
	else if ( input&IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_SLOW_TURN )
			lara.turn_rate = LARA_SLOW_TURN;
	}
}

//----------------------------------- NULL ------------------------------------
void	lara_as_null( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;      			// No spazing or pushing
	coll->enable_baddie_push = 0;
}

//---------------------------------- FAST_TURN ------------------------------

void	lara_as_fastturn( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->hit_points<=0 )						// Time To Die !!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
#ifdef PC_JOYSTICK
	lara.turn_rate = LARA_FAST_TURN * joy_x >> 4;
#endif
	if ( lara.turn_rate<0 )
	{
#ifndef PC_JOYSTICK
		lara.turn_rate = -LARA_FAST_TURN;
#endif
		if ( !(input&IN_LEFT) )
			item->goal_anim_state = AS_STOP;
	}
	else
	{
#ifndef PC_JOYSTICK
		lara.turn_rate = LARA_FAST_TURN;
#endif
		if ( !(input&IN_RIGHT) )
			item->goal_anim_state = AS_STOP;
	}
}

//----------------------------------- STEP_RIGHT ---------------------------

void	lara_as_stepright( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	if ( item->hit_points<=0 )						// Time To Die !!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
	if ( !(input&IN_STEPR) )
		item->goal_anim_state = AS_STOP;			// Go Back To A Stop straight away..

	if ( input&IN_LEFT )
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_SLOW_TURN )
			lara.turn_rate = -LARA_SLOW_TURN;
	}
	else if ( input&IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_SLOW_TURN )
			lara.turn_rate = LARA_SLOW_TURN;
	}
}

//----------------------------------- STEP_LEFT ----------------------------

void	lara_as_stepleft( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	if ( item->hit_points<=0 )						// Time To Die !!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
	if ( !(input&IN_STEPL) )
		item->goal_anim_state = AS_STOP;			// Go Back To A Stop straight away..
	if ( input&IN_LEFT )
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_SLOW_TURN )
			lara.turn_rate = -LARA_SLOW_TURN;
	}
	else if ( input&IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_SLOW_TURN )
			lara.turn_rate = LARA_SLOW_TURN;
	}
}

//----------------------------------- SLIDE ----------------------------

void	lara_as_slide( ITEM_INFO *item, COLL_INFO *coll )
{
	camera.flags = NO_CHUNKY;
	camera.target_elevation = -45 * ONE_DEGREE;
	if ( (input&IN_JUMP) && !(input&IN_BACK))
		item->goal_anim_state = AS_FORWARDJUMP;
}

//----------------------------------- BACKJUMP ----------------------------

void	lara_as_backjump( ITEM_INFO *item, COLL_INFO *coll )
{
	camera.target_angle = ONE_DEGREE * 135;
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
	else if (item->goal_anim_state == AS_RUN) // twist from forward jump; may have set goal as RUN, but need STOP in backjump
		item->goal_anim_state = AS_STOP;
	else if ((input&IN_FORWARD || input&IN_ROLL) && item->goal_anim_state!=AS_STOP)
		item->goal_anim_state = AS_TWIST;
}

//----------------------------------- RIGHTJUMP ----------------------------

void	lara_as_rightjump( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
	else if (input&IN_LEFT && item->goal_anim_state!=AS_STOP)
		item->goal_anim_state = AS_TWIST;
}

//----------------------------------- LEFTJUMP ----------------------------

void	lara_as_leftjump( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
	else if (input&IN_RIGHT && item->goal_anim_state!=AS_STOP)
		item->goal_anim_state = AS_TWIST;
}

//----------------------------------- UPJUMP ----------------------------

void	lara_as_upjump( ITEM_INFO *item, COLL_INFO *coll )
{
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
}


//-------------------------------- FALLBACK ----------------------------

void	lara_as_fallback( ITEM_INFO *item, COLL_INFO *coll )
{
	if (item->fallspeed > LARA_FASTFALL_SPEED)
		item->goal_anim_state = AS_FASTFALL;
	if ( (input&IN_ACTION) && lara.gun_status==LG_ARMLESS)
		item->goal_anim_state = AS_REACH;
}


//-------------------------------- HANGLEFT ----------------------------
void	lara_as_hangleft( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = CAM_A_HANG;
	camera.target_elevation = CAM_E_HANG;
	if ( !(input&IN_LEFT) && !(input&IN_STEPL) )
		item->goal_anim_state = AS_HANG;
}


//-------------------------------- HANGRIGHT ----------------------------
void	lara_as_hangright( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = CAM_A_HANG;
	camera.target_elevation = CAM_E_HANG;
	if ( !(input&IN_RIGHT) && !(input&IN_STEPR) )
		item->goal_anim_state = AS_HANG;
}
//-------------------------------- SLIDEBACK ----------------------------
void	lara_as_slideback( ITEM_INFO *item, COLL_INFO *coll )
{
	if ((input&IN_JUMP) && !(input&IN_FORWARD))
		item->goal_anim_state = AS_BACKJUMP;
}

//------------------------------- PUSHBLOCK -----------------------------
void	lara_as_pushblock( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.flags = FOLLOW_CENTRE;
	camera.target_angle = 35*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
}

//------------------------------- PULLBLOCK -----------------------------
void	lara_as_pullblock( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.flags = FOLLOW_CENTRE;
	camera.target_angle = 35*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
}

//------------------------------- PPREADY -------------------------------
void	lara_as_ppready( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = 75*ONE_DEGREE;
	if ( !(input&IN_ACTION) )				// if user releases ACTION
		item->goal_anim_state = AS_STOP;    // go back to stop
}

//------------------------------- PICKUP -------------------------------
void	lara_as_pickup( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = -130*ONE_DEGREE;
	camera.target_elevation = -15*ONE_DEGREE;
	camera.target_distance = WALL_L;
}

//------------------------------- PICKUP FLARE --------------------------
void	lara_as_pickupflare( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = +130*ONE_DEGREE;
	camera.target_elevation = -15*ONE_DEGREE;
	camera.target_distance = WALL_L;

	/* In case flare goes out before end of anim, free up hands automatically! */
	if (item->frame_number == anims[item->anim_number].frame_end-1)
		lara.gun_status = LG_ARMLESS;
}

//------------------------------- SWITCHON -------------------------------
void	lara_as_switchon( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = 80*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
	camera.target_distance = WALL_L;
	camera.speed = 6;
}

//------------------------------- SWITCHOFF ------------------------------
void	lara_as_switchoff( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = 80*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
	camera.target_distance = WALL_L;
	camera.speed = 6;
}

//------------------------------- USEKEY ---------------------------------
void	lara_as_usekey( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = -80*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
	camera.target_distance = WALL_L;
}

//------------------------------- USEPUZZLE ------------------------------
void	lara_as_usepuzzle( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 0;
	camera.target_angle = -80*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
	camera.target_distance = WALL_L;
}

//------------------------------- ROLL -----------------------------------
void	lara_as_roll( ITEM_INFO *item, COLL_INFO *coll )
{
}

//----------------------------------- ROLL2 ----------------------------
void	lara_as_roll2( ITEM_INFO *item, COLL_INFO *coll )
{
}

//-------------------------- SPECIAL DEATH --------------------------------
void	lara_as_special( ITEM_INFO *item, COLL_INFO *coll )
{
	camera.flags = FOLLOW_CENTRE;                   // Dino death etc...
	camera.target_angle = 170*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
}

//-------------------------- USE MIDAS --------------------------------
void	lara_as_usemidas( ITEM_INFO *item, COLL_INFO *coll )
{

}

//-------------------------- DIE MIDAS --------------------------------
void	lara_as_diemidas( ITEM_INFO *item, COLL_INFO *coll )
{

}

//-------------------------- SWAN DIVE --------------------------------
void	lara_as_swandive( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 1;
	if (item->fallspeed > LARA_FASTFALL_SPEED && item->goal_anim_state!=AS_DIVE)
		item->goal_anim_state = AS_FASTDIVE;
}

//-------------------------- FAST DIVE --------------------------------
void	lara_as_fastdive( ITEM_INFO *item, COLL_INFO *coll )
{
	if ((input&IN_ROLL) && item->goal_anim_state == AS_FASTDIVE)
		item->goal_anim_state = AS_TWIST;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 1;
	FASTFALL_FRICTION;
}

//-------------------------- GYMNASTICS --------------------------------
void	lara_as_gymnast( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;      			// No spazing or pushing
	coll->enable_baddie_push = 0;
//	camera.flags = FOLLOW_CENTRE;
//	camera.target_angle = 35*ONE_DEGREE;
//	camera.target_elevation = -25*ONE_DEGREE;
//	camera.target_distance = WALL_L;
}

//-------------------------------WATER-OUT ------------------------------------
void	lara_as_waterout( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->enable_spaz = 0;      			// same as null but no bum-zoom
	coll->enable_baddie_push = 0;
	camera.flags = FOLLOW_CENTRE;
}

void	lara_as_laratest1( ITEM_INFO *item, COLL_INFO *coll )
{
}

void	lara_as_laratest2( ITEM_INFO *item, COLL_INFO *coll )
{
}

void	lara_as_laratest3( ITEM_INFO *item, COLL_INFO *coll )
{
}

void	lara_as_wade( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( item->hit_points<=0 ) 					// Time To Die!!!
	{
		item->goal_anim_state = AS_STOP;
		return;
	}
	camera.target_elevation = -22*ONE_DEGREE;

	if ( input&IN_LEFT )
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_FAST_TURN )
			lara.turn_rate = -LARA_FAST_TURN;
		item->pos.z_rot -= LARA_LEAN_RATE;
		if ( item->pos.z_rot< - LARA_LEAN_MAX )
			item->pos.z_rot = -LARA_LEAN_MAX;
	}
	else if ( input&IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_FAST_TURN )
			lara.turn_rate = LARA_FAST_TURN;
		item->pos.z_rot += LARA_LEAN_RATE;
		if ( item->pos.z_rot > LARA_LEAN_MAX )
			item->pos.z_rot = LARA_LEAN_MAX;
	}

	if (input & IN_FORWARD )
	{
		if ( lara.water_status==LARA_ABOVEWATER )
			item->goal_anim_state = AS_RUN;
		else
			item->goal_anim_state = AS_WADE;
	}
	else
		item->goal_anim_state = AS_STOP;
}

void	lara_as_twist( ITEM_INFO *item, COLL_INFO *coll )
{
	// NEVER ACTUALLY USED (NO ANIM HAS THIS STATE, BUT LINKS DO)
}

void lara_as_kick( ITEM_INFO *item, COLL_INFO *coll )
{
}

void lara_as_deathslide( ITEM_INFO *item, COLL_INFO *coll )
{
	sint16 room_number;
	FLOOR_INFO *floor;

	camera.target_angle = ONE_DEGREE * 70;

	// test triggers
	room_number = item->room_number;
	floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
	GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos);
	coll->trigger = trigger_index;

	if (!(input&IN_ACTION))
	{
		item->goal_anim_state = AS_FORWARDJUMP;
		AnimateLara(item);
		lara_item->gravity_status = 1;
		lara_item->speed = 100;
		lara_item->fallspeed = 40;
		lara.move_angle = item->pos.y_rot;
	}
}

/***************************** EXTRA ANIMATIONS ********************************/
void extra_as_breath(ITEM_INFO *item, COLL_INFO *coll)
{
	/* Finished extra animation, so jump back to normal breath stance */
	item->anim_number = BREATH_A;
	item->frame_number = BREATH_F;
	item->current_anim_state = item->goal_anim_state = AS_STOP;

	lara.gun_status = LG_ARMLESS;

	camera.type = CHASE_CAMERA;
	AlterFOV(GAME_FOV*ONE_DEGREE);

	lara.extra_anim = 0;
}

void extra_as_plunger(ITEM_INFO *item, COLL_INFO *coll)
{
	// erm... do some stuff here...
}

void extra_as_yetikill(ITEM_INFO *item, COLL_INFO *coll)
{
	camera.target_angle = ONE_DEGREE * 160;
	camera.target_distance = 3*WALL_L;
	lara.hit_direction = -1;

	if (item->frame_number < anims[item->anim_number].frame_end - 30)
		lara.death_count = 1;
}

void extra_as_sharkkill(ITEM_INFO *item, COLL_INFO *coll)
{
	int wh;

	camera.target_angle = ONE_DEGREE * 160;
	camera.target_distance = 3*WALL_L;
	lara.hit_direction = -1;

	/* Lara floats upwards at end of anim */
	if (item->frame_number == anims[item->anim_number].frame_end)
	{
		wh = GetWaterHeight( item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, item->room_number );
		if ( wh!=NO_HEIGHT && wh<item->pos.y_pos-100 )
			item->pos.y_pos -= 5;
	}

	if (item->frame_number < anims[item->anim_number].frame_end - 30)
		lara.death_count = 1;
}

void extra_as_airlock(ITEM_INFO *item, COLL_INFO *coll)
{
	camera.target_angle = 80*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
}

void extra_as_gongbong(ITEM_INFO *item, COLL_INFO *coll)
{
	camera.target_angle = -25*ONE_DEGREE;
	camera.target_elevation = -20*ONE_DEGREE;
	camera.target_distance = WALL_L*3;
}

void extra_as_dinokill(ITEM_INFO *item, COLL_INFO *coll)
{
	camera.flags = FOLLOW_CENTRE;
	camera.target_angle = 170*ONE_DEGREE;
	camera.target_elevation = -25*ONE_DEGREE;
	lara.hit_direction = -1;
	if (item->frame_number < anims[item->anim_number].frame_end - 30)
		lara.death_count = 1;
}

void extra_as_pulldagger(ITEM_INFO *item, COLL_INFO *coll)
{
	sint16 room_number;
	int frame;
	FLOOR_INFO *floor;

	frame = item->frame_number - anims[item->anim_number].frame_base;
	if (frame == 1)
		S_StartSyncedAudio(28);
	else if (frame == 180)
	{
		lara.mesh_ptrs[HAND_R] = meshes[objects[LARA].mesh_index + HAND_R];
		Inv_AddItem(PUZZLE_ITEM2);
	}

	if (item->frame_number == anims[item->anim_number].frame_end)
	{
		item->pos.y_rot += 0x4000;

		room_number = item->room_number;
		floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
		GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos);
		TestTriggers(trigger_index, 1); // activate HEAVY triggers for exit doors
	}
}

void extra_as_startanim(ITEM_INFO *item, COLL_INFO *coll)
{
	sint16 room_number;
	FLOOR_INFO *floor;
	room_number = item->room_number;
	floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
	GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos);
	TestTriggers(trigger_index, 0);
}

void extra_as_starthouse(ITEM_INFO *item, COLL_INFO *coll)
{
	int frame;

	frame = item->frame_number - anims[item->anim_number].frame_base;
	if (frame == 1)
	{
		S_StartSyncedAudio(63);
		lara.mesh_ptrs[HAND_R] = meshes[objects[LARA_EXTRA].mesh_index + HAND_R];
		lara.mesh_ptrs[HIPS] = meshes[objects[LARA_EXTRA].mesh_index + HIPS];
	}
	else if (frame == 401)
	{
		lara.mesh_ptrs[HAND_R] = meshes[objects[LARA].mesh_index + HAND_R];
		lara.mesh_ptrs[HIPS] = meshes[objects[LARA].mesh_index + HIPS];
		Inv_AddItem(PUZZLE_ITEM1);
	}
	else if (item->frame_number == anims[item->anim_number].frame_end)
	{
		camera.type = CHASE_CAMERA;
		AlterFOV(GAME_FOV*ONE_DEGREE);
	}
}

void extra_as_finalanim(ITEM_INFO *item, COLL_INFO *coll)
{
	int frame;

	item->hit_points = LARA_HITPOINTS; // stop health bar showing

	frame = item->frame_number - anims[item->anim_number].frame_base;
	if (frame == 1)
	{
		lara.back_gun = 0;
		lara.mesh_ptrs[HAND_R] = meshes[objects[LARA].mesh_index + HAND_R];
		lara.mesh_ptrs[HEAD] = meshes[objects[LARA].mesh_index + HEAD];
		lara.mesh_ptrs[HIPS] = meshes[objects[LARA_EXTRA].mesh_index + HIPS];
		S_StartSyncedAudio(27);
	}
	else if (frame == 316)
		lara.mesh_ptrs[HAND_R] = meshes[objects[SHOTGUN].mesh_index + HAND_R];
	else if (item->frame_number == anims[item->anim_number].frame_end-1)
		level_complete = 1;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 +					Lara control Routines Are Here
 +			these Request Different Anim States according to input..
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int LaraFallen( ITEM_INFO *item, COLL_INFO *coll )
{
	// if the ground has gone from under our feet (trapdoor or falling floor), then initiate a fall
	if ( coll->mid_floor > STEPUP_HEIGHT && lara.water_status != LARA_WADE )
	{
		item->anim_number = FALLDOWN_A;
		item->frame_number = FALLDOWN_F;
		item->current_anim_state = AS_FORWARDJUMP;
		item->goal_anim_state = AS_FORWARDJUMP;
		item->fallspeed = 0;
		item->gravity_status = 1;
		return 1;
	}
	return 0;
}

void LaraCollideStop(ITEM_INFO *item, COLL_INFO *coll)
{
/* Lara has run/walked etc into something and needs to be in stop state.
 * However, if she started the control phase in this state, then should
 * continue old anim */

	switch (coll->old_anim_state)
	{
		case AS_STOP:
		case AS_TURN_L:
		case AS_TURN_R:
		case AS_FASTTURN:
			item->current_anim_state = coll->old_anim_state;
			item->anim_number = coll->old_anim_number;
			item->frame_number = coll->old_frame_number;
			if ( input&IN_LEFT )
				item->goal_anim_state = AS_TURN_L;
			else if ( input&IN_RIGHT )
				item->goal_anim_state = AS_TURN_R;
			else
				item->goal_anim_state = AS_STOP;
			AnimateLara(item);
			break;

		default:
			item->anim_number = STOP_A;
			item->frame_number = STOP_F;
	}
}

//+++++++++++++++++++++++++++ WALK +++++++++++++++++++++++++++++++++++++++++
void	lara_col_walk( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;				// No Gravity Effects
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	coll->lava_is_pit = 1;
	GetLaraCollisionInfo( item, coll );

	if ( LaraHitCeiling( item,coll ) )
		return;
	if ( TestLaraVault( item,coll ) )
		return;

	if (LaraDeflectEdge( item,coll ))						  // If Hit Wall or DropOff Head ON
	{
		if ( item->frame_number>=22+7 && item->frame_number<=22+25 )
		{
			item->anim_number = STOP_RIGHT_A;                 // Animation for Walk stop Right
			item->frame_number = STOP_RIGHT_F;
		}
		else if ( (item->frame_number>=22 && item->frame_number<=22+6) ||
		 	  	(item->frame_number>=22+26 && item->frame_number<=22+35)	)
		{
			item->anim_number = STOP_LEFT_A;                  // Animation for Walk stop Left
			item->frame_number = STOP_LEFT_F;
		}
		else
			LaraCollideStop(item, coll);
	}

	if (LaraFallen(item, coll))
		return;

	if ( coll->mid_floor > STEP_L/2 )									// Need to STEP DOWN
	{
		if ( item->frame_number>=28 && item->frame_number<=45 )
		{
			item->anim_number = WALKSTEPD_RIGHT_A;
			item->frame_number = WALKSTEPD_RIGHT_F;
		}
		else
		{
			item->anim_number = WALKSTEPD_LEFT_A;
			item->frame_number = WALKSTEPD_LEFT_F;
		}
	}
	if ( coll->mid_floor >= -STEPUP_HEIGHT && coll->mid_floor < -STEP_L/2 )	// Need to STEP UP
	{
		if ( item->frame_number>=27 && item->frame_number<=44 )
		{
			item->anim_number = WALKSTEPUP_RIGHT_A;
			item->frame_number = WALKSTEPUP_RIGHT_F;
		}
		else
		{
			item->anim_number = WALKSTEPUP_LEFT_A;
			item->frame_number = WALKSTEPUP_LEFT_F;
		}
	}

	if ( TestLaraSlide(item,coll ) )
		return;

	item->pos.y_pos += coll->mid_floor;							// Otherwise Position Is OK..
}

//+++++++++++++++++++++++++++ RUN +++++++++++++++++++++++++++++++++++++++++
void	lara_col_run( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_walls = 2;
//	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;
	if ( TestLaraVault( item,coll ) )
		return;
	if (LaraDeflectEdge( item,coll ))					// Make Lara Stop because hit wall
	{                                                   // straight on..
		item->pos.z_rot = 0;
		if ( item->anim_number!=STARTRUN_A &&
			 TestWall(item, 256, 0, -640)						// Test for wall at shoulder height
			 //coll->front_type==WALL &&
			 //coll->front_floor < -(STEP_L*5)/2
			)    // only splat if floor is above
		{															  		// certain height in front
			item->current_anim_state = AS_SPLAT;
			if ( item->frame_number>=0 && item->frame_number<=9 )
			{
				item->anim_number = HITWALLLEFT_A;
				item->frame_number = HITWALLLEFT_F;
				return;
			}
			if ( item->frame_number>=10 && item->frame_number<=21 )
			{
				item->anim_number = HITWALLRIGHT_A;
				item->frame_number = HITWALLRIGHT_F;
				return;
			}
		}

		LaraCollideStop(item, coll);
	}

	if (LaraFallen(item, coll))
		return;

	if ( coll->mid_floor >= -STEPUP_HEIGHT && coll->mid_floor < -STEP_L/2 )		// We need to step up
	{
		if ( item->frame_number>=3 && item->frame_number<=14 )
		{
			item->anim_number = RUNSTEPUP_LEFT_A; 			// So kick off Left or
			item->frame_number = RUNSTEPUP_LEFT_F;          // Right foot Animation
		}
		else
		{
			item->anim_number = RUNSTEPUP_RIGHT_A;
			item->frame_number = RUNSTEPUP_RIGHT_F;
		}
	}
	if ( TestLaraSlide(item,coll ) )
		return;
	if ( coll->mid_floor >= 50 ) 							// Weve RUN off a Smallish Step
	{                                                   	// so Let lara fall down
		item->pos.y_pos += 50;
		return;
	}
	item->pos.y_pos += coll->mid_floor;							// Otherwise Position Is OK..
}

//+++++++++++++++++++++++++++ STOP +++++++++++++++++++++++++++++++++++++++++
void	lara_col_stop( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;			// No Gravity Effects
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );					// May Need to Change Room etc..

	if ( LaraHitCeiling( item,coll ) )
		return;
	if (LaraFallen(item,coll))
		return;
	if ( TestLaraSlide(item,coll ) )
		return;
	ShiftItem( item,coll );
	item->pos.y_pos += coll->mid_floor;                 // Enforce to floor height..
}

//+++++++++++++++++++++++ FORWARD JUMP +++++++++++++++++++++++++++++++++++++
void	lara_col_forwardjump( ITEM_INFO *item, COLL_INFO *coll )
{
	if (item->speed >= 0)
		lara.move_angle = item->pos.y_rot;
	else
		lara.move_angle = item->pos.y_rot-0x8000;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	LaraDeflectEdgeJump( item,coll );
	if (item->speed < 0)
		lara.move_angle = item->pos.y_rot;
	if ( coll->mid_floor<=0 && item->fallspeed>0 )		// We are now falling
	{                                                   // and have landed..
#ifndef INVINCABLE_LARA
		if ( LaraLandedBad(item,coll) )
			item->goal_anim_state = AS_DEATH;			// If Died cos fallen too far
		else
#endif
		{
			if ( lara.water_status==LARA_WADE)
			{
				item->goal_anim_state = AS_STOP;
			}
			else
			{
				if ( input&IN_FORWARD && !(input&IN_SLOW) )
					item->goal_anim_state = AS_RUN;    		// We are now landing
				else                                   		// into a run or stop
					item->goal_anim_state = AS_STOP;
			}
		}
		item->fallspeed = 0;
		item->pos.y_pos += coll->mid_floor;
		item->gravity_status = 0;
		item->speed = 0;
		AnimateLara(item);								// Move Lara and animate...
	}
}

//+++++++++++++++++++++++++++ POSE +++++++++++++++++++++++++++++++++++++++++
void	lara_col_pose( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_col_stop( item,coll );
}

//+++++++++++++++++++++++++ FASTBACK +++++++++++++++++++++++++++++++++++++++
void	lara_col_fastback( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;		// No Gravity Effects
	lara.move_angle = item->pos.y_rot - 32768;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
//	coll->slopes_are_walls = 1;
	coll->slopes_are_walls = 0;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;
	if ( coll->mid_floor > 200 )					   // Weve RUN Off A Big Edge..
	{
		item->anim_number = FALLBACK_A;
		item->frame_number = FALLBACK_F;               // so make her fall backwards
		item->current_anim_state = AS_FALLBACK;
		item->goal_anim_state = AS_FALLBACK;
		item->fallspeed = 0;
		item->gravity_status = 1;
		return;
	}
	if ( TestLaraSlide(item,coll ) )	// Gibby.
		return;					// Gibby.
	if (LaraDeflectEdge( item,coll ))				   // Stop Lara Dead
		LaraCollideStop(item, coll);
	item->pos.y_pos += coll->mid_floor;
}

//+++++++++++++++++++++++++++ TURN_R +++++++++++++++++++++++++++++++++++++++
void	lara_col_turn_r( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;			// No Gravity Effects
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	if ( coll->mid_floor > 100 )						// Floor Has Fallen Away From
	{                                                   // Under Us...
		item->anim_number = FALLDOWN_A;					// So Initiate A Fall
		item->frame_number = FALLDOWN_F;
		item->current_anim_state = AS_FORWARDJUMP;
		item->goal_anim_state = AS_FORWARDJUMP;
		item->fallspeed = 0;
		item->gravity_status = 1;
		return;
	}
	if ( TestLaraSlide(item,coll ) )
		return;
	item->pos.y_pos += coll->mid_floor;
}

//+++++++++++++++++++++++++++ TURN_L +++++++++++++++++++++++++++++++++++++++
void	lara_col_turn_l( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_col_turn_r( item,coll );				// Exactly Same Collision as turn_r
}

//+++++++++++++++++++++++++++ DEATH ++++++++++++++++++++++++++++++++++++++++
void	lara_col_death( ITEM_INFO *item, COLL_INFO *coll )
{
	StopSoundEffect(30); // stop that screaming woman
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->radius = LARA_RAD*4;
	GetLaraCollisionInfo( item, coll );
	ShiftItem( item,coll );
	item->pos.y_pos += coll->mid_floor;
	item->hit_points = -1;
	lara.air = -1;
}

//+++++++++++++++++++++++++++ FASTFALL +++++++++++++++++++++++++++++++++++++
void	lara_col_fastfall( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = 1;
	coll->bad_pos = NO_BAD_POS;					// DONT SET Move Angle
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	LaraSlideEdgeJump( item,coll );
	if ( coll->mid_floor <= 0 )
	{                                                   // IF Landed
#ifndef INVINCABLE_LARA
  		if (  LaraLandedBad(item,coll) )      			// So either Die
			item->goal_anim_state = AS_DEATH;
		else
#endif
		{
			item->goal_anim_state = AS_STOP;			// or Stop
			item->current_anim_state = AS_STOP;
			item->frame_number = LANDFAR_F;
			item->anim_number = LANDFAR_A;
		}
		StopSoundEffect(30);
		item->pos.y_pos += coll->mid_floor;
		item->gravity_status = 0;
		item->fallspeed = 0;
	}
}

//+++++++++++++++++++++++++++ HANG +++++++++++++++++++++++++++++++++++++++++
void	lara_col_hang( ITEM_INFO *item, COLL_INFO *coll )
{

	LaraHangTest( item,coll );
	if ( (item->goal_anim_state==AS_HANG) )
	{
		if ( input&IN_FORWARD )
		{
			if ( coll->front_floor>-850 && coll->front_floor<-650 &&
				 coll->front_floor-coll->front_ceiling>=0 &&		// Exit Now if no space to vault into
				 coll->left_floor-coll->left_ceiling>=0 &&
				 coll->right_floor-coll->right_ceiling>=0 &&
				!coll->hit_static )
				{
					if ( input&IN_SLOW )
						item->goal_anim_state = AS_GYMNAST;         // Else goto Climb Up animation
					else
						item->goal_anim_state = AS_NULL;            // Else goto Climb Up animation

				}
			else if ( lara.climb_status &&
				      item->anim_number==HANG_A &&
					  item->frame_number==HANG_F &&
					  coll->mid_ceiling<=-256 )
			{
				item->goal_anim_state = AS_HANG;
				item->current_anim_state = AS_HANG;
				item->anim_number = HANGUP_A;
				item->frame_number = HANGUP_F;
			}
		}
		else if ( input&IN_BACK && lara.climb_status &&
			      item->anim_number==HANG_A &&
				  item->frame_number==HANG_F)
		{
			item->goal_anim_state = AS_HANG;
			item->current_anim_state = AS_HANG;
			item->anim_number = HANGDOWN_A;
			item->frame_number = HANGDOWN_F;
		}
	}
}

//+++++++++++++++++++++++++++ REACH ++++++++++++++++++++++++++++++++++++++++
void	lara_col_reach( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = 1;
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
//	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_neg = 0;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	if ( LaraTestHangJump( item,coll ) )                	// First Check Reach Positions
		return;
	LaraSlideEdgeJump( item,coll );

	if ( item->fallspeed > 0 )								// We are now falling..
	{
		if ( coll->mid_floor <= 0 )
		{                                                   // IF Landed
#ifndef INVINCABLE_LARA
  			if ( LaraLandedBad(item,coll) )						// either Die
				item->goal_anim_state = AS_DEATH;
			else
#endif
				item->goal_anim_state = AS_STOP;			// Or Stop
			item->fallspeed = 0;
			item->pos.y_pos += coll->mid_floor;
			item->gravity_status = 0;
		}
	}
}

//+++++++++++++++++++++++++++ SPLAT ++++++++++++++++++++++++++++++++++++++++
void	lara_col_splat( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	ShiftItem( item,coll );

	if (coll->mid_floor > -STEP_L && coll->mid_floor < STEP_L)
		item->pos.y_pos += coll->mid_floor;							// for lift
}

//+++++++++++++++++++++++++++ LAND +++++++++++++++++++++++++++++++++++++++++
void	lara_col_land( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_col_stop( item,coll );				// Is this Routine Used???
}

//+++++++++++++++++++++++++++ COMPRESS +++++++++++++++++++++++++++++++++++++
void	lara_col_compress( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;		// No Gravity Effects
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = NO_BAD_NEG;
	coll->bad_ceiling = 0;
	GetLaraCollisionInfo( item, coll );
	if ( coll->mid_ceiling > -100 )
	{
		item->goal_anim_state = AS_STOP;			// PreEmptive Stop Jumping
		item->current_anim_state = AS_STOP;         // If Ceiling is very Low
		item->anim_number = STOP_A;
		item->frame_number = STOP_F;
		item->speed = 0;
		item->fallspeed = 0;
		item->gravity_status = 0;
		item->pos.x_pos = coll->old.x;
		item->pos.y_pos = coll->old.y;
		item->pos.z_pos = coll->old.z;
	}

	if (coll->mid_floor > -STEP_L && coll->mid_floor < STEP_L) // for jumping in lift (limit stops weirdness when on falling blocks)
		item->pos.y_pos += coll->mid_floor;
}

//+++++++++++++++++++++++++++ BACK +++++++++++++++++++++++++++++++++++++++++
void	lara_col_back( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;		// No Gravity Effects
	lara.move_angle = item->pos.y_rot - 32768;
	if (lara.water_status == LARA_WADE)
		coll->bad_pos = NO_BAD_POS;
	else
		coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;

	if (LaraDeflectEdge( item,coll ))				// Stop Lara Dead
		LaraCollideStop(item, coll);

	if (LaraFallen(item,coll))
		return;
	if ( coll->mid_floor > STEP_L/2  && coll->mid_floor < (STEP_L*3)/2 )
	{
		if ( item->frame_number>=964 && item->frame_number<=993 )       // We Need to Step Down
		{
			item->anim_number = BACKSTEPD_RIGHT_A; 						// So kick off Left or
			item->frame_number = BACKSTEPD_RIGHT_F;                     // Right foot Animation
		}
		else
		{
			item->anim_number = BACKSTEPD_LEFT_A;
			item->frame_number = BACKSTEPD_LEFT_F;
		}
	}
	if ( TestLaraSlide(item,coll ) )
		return;
	item->pos.y_pos += coll->mid_floor;
}

//+++++++++++++++++++++++++++ NULL +++++++++++++++++++++++++++++++++++++++++
void	lara_col_null( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//+++++++++++++++++++++++++ FAST TURN ++++++++++++++++++++++++++++++++++++++
void	lara_col_fastturn( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_col_stop( item,coll );
}

//++++++++++++++++++++++++ STEP RIGHT ++++++++++++++++++++++++++++++++++++++
void	lara_col_stepright( ITEM_INFO *item, COLL_INFO *coll )
{
	if (item->current_anim_state == AS_STEPRIGHT)
		lara.move_angle = item->pos.y_rot + 16384;
	else
		lara.move_angle = item->pos.y_rot - 16384;

	item->gravity_status = item->fallspeed = 0;		// No Gravity Effects
	if (lara.water_status == LARA_WADE)
		coll->bad_pos = NO_BAD_POS;
	else
		coll->bad_pos = STEP_L/2;
	coll->bad_neg = -STEP_L/2;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;
	if (LaraDeflectEdge( item,coll ))
		LaraCollideStop(item, coll);
	if (LaraFallen( item,coll ))
		return;
	if ( TestLaraSlide(item,coll ) )
		return;
	item->pos.y_pos += coll->mid_floor;
}

//++++++++++++++++++++++++ STEP LEFT +++++++++++++++++++++++++++++++++++++++
void	lara_col_stepleft( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_col_stepright(item, coll);
}

//++++++++++++++++++++++++++ SLIDE ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_slide( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	lara_slide_slope( item,coll );
}

//++++++++++++++++++++++++++ BACKJUMP +++++++++++++++++++++++++++++++++++++++
void	lara_col_backjump( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot - 32768;
	lara_col_jumper( item,coll );
}

//++++++++++++++++++++++++++ RIGHTJUMP ++++++++++++++++++++++++++++++++++++++
void	lara_col_rightjump( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot + 16384;
	lara_col_jumper( item,coll );
}

//++++++++++++++++++++++++++ LEFTJUMP +++++++++++++++++++++++++++++++++++++++
void	lara_col_leftjump( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot - 16384;
	lara_col_jumper( item,coll );
}

//++++++++++++++++++++++++++ UPJUMP +++++++++++++++++++++++++++++++++++++++++
void	lara_col_upjump( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	// Gav 6/3/97
	if (item->speed < 0)
		coll->facing = lara.move_angle - 32768;
	else
	// End
		coll->facing = lara.move_angle;
	GetCollisionInfo( coll, item->pos.x_pos,item->pos.y_pos,item->pos.z_pos,item->room_number,870 );
	if ( LaraTestHangJumpUp( item,coll ) )					// Test If We Can Hang..
		return;
//	LaraSlideEdgeJump( item,coll );	//SONY BUG FIX A30
	ShiftItem( item,coll );			//STOPS LARA GOING INTO BLACKNESS IN CLAMPED CORNERS EG.'EMPRTOMB' START
	if (coll->coll_type==COLL_CLAMP || coll->coll_type==COLL_TOP || coll->coll_type==COLL_TOPFRONT)
		item->goal_anim_state = AS_STOP;
	// Gav
	if (coll->coll_type)
		item->speed = (item->speed>0)? 2 : -2;
	else if (item->fallspeed < -70)
	{
		if (input & IN_FORWARD && item->speed < 5)
			item->speed++;
		else if (input & IN_BACK && item->speed > -5)
			item->speed-=2; //needs more for back jump to get onto 3/4 block
	}
	// End
	if ( item->fallspeed > 0 )								// We are now falling
	{
		if ( coll->mid_floor <= 0 )
		{                                                   // IF Landed
#ifndef INVINCABLE_LARA
  			if ( LaraLandedBad(item,coll) )					// So either Die
				item->goal_anim_state = AS_DEATH;
			else
#endif
				item->goal_anim_state = AS_STOP;			// Or Stop
			item->fallspeed = 0;
			item->pos.y_pos += coll->mid_floor;
			item->gravity_status = 0;
		}
	}
}

//++++++++++++++++++++++++++ FALLBACK ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_fallback( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot - 32768;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	LaraDeflectEdgeJump( item,coll );
	if ( coll->mid_floor<=0 && item->fallspeed>0 )			// We are now falling
	{                                                   	// and have landed..
#ifndef INVINCABLE_LARA
  		if ( LaraLandedBad(item,coll) )    						// So either Die
			item->goal_anim_state = AS_DEATH;
		else
#endif
			item->goal_anim_state = AS_STOP;
		item->fallspeed = 0;
		item->pos.y_pos += coll->mid_floor;
		item->gravity_status = 0;
	}
}

//++++++++++++++++++++++++++ HANGLEFT ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_hangleft( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot-16384;
	LaraHangTest( item,coll );
	lara.move_angle = item->pos.y_rot-16384;
}

//++++++++++++++++++++++++++ HANGRIGHT ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_hangright( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot+16384;
	LaraHangTest( item,coll );
	lara.move_angle = item->pos.y_rot+16384;
}
//++++++++++++++++++++++++++ SLIDEBACK ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_slideback( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot - 32768;
	lara_slide_slope( item,coll );
}

//++++++++++++++++++++++++++ PUSHBLOCK ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_pushblock( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ PULLBLOCK ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_pullblock( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ PPREADY ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_ppready( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}


//++++++++++++++++++++++++++ PICKUP ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_pickup( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ SWITCHON ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_switchon( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ SWITCHOFF ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_switchoff( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ USE KEY ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_usekey( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ USE PUZZLE ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_usepuzzle( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//++++++++++++++++++++++++++ ROLL ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_roll( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;		// No Gravity Effects
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;
	if ( TestLaraSlide(item,coll ) )
		return;
	if (LaraFallen(item,coll))
		return;
	ShiftItem( item,coll );
	item->pos.y_pos += coll->mid_floor;
}

//++++++++++++++++++++++++++ ROLL2 ++++++++++++++++++++++++++++++++++++++++++
void	lara_col_roll2( ITEM_INFO *item, COLL_INFO *coll )
{
	item->gravity_status = item->fallspeed = 0;		// No Gravity Effects
	lara.move_angle = item->pos.y_rot-32768;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;
	if ( TestLaraSlide(item,coll ) )
		return;
	if ( coll->mid_floor > 200 )						// Weve Rolled Off A Big Edge..
	{
		item->anim_number = FALLBACK_A;
		item->frame_number = FALLBACK_F;                // so make her fall backwards
		item->current_anim_state = AS_FALLBACK;         // this allows her to do
		item->goal_anim_state = AS_FALLBACK;            // Handy forward Roll off Ledge
		item->fallspeed = 0;                            // and Grab hold of it!!
		item->gravity_status = 1;
		return;
	}
	ShiftItem( item,coll );
	item->pos.y_pos += coll->mid_floor;
}


//+++++++++++++++++++++++++ SPECIAL DEATH +++++++++++++++++++++++++++++++++++++
void	lara_col_special( ITEM_INFO *item, COLL_INFO *coll )
{
}


//+++++++++++++++++++++++++++ USE MIDAS +++++++++++++++++++++++++++++++++++++++
void	lara_col_usemidas( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//+++++++++++++++++++++++++++ DIE MIDAS +++++++++++++++++++++++++++++++++++++++
void	lara_col_diemidas( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//+++++++++++++++++++++++++++ SWAN DIVE +++++++++++++++++++++++++++++++++++++++
void	lara_col_swandive( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	LaraDeflectEdgeJump( item,coll );
	if ( coll->mid_floor<=0 && item->fallspeed>0 )		// We are now falling
	{                                                   // and have landed..
		item->goal_anim_state = AS_STOP;
		item->fallspeed = 0;
		item->pos.y_pos += coll->mid_floor;
		item->gravity_status = 0;
	}
}

//+++++++++++++++++++++++++++ FAST DIVE +++++++++++++++++++++++++++++++++++++++
void	lara_col_fastdive( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	LaraDeflectEdgeJump( item,coll );
	if ( coll->mid_floor<=0 && item->fallspeed>0 )		// We are now falling
	{                                                   // and have landed..
#ifndef INVINCABLE_LARA
		if ( item->fallspeed>133 )
			item->goal_anim_state = AS_DEATH;
		else
#endif
			item->goal_anim_state = AS_STOP;
		item->fallspeed = 0;
		item->pos.y_pos += coll->mid_floor;
		item->gravity_status = 0;
	}
}

//+++++++++++++++++++++++++++ GYMNAST +++++++++++++++++++++++++++++++++++++++
void	lara_col_gymnast( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

//+++++++++++++++++++++++++++ WATER OUT +++++++++++++++++++++++++++++++++++++++++
void	lara_col_waterout( ITEM_INFO *item, COLL_INFO *coll )
{
	lara_default_col( item,coll );
}

void	lara_col_laratest1( ITEM_INFO *item, COLL_INFO *coll )
{

}
void	lara_col_laratest2( ITEM_INFO *item, COLL_INFO *coll )
{

}
void	lara_col_laratest3( ITEM_INFO *item, COLL_INFO *coll )
{

}
void	lara_col_wade( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );

	if ( LaraHitCeiling( item,coll ) )
		return;
	if ( TestLaraVault( item,coll ) )
		return;
	if (LaraDeflectEdge( item,coll ))					// Make Lara Stop because hit wall
	{                                                   // straight on..
		item->pos.z_rot = 0;
		if (coll->front_type==WALL && coll->front_floor < -(STEP_L*5)/2)    // only splat if floor is above
		{															  		// certain height in front
			item->current_anim_state = AS_SPLAT;
			if ( item->frame_number>=0 && item->frame_number<=9 )
			{
				item->anim_number = HITWALLLEFT_A;
				item->frame_number = HITWALLLEFT_F;
				return;
			}
			if ( item->frame_number>=10 && item->frame_number<=21 )
			{
				item->anim_number = HITWALLRIGHT_A;
				item->frame_number = HITWALLRIGHT_F;
				return;
			}
		}

		LaraCollideStop(item, coll);
	}

	if (LaraFallen(item,coll))
		return;
	if ( coll->mid_floor >= -STEPUP_HEIGHT && coll->mid_floor < -STEP_L/2 )		// We need to step up
	{
		if ( item->frame_number>=3 && item->frame_number<=14 )
		{
			item->anim_number = RUNSTEPUP_LEFT_A; 			// So kick off Left or
			item->frame_number = RUNSTEPUP_LEFT_F;          // Right foot Animation
		}
		else
		{
			item->anim_number = RUNSTEPUP_RIGHT_A;
			item->frame_number = RUNSTEPUP_RIGHT_F;
		}
	}
	if ( TestLaraSlide(item,coll ) )
		return;
	if ( coll->mid_floor >= 50 ) 							// Weve RUN off a Smallish Step
	{                                                   	// so Let lara fall down
		item->pos.y_pos += 50;
		return;
	}
	item->pos.y_pos += coll->mid_floor;							// Otherwise Position Is OK..
}

void	lara_col_twist( ITEM_INFO *item, COLL_INFO *coll )
{
}

/******************************************************************************
 *			Collision routine for switch pulling etc etc
 *****************************************************************************/
void		lara_default_col( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.move_angle = item->pos.y_rot;
	coll->bad_pos = STEPUP_HEIGHT;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	coll->slopes_are_pits = 1;
	coll->slopes_are_walls = 1;
	GetLaraCollisionInfo( item, coll );
}


/******************************************************************************
 *			Routine for MultiWay Jumps except forwards...
 *****************************************************************************/
void	lara_col_jumper( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = BAD_JUMP_CEILING;
	GetLaraCollisionInfo( item, coll );
	LaraDeflectEdgeJump( item,coll );
	if ( item->fallspeed > 0 )								// We are now falling
	{
		if ( coll->mid_floor <= 0 )
		{                                                   // IF Landed
#ifndef INVINCABLE_LARA
  			if ( LaraLandedBad(item,coll) )    					// So either Die
				item->goal_anim_state = AS_DEATH;
			else
#endif
				item->goal_anim_state = AS_STOP;
			item->fallspeed = 0;
			item->pos.y_pos += coll->mid_floor;
			item->gravity_status = 0;
		}
	}
}

void lara_col_kick( ITEM_INFO *item, COLL_INFO *coll )
{
}

// death slide
void lara_col_deathslide( ITEM_INFO *item, COLL_INFO *coll )
{
	// may use another state
}

/*****************************************************************************
 *			Calculate Floor Heights etc for Bounding Box...
 ****************************************************************************/
void	GetLaraCollisionInfo( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->facing = lara.move_angle;
	GetCollisionInfo( coll, item->pos.x_pos,item->pos.y_pos,item->pos.z_pos,
					  item->room_number,LARA_HITE );
}

/******************************************************************************
 *				Routine for Multiway Sliding...
 *****************************************************************************/
void	lara_slide_slope( ITEM_INFO *item, COLL_INFO *coll )
{
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -512;								// Allow player to Pop out of Bad-Holes
	coll->bad_ceiling = 0;
	GetLaraCollisionInfo( item, coll );
	if ( LaraHitCeiling( item,coll ) )
		return;
	LaraDeflectEdge( item,coll );
	if ( coll->mid_floor > 200 )						// Floor Has Fallen Away From
	{                                                   // Under Us...
		if ( item->current_anim_state==AS_SLIDE )
		{
			item->anim_number = FALLDOWN_A;					// So Initiate A Fall
			item->frame_number = FALLDOWN_F;
			item->current_anim_state = AS_FORWARDJUMP;
			item->goal_anim_state = AS_FORWARDJUMP;
		}
		else
		{
			item->anim_number = FALLBACK_A;					// So Initiate A Fall
			item->frame_number = FALLBACK_F;
			item->current_anim_state = AS_FALLBACK;
			item->goal_anim_state = AS_FALLBACK;
		}
		item->fallspeed = 0;
		item->gravity_status = 1;
		return;
	}
	TestLaraSlide( item,coll );
	item->pos.y_pos += coll->mid_floor;                 	// Enforce to floor height..

	if ( (ABS(coll->tilt_x))<=2 && (ABS(coll->tilt_z))<=2 ) // then Return to Stop Position
		item->goal_anim_state = AS_STOP;
}

/*******************************************************************************
 *			Test If Lara Has Hit Ceiling whilst not jumping..
 *            If so make her come to Stop straight away
 ******************************************************************************/
int		LaraHitCeiling( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( coll->coll_type==COLL_TOP || coll->coll_type==COLL_CLAMP )
	{
		item->pos.x_pos = coll->old.x;
		item->pos.y_pos = coll->old.y;
		item->pos.z_pos = coll->old.z;
		item->goal_anim_state = AS_STOP;
		item->current_anim_state = AS_STOP;
		item->frame_number = STOP_F;
		item->anim_number = STOP_A;
		item->speed = 0;
		item->fallspeed = 0;
		item->gravity_status = 0;
		return(1);
	}
	return(0);
}


/*****************************************************************************
 *		Lara Has Walked To An Edge Of A DropOff
 *			so Deflect or Stop..
 ****************************************************************************/

int		LaraDeflectEdge( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( coll->coll_type==COLL_FRONT || coll->coll_type==COLL_TOPFRONT )
	{
		ShiftItem( item,coll );
		item->goal_anim_state = AS_STOP;         // Make Player Stop Immediately
		item->current_anim_state = AS_STOP;      // Because cant slide along Wall
		item->speed = 0;
		item->gravity_status = 0;
		return (1);
	}
	else if ( coll->coll_type==COLL_LEFT )
	{
		ShiftItem( item,coll );
		item->pos.y_rot += LARA_DEF_ADD_EDGE;
	}
	else if ( coll->coll_type==COLL_RIGHT )
	{
		ShiftItem( item,coll );
		item->pos.y_rot -= LARA_DEF_ADD_EDGE;
	}
	return (0);
}

/*****************************************************************************
 *		Test if Lara Has Hit A Wall in the Middle of A Jump..
 *					so Deflect or Stop..
 *			Also handles Hitting Ceiling
 ****************************************************************************/
void	LaraDeflectEdgeJump( ITEM_INFO *item, COLL_INFO *coll )
{
	ShiftItem( item,coll );
	switch ( coll->coll_type )
	{
		case COLL_FRONT:
		case COLL_TOPFRONT:
			// Ignore front collision if dropping from climb stance
			if (lara.climb_status && item->speed==2)
				return;

			/* Choose anim to jump to based on severity of collision */
			if (coll->mid_floor > 512)
			{
				item->goal_anim_state = AS_FASTFALL;      	// Make Player Stop Immediately
				item->current_anim_state = AS_FASTFALL;   	// and Skip directly into fastfall
				item->frame_number = FASTSPLAT_F;
				item->anim_number = FASTSPLAT_A;
			}
			else if (coll->mid_floor <= 128)
			{
				item->goal_anim_state = AS_LAND;
				item->current_anim_state = AS_LAND;
				item->frame_number = LAND_F;
				item->anim_number = LAND_A;
			}
			item->speed /= 4;
			lara.move_angle += -0x8000;
			if ( item->fallspeed<=0 )
				item->fallspeed = 1;
		break;

		case COLL_LEFT:
			item->pos.y_rot += LARA_DEF_ADD_EDGE;
		break;

		case COLL_RIGHT:
			item->pos.y_rot -= LARA_DEF_ADD_EDGE;
		break;

		case COLL_TOP:
			if ( item->fallspeed<=0 )					// If hit ceiling whilst going upwards
				item->fallspeed = 1;                    // then start falling
		break;

		case COLL_CLAMP:								// If hit ceiling and floor then Use old Position
			item->pos.z_pos -= (phd_cos(coll->facing)*100)>>W2V_SHIFT;		// shift away from the clamp
			item->pos.x_pos -= (phd_sin(coll->facing)*100)>>W2V_SHIFT;       // position
			item->speed = 0;
			coll->mid_floor = 0;
			if ( item->fallspeed<=0 )                   // make jump velocity positive
				item->fallspeed = 16;                    // so we can land
		break;
	}
}

/*****************************************************************************
 *		Test if Lara Has Hit A Wall in the Middle of A Jump..
 *					so Slide or Stop..
 *			Also handles Hitting Ceiling
 ****************************************************************************/
void	LaraSlideEdgeJump( ITEM_INFO *item, COLL_INFO *coll )
{
	ShiftItem( item,coll );
	switch ( coll->coll_type )
	{
		case COLL_LEFT:
			item->pos.y_rot += LARA_DEF_ADD_EDGE;
		break;

		case COLL_RIGHT:
			item->pos.y_rot -= LARA_DEF_ADD_EDGE;
		break;

		case COLL_TOP:
		case COLL_TOPFRONT:
			if ( item->fallspeed<=0 )					// If hit ceiling whilst going upwards
				item->fallspeed = 1;                    // then start falling
		break;

		case COLL_CLAMP:								// If hit ceiling and floor
			item->pos.z_pos -= (phd_cos(coll->facing)*100)>>W2V_SHIFT;		// shift away from the clamp
			item->pos.x_pos -= (phd_sin(coll->facing)*100)>>W2V_SHIFT;       // position
			item->speed = 0;
			coll->mid_floor = 0;
			if ( item->fallspeed<=0 )                   // make jump velocity positive
				item->fallspeed = 16;                    // so we can land
		break;

		default:
		break;
	}
}

int LaraTestClimbPos(ITEM_INFO *item, int front, int right, int origin, int height, int *shift);

int LaraTestHangOnClimbWall(ITEM_INFO *item, COLL_INFO *coll)
{
	// check if valid hang position; return 0 if not
	int shift, result;
	sint16 *bounds;

	// easy checks first
	if (!lara.climb_status || item->fallspeed<0)
		return 0;

	switch ((uint16)(item->pos.y_rot+0x2000)/0x4000)
	{
		case NORTH:
		case SOUTH:
			item->pos.z_pos += coll->shift.z;
			break;
		case EAST:
		case WEST:
			item->pos.x_pos += coll->shift.x;
			break;
	}

	// test middle/left/right
	bounds = GetBoundsAccurate( item );

	if (!LaraTestClimbPos(item, coll->radius, coll->radius, bounds[2], bounds[3]-bounds[2], &shift) ||
		 !LaraTestClimbPos(item, coll->radius, -coll->radius, bounds[2], bounds[3]-bounds[2], &shift))
		return 0;

	result = LaraTestClimbPos(item, coll->radius, 0, bounds[2], bounds[3]-bounds[2], &shift);
	if (!result)
		return 0;
	else if (result==1) // saying climb OK, but not really valid test (so ignore y shift)
		return 1;

	item->pos.y_pos += shift;

	return 1;
}


int LaraTestClimbStance( ITEM_INFO *item, COLL_INFO *coll )
{
	// returns 0 if bad, 1 if good
	int result_r, result_l, shift_r, shift_l;

	// test both left and right sides; test at 700 to allow Lara to go to climb stance of hanging on slope
	result_r = LaraTestClimbPos(item, coll->radius, coll->radius+CLIMB_WIDTHR, -700, (STEP_L*2), &shift_r);
	if (result_r != 1)
		return 0;

	result_l = LaraTestClimbPos(item, coll->radius, -(coll->radius+CLIMB_WIDTHL), -700, (STEP_L*2), &shift_l);
	if (result_l != 1)
		return 0;

	if (shift_r)
	{
		if (shift_l)
		{
			// 2 shifts! if oppose, then bad pos, else use biggest shift
			if ((shift_l < 0) ^ (shift_r < 0))
				return 0;
			if (shift_r < 0 && shift_l < shift_r)
				shift_r = shift_l;
			else if (shift_r > 0 && shift_l > shift_r)
				shift_r = shift_l;
		}

		item->pos.y_pos += shift_r;
	}
	else if (shift_l)
		item->pos.y_pos += shift_l;

	return 1;
}

void	LaraHangTest( ITEM_INFO *item, COLL_INFO *coll )
{
	PHD_ANGLE	angle;
	sint16 		*bounds;
	int			flag=0;
	int			hdif;
	PHD_VECTOR	pos;

	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = NO_BAD_NEG;
	coll->bad_ceiling = 0;
	GetLaraCollisionInfo( item, coll );
	if ( coll->front_floor < 200 )
		flag=1;

	item->gravity_status = item->fallspeed = 0;			// No Gravity Effects
	lara.move_angle = item->pos.y_rot;

	angle = (uint16)(item->pos.y_rot+0x2000)/0x4000;
	switch ( angle )
	{
		case NORTH:
			item->pos.z_pos+=2;							// Move Lara towards where we are Hanging.
		break;

		case WEST:
			item->pos.x_pos-=2;
		break;

		case SOUTH:
			item->pos.z_pos-=2;
		break;

		case EAST:
			item->pos.x_pos+=2;
		break;
	}
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -STEPUP_HEIGHT;
	coll->bad_ceiling = 0;
	GetLaraCollisionInfo( item, coll );

	if ( lara.climb_status )
	{
		// CLIMBABLE WALL STUFF
		if ( !(input&IN_ACTION) || item->hit_points<=0)	// If user Dies Or releases Action
		{
			pos.x = pos.y = pos.z = 0; // move to hip pos, else nasty snap when go drop from some anims
			GetJointAbsPosition(item, &pos, 0);
			if (angle==NORTH || angle==SOUTH) // only sideways; not away from wall or no regrab possible
				item->pos.x_pos = pos.x;
			else
				item->pos.z_pos = pos.z;

			item->goal_anim_state = AS_FORWARDJUMP;				// Jump straight to falldown
			item->current_anim_state = AS_FORWARDJUMP;           // UpJump status if user releases
			item->anim_number = FALLDOWN_A;                 // Action button
			item->frame_number = FALLDOWN_F;
			item->pos.y_pos += 256;
			item->gravity_status = 1;
			item->speed = 2;
			item->fallspeed = 1;
			lara.gun_status = LG_ARMLESS;
			return;
		}

		if (!LaraTestHangOnClimbWall(item, coll)) // this does coll->shift
		{
			item->pos.x_pos = coll->old.x;
			item->pos.y_pos = coll->old.y;
			item->pos.z_pos = coll->old.z;
			item->goal_anim_state = AS_HANG;
			item->current_anim_state = AS_HANG;
			item->frame_number = HANG_F;
			item->anim_number = HANG_A;
			return;
		}

		if (item->anim_number==HANG_A &&	item->frame_number==HANG_F)
		{
			if (LaraTestClimbStance( item, coll ))
				item->goal_anim_state = AS_CLIMBSTNC;
		}

		return;
	}

	// NON CLIMBABLE WALL
	if ( !(input&IN_ACTION) || item->hit_points<=0 || coll->front_floor > 0)	// If user Dies Or releases Action
	{
		item->goal_anim_state = AS_UPJUMP;				// Jump straight to falldown
		item->current_anim_state = AS_UPJUMP;           // UpJump status if user releases
		item->anim_number = STOPHANG_A;                 // Action button
		item->frame_number = STOPHANG_F;
		bounds = GetBoundsAccurate( item );
//		item->pos.y_pos += coll->front_floor - bounds[2] + 2;
		item->pos.y_pos += bounds[3];
		item->pos.x_pos += coll->shift.x;
		item->pos.z_pos += coll->shift.z;
		item->gravity_status = 1;
		item->speed = 2;
		item->fallspeed = 1;
		lara.gun_status = LG_ARMLESS;
		return;
	}

	bounds = GetBoundsAccurate( item );
	hdif = coll->front_floor - bounds[2];
	if ( (ABS(coll->left_floor-coll->right_floor))>=SLOPE_DIF ||
	     coll->mid_ceiling>=0 || coll->coll_type!=COLL_FRONT || flag || coll->hit_static ||
		  hdif<-SLOPE_DIF || hdif>SLOPE_DIF ) // last 2 checks are for if gone from climbable to unclimbable wall
	{
		item->pos.x_pos = coll->old.x;
		item->pos.y_pos = coll->old.y;
		item->pos.z_pos = coll->old.z;
		if ( item->current_anim_state==AS_HANGLEFT || item->current_anim_state==AS_HANGRIGHT )
		{
			item->goal_anim_state = AS_HANG;
			item->current_anim_state = AS_HANG;
			item->frame_number = HANG_F;
			item->anim_number = HANG_A;
		}
		return;
	}

	switch ( angle )
	{
		case NORTH:
		case SOUTH:
			item->pos.z_pos += coll->shift.z;
		break;

		case WEST:
		case EAST:
			item->pos.x_pos += coll->shift.x;
		break;
	}

	item->pos.y_pos += hdif;
}


int LaraTestEdgeCatch( ITEM_INFO *item, COLL_INFO *coll, sint32 *edge )
{
	int			hdif;
	sint16		*bounds;

	bounds = GetBoundsAccurate( item );
	hdif = coll->front_floor - bounds[2];
	if ( (hdif<0 && hdif+item->fallspeed<0) || (hdif>0 && hdif+item->fallspeed>0) )
	{
		// not got edge; see if got 1/4 block boundary (if climable wall, this is as good)
		hdif = item->pos.y_pos + bounds[2];
		if ((hdif>>(WALL_SHIFT-2)) != ((hdif+item->fallspeed)>>(WALL_SHIFT-2)))
		{
			if (item->fallspeed > 0)
				*edge = (hdif+item->fallspeed) & ~(STEP_L-1);
			else
				*edge = hdif & ~(STEP_L-1);
			return(-1);
		}
		return(0);
	}

	if ( ABS(coll->left_floor-coll->right_floor) >= SLOPE_DIF ) // too slanty
		return(0);

	return(1); // got edge
}

/******************************************************************************
 *		Test For Ability to Hang when doing Up Jump
 *****************************************************************************/
int		LaraTestHangJumpUp( ITEM_INFO *item, COLL_INFO *coll )
{
#define HANG_ANGLE  (35*ONE_DEGREE)

	int				edge_catch;
	PHD_ANGLE		angle;
	sint16 			*bounds;
	sint32			edge;

	if ( coll->coll_type!=COLL_FRONT || !(input&IN_ACTION) || lara.gun_status!=LG_ARMLESS || coll->hit_static)
		 return(0);
	if ( coll->mid_ceiling>-STEPUP_HEIGHT )   // If Ceiling is Bad exit
		return(0);

	// check if catch edge of block; if not try catching anyplace on climbable wall
	edge_catch = LaraTestEdgeCatch(item, coll, &edge);
	if (!edge_catch)
		return(0);
	if (edge_catch<0 && !LaraTestHangOnClimbWall(item, coll))
		return(0);

	angle = item->pos.y_rot;
	if ( angle>=0-HANG_ANGLE && angle<=0+HANG_ANGLE)                     // North Wall
		angle = 0;
	else if ( angle>=16384-HANG_ANGLE && angle<=16384+HANG_ANGLE ) 		 // East Wall
		angle = 16384;
	else if ( angle>=32767-HANG_ANGLE || angle<=-32767+HANG_ANGLE ) 	 // South Wall
		angle = -32768;
	else if ( angle>=-16384-HANG_ANGLE && angle<=-16384+HANG_ANGLE )     // West Wall
		angle = -16384;
	if ( angle&0x3fff )
		return(0);

	item->goal_anim_state = AS_HANG;									// Jump straight to Hang
	item->current_anim_state = AS_HANG;                                 // status
	item->anim_number = STARTHANG_A;
	item->frame_number = STARTHANG_F;
	bounds = GetBoundsAccurate( item );
	if (edge_catch>0)
		item->pos.y_pos += coll->front_floor - bounds[2]; // catch edge
	else
		item->pos.y_pos = edge - bounds[2];
//		item->pos.y_pos = ((item->pos.y_pos + bounds[2]) & ~(STEP_L-1)) - bounds[2]; // catch 1/4
	item->pos.x_pos += coll->shift.x;
	item->pos.z_pos += coll->shift.z;
	item->pos.y_rot = angle;
	item->gravity_status = 0;
	item->speed = 0;
	item->fallspeed = 0;
	lara.gun_status = LG_HANDSBUSY;
	return(1);

#undef HANG_ANGLE
}

/******************************************************************************
 *		Test For Ability to Hang when doing Forward Jump Also
 *****************************************************************************/
int		LaraTestHangJump( ITEM_INFO *item, COLL_INFO *coll )
{
#define HANG_ANGLE  (35*ONE_DEGREE)

	int				edge_catch;
	PHD_ANGLE		angle;
	sint16 			*bounds;
	sint32			edge;

	// Is a wall there? Pressing 'action? No weapons?
	if ( coll->coll_type!=COLL_FRONT ||	!(input&IN_ACTION) || lara.gun_status!= LG_ARMLESS || coll->hit_static)
		return(0);

	// is there room above and below lara.
	if ( coll->mid_ceiling>-STEPUP_HEIGHT || coll->mid_floor<200 )
		return(0);

	// Check if Hands are in Correct place
	edge_catch = LaraTestEdgeCatch(item, coll, &edge);
	if (!edge_catch)
		return(0);
	if (edge_catch<0 && !LaraTestHangOnClimbWall(item, coll))
		return(0);

	angle = item->pos.y_rot;
	if ( angle>=0-HANG_ANGLE && angle<=0+HANG_ANGLE)                     // North Wall
		angle = 0;
	else if ( angle>=16384-HANG_ANGLE && angle<=16384+HANG_ANGLE ) 		 // East Wall
		angle = 16384;
	else if ( angle>=32767-HANG_ANGLE || angle<=-32767+HANG_ANGLE ) 	 // South Wall
		angle = -32768;
	else if ( angle>=-16384-HANG_ANGLE && angle<=-16384+HANG_ANGLE )     // West Wall
		angle = -16384;

	if ( angle&0x3fff )
		return(0);

	// Now Decide if should swing inwards or hit Wall
	if ( TestHangSwingIn(item,angle) )
	{
		// Swing
	 	item->anim_number = GRABLEDGEIN_A;
		item->frame_number = GRABLEDGEIN_F;
	}
	else
	{
		// Slam
	 	item->anim_number = GRABLEDGE_A;
		item->frame_number = GRABLEDGE_F;
	}

	item->current_anim_state = AS_HANG;
	item->goal_anim_state = AS_HANG;

	bounds = GetBoundsAccurate( item );
	if (edge_catch>0)
	{
		item->pos.y_pos += coll->front_floor-bounds[2]; // catch edge
		item->pos.x_pos += coll->shift.x;
		item->pos.z_pos += coll->shift.z;
	}
	else
		item->pos.y_pos = edge - bounds[2];
		//item->pos.y_pos = ((item->pos.y_pos + bounds[2]) & ~(STEP_L-1)) - bounds[2]; // catch 1/4
	item->pos.y_rot = angle;
	item->gravity_status = 1;
	item->speed = 2;
	item->fallspeed = 1;
	lara.gun_status = LG_HANDSBUSY;
	return(1);

#undef HANG_ANGLE
}

/******************************************************************************
 *		Test if Lara Can swing inwards when Doing Hang Reach
 *****************************************************************************/
int		TestHangSwingIn( ITEM_INFO *item, PHD_ANGLE angle )
{
	int			x,y,z;
	int			h,c;
	FLOOR_INFO	*floor;
	sint16		room_num;

	x = item->pos.x_pos;
	y = item->pos.y_pos;
	z = item->pos.z_pos;
	room_num = item->room_number;
	switch ( angle )
	{
		case 0:      z += 256; break;
		case 16384:  x += 256; break;
		case -16384: x -= 256; break;
		case -32768: z -= 256; break;
	}
	floor = GetFloor( x,y,z, &room_num );				// Get Heights for MID Position
	h = GetHeight( floor,x,y,z );
	c = GetCeiling( floor,x,y,z );
	if ( h!=NO_HEIGHT )
	{
		if ( (h-y)>0 && (c-y)<-400 )
			return(1);
	}
	return(0);
}

/*******************************************************************************
 *		Test For And Initiate A VAULT animation if need be..
 *				Returns TRUE if Vault started
 ******************************************************************************/
int		TestLaraVault( ITEM_INFO *item, COLL_INFO *coll )
{
#define VAULT_ANGLE	(30*ONE_DEGREE)

	int			hdif, slope;
	PHD_ANGLE	angle;

	if ( coll->coll_type!=COLL_FRONT || !(input&IN_ACTION) || lara.gun_status!=LG_ARMLESS)						// or Arms are Busy
		return(0);

	angle = item->pos.y_rot;
	if ( angle>=0-VAULT_ANGLE && angle<=0+VAULT_ANGLE)                         // North Wall
		angle = 0;
	else if ( angle>=16384-VAULT_ANGLE && angle<=16384+VAULT_ANGLE ) 		   // East Wall
		angle = 16384;
	else if ( angle>=32767-VAULT_ANGLE || angle<=-32767+VAULT_ANGLE ) 		   // South Wall
		angle = -32768;
	else if ( angle>=-16384-VAULT_ANGLE && angle<=-16384+VAULT_ANGLE )         // West Wall
		angle = -16384;

	if ( angle&0x3fff )
		return(0);

	hdif =  coll->front_floor;		  					  	// Get Average Height In front of Lara
	slope = ( ABS(coll->left_floor-coll->right_floor) >= SLOPE_DIF );
	if ( hdif >= -STEP_L*2 - STEP_L/2  && hdif <= -STEP_L*2 + STEP_L/2 )
	{
		if ( slope || coll->front_floor-coll->front_ceiling<0 ||
			 coll->left_floor-coll->left_ceiling<0 ||
			 coll->right_floor-coll->right_ceiling<0 )	// Exit Now if no space to vault into
			return(0);
		item->anim_number = VAULT12_A;					  	// Small Vault
		item->frame_number = VAULT12_F;
		item->current_anim_state = AS_NULL;
		item->goal_anim_state = AS_STOP;
		item->pos.y_pos += STEP_L*2 + hdif;
		lara.gun_status = LG_HANDSBUSY;
	}
	else if ( hdif >= -STEP_L*3 - STEP_L/2 && hdif <= -STEP_L*3 + STEP_L/2 )
	{
		if ( slope || coll->front_floor-coll->front_ceiling<0 ||		// Exit Now if no space to vault into
			 coll->left_floor-coll->left_ceiling<0 ||
			 coll->right_floor-coll->right_ceiling<0 )
			return(0);
		item->anim_number = VAULT34_A;						// Medium Vault
		item->frame_number = VAULT34_F;
		item->current_anim_state = AS_NULL;
		item->goal_anim_state = AS_STOP;
		item->pos.y_pos += STEP_L*3 + hdif;
		lara.gun_status = LG_HANDSBUSY;
	}
	else if ( !slope && hdif >= -STEP_L*7 - STEP_L/2 && hdif <= -STEP_L*4 + STEP_L/2 )
	{
		/* Jump up to grab walls within reach */
		item->anim_number = STOP_A;							// Start Jump Up animation
		item->frame_number = STOP_F;
		item->goal_anim_state = AS_UPJUMP;
		item->current_anim_state = AS_STOP;
		lara.calc_fallspeed = -(sint16)(phd_sqrt( (int)(-2*GRAVITY*(hdif+800)) ) + 3);
		AnimateLara( item );
	}
	else if (lara.climb_status && hdif <= -STEP_L*8 + STEP_L/2 && lara.water_status!=LARA_WADE &&
		coll->left_floor <= -STEP_L*8 + STEP_L/2 && coll->right_floor <= -STEP_L*8 &&
		coll->mid_ceiling <= -STEP_L*8 + STEP_L/2 + LARA_HITE)
	{
		// Jump up onto tall climbable wall; won't do this for tall ceiling walls lowered below platform we're on (v.rare)
		item->anim_number = STOP_A;							// Start Jump Up animation
		item->frame_number = STOP_F;
		item->goal_anim_state = AS_UPJUMP;
		item->current_anim_state = AS_STOP;
		lara.calc_fallspeed = -116; // from that sqrt equation above
		AnimateLara( item );
	}
	else if ( lara.climb_status && (hdif < -STEP_L*4 ||	// Is wall's height > a full block
		 coll->front_ceiling >= LARA_HITE-STEP_L)  && // or a ceilingwall, lower than Lara
		 coll->mid_ceiling <= -STEP_L*5 + LARA_HITE)
	{
		ShiftItem(item,coll);
		if (LaraTestClimbStance(item, coll))
		{
			// Climb wall
			item->anim_number = STOP_A;							// Start climb anim
			item->frame_number = STOP_F;
			item->goal_anim_state = AS_CLIMBSTNC;
			item->current_anim_state = AS_STOP;
			AnimateLara( item );
			item->pos.y_rot = angle;                                // line up angles
			lara.gun_status = LG_HANDSBUSY;
			return(1);
		}
		return(0);
	}
	else
		return(0);

	item->pos.y_rot = angle;                                // line up angles
	ShiftItem( item,coll );                                 // shift away from wall
	return(1);

#undef VAULT_ANGLE
}

/******************************************************************************
 *			Test If Lara Is Standing On a Tilted Block
 *	returns if slide has been initiated
 *****************************************************************************/
int		TestLaraSlide( ITEM_INFO *item, COLL_INFO *coll )
{
	static	PHD_ANGLE 	old_ang=1;
	PHD_ANGLE			adif,ang;

	/* No Slide if slope is Small */
	if ( (ABS(coll->tilt_x))<=2 && (ABS(coll->tilt_z))<=2 )
		return(0);

	ang = 0;
	if ( coll->tilt_x>2 )                       		// get angle of Slope if any
		ang = -16384;
	else if ( coll->tilt_x<-2 )
		ang = 16384;
	if ( coll->tilt_z>2 && coll->tilt_z>(ABS(coll->tilt_x)) )
		ang = -32768;
	else if ( coll->tilt_z<-2 && -coll->tilt_z>(ABS(coll->tilt_x)) )
		ang = 0;

	adif = ang - item->pos.y_rot;
	ShiftItem( item,coll );
	if ( adif>=-16384 && adif<=16384 )
	{
		if ( item->current_anim_state!=AS_SLIDE || old_ang!=ang )
		{
			item->anim_number = SLIDE_A;				// Slide Forwards Animation
			item->frame_number = SLIDE_F;
			item->goal_anim_state = AS_SLIDE;			// Jump straight to Slide
			item->current_anim_state = AS_SLIDE;    	// status
			item->pos.y_rot = ang;
			lara.move_angle = ang;
			old_ang = ang;
		}
	}
	else
	{
		if ( item->current_anim_state!=AS_SLIDEBACK || old_ang!=ang )
		{
			item->anim_number = SLIDEBACK_A;			// Slide Backwards Animation
			item->frame_number = SLIDEBACK_F;
			item->goal_anim_state = AS_SLIDEBACK;		// Jump straight to slide backwards
			item->current_anim_state = AS_SLIDEBACK;    // status
			item->pos.y_rot = ang - 32768;
			lara.move_angle = ang;
			old_ang = ang;
		}
	}
	return(1);
}

/************************************************************************************
 *			Return Relative floor Height of ITEM at dist in front at Angle
 ***********************************************************************************/
sint16	LaraFloorFront( ITEM_INFO *item, PHD_ANGLE ang, sint32 dist )
{
	FLOOR_INFO 		*floor;
	sint32			x,y,z,height;
	sint16			room;

	x = item->pos.x_pos + (( phd_sin(ang) * dist ) >> W2V_SHIFT );
	y = item->pos.y_pos - LARA_HITE;
	z = item->pos.z_pos + (( phd_cos(ang) * dist ) >> W2V_SHIFT );
	room = item->room_number;

	floor=GetFloor( x, y, z, &room );  				// Get Height directly in front
	height = GetHeight( floor, x, y, z );
	if ( height != NO_HEIGHT)
		height -= item->pos.y_pos;
	return((sint16)height);
}

/****************************************************************************************
 *				Get Absolute World pos of certain joint on Lara
 ***************************************************************************************/
void	GetLaraJointAbsPosition( PHD_VECTOR *vec, int joint )
{
	/* TODO: this routine currently actually ignores joint and only returns either left or right hand position
		depending on whether it is the flare or a weapon that calls it. As I'd also like to know her hair pos,
		probably needs tidying up to work for any joint */
	int			fire_arms;
	int			frac,rate,size;
	sint16		*frmptr[2];
	OBJECT_INFO *object;
	sint32 		*bone;
	sint16		*rotation;
	sint16 		*frame;
	ITEM_INFO *item;

	item = lara_item;

	if ( lara.hit_direction<0 && (frac=GetFrames(item,frmptr,&rate) ) )
	{
		GetLJAInt( item,vec,frmptr[0],frmptr[1],frac,rate );
		return;
	}

	object = &objects[item->object_number];
	if ( lara.hit_direction>=0 )
	{
		switch ( lara.hit_direction )
		{
			default:
			case NORTH:     frame = anims[SPAZ_FORWARD_A].frame_ptr; size = anims[SPAZ_FORWARD_A].interpolation>>8; break;
			case EAST:		frame = anims[SPAZ_RIGHT_A].frame_ptr;	size = anims[SPAZ_RIGHT_A].interpolation>>8; break;
			case SOUTH:		frame = anims[SPAZ_BACK_A].frame_ptr; size = anims[SPAZ_BACK_A].interpolation>>8; break;
			case WEST:		frame = anims[SPAZ_LEFT_A].frame_ptr; size = anims[SPAZ_LEFT_A].interpolation>>8; break;
		}
		frame += (int)( lara.hit_frame*size );
	}
	else
		frame = frmptr[0];

	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);

	bone = bones + object->bone_index;
	rotation = frame+9;

	phd_TranslateRel((sint32)*(frame+6), (sint32)*(frame+7), (sint32)*(frame+8));
	gar_RotYXZsuperpack(&rotation, 0);
	// Hips pos

	phd_TranslateRel( *(bone+1+24), *(bone+2+24), *(bone+3+24) );
	gar_RotYXZsuperpack(&rotation, 6);
	phd_RotYXZ( lara.torso_y_rot, lara.torso_x_rot, lara.torso_z_rot );
	// Torso pos

	fire_arms = LG_UNARMED;						// Get what Gun is currently in Use
	if ( lara.gun_status==LG_READY ||       	// if Guns are Away dont use Animations...
		 lara.gun_status==LG_SPECIAL ||
		 lara.gun_status==LG_DRAW ||
		 lara.gun_status==LG_UNDRAW )
		 fire_arms = lara.gun_type;

	if (lara.gun_type == LG_FLARE )
	{
		// Get LEFT hand position

		phd_TranslateRel( *(bone+1+40), *(bone+2+40), *(bone+3+40) );
		if ( lara.flare_control_left )
		{
			rotation = lara.left_arm.frame_base + (lara.left_arm.frame_number - anims[lara.left_arm.anim_number].frame_base)
					* (anims[lara.left_arm.anim_number].interpolation>>8) + 9;
			gar_RotYXZsuperpack(&rotation, 11);
		}
		else
			gar_RotYXZsuperpack(&rotation, 3);

		// Left Upper Arm pos
	   	phd_TranslateRel( *(bone+1+44), *(bone+2+44), *(bone+3+44) );
		gar_RotYXZsuperpack(&rotation, 0);

		// Left Lower Arm pos
	   	phd_TranslateRel( *(bone+1+48), *(bone+2+48), *(bone+3+48) );
		gar_RotYXZsuperpack(&rotation, 0);

		// Left Hand pos
		phd_TranslateRel( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;
	}
	else if (fire_arms != LG_UNARMED)
	{
		// Get RIGHT hand position
		phd_TranslateRel( *(bone+1+28), *(bone+2+28), *(bone+3+28) );
		rotation = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
		gar_RotYXZsuperpack(&rotation, 8);

		// Right Upper Arm pos
		phd_TranslateRel( *(bone+1+32), *(bone+2+32), *(bone+3+32) );
		gar_RotYXZsuperpack(&rotation, 0);

		// Right Lower Arm pos
		phd_TranslateRel( *(bone+1+36), *(bone+2+36), *(bone+3+36) );
		gar_RotYXZsuperpack(&rotation, 0);

		// Right Hand pos
		phd_TranslateRel( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;
	}
	phd_PopMatrix();
}


void	GetLJAInt( ITEM_INFO *item, PHD_VECTOR *vec, sint16 *frame1, sint16 *frame2, int frac, int rate )
{
	OBJECT_INFO *object;
	sint32 		*bone;
	sint16		*rotation1, *rotation2;
	sint16		*bounds;
	int			  fire_arms;

	object = &objects[item->object_number];
	bounds = GetBoundsAccurate( item );

	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);

	bone = bones + object->bone_index;
	rotation1 = frame1+9;
	rotation2 = frame2+9;

	InitInterpolate(frac,rate);

	phd_TranslateRel_ID( (sint32)*(frame1+6), (sint32)*(frame1+7), (sint32)*(frame1+8),
					     (sint32)*(frame2+6), (sint32)*(frame2+7), (sint32)*(frame2+8) );
	gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);
	// HIPS

	phd_TranslateRel_I( *(bone+1+24), *(bone+2+24), *(bone+3+24) );
	gar_RotYXZsuperpack_I(&rotation1, &rotation2, 6);
	phd_RotYXZ_I( lara.torso_y_rot, lara.torso_x_rot, lara.torso_z_rot );
	// TORSO

	fire_arms = LG_UNARMED;						// Get what Gun is currently in Use
	if ( lara.gun_status==LG_READY ||       	// if Guns are Away dont use Animations...
		 lara.gun_status==LG_SPECIAL ||
		 lara.gun_status==LG_DRAW ||
		 lara.gun_status==LG_UNDRAW )
		 	fire_arms = lara.gun_type;

	if ( lara.gun_type==LG_FLARE )
	{
		InterpolateMatrix();
		phd_TranslateRel( *(bone+1+40), *(bone+2+40), *(bone+3+40) );
		if ( lara.flare_control_left )
		{
			rotation1 = lara.left_arm.frame_base + (lara.left_arm.frame_number - anims[lara.left_arm.anim_number].frame_base)
					* (anims[lara.left_arm.anim_number].interpolation>>8) + 9;
			gar_RotYXZsuperpack(&rotation1, 11);
		}
		else
			gar_RotYXZsuperpack(&rotation1, 3);

		// UPPER LEFT ARM
		phd_TranslateRel( *(bone+1+44), *(bone+2+44), *(bone+3+44) );
		gar_RotYXZsuperpack(&rotation1, 0);

		// LOWER LEFT ARM
		phd_TranslateRel( *(bone+1+48), *(bone+2+48), *(bone+3+48) );
		gar_RotYXZsuperpack(&rotation1, 0);

		// LEFT HAND
		phd_TranslateRel( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;
	}
	else if (fire_arms != LG_UNARMED)
	{
		// Get RIGHT hand position
		InterpolateMatrix();
		phd_TranslateRel( *(bone+1+28), *(bone+2+28), *(bone+3+28) );
		rotation1 = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
		gar_RotYXZsuperpack(&rotation1, 8);

		// UPPER RIGHT ARM
		phd_TranslateRel( *(bone+1+32), *(bone+2+32), *(bone+3+32) );
		gar_RotYXZsuperpack(&rotation1, 0);

		// LOWER RIGHT ARM
		phd_TranslateRel( *(bone+1+36), *(bone+2+36), *(bone+3+36) );
		gar_RotYXZsuperpack(&rotation1, 0);

		// RIGHT HAND
		phd_TranslateRel( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;
	}
	phd_PopMatrix();
}


/****************************************************************************************
 *				Get Absolute World pos of left/right hand on Lara
 ***************************************************************************************/

void	GetLaraHandAbsPosition( PHD_VECTOR *vec, int leftright )	// 0 = left / 1 = right / 2=hips
{
	int			fire_arms;
	int			frac,rate,size;
	sint16		*frmptr[2];
	OBJECT_INFO 	*object;
	sint32 		*bone;
	sint16		*rotation;
	sint16 		*frame;
	ITEM_INFO 	*item;

	item = lara_item;

	if ( lara.hit_direction<0 && (frac=GetFrames(item,frmptr,&rate) ) )
	{
		GetLHAInt( item,vec,frmptr[0],frmptr[1],frac,rate,leftright );
		return;
	}

	object = &objects[item->object_number];
	if ( lara.hit_direction>=0 )
	{
		switch ( lara.hit_direction )
		{
			default:
			case NORTH:
				frame = anims[SPAZ_FORWARD_A].frame_ptr;
				size = anims[SPAZ_FORWARD_A].interpolation>>8;
				break;

			case EAST:
				frame = anims[SPAZ_RIGHT_A].frame_ptr;
				size = anims[SPAZ_RIGHT_A].interpolation>>8;
				break;

			case SOUTH:
				frame = anims[SPAZ_BACK_A].frame_ptr;
				size = anims[SPAZ_BACK_A].interpolation>>8;
				break;

			case WEST:
				frame = anims[SPAZ_LEFT_A].frame_ptr;
				size = anims[SPAZ_LEFT_A].interpolation>>8;
				break;
		}
		frame += (int)( lara.hit_frame*size );
	}
	else
		frame = frmptr[0];

	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();

	bone = bones + object->bone_index;
	rotation = frame+9;

	phd_TranslateRel((sint32)*(frame+6), (sint32)*(frame+7), (sint32)*(frame+8));
	gar_RotYXZsuperpack(&rotation, 0);

	if (leftright == LARA_HIPS)
	{
		phd_TranslateRel( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;

		phd_PopMatrix();
		phd_PopMatrix();
		return;
	}
	// Hips pos

	phd_TranslateRel( *(bone+1+24), *(bone+2+24), *(bone+3+24) );

	if (lara.weapon_item!=NO_ITEM && lara.gun_type==LG_M16 &&
		 (items[lara.weapon_item].current_anim_state==0 || items[lara.weapon_item].current_anim_state==2 || items[lara.weapon_item].current_anim_state==4))
	{
		rotation = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
		gar_RotYXZsuperpack(&rotation, 7);
	}
	else
		gar_RotYXZsuperpack(&rotation, 6);

	phd_RotYXZ( lara.torso_y_rot, lara.torso_x_rot, lara.torso_z_rot );
	if (leftright == LARA_TORSO)
	{
		phd_TranslateRel( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;

		phd_PopMatrix();
		phd_PopMatrix();
		return;
	}
	// Torso pos

	fire_arms = LG_UNARMED;						// Get what Gun is currently in Use
	if ( lara.gun_status==LG_READY ||       	// if Guns are Away dont use Animations...
		 lara.gun_status==LG_SPECIAL ||
		 lara.gun_status==LG_DRAW ||
		 lara.gun_status==LG_UNDRAW )
		 fire_arms = lara.gun_type;

	if (leftright == 0)		// Get LEFT hand position
	{
		phd_TranslateRel( *(bone+1+40), *(bone+2+40), *(bone+3+40) );

		switch(fire_arms)
		{
			case	LG_UNARMED:
			case LG_FLARE:
				if (lara.flare_control_left)
				{
					rotation = lara.left_arm.frame_base + (lara.left_arm.frame_number - anims[lara.left_arm.anim_number].frame_base)
																		* (anims[lara.left_arm.anim_number].interpolation>>8) + 9;
					gar_RotYXZsuperpack(&rotation, 11);
				}
				else
					gar_RotYXZsuperpack(&rotation, 3);
				break;

			case LG_PISTOLS:
			case LG_MAGNUMS:
			case LG_UZIS:
				*(phd_mxptr+M00) = *(phd_mxptr+M00-12);
				*(phd_mxptr+M01) = *(phd_mxptr+M01-12);	  	// Restore Laras Main Rotations
				*(phd_mxptr+M02) = *(phd_mxptr+M02-12);     // Less any torso rotations
				*(phd_mxptr+M10) = *(phd_mxptr+M10-12);     // avoids Wobbly arms when
				*(phd_mxptr+M11) = *(phd_mxptr+M11-12);     // moving 'n' shooting COOL
				*(phd_mxptr+M12) = *(phd_mxptr+M12-12);
				*(phd_mxptr+M20) = *(phd_mxptr+M20-12);
				*(phd_mxptr+M21) = *(phd_mxptr+M21-12);
				*(phd_mxptr+M22) = *(phd_mxptr+M22-12);
				phd_RotYXZ( lara.left_arm.y_rot, lara.left_arm.x_rot, lara.left_arm.z_rot );
				rotation = lara.left_arm.frame_base + (lara.left_arm.frame_number - anims[lara.left_arm.anim_number].frame_base)
																	* (anims[lara.left_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack(&rotation, 11);
				break;

			case LG_SHOTGUN:
			case LG_HARPOON:
			case LG_ROCKET:
			case LG_M16:
			default:
		 		gar_RotYXZsuperpack(&rotation, 3);
				break;
		}

		// Left Upper Arm pos
	   	phd_TranslateRel( *(bone+1+44), *(bone+2+44), *(bone+3+44) );
		gar_RotYXZsuperpack(&rotation, 0);

		// Left Lower Arm pos
	   	phd_TranslateRel( *(bone+1+48), *(bone+2+48), *(bone+3+48) );
		gar_RotYXZsuperpack(&rotation, 0);

	}
	else 	// Right hand
	{
		phd_TranslateRel( *(bone+1+28), *(bone+2+28), *(bone+3+28) );

		switch(fire_arms)
		{
			case	LG_UNARMED:
			case LG_FLARE:
				gar_RotYXZsuperpack(&rotation, 0);
				break;

			case LG_PISTOLS:
			case LG_MAGNUMS:
			case LG_UZIS:
				*(phd_mxptr+M00) = *(phd_mxptr+M00-12);
				*(phd_mxptr+M01) = *(phd_mxptr+M01-12);	  	// Restore Laras Main Rotations
				*(phd_mxptr+M02) = *(phd_mxptr+M02-12);     // Less any torso rotations
				*(phd_mxptr+M10) = *(phd_mxptr+M10-12);     // avoids Wobbly arms when
				*(phd_mxptr+M11) = *(phd_mxptr+M11-12);     // moving 'n' shooting
				*(phd_mxptr+M12) = *(phd_mxptr+M12-12);
				*(phd_mxptr+M20) = *(phd_mxptr+M20-12);
				*(phd_mxptr+M21) = *(phd_mxptr+M21-12);
				*(phd_mxptr+M22) = *(phd_mxptr+M22-12);
				phd_RotYXZ( lara.right_arm.y_rot, lara.right_arm.x_rot, lara.right_arm.z_rot );
				rotation = lara.right_arm.frame_base + (lara.right_arm.frame_number - anims[lara.right_arm.anim_number].frame_base)
																	* (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack(&rotation, 8);
				break;

			case LG_SHOTGUN:
			case LG_HARPOON:
			case LG_ROCKET:
			case LG_M16:
				rotation = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack(&rotation, 8);
				break;
		}

		// Right Upper Arm pos
		phd_TranslateRel( *(bone+1+32), *(bone+2+32), *(bone+3+32) );
		gar_RotYXZsuperpack(&rotation, 0);

		// Right Lower Arm pos
		phd_TranslateRel( *(bone+1+36), *(bone+2+36), *(bone+3+36) );
		gar_RotYXZsuperpack(&rotation, 0);

	}

//	Apply offset vector.

	phd_TranslateRel( vec->x, vec->y, vec->z );
	vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
	vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
	vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;

	phd_PopMatrix();
	phd_PopMatrix();
}


void	GetLHAInt( ITEM_INFO *item, PHD_VECTOR *vec, sint16 *frame1, sint16 *frame2, int frac, int rate, long leftright)
{
	OBJECT_INFO *object;
	sint32 		*bone;
	sint16		*rotation1, *rotation2;
	sint16		*bounds;
	int			  fire_arms;

	object = &objects[item->object_number];
	bounds = GetBoundsAccurate( item );

	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();

	bone = bones + object->bone_index;
	rotation1 = frame1+9;
	rotation2 = frame2+9;

	InitInterpolate(frac,rate);

	phd_TranslateRel_ID( (sint32)*(frame1+6), (sint32)*(frame1+7), (sint32)*(frame1+8),
		     	      (sint32)*(frame2+6), (sint32)*(frame2+7), (sint32)*(frame2+8) );
	gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

	if (leftright == LARA_HIPS)
	{
		phd_TranslateRel_I( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;

		phd_PopMatrix();
		phd_PopMatrix();
		return;
	}
	// HIPS

	phd_TranslateRel_I( *(bone+1+24), *(bone+2+24), *(bone+3+24) );
	// TORSO

	if (lara.weapon_item!=NO_ITEM && lara.gun_type==LG_M16 &&
		 (items[lara.weapon_item].current_anim_state==0 || items[lara.weapon_item].current_anim_state==2 || items[lara.weapon_item].current_anim_state==4))
	{
		rotation1 = rotation2 = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
		gar_RotYXZsuperpack_I(&rotation1, &rotation2, 7);
	}
	else
		gar_RotYXZsuperpack_I(&rotation1, &rotation2, 6);

	phd_RotYXZ_I( lara.torso_y_rot, lara.torso_x_rot, lara.torso_z_rot );

	if (leftright == LARA_TORSO)
	{
		phd_TranslateRel_I( vec->x, vec->y, vec->z );
		vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
		vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
		vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;

		phd_PopMatrix();
		phd_PopMatrix();
		return;
	}
	// TORSO

	fire_arms = LG_UNARMED;						// Get what Gun is currently in Use
	if ( lara.gun_status==LG_READY ||       	// if Guns are Away dont use Animations...
		 lara.gun_status==LG_SPECIAL ||
		 lara.gun_status==LG_DRAW ||
		 lara.gun_status==LG_UNDRAW )
		 	fire_arms = lara.gun_type;

	if ( leftright == 0)	// Left hand.
	{
		phd_PushMatrix_I();
		phd_TranslateRel_I( *(bone+1+40), *(bone+2+40), *(bone+3+40) );
		switch (fire_arms)
		{
			case LG_UNARMED:					// UNARMED
			case LG_FLARE:
				if ( lara.flare_control_left )
				{
					rotation1 = rotation2 = lara.left_arm.frame_base + (lara.left_arm.frame_number - anims[lara.left_arm.anim_number].frame_base)
																							* (anims[lara.left_arm.anim_number].interpolation>>8) + 9;
					gar_RotYXZsuperpack_I(&rotation1, &rotation2, 11);
				}
				else
					gar_RotYXZsuperpack_I(&rotation1, &rotation2, 3);

				// UPPER LEFT ARM
				phd_TranslateRel_I( *(bone+1+44), *(bone+2+44), *(bone+3+44) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

				// LOWER LEFT ARM
				phd_TranslateRel_I( *(bone+1+48), *(bone+2+48), *(bone+3+48) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

		    		break;

			case LG_PISTOLS:
			case LG_MAGNUMS:
			case LG_UZIS:
				InterpolateArmMatrix();
				phd_RotYXZ( lara.left_arm.y_rot, lara.left_arm.x_rot, lara.left_arm.z_rot );
				rotation1 = lara.left_arm.frame_base + (lara.left_arm.frame_number - anims[lara.left_arm.anim_number].frame_base)
																		* (anims[lara.left_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack(&rotation1, 11);

				// UPPER LEFT ARM
				phd_TranslateRel( *(bone+1+44), *(bone+2+44), *(bone+3+44) );
				gar_RotYXZsuperpack(&rotation1, 0);

				// LOWER LEFT ARM
				phd_TranslateRel( *(bone+1+48), *(bone+2+48), *(bone+3+48) );
				gar_RotYXZsuperpack(&rotation1, 0);

				break;

			case LG_SHOTGUN:
			case LG_HARPOON:
			case LG_ROCKET:
			case LG_M16:
				rotation1 = rotation2 = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 11);

				// UPPER LEFT ARM
				phd_TranslateRel_I( *(bone+1+44), *(bone+2+44), *(bone+3+44) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

				// LOWER LEFT ARM
				phd_TranslateRel_I( *(bone+1+48), *(bone+2+48), *(bone+3+48) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);
				break;
		}

	}
	else		// Right hand
	{
		switch (fire_arms)
		{
			case LG_UNARMED:					// UNARMED
			case LG_FLARE:
				phd_PushMatrix_I();
				phd_TranslateRel_I( *(bone+1+28),*(bone+2+28),*(bone+3+28) );

				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

				// UPPER RIGHT ARM.
				phd_TranslateRel_I( *(bone+1+32), *(bone+2+32), *(bone+3+32) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

				// LOWER RIGHT ARM.
				phd_TranslateRel_I( *(bone+1+36), *(bone+2+36), *(bone+3+36) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);
		    		break;

			case LG_PISTOLS:
			case LG_MAGNUMS:
			case LG_UZIS:
				phd_PushMatrix_I();
				phd_TranslateRel_I( *(bone+1+28),*(bone+2+28),*(bone+3+28) );
				InterpolateArmMatrix();
				phd_RotYXZ( lara.right_arm.y_rot, lara.right_arm.x_rot, lara.right_arm.z_rot );
				rotation1 = lara.right_arm.frame_base + (lara.right_arm.frame_number - anims[lara.right_arm.anim_number].frame_base)
																		* (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack(&rotation1, 8);

				// UPPER RIGHT ARM.
				phd_TranslateRel( *(bone+1+32), *(bone+2+32), *(bone+3+32) );
				gar_RotYXZsuperpack(&rotation1, 0);

				// LOWER RIGHT ARM.
				phd_TranslateRel( *(bone+1+36), *(bone+2+36), *(bone+3+36) );
				gar_RotYXZsuperpack(&rotation1, 0);
				break;

			case LG_SHOTGUN:
			case LG_HARPOON:
			case LG_ROCKET:
			case LG_M16:
				phd_PushMatrix_I();
				phd_TranslateRel_I( *(bone+1+28),*(bone+2+28),*(bone+3+28) );
				rotation1 = rotation2 = lara.right_arm.frame_base + lara.right_arm.frame_number * (anims[lara.right_arm.anim_number].interpolation>>8) + 9;
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 8);

				// UPPER RIGHT ARM.
				phd_TranslateRel_I( *(bone+1+32), *(bone+2+32), *(bone+3+32) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);

				// LOWER RIGHT ARM.
				phd_TranslateRel_I( *(bone+1+36), *(bone+2+36), *(bone+3+36) );
				gar_RotYXZsuperpack_I(&rotation1, &rotation2, 0);
				break;
		}

	}

//	Apply offset vector.

	phd_TranslateRel_I( vec->x, vec->y, vec->z );
	vec->x = (*(phd_mxptr+M03)>>W2V_SHIFT) + item->pos.x_pos;
	vec->y = (*(phd_mxptr+M13)>>W2V_SHIFT) + item->pos.y_pos;
	vec->z = (*(phd_mxptr+M23)>>W2V_SHIFT) + item->pos.z_pos;
	phd_PopMatrix();
	phd_PopMatrix();
	phd_PopMatrix();
}
