/***********************************************************************************************************/
/*                                                                                                         */
/* Lara Underwater Stuff                                                                                   */
/*                                                                                                         */
/***********************************************************************************************************/

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

#ifdef PSX_VERSION
#include "../spec_psx/typedefs.h"
#include "../spec_psx/psxinput.h"
#include "../spec_psx/maths.h"
#else
#include "../specific/standard.h"
#include "../specific/input.h"
#endif

#include "lara.h"
#include "input.h"
#include "control.h"
#include "laraanim.h"
#include "laramisc.h"
#include "laraswim.h"
#include "camera.h"

extern uchar 	LaraOnPad;		// For House level.
extern	short	rcossin_tbl[];

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

#define UW_MAXSPEED		(50*4)
#define LARA_LEAN_MAX_UW	(LARA_LEAN_MAX*2)
#define WATER_FRICTION	6
#define UW_WALLDEFLECT	(2*ONE_DEGREE)

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

static void LaraTestWaterDepth(ITEM_INFO *item, COLL_INFO *coll)
{
	int wd;
	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);

	wd = GetWaterDepth(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, room_number);
	if (wd == NO_HEIGHT)
	{
		/* Don't allow Lara to swim onto bank as causes her many grievances */
		item->pos.x_pos = coll->old.x;
		item->pos.y_pos = coll->old.y;
		item->pos.z_pos = coll->old.z;
		item->fallspeed = 0;
	}
	else if (wd <= STEP_L*2)
	{
		/* 1/2 depth water or less; Lara automatically stands up */
		item->anim_number = SWIM2QSTND_A;
		item->frame_number = SWIM2QSTND_F;
		item->current_anim_state = AS_WATEROUT;
		item->goal_anim_state = AS_STOP;
		item->pos.x_rot = item->pos.z_rot = 0;
		item->gravity_status = 0;
		item->speed = 0;
		item->fallspeed = 0;
		lara.water_status = LARA_WADE;

		/* Origin on floor */
		item->pos.y_pos = GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos);
	}
}

static void LaraSwimCollision( ITEM_INFO *item, COLL_INFO *coll )
{
	int height;

	if ( item->pos.x_rot>=-16384 && item->pos.x_rot<=16384 )
		coll->facing = lara.move_angle = item->pos.y_rot;
	else
		coll->facing = lara.move_angle = item->pos.y_rot-32768;

//	GetCollisionInfo( coll, item->pos.x_pos,item->pos.y_pos+UW_HITE/2,item->pos.z_pos,item->room_number,UW_HITE,NULL );
	height = phd_sin(item->pos.x_rot) * LARA_HITE >> W2V_SHIFT;
	if (height < 0)
		height = -height;
	if (height < 200)
		height = 200;
	coll->bad_neg = -height; // try this to avoid bashing edges
	GetCollisionInfo( coll, item->pos.x_pos,item->pos.y_pos+height/2,item->pos.z_pos,item->room_number,height );
	ShiftItem( item,coll );
	if ( coll->coll_type==COLL_FRONT ) 			// Weve Hit something at the Front...
	{
		if ( item->pos.x_rot>45*ONE_DEGREE )
			item->pos.x_rot += UW_WALLDEFLECT;
		else if ( item->pos.x_rot<-45*ONE_DEGREE )	//## Was 35
			item->pos.x_rot -= UW_WALLDEFLECT;
		else
			item->fallspeed = 0;
	}
	else if ( coll->coll_type==COLL_TOP )
	{
		if ( item->pos.x_rot>= -45*ONE_DEGREE )
			item->pos.x_rot -= UW_WALLDEFLECT;
	}
	else if ( coll->coll_type==COLL_TOPFRONT )
		item->fallspeed = 0;
	else if ( coll->coll_type==COLL_LEFT )
		item->pos.y_rot += 5*ONE_DEGREE;
	else if ( coll->coll_type==COLL_RIGHT )
		item->pos.y_rot -= 5*ONE_DEGREE;
	else if ( coll->coll_type==COLL_CLAMP )
	{
		item->pos.x_pos = coll->old.x; // 2/10/97: attempt to stop dodgy shift
		item->pos.y_pos = coll->old.y;
		item->pos.z_pos = coll->old.z;
		item->fallspeed = 0;
		return;
	}

	if ( coll->mid_floor<0 )
	{
		item->pos.y_pos += coll->mid_floor;
		item->pos.x_rot += UW_WALLDEFLECT;
	}

	/* Lara cannot swim into v.shallow water; 1/4 depth just blocks her, 1/2 and she stands up */
	if ( lara.water_status!=LARA_CHEAT && !lara.extra_anim)
		LaraTestWaterDepth(item, coll);
}

static void SwimTurn(ITEM_INFO *item)
{
	/* 20/7/97: use 'turn_rate' like run control for more precise underwater steering */
	if ( input&IN_FORWARD )
		item->pos.x_rot -= 2*ONE_DEGREE;
	else if ( input&IN_BACK )
		item->pos.x_rot += 2*ONE_DEGREE;

	if ( input&IN_LEFT )
	{
		lara.turn_rate -= LARA_TURN_RATE;
		if ( lara.turn_rate < -LARA_MED_TURN )
			lara.turn_rate = -LARA_MED_TURN;
		// old code just jumped immediately to full turn
		//item->pos.y_rot -= LARA_MED_TURN;
		item->pos.z_rot -= LARA_LEAN_RATE*2;
	}
	else if ( input & IN_RIGHT )
	{
		lara.turn_rate += LARA_TURN_RATE;
		if ( lara.turn_rate > LARA_MED_TURN )
			lara.turn_rate = LARA_MED_TURN;
		//item->pos.y_rot += LARA_MED_TURN;
		item->pos.z_rot += LARA_LEAN_RATE*2;
	}
}

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

void	LaraUnderWater( ITEM_INFO *item, COLL_INFO *coll )
{
	// Set up default collision stuff
	coll->bad_pos = NO_BAD_POS;
	coll->bad_neg = -UW_HITE;
	coll->bad_ceiling = UW_HITE;
	coll->old.x = item->pos.x_pos;
	coll->old.y = item->pos.y_pos;
	coll->old.z = item->pos.z_pos;
	coll->radius = UW_RADIUS;
	coll->trigger = NULL;
	coll->slopes_are_walls = 0;
	coll->slopes_are_pits = 0;
	coll->lava_is_pit = 0;
	coll->enable_spaz = 0;
	coll->enable_baddie_push = 1;

	if ((input & IN_LOOK) && lara.look)
		LookLeftRight();
	else
		ResetLook();
	lara.look = 1;

	// Get Input given current state
	if (lara.extra_anim)
		(*extra_control_routines[item->current_anim_state])(item, coll);
	else
		(*lara_control_routines[item->current_anim_state])( item,coll );

	// Unroll Banking
	if ( item->pos.z_rot >= -(2*LARA_LEAN_UNDO) && item->pos.z_rot <= 2*LARA_LEAN_UNDO )
		item->pos.z_rot = 0;
	else if ( item->pos.z_rot<0 )
		item->pos.z_rot += 2*LARA_LEAN_UNDO;
	else
		item->pos.z_rot -= 2*LARA_LEAN_UNDO;

	// Make sure Under water angles are within allowable limits
	if ( item->pos.x_rot < -85*ONE_DEGREE ) // gav: angles were 100 (greater than 90 => camera stress)
		item->pos.x_rot = -85*ONE_DEGREE;
	else if ( item->pos.x_rot > 85*ONE_DEGREE )
		item->pos.x_rot = 85*ONE_DEGREE;
	if ( item->pos.z_rot < -LARA_LEAN_MAX_UW )
		item->pos.z_rot = -LARA_LEAN_MAX_UW;
	else if ( item->pos.z_rot > LARA_LEAN_MAX_UW )
		item->pos.z_rot = LARA_LEAN_MAX_UW;

	/* Gav: let's try some turn rate stuff like the run uses */
	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;

	if (lara.current_active && lara.water_status!=LARA_CHEAT )
		LaraWaterCurrent( coll );

	AnimateLara(item);
	item->pos.y_pos -= (phd_sin(item->pos.x_rot) * item->fallspeed ) >> (W2V_SHIFT+2);
	item->pos.x_pos += (((phd_sin(item->pos.y_rot) * item->fallspeed) >> (W2V_SHIFT+2)) * phd_cos(item->pos.x_rot) ) >> W2V_SHIFT;
	item->pos.z_pos += (((phd_cos(item->pos.y_rot) * item->fallspeed) >> (W2V_SHIFT+2)) * phd_cos(item->pos.x_rot) ) >> W2V_SHIFT;

	if ((lara.water_status != LARA_CHEAT)
	&&  (!lara.extra_anim))
		LaraBaddieCollision( item,coll );										// Do any Baddie collisions...

	if ((!lara.extra_anim)
	&&  (lara.skidoo == NO_ITEM))
		(*lara_collision_routines[item->current_anim_state])( item,coll );			// Now Handle Any Collision Issues..

	UpdateLaraRoom( item,0 );

	LaraGun();

	LaraOnPad = 0;
	TestTriggers( coll->trigger, 0 );	// Gibbytesttriggers
	if (!LaraOnPad)
		lara_item->item_flags[1] = 0;	// Reset lara on pad flag.
}

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

	if ( input&IN_ROLL )
	{
		item->current_anim_state = AS_WATERROLL;
		item->anim_number = WATERROLL_A;
		item->frame_number = WATERROLL_F;
		return;
	}

	SwimTurn(item);

	item->fallspeed += 2*4;									// Use fallspeed to record in water speed
	if ( item->fallspeed>UW_MAXSPEED )                  // as usual speed gets updated by animateLara
		item->fallspeed =  UW_MAXSPEED;

	if ( !(input&IN_JUMP) )
		item->goal_anim_state = AS_GLIDE;
}


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

	if ( input&IN_ROLL )
	{
		item->current_anim_state = AS_WATERROLL;
		item->anim_number = WATERROLL_A;
		item->frame_number = WATERROLL_F;
		return;
	}

	SwimTurn(item);

	if ( input&IN_JUMP )
		item->goal_anim_state = AS_SWIM;

	item->fallspeed -= WATER_FRICTION;
	if ( item->fallspeed<0 )
		item->fallspeed = 0;

	// return to TREAD if slowing down
	if ( item->fallspeed <= (UW_MAXSPEED*2)/3 )
		item->goal_anim_state = AS_TREAD;
}

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

	if ( input&IN_ROLL )
	{
		item->current_anim_state = AS_WATERROLL;
		item->anim_number = WATERROLL_A;
		item->frame_number = WATERROLL_F;
		return;
	}

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

	SwimTurn(item);

	if ( input&IN_JUMP )
		item->goal_anim_state = AS_SWIM;

	item->fallspeed -= WATER_FRICTION;
	if ( item->fallspeed<0 )
		item->fallspeed = 0;

	if (lara.gun_status == LG_HANDSBUSY)
		lara.gun_status = LG_ARMLESS; // 27/9/97: general HANDSFREE thing in tread (just in case)
}

//----------------------------- DIVE ----------------------------------------
void	lara_as_dive( ITEM_INFO *item, COLL_INFO *coll )
{
	if ( input&IN_FORWARD )
		item->pos.x_rot -= ONE_DEGREE;
}

//------------------------ UNDERWATER DEATH ----------------------------------
void	lara_as_uwdeath( ITEM_INFO *item, COLL_INFO *coll )
{
	lara.look = 0;

	// Decrease speed quickly if Lara is dying
	item->fallspeed -= 8;
	if ( item->fallspeed<=0 )
		item->fallspeed = 0;

	// Alter so Lara is pitched forward
	if ( item->pos.x_rot>=-2*ONE_DEGREE && item->pos.x_rot<=2*ONE_DEGREE )
		item->pos.x_rot = 0;
	else if ( item->pos.x_rot<0 )
		item->pos.x_rot += 2*ONE_DEGREE;
	else
		item->pos.x_rot -= 2*ONE_DEGREE;
}

void	lara_as_waterroll( ITEM_INFO *item, COLL_INFO *coll )
{
	item->fallspeed = 0;
}

/******************************************************************************
 ******************************************************************************
 *			Swimming Collision Routines...
 ******************************************************************************
 *****************************************************************************/


//+++++++++++++++++++++++++++++++++ SWIM ++++++++++++++++++++++++++++++++

void	lara_col_swim( ITEM_INFO *item, COLL_INFO *coll )
{
	LaraSwimCollision( item,coll );
}

//+++++++++++++++++++++++++++++++ GLIDE ++++++++++++++++++++++++++++++++
void	lara_col_glide( ITEM_INFO *item, COLL_INFO *coll )
{
	LaraSwimCollision( item,coll );
}
//+++++++++++++++++++++++++++++++ TREAD ++++++++++++++++++++++++++++++++
void	lara_col_tread( ITEM_INFO *item, COLL_INFO *coll )
{
	LaraSwimCollision( item,coll );
}

//+++++++++++++++++++++++++ DIVE ++++++++++++++++++++++++++++++++
void	lara_col_dive( ITEM_INFO *item, COLL_INFO *coll )
{
	LaraSwimCollision( item,coll );
}

//+++++++++++++++++++++++++ UNDERWATER DEATH ++++++++++++++++++++++++++++++++
void	lara_col_uwdeath( ITEM_INFO *item, COLL_INFO *coll )
{
	int		wh;

	item->hit_points = -1;
	lara.air = -1;
	lara.gun_status = LG_HANDSBUSY;
	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;
	LaraSwimCollision( item,coll );
}
//+++++++++++++++++++++++++ UNDERWATER ROLL ++++++++++++++++++++++++++++++++
void	lara_col_waterroll( ITEM_INFO *item, COLL_INFO *coll )
{
	LaraSwimCollision( item,coll );
}


sint32 GetWaterDepth(sint32 x, sint32 y, sint32 z, sint16 room_number)
{
	/* Returns depth of water below surface or 0x7fff if no surface
		(as GetWaterHeight returns ceiling height even if no surface) */
	int wh;
	ROOM_INFO *r;
	FLOOR_INFO *floor;
	sint16 data;
	int x_floor, y_floor;

	//r = &room[room_number];
	//floor = &r->floor[((z - r->z) >> WALL_SHIFT) + ((x - r->x) >> WALL_SHIFT) * r->x_size];

	// BUG FIX2 6/11/97: Possible evil bug? x and y could be outside room boundaries
	r = &room[room_number];
	do
	{
		/* Clip position to edge of room (that way doorways are detected) */
	  	x_floor = (z - r->z) >> WALL_SHIFT;
		y_floor = (x - r->x) >> WALL_SHIFT;

		/* Gav 19/9/96: this more complex code is just to ensure we don't test the corner of a room's floor data,
							 as this can cause problems when 4 rooms join at a point */
		if (x_floor <= 0)
		{
			x_floor = 0;
			if (y_floor < 1)
				y_floor = 1;
			else if (y_floor > r->y_size-2)
				y_floor = r->y_size-2;
		}
		else if (x_floor >= r->x_size-1)
		{
			x_floor = r->x_size - 1;
			if (y_floor < 1)
				y_floor = 1;
			else if (y_floor > r->y_size-2)
				y_floor = r->y_size-2;
		}
		else if (y_floor < 0)
			y_floor = 0;
		else if (y_floor >= r->y_size)
			y_floor = r->y_size - 1;

		/* If doorway, go through and retest, else move onto next stage */
		floor = &r->floor[x_floor + y_floor * r->x_size];
		data = GetDoor(floor);
		if (data != NO_ROOM)
		{
			room_number = data;
			r = &room[data];
		}
	}
	while (data != NO_ROOM);

//	if (r->flags & UNDERWATER)
	if (r->flags & (UNDERWATER|SWAMP))
	{
		/* Upwards until leave water */
		while (floor->sky_room != NO_ROOM)
		{
			r = &room[floor->sky_room];
//			if (!(r->flags & UNDERWATER))
			if (!(r->flags & (UNDERWATER|SWAMP)))
			{
				wh = floor->ceiling << 8;
				floor = GetFloor(x, y, z, &room_number);
				return (GetHeight(floor, x, y, z) - wh);
			}
			floor = &r->floor[((z - r->z) >> WALL_SHIFT) + ((x - r->x) >> WALL_SHIFT) * r->x_size];
		}
		return (0x7fff); // no surface, so treat as deep water
	}
	else
	{
		/* Go down until hit water */
		while (floor->pit_room != NO_ROOM)
		{
			r = &room[floor->pit_room];
//			if (r->flags & UNDERWATER)
			if (r->flags & (UNDERWATER|SWAMP))
			{
				wh = floor->floor << 8;
				floor = GetFloor(x, y, z, &room_number);
				return (GetHeight(floor, x, y, z) - wh);
			}
			floor = &r->floor[((z - r->z) >> WALL_SHIFT) + ((x - r->x) >> WALL_SHIFT) * r->x_size];
		}
		return (NO_HEIGHT); // no water!; treat as very bad indeed
	}
}

/******************************************************************************
 *			Do Water Current Stuff.....
 *****************************************************************************/

#if	0

void	LaraWaterCurrent( COLL_INFO *coll )
{
	/* Routine to suck Lara in direction of sink */
	PHD_VECTOR 	target;
	ROOM_INFO 	*r;
	FLOOR_INFO 	*floor;
	ITEM_INFO	*item;


	item = lara_item;
	r = &room[lara_item->room_number];
	floor = &r->floor[((item->pos.z_pos - r->z) >> WALL_SHIFT) + ((item->pos.x_pos - r->x) >> WALL_SHIFT) * r->x_size];
	item->box_number = floor->box;

	/* No AI assigned */
	if (!lara.creature)
	{
		lara.current_active = 0;
		return;
	}

	/* Calculate target using LOT table stuff */
	if (CalculateTarget(&target, item, &lara.creature->LOT) == NO_TARGET)
		return;

	/* Move Lara in direction of this target point */
	target.x -= item->pos.x_pos;
	if (target.x > lara.current_active)
		item->pos.x_pos += lara.current_active;
	else if (target.x < -lara.current_active)
		item->pos.x_pos -= lara.current_active;
	else
		item->pos.x_pos += target.x;

	target.z -= item->pos.z_pos;
	if (target.z > lara.current_active)
		item->pos.z_pos += lara.current_active;
	else if (target.z < -lara.current_active)
		item->pos.z_pos -= lara.current_active;
	else
		item->pos.z_pos += target.z;

	target.y -= item->pos.y_pos;
	if (target.y > lara.current_active)
		item->pos.y_pos += lara.current_active;
	else if (target.y < -lara.current_active)
		item->pos.y_pos -= lara.current_active;
	else
		item->pos.y_pos += target.y;

	/* Reset current (will get set again so long as Lara is over triggers) */
	lara.current_active = 0;

	coll->facing = phd_atan( (item->pos.z_pos-coll->old.z),(item->pos.x_pos-coll->old.x) );
	GetCollisionInfo( coll, item->pos.x_pos,item->pos.y_pos+UW_HITE/2,item->pos.z_pos, item->room_number,UW_HITE );
	if ( coll->coll_type==COLL_FRONT )
	{
		if ( item->pos.x_rot>35*ONE_DEGREE )
			item->pos.x_rot += UW_WALLDEFLECT;
		else if ( item->pos.x_rot<-35*ONE_DEGREE )
			item->pos.x_rot -= UW_WALLDEFLECT;
		else
			item->fallspeed = 0;
	}
	else if ( coll->coll_type==COLL_TOP )
		item->pos.x_rot -= UW_WALLDEFLECT;
	else if ( coll->coll_type==COLL_TOPFRONT )
		item->fallspeed = 0;
	else if ( coll->coll_type==COLL_LEFT )
		item->pos.y_rot += 5*ONE_DEGREE;
	else if ( coll->coll_type==COLL_RIGHT )
		item->pos.y_rot -= 5*ONE_DEGREE;

	if ( coll->mid_floor<0 )
	{
		item->pos.y_pos += coll->mid_floor;
		item->pos.x_rot += UW_WALLDEFLECT;
	}
	ShiftItem( item,coll );

	// update old positions
	coll->old.x = item->pos.x_pos;
	coll->old.y = item->pos.y_pos;
	coll->old.z = item->pos.z_pos;
}

#else

void	LaraWaterCurrent( COLL_INFO *coll )
{
	/* Routine to suck Lara in direction of sink */
	PHD_VECTOR 	target;
	ROOM_INFO 	*r;
	ITEM_INFO	*item;

	item = lara_item;
	r = &room[lara_item->room_number];

	if (!lara.current_active)
	{
		long	shifter,absvel;

		absvel = abs(lara.current_xvel);
		if (absvel > 16)
			shifter = 4;
		else if (absvel > 8)
			shifter = 3;
		else
			shifter = 2;

		lara.current_xvel -= lara.current_xvel >> shifter;
		if (abs(lara.current_xvel) < 4)
			lara.current_xvel = 0;


		absvel = abs(lara.current_zvel);
		if (absvel > 16)
			shifter = 4;
		else if (absvel > 8)
			shifter = 3;
		else
			shifter = 2;

		lara.current_zvel -= lara.current_zvel >> shifter;
		if (abs(lara.current_zvel) < 4)
			lara.current_zvel = 0;

		if (	lara.current_xvel == 0 &&
			lara.current_zvel == 0)
			return;
	}
	else
	{
		long	angle,dx,dz,speed,sinkval;

		sinkval = lara.current_active-1;
		target.x = camera.fixed[sinkval].x;
		target.y = camera.fixed[sinkval].y;
		target.z = camera.fixed[sinkval].z;
		angle = ((mGetAngle(target.x,target.z,lara_item->pos.x_pos,lara_item->pos.z_pos)-0x4000)>>4)&4095;

		dx = target.x - lara_item->pos.x_pos;
		dz = target.z - lara_item->pos.z_pos;

		speed = camera.fixed[sinkval].data;
		dx = (((rcossin_tbl[(angle<<1)] * speed))) >> 2; // / distance)<<4;
		dz = (((rcossin_tbl[(angle<<1)+1] * speed))) >> 2;// / distance)<<4;

//		if (input & IN_ACTION)
//			printf("Speed %d, Dist %d, dx %d, dz %d, Xv %d, Zv %d \n",speed,distance,dx,dz,lara.current_xvel,lara.current_zvel);

		lara.current_xvel += (dx - lara.current_xvel)>>4;
		lara.current_zvel += (dz - lara.current_zvel)>>4;
		lara_item->pos.y_pos += (target.y - lara_item->pos.y_pos) >> 4;
	}

	/* Move Lara in direction of sink. */

	item->pos.x_pos += lara.current_xvel>>8;
	item->pos.z_pos += lara.current_zvel>>8;

	/* Reset current (will get set again so long as Lara is over triggers) */
	lara.current_active = 0;

	coll->facing = phd_atan( (item->pos.z_pos-coll->old.z),(item->pos.x_pos-coll->old.x) );
	GetCollisionInfo( coll, item->pos.x_pos,item->pos.y_pos+UW_HITE/2,item->pos.z_pos, item->room_number,UW_HITE );
	if ( coll->coll_type==COLL_FRONT )
	{
		if ( item->pos.x_rot>35*ONE_DEGREE )
			item->pos.x_rot += UW_WALLDEFLECT;
		else if ( item->pos.x_rot<-35*ONE_DEGREE )
			item->pos.x_rot -= UW_WALLDEFLECT;
		else
			item->fallspeed = 0;
	}
	else if ( coll->coll_type==COLL_TOP )
		item->pos.x_rot -= UW_WALLDEFLECT;
	else if ( coll->coll_type==COLL_TOPFRONT )
		item->fallspeed = 0;
	else if ( coll->coll_type==COLL_LEFT )
		item->pos.y_rot += 5*ONE_DEGREE;
	else if ( coll->coll_type==COLL_RIGHT )
		item->pos.y_rot -= 5*ONE_DEGREE;

	if ( coll->mid_floor<0 )
	{
		item->pos.y_pos += coll->mid_floor;
//		item->pos.x_rot += UW_WALLDEFLECT;
	}
	ShiftItem( item,coll );

	// update old positions
	coll->old.x = item->pos.x_pos;
	coll->old.y = item->pos.y_pos;
	coll->old.z = item->pos.z_pos;
}

#endif
