

#include "generic.h"
#include "lfptypes.h"

#include "define.h"
#include "ml.h"

#include "ctrl.h"

#include "audio.h"

#ifdef PC
 #include "textcode.h"
 #include "kernel.h"
#endif


static int hold_on[3]={
ONE_SEC, HALF_SEC, 0};

int pass_scores[5];

int threat_plyr;
SW  threat_angle;

static playert * get_free_pass_scores(playert *plyr);
static playert * get_pass_scores(playert *plyr);
static int		 shot_score(int percent, int sc);
static bool			step_defender(playert *plyr);

static int last_bh_basket_dist;
static UI last_post_decision;

int back_down_ticks;
int postup_move;
int	in_set_flag;

bool	first_step_flag=FALSE;


void ball_handling_ai(void)
{
int shoot_score;
int postup_score;
int pass_score;
int hold_score;
int t;
bool	pf=TRUE;

	int		i,j;
	int		ctrli;		// Index of controller to check for roleplay called ball move
	ctrlrT	*ctrlr;
	teamt	*team;
	int		called_pass=FALSE;
	SW		a;			// Angle delta of player's facing towards that of the hoop
	SW		ta;			// Threat angle delta from hoop direction

/*
 * pass back and forth
 */
//	int_recvr = ball_handler^(5^6);
//	current_ctrlr->mctrlr = CTRL_PASS;
//	return;

	if (ai_off_flag)	return;

	if (dunk_flag)		return;

	if (pass_flag)		return;

	if (bhp->zco)		return;

	if ((!bhp->control) && (in_play_flag))
	{
		team=&ai_team[bhp->team];

		// Check for roleplaying called passes or shots
		for (i=0; i<5; i++)
		{
			// No more human controlled players?
			if ((ctrli=team->controllers[i])<1)
				break;

			// Ensure player is roleplaying
			ctrlr=&ctrlrs[ctrli];
			if (ctrlr->roleplay==CPL_NOLOCK)
				continue;

			// Check for roleplaying called actions
			if (CTL_DOWN(ctrlr,CTRL_SHOOT))
				CTL_SETDOWN(current_ctrlr,CTRL_SHOOT);

			if (CTL_DOWN(ctrlr,CTRL_PASS))
			{
				for (j=0; j<10; j++)
				{
					if (player[j].control==ctrli)
					{
						int_recvr=j;
						break;
					}
				}
				called_pass=TRUE;
				current_ctrlr->mctrlr=CTRL_PASS;
			}
		}

		// Check for first step move stuff here
		ta=bhp->basket_angle-threat_angle;
		a=bhp->angle-bhp->basket_angle;
		if (first_step_flag)
		{
			if (abs(a)>0x800)
			{
				pivot_turn_to(bhp,bhp->basket_angle);
				return;
			}
			else if (lp_ctr-special_time > (3*ONE_SEC))
			{
				special_time=lp_ctr;
				if (ReadRnd250()<0xb0)
					CTL_SETHOLD(current_ctrlr,CTRL_DRIBBLE);
				else
					CTL_SETTAP(current_ctrlr,CTRL_DRIBBLE);
				//first_step_flag=FALSE;
				return;
			}
		}
		else
			if (!dribble_flag)
				if (bhp->basket_dist<0x800000 && bhp->basket_dist>0x400000)
					if (MANHATTAN(bhp->xvel,bhp->yvel)<0x200)
						if (step_defender(bhp))
							if (ReadRnd250()<0x40)
							{
								first_step_flag=TRUE;
								bhp->target_x=bhp->xco;
								bhp->target_y=bhp->yco;
								return;
							}

		if (ArcadeMode && dunk_test(bhp) && (DIFFICULTY!=0))
		{
			current_ctrlr->mctrlr = CTRL_SHOOT;
			return;
		}

		if ((blocked_basket_test(bhp) == 0xe)
			|| ( ((UI)(lp_ctr-last_post_decision) < ONE_SEC) && (postup_move==SPIN_OFF)) )
	 
		{
			if (bhp->basket_dist < 0xa0000 && PLY(bhp)<GLASS_Y)
			{
				current_ctrlr->mctrlr = CTRL_SHOOT;
				return;
			}

			if ((DIFFICULTY!=0) || (fast_break_flag) || (shot_clock<5*ONE_SEC))
			{

				current_ctrlr->force = 0xf0;
				current_ctrlr->d_angle = bhp->basket_angle;

				if ((bhp->last_speed==0) || (bhp->shuffle))
				{
					if (sdunk_test(bhp))		return;
				}
				else
				{
					t = dunk_test(bhp);
					if (t)
					{
						current_ctrlr->mctrlr = CTRL_SHOOT;
					}
				}

				return;
			}
		}

		// When picking, go to the appropriate spot
		{
			if (is_pick_on(bhp))
			{
				dribble_to_place(bhp);
				return;
			}
		}
	
	}


//should i shoot
//what are my chances of making a basket
	shoot_score = get_shoot_score(bhp);

//postup ?
	postup_score = get_postup_score(bhp);

//look for pass
	if (!called_pass)
	{
		int	hx,hy;

		int_recvr = get_free_pass_scores2(bhp, &pass_score, &hold_score);
		if (HotSpot_GetPos(&hx,&hy))
			if (bhp->target_x==hx && bhp->target_y==hy &&
				(PMR(bhp)==dribble || ((PMR(bhp)==stand_with_ball || PMR(bhp)==stand_with_ball2) && !dribble_flag) ) )
			{
				if (HotSpot_Check(bhp))
					current_ctrlr->ctrlr=current_ctrlr->mctrlr=CTRL_SHOOT;
				else
					dribble_to_place(bhp);
				return;
			}
	}

	// When in low time, check for quick play
	if (should_waste_time(bhp->team^1))
	{
		if (get_shot_percent(bhp,bhp->basket_dist)>60)
			shoot_score=0;
		else
		{
			if (hold_score<pass_score && pass_score-hold_score<0x10000)
				hold_score=pass_score+100;
		}
	}

	if (back_down_ticks)
	{
		if (hold_score<postup_score)
		{
			postup_score = hold_score-1;
		}

		if (shoot_score<postup_score)
		{
			choose_postup_move(bhp);
			return;
		}
	}


	if (bhp->control)	return;

	if (((shoot_score < postup_score) && (shoot_score<pass_score) && (shoot_score<hold_score) && !(PLY(bhp)>GLASS_Y && abs(bhp->xco)<0x1C0000))
		|| (!shoot_score && time_left<2*ONE_SEC))
	{
		back_down_ticks = 0;
		
		shoot_score = get_shoot_score(bhp);

		current_ctrlr->ctrlr  =
		current_ctrlr->mctrlr = CTRL_SHOOT;
		return;
	}
	else if ((postup_score < pass_score) && !(PLY(bhp)>GLASS_Y && abs(bhp->xco)<0x1C0000))
	{
		back_down_ticks++;

		if (bhp->basket_dist<0x180000)
		{
			choose_postup_move(bhp);
			return;
		}

		if (back_down_ticks < ONE_SEC)
		{
			back_down(bhp);
		}
		else
		{
			if ((bhp->basket_dist >= last_bh_basket_dist) || (bhp->key_ctr>2*ONE_SEC))
			{
				choose_postup_move(bhp);
			}
			else
			{
				back_down(bhp);
			}
		}
		return;
	}
	else if (pass_score < hold_score)
	{
		back_down_ticks = 0;

		if (pass_flag)
			pf=FALSE;
		if (is_pick_on(bhp) || first_step_flag)
			pf=FALSE;
		else if (!fast_break_flag && !in_set_flag && bhp->no-bhp->base==0 && (!dribble_flag || bhp->main_routine==dribble) && threat_plyr==-1)
		{
			pf=FALSE;
			dribble_to_place(bhp);
			return;
		}

		if (pf)
		{
			current_ctrlr->ctrlr =
			current_ctrlr->mctrlr = CTRL_PASS;
			return;
		}
	}
	else
	{
		back_down_ticks = 0;

		dribble_to_place(bhp);
	}
	return;
}




void dribble_to_place(playert *plyr)
{
SW a_diff;
int target_dist;

	//look out for anyone to hide the ball from

	if (threat_plyr>=0)
	{
		a_diff = plyr->basket_angle-plyr->angle;
		if (abs(a_diff) < 0x2000)
		{
			if (lp_ctr-special_time > (3*ONE_SEC))
			{
				current_ctrlr->mctrlr = CTRL_DRIBBLE;
			}
		}
		else
		{
			target_dist = MANHATTAN(plyr->target_x-plyr->xco, plyr->target_y-plyr->yco);
			current_ctrlr->d_angle = LFPAtn(plyr->target_x-plyr->xco, plyr->target_y-plyr->yco);

			current_ctrlr->ctrlr  |= CTRL_SHUFFLE;

			if (target_dist > SHUFFLE_SLOW_ZONE)
			{
				current_ctrlr->force   = 0xf0;
			}
			else if (target_dist > SHUFFLE_STOP_ZONE)
			{
				current_ctrlr->ctrlr  |= CTRL_SHUFFLE;
				current_ctrlr->force   = 0x70;
			}
			return;
		}
	}

	attack_home_in(plyr, (SW)plyr->basket_angle);
}

#define	TD(m,s)		((m)*ONE_MIN+(s)*ONE_SEC)
int should_waste_time(int team)
{
	int	i;
	int	ds;
	int	dx,dy;
	int	dist;
	static int	breakdowns[][3]=
					{
					TD(0,24),	1,	10,
					TD(0,48),	2,	10,
					TD(1,12),	3,	12,
					TD(1,36),	5,	12,
					TD(2,00),	8,	15,
					};

	if (!in_play_flag)
		return 0;

	if (!possession_flag || bhp->zco)
		return 0;
/*
	if (pcl__gMatch->sb___mQuarter<3)
		return 0;
*/
	if (time_left>2*ONE_MIN)
		return 0;

	ds=pcl__gMatch->apcl_mTeamRam[1-team]->uw___tPoints-pcl__gMatch->apcl_mTeamRam[team]->uw___tPoints;
	if (ds>0)
		return 0;

	// Determine correct time interval
	for (i=0; i<sizeof(breakdowns)/sizeof(breakdowns[0]); i++)
		if (time_left<breakdowns[i][0])
			break;

	// Check to see if foul-time
	if (ds>-breakdowns[i][1])
		return 0;

	if (team!=bhp->team)
		return 1;

	return 1;
}


int get_free_pass_scores2(playert *plyr, int *lowest_score, int *hold_score)
{
int i;
int score;
int recvr;
SW a_diff;

	plyr = player + plyr->base;
	*lowest_score = 0x7fffffff;
	recvr = ball_handler;

	for (i=0; i<5; i++)
	{
		int bd;

		bd = plyr->ball_dist;
		if (plyr->no != ball_handler)
		{
			//dis-favour short passes
			if (in_play_flag)
			{
				if (bd < 0x200000)
					bd = 0x800000;
				else if (bd < 0x500000)
					bd = 0x500000;
			}
		}

		score = plyr->basket_dist/2 + bd;

		if (blocked_basket_test(plyr) == 0xe)
			score -= 0x800000;

		// Dump off to player standing on a hotspot
		if (plyr->no!=bhp->no && HotSpot_Check(plyr))
			score-=0xC00000;

		//pass to PG
		if ((plyr->no == cur_team->base) && (!fast_break_flag) && (bhp->basket_dist>0xa00000)
			&& !(plyr->no==bhp->no && dribble_flag && (plyr->main_routine==stand_with_ball || plyr->main_routine==stand_with_ball2)))
		{
			score -= 0x800000;
		}

		//no back-court violations please
		if (half_flag)
		{
			if ((plyr->no > 4)^(plyr->yco < 0))
				score += 0x1000000;
		}

		if (plyr->main_routine==set_pick || plyr->main_routine==picked)
			score+=0x1000000;

		if (plyr != bhp)
		{
			#ifndef DEBUG
			if (plyr->flags & OFF_SCREEN)
				score += 0x400000;
			#endif			
			
			//dis-favour player who just passed to me
			if ((plyr->no==last_handler) && (possession_ticks<2*ONE_SEC))
				score+=0x200000;

			//make sure player is in bounds
			if (player_inbounds_check(plyr))
				score+=0x1000000;

			//favour unmarked players
			if (plyr->basket_dist<0xa00000)
				if (plyr->nearest_dist > 0x200000)
				{
					if (plyr->nearest_dist > 0x400000)
						score -= 0x800000;
					else
						score -= (plyr->nearest_dist-0x200000)*4;
				}

			//dis-favour players behind me
			a_diff = plyr->ball_angle - bhp->angle;
			if (abs(a_diff) > 0x4000)
				score -= 0x100000;

			//dis-favour blocked passes
			if (check_pass(plyr) != 0xe)
				score += 0x1000000;

			//dis-favour guy who passed to me
			if (plyr->no == last_handler)
				if (possession_ticks < 5*ONE_SEC)
					score += 0x200000;

			//favour guys running towards the basket
			//dis-favour running away from basket
			if (plyr->last_speed > 0x800)
			{
				a_diff = plyr->angle-plyr->basket_angle;
				if (abs(a_diff) < 0x3000)
					score -= 0x200000;
				if (abs(a_diff) > 0x4800)
					score += 0x300000;

				//dis favour players not facing ball
				a_diff = plyr->angle-plyr->ball_angle;
				if (abs(a_diff) > 0x6000)
					score += 0x200000;
			}
			else
			{
				//dis favour players not facing ball
				a_diff = plyr->angle-plyr->ball_angle;
				if (abs(a_diff) > 0x6000)
					score += 0x400000;
			}

			//rule-out players falling over
			if (plyr->flags & FALLING)
				score += 0x1000000;

			if (!in_play_flag)
				if (plyr->nearest_dist<0x100000)
					score += 0x400000;
		}
		else
		{
			if (!in_play_flag)
				score += 0x800000;
			else
				score += 0x400000;

			if (dribble_flag==2 && player[threat_plyr].ball_dist<2*COL_DI)
				score += 0x800000;

			if (possession_ticks < plyr->ctr2)
				score -= 0x600000-(possession_ticks*(0x600000/plyr->ctr2));
			else
				score += (possession_ticks-plyr->ctr2) * (0x180000/0x20);
		}

		score-=plyr->plyrROM->ub___pAttrGoto*0x28000;
		pass_scores[i]= score;
//		plyr->score = score>>4;

#if 0
		{
			plyr->score2 = check_pass(plyr)
						  + (blocked_basket_test(plyr)<<4);
							//+ (((plyr->ball_angle - bhp->angle) & 0xf000) >> 4)
							//+ (((plyr->basket_dist/2 + plyr->ball_dist) & 0x3ff0000) );
		}
#endif

		if (plyr!=bhp)
		{
			if (score<*lowest_score)
			{
				recvr = plyr->no;
				*lowest_score = score;
			}
		}
		else
		{
			*hold_score = score;
		}
		plyr++;
	}

	score = hold_on[DIFFICULTY];
	if (score==0)
		if (!fast_break_flag)
			score = HALF_SEC;



	if (possession_ticks < score && recvr!=HotSpotPlyr)
		*lowest_score=0x7fffffff;

	return recvr;
}



int get_postup_score(playert *plyr)
{
int score;

	
	//too far away
	if ((plyr->basket_dist > 0x500000) || (!in_play_flag))
	{
		return 0x7fffffff;
	}

	score = plyr->basket_dist;

	//what position am I playing
	switch (ball_handler-bhp->base)
	{
		case 0:
		case 1:
		case 2:
		break;

		case 3:
		score -= 0x180000;
		break;

		case 4:
		score -= 0x300000;
		break;
	}

	//score += (shot_clock/(5*ONE_SEC)) * 0x100000;

	return score;
}



int estimate_block_factor(playert *plyr)
{
SW a_diff;
int x_diff, y_diff;
int dist;
int lowest;
int score;

playert *op;

	lowest = 0x100;

	//look thru opposing team for some one who might be blocking my view of basket
	for (op = ai_team[plyr->team^1].plyr1; op < ai_team[plyr->team^1].plyr1+5; op++)
	{
		if (op->basket_dist < plyr->basket_dist)
		{
			if (op->ball_dist < 0x300000)
			{
				int px, py;

				//project where blocker will be
				if (op->ball_dist > 0xd0000)
				{
					px = op->xco + (LFPCos(op->ball_angle) * 0x28);
					py = op->yco + (LFPSin(op->ball_angle) * 0x28);

					if (!in_play_flag)	BRK;
					//ball.target_x = px;
					//ball.target_y = py;

					x_diff = px - plyr->xco;
					y_diff = py - plyr->yco;

					dist   = MANHATTAN(x_diff, y_diff);
					if (dist < COL_DI)	dist = COL_DI;
				}
				else
				{
					x_diff = LFPCos(plyr->basket_angle);
					y_diff = LFPSin(plyr->basket_angle);
					dist = COL_DI;
				}


				if (dist < 0x200000)
				{
					a_diff = plyr->basket_angle - LFPAtn(x_diff, y_diff);
					if ( LFPAsin(COL_DI / (dist>>14)) > a_diff)
					{
						int head_height;
						int arm_height;

						//plyr head_height
						head_height  = (2000<<2)*plyr->scale + plyr->zco;
						//add for FG strength

						arm_height   = (2300<<2)*op->scale + op->zco;

						switch(abs(plyr->last_top_anim))
						{

						case TOP_LOW_TO_HI:
							// if arms far enough up treat as gaurding high...
							// ...else normal
							if (plyr->last_top_frame < 0x300)	break;

						case TOP_GRDH:
							// two handed block
							plyr->top_anim = TOP_BLOCK2H1;

						case TOP_LP_GRD:

							arm_height+=0x20000;
						}

						if (arm_height > head_height)
						{
		  					score = 0x100 - (arm_height-head_height)/(dist>>8);
							if (score < 0x10)	score = 0x10;
							if (score<lowest)	lowest=score;
						}
					}
				}
			}
		}
	}


	if (plyr->basket_dist<0x400000)
	{
		score  = 0x100 - lowest;
		lowest = 0x100 - (score * (0x400000+plyr->basket_dist) )/0x800000;
	}

	return lowest;
}












int blocked_basket_test(playert *plyr)
{

playert *op;
SW  a_diff;
int dist;

	for (op = player+(plyr->base^5); op < (player+(plyr->base^5)+5) ; op++)
	{
		if ( op->basket_dist < plyr->basket_dist)
		{
			a_diff = op->basket_angle - plyr->basket_angle;

			if (abs(a_diff) < 0x4000)
			{
				int x_diff, y_diff;


				x_diff = op->xco - plyr->xco;
				y_diff = op->yco - plyr->yco;


				a_diff = LFPAtn(x_diff, y_diff) - plyr->basket_angle;
				a_diff = abs(a_diff);

				if (a_diff < 0x1000)			goto exit_blocked;

				if (a_diff < 0x3000)
				{
					dist   = MANHATTAN(x_diff, y_diff)>>12;
					if (dist==0)				goto exit_blocked;
					a_diff -= 0x200000/dist;

					if (a_diff < 0x1000)		goto exit_blocked;
				}
			}
		}
	}
	return 0xe;

exit_blocked:
	return op->no;
}



int clear_pass(playert *plyr)
{
playert *op;
SW  a_diff;
int d_diff;
int b_x, b_y;
int bd, obd;
SW  ba, oba;

	b_x = ball.xco + bhp->xvel*(ONE_SEC/3);
	b_y = ball.yco + bhp->yvel*(ONE_SEC/3);

	bd = plyr->ball_dist;				//MANHATTAN(b_x-plyr->proj_x, b_y-plyr->proj_y);
	ba = plyr->ball_angle;				//LFPAtn(b_x-plyr->proj_x, b_y-plyr->proj_y);

	for (op = player+(plyr->base^5); op < (player+(plyr->base^5)+5) ; op++)
	{
		obd = op->ball_dist;			//MANHATTAN(b_x-op->proj_x, b_y-op->proj_y);

		d_diff = bd - obd;
		if (d_diff > 0)
		{
			if ((d_diff < 0x300000) || (obd < 0x400000))
			{
				oba = op->ball_angle;	//LFPAtn(b_x-op->proj_x, b_y-op->proj_y);

				a_diff = ba - oba;
				a_diff = abs(a_diff);

				if (a_diff < 0x600)		return op->no;
				a_diff -= 0x200000/(obd>>12);
				if (a_diff < 0x600)		return op->no;
			}
		}
	}
	return 0xe;
}




int check_pass(playert *recvr)
{
playert *op;
SW  a_diff;
int r_x, r_y;
int rd;
SW  ra;

	r_x = recvr->proj_x - bhp->proj_x;
	r_y = recvr->proj_y - bhp->proj_y;
	rd  = MANHATTAN(r_x, r_y);
	ra  = LFPAtn(r_x, r_y);

	for (op = player+(bhp->base^5); op < (player+(bhp->base^5)+5) ; op++)
	{
		int o_x, o_y;

		o_x = op->proj_x - bhp->proj_x;
		o_y = op->proj_y - bhp->proj_y;

		if (rd > MANHATTAN(o_x, o_y))
		{
			a_diff = LFPAtn(o_x, o_y) - ra;

			if (abs(a_diff) < 0xa00)
			{
				//am i facing ball?
				//a_diff = op->ball_angle - op->angle;
				//if (abs(a_diff) < 0x4000)
				{
					//recvr nearer?
	 				return op->no;
				}
			}
		}
	}
	return 0xe;
}




void find_threat(playert *bh)
{
playert *op;
int bv;

	threat_plyr = -1;

	bv = MANHATTAN(bhp->xvel, bhp->yvel);

	if (bv < 0x18000)
	{
		int nearest = 0x180000;

		for (op = player+(bh->base^5); op < (player+(bh->base^5)+5) ; op++)
		{
			if (op->ball_dist < nearest)
			{
				nearest = op->ball_dist;
				threat_plyr = op->no;
			}
		}
	}
	else
	{
		int bx2;

		bx2 = 0x300000;

		for (op = player+(bh->base^5); op < (player+(bh->base^5)+5) ; op++)
		{
			if (op->ball_dist < 0x400000)
			{
				int xd, yd;
				int xv, yv;
				int y2,x2;
				int s;
				SW a;

				xd = op->xco - ball.xco;
				yd = op->yco - ball.yco;
				xv = bh->xvel - op->xvel;
				yv = bh->yvel - op->yvel;

				s = MANHATTAN(xv, yv);
				a = LFPAtn(xv, yv);

				x2 = ( xd*(LFPCos(a)>>6) + yd*(LFPSin(a)>>6) ) >> 8;
				y2 = ( -xd*(LFPSin(a)>>6) + yd*(LFPCos(a)>>6) ) >> 8;

				x2 += 0x80000;

				if (x2 > 0)
				{
					if (x2 < bx2)
					{
						if (abs(y2) < 0x180000)
						{
							threat_plyr = op->no;
							bx2 = x2;
						}
					}
				}
			}
		}
	}

	if (threat_plyr!=-1)
	{
		threat_angle= bhp->angle - player[threat_plyr].ball_angle;
	}
}


void auto_crossover(void)
{
SW ta;

	if (first_step_flag)
		return;

	// Don't crossover if the player sucks at dribbling
	if (RANDOM(10000)>bhp->plyrROM->ub___pAttrDribble*bhp->plyrROM->ub___pAttrDribble/8)
		return;

	if (threat_plyr>0)
	{
	  	ta = 0x3000;
		if (bhp->top_anim>0)				ta = 0x9000;

	    if ((UW)(threat_angle-ta) < 0x4000)
		{
			//status_var3 = threat_angle-ta;
			current_ctrlr->mctrlr |= CTRL_CROSSOVER;
		}
	}
}


void back_down(playert *plyr)
{
	last_bh_basket_dist  = plyr->basket_dist;
	current_ctrlr->ctrlr = CTRL_SHUFFLE;
	current_ctrlr->force = 0x100;
	current_ctrlr->d_angle = plyr->basket_angle;

	if ((abs(plyr->top_anim) == TOP_PRT_DRIB) && (plyr->top_blend_ctr==0))
	{
		if ((plyr->xco^plyr->yco^plyr->top_anim) > 0)
		{
			current_ctrlr->mctrlr |= CTRL_CROSSOVER;
		}
	}
}




SB xlate[]=
{
	SPIN_OFF,
	UP_FADE,
	TURN_AROUND,
	BABY_HOOK,
	UP_UNDER,
	SPIN_OFF,
	UP_FADE,
	UP_FADE,
};



void choose_postup_move(playert *plyr)
{
	if ((UI)(lp_ctr-last_post_decision) < ONE_SEC)	return;

	last_post_decision=lp_ctr;

spin_again:

	postup_move = RANDOM(7);

try_again:

	switch(postup_move)
	{
	case UP_UNDER:
	case UP_FADE:
		current_ctrlr->force   = 0xf0;
		current_ctrlr->d_angle = plyr->basket_angle;
		current_ctrlr->mctrlr  = CTRL_SHOOT+CTRL_SHUFFLE; 
		current_ctrlr->ctrlr   = CTRL_SHOOT+CTRL_SHUFFLE; 
		break;

	case BABY_HOOK:
		current_ctrlr->force   = 0;
		current_ctrlr->mctrlr  = CTRL_SHOOT+CTRL_SHUFFLE; 
		current_ctrlr->ctrlr   = CTRL_SHOOT+CTRL_SHUFFLE; 
		break;

	case SPIN_OFF:
		if (bhp->basket_dist < 0x180000)	goto spin_again;
		current_ctrlr->force   = 0xf0;
		current_ctrlr->d_angle = plyr->basket_angle;
		current_ctrlr->mctrlr  = 
		current_ctrlr->ctrlr   = 0; 
		break;

	case TURN_AROUND:
		current_ctrlr->force   = 0x0;
		current_ctrlr->mctrlr  = CTRL_SHOOT; 
		current_ctrlr->ctrlr   = CTRL_SHOOT; 
		return;

	case 5:
	case 6:
		postup_move = xlate[plyr->plyrROM->ub___pPostUps];
		goto try_again;
	}
}





static int last_shoot_score=0x7fffffff;




int get_shoot_score(playert *plyr)
{
int score;

int pt3_rating;
int range;
int percent;

int turn_factor;
int speed_factor;
int block_factor;

long int t;

float dist;

SW a_diff;


//	if (shot_clock < (3*ONE_SEC))	return 0;

	if (plyr->zco)		return last_shoot_score;

	if (!in_play_flag)	return 0x7fffffff;

	if (should_waste_time(plyr->team) && shot_clock>ONE_SEC*4)
		return 0x7fffffff;

	block_factor = estimate_block_factor(plyr);
	/*
	if (abs(plyr->top_anim) == TOP_OVER_BALL)
	{
		block_factor += (0x100-block_factor)/2;
	}
	*/

	pt3_rating = plyr->plyrROM->ub___pAttr3P;
	range      = plyr->plyrROM->ub___pAttrRange;
	dist       = ((float)plyr->basket_dist/0x100000);

	/*
	switch (abs(plyr->top_anim))
	{
		case TOP_FJS2:
		//reduce shooting rating
		dist += 0x2000000;
		//reduce effect of block
		block_factor = 0x100 - ((0x100-block_factor)/3);
		break;

		case TOP_HOOK2:
		dist += 0x3000000;
		block_factor = 0x100 - (2*((0x100-block_factor)/3));
		break;
	}
	*/

	//get bare %
	percent = get_shot_percent(bhp, dist);

	//how far have i turned
	turn_factor = 100;
	a_diff = plyr->basket_angle - plyr->angle;
	if (a_diff == -0x8000)	a_diff--;
	a_diff = abs(a_diff);
	if (a_diff > 0x4000)
	{
		turn_factor = 60+((0x8000-a_diff)*40)/0x4000;
	}


	//how fast was i running
	speed_factor = 100;
	if (plyr->last_speed > 0x900)
	{
		speed_factor = 50 + (((0x1700-plyr->last_speed)*50)/0x1000);
	}



//#ifdef DEBUG
	if (shoot_stage==0)
	{
		/*
		sprintf(statusString2, "st    , tf   , sf   , bf   , final    ");
		IntToDecStr(percent, &statusString2[3]);
		IntToDecStr(turn_factor, &statusString2[10]);
		IntToDecStr(speed_factor, &statusString2[17]);
		IntToDecStr((block_factor*100)/256, &statusString2[24]);

		IntToDecStr((percent*turn_factor*speed_factor*block_factor)/(10000*256), &statusString2[35]);
		*/
	}
//#endif

	percent = (percent*turn_factor*speed_factor*block_factor)/(10000*256);

	if (pt3_detect(plyr))	percent+=percent/2;
	last_shoot_score = percent;

	t = shot_score(percent, shot_clock/ONE_SEC);

	if ((t==0) && (percent<30))
	{
		t = shot_score(percent, shot_clock/ONE_SEC);
	}

	if (HotSpot_Check(plyr))
		t=-(0x80000000-1);

	return t;
}


int shot_score(int percent, int sc)
{
	if		(possession_ticks < ONE_SEC/2)	percent /= 2;
	else if (possession_ticks < ONE_SEC)	percent -= percent/4;

	if		(abs(ball.yco) > GLASS_Y)		percent /= 2; 

	if (time_left>10*ONE_SEC && shot_clock<time_left)
	{
		if (sc > 16)
		{
			if (percent > 60)	return 0;
		}
		else if (sc > 10)
		{
			if (percent > 40)	return 0;
		}
		else if (sc >3)
		{
			if (percent > 20)	return 0;
		}
		else
		{
			if (percent > 5)	return 0;
		}
	}
	else
	{
		if (time_left<2*ONE_SEC)
			return 0;
	}

	return 0x7fffffff;
	//return (sc<<21)/(percent+1);
}




bool step_defender(playert *plyr)
{
	int		dx,dy;
	int		a,da;
	playert	*p,*e;

	p=&player[plyr->base^5];
	e=p+5;

	do
	{
		dx=p->xco-plyr->xco;
		dy=p->yco-plyr->yco;
		if (MANHATTAN(dx,dy)>0x1c0000)
			continue;

		a=LFPAtn(dx,dy);
		da=a-plyr->angle;
		if (abs(da)<0x2000)
			return TRUE;
	} while(++p<e);

	return FALSE;
}
