

#include "generic.h"
#include "lfptypes.h"
#include "define.h"
#include "ml.h"

#include "ctrl.h"

#ifndef NPP
 #ifndef N64
  #include "fontcode.h"
  #include "dbugtxt.h"
 #endif
#endif

static bool defend_home_in(playert *plyr, playert * mark, int dist, SW face_angle);


bool	can_helper_d=CAN_HELPER_D;


static bool stage2_jump_check(playert *plyr, int coverage)
{
	if (coverage==2)
	{
		if ( (projected_release_time-lp_ctr) < 10)
		{
			if (fast_break_flag)
				return TRUE;

			if (bhp->basket_dist > 0x400000)
			{
				int seed, threshold;

				seed = (steal_ticks^plyr->plyrROM->ub___pAttrJump) & 7;

				threshold = MIN_MAX(plyr->plyrROM->ub___pAttrBlock, 3, 8) + DIFFICULTY;

				if ((cur_team->controllers[0]==0) && (bhp->control!=0))
				{
					return (seed<threshold);
				}
			}

			return TRUE;
		}
	}

	return FALSE;
}




static bool stage1_jump_check(playert *plyr, int coverage)
{
int x_diff, y_diff;
int dist;

	//don't buy fake if more or less in place
	if (coverage==2)
	{
		if (!bhp->control)
			return FALSE;

		if (CTL_DOWN(&ctrlrs[bhp->control],CTRL_SHOOT))
			return FALSE;

		if (rand()%(3+frames_to_go(bhp)/2))
			return FALSE;
	}

	x_diff = plyr->target_x - plyr->xco;
	y_diff = plyr->target_y - plyr->yco;

	dist  = MANHATTAN(x_diff, y_diff);

	if (plyr->basket_dist > bhp->basket_dist)	return FALSE;

	if (dist > 0x150000+(fast_break_flag? 0x150000 : 0))	return FALSE;

	if (bhp->top_frame<0x600)	return FALSE;

	if ( (projected_release_time-lp_ctr) > 10)	return FALSE;

	return TRUE;
}





global void defend (playert *plyr)
{

playert *mark;
SW  angle;
SW	a_diff;
int	dist,dist2;
int h_check;

	CallChainP(defend);

//	if ((plyr->shuffle))

	if (plyr->markee==ball_handler)
		a_diff=0;

	if (plyr->hand_check_flag)	plyr->hand_check_flag--;

#ifndef PLAY

	if (possession_flag && in_play_flag)
	{
		check_intentional_foul(plyr);
		if (CCTL_DOWN(CTRL_FOUL) && in_play_flag && DEFENSIVE_FOULS)
		{
				foul_start(plyr);
				return;
		}
	}

	if ((!possession_flag) || (!in_play_flag))
	{
		//can I intercept ?
		if (ball.ctr2 > 8)
			interception_check(plyr);
	}
	else
	{
		int threshold;


		if ((ai_team[plyr->team].controllers[0] != 0) && (ai_team[plyr->team^1].controllers[0] != 0))
		{
			//Human vs Human
			threshold = ONE_SEC*(3-pressures[plyr->no]);
		}
		else if ((ai_team[plyr->team].controllers[0] == 0) && (ai_team[plyr->team^1].controllers[0] != 0))
		{
			//CPU vs Human
			threshold = ONE_SEC*(4-DIFFICULTY);
		}
		else if ((ai_team[plyr->team].controllers[0] != 0) && (ai_team[plyr->team^1].controllers[0] == 0))
		{
			//Human vs CPU
			threshold = ONE_SEC*(1+DIFFICULTY);
		}
		else
		{
			//CPU vs CPU
			threshold = ONE_SEC*(3-pressures[plyr->no]);
		}

		threshold += MIN_MAX(plyr->plyrROM->ub___pAttrSteal, 0, HALF_SEC);
		
		if (bhp->last_speed > TURBO_THRESHOLD)	threshold = 0;
		if (bhp->basket_dist > 0x900000)		threshold *= 2;
		if (dribble_flag==2)					threshold -= ONE_SEC;
		if (ball.zco > bhp->scale*0x1a00)		threshold -= ONE_SEC;

		if (foul_trouble(plyr))					threshold += ONE_SEC*2;

		if (abs(bhp->xco)<LANE_X*5/4 && PLY(bhp)>(FOUL_LINE+BASE_LINE)/2)
			threshold*=2;

		threshold*=2;

		//can I steal
		if (steal_ticks > threshold)
		{
			if (steal_test(plyr))
			{
				steal_start(plyr);
				return;
			}
		}
	}

#endif


	mark = &player[plyr->markee];

	//don't get too close until they're in your half
	if (mark->basket_dist > 0xc00000)
	{
		if (player[ball_handler].basket_dist > 0xc00000)
		{
			if (plyr->no-plyr->base > 2)
			{
				dist = mark->basket_dist + ((plyr->no-plyr->base-2)<<21) - 0x500000;
				if (ArcadeMode || in_play_flag)
					dist=dist*2/3;

				goto got_dist;
			}
		}

		dist = 0x2a0000+((mark->basket_dist-0xc00000)*26/32);
		goto got_dist;
	}




	if ((mark->no == ball_handler) && (possession_flag))
	{

		//stage1_jump_check(plyr, h_check);

		h_check	= covered2(mark, plyr);


		//block jump shot ?
		if (shoot_stage == 2)
		{
			if (stage2_jump_check(plyr, h_check))
			{
				jump_start(plyr);
				return;
			}
		}
		else if (shoot_stage==1)
		{
			if (stage1_jump_check(plyr, h_check))
			{
				jump_start(plyr);
		 		return;
			}
		}

		//a_diff = mark->basket_angle-mark->d_angle;

		if ( (h_check==2) )		//|| ((h_check==1) && (abs(a_diff)>0x2000)) )
		{

#ifndef MOVE

			//push out
			if (mark->basket_dist < 0x480000 && !fast_break_flag && plyr->basket_dist<player[plyr->markee].basket_dist)
			{
				SW   a_diff;
				SW   mark_angle;
				bool hc_flag;
				//int mark_dist;

				//mark_dist  = MANHATTAN(plyr->xco - mark->xco,
				//					   plyr->yco - mark->yco);


				mark_angle = LFPAtn(plyr->xco - mark->xco,
									plyr->yco - mark->yco);

				a_diff	   = mark_angle - mark->basket_angle;

				//back to basket ?
				if (abs(a_diff) < 0x1000)
				{
					SW a_diff2;


					a_diff2  = mark->angle-mark->basket_angle;
					hc_flag = (abs(a_diff2)>0x4000);

					if (hc_flag)
					{
						if (plyr->hand_check_flag)	plyr->hand_check_flag++;
					}

					//how fast is lateral motion of mark
					a_diff2 = mark->basket_angle - LFPAtn(-mark->xco, current_basket_y-mark->yco);

					if (abs(a_diff2) < 0xc0)
					{
					 	if (hc_flag)	plyr->hand_check_flag = ONE_SEC/3;

						current_ctrlr->ctrlr   = CTRL_SHUFFLE;
						current_ctrlr->d_angle = mark_angle+(a_diff>>1)-0x8000;

						if (mark->basket_dist < 0x200000)	current_ctrlr->force = 0x100;
						else								current_ctrlr->force = 0x100 + ((0x200000 - mark->basket_dist) >> 15);
						return;
					}
				}
			}
#endif

		}

		//status_var1 = ball.zco/mark->scale;
		//picked up dribble?
		if ((dribble_flag == 2) || (plyr->top_anim == TOP_LP_GRD) ||
			(pressures[plyr->no]==2) || (ball.zco>mark->scale*0x1a00))		goto real_close;
	}
	else
	{
		if (fronts[plyr->no] && plyr->markee!=bhp->no)
		{
			//if (mark->basket_dist < 0x400000)
			{
				//fronting
				plyr->target_x = mark->xco + (0x400*LFPCos(mark->ball_angle));
				plyr->target_y = mark->yco + (0x400*LFPSin(mark->ball_angle));
			}
		}
	}

	//if mark is moving away from or standing facing away from basket then no need to back off
	if (mark->xvel || mark->yvel)
	{
		a_diff = LFPAtn(mark->xvel, mark->yvel) - mark->basket_angle;
	}
	else
	{
		a_diff = mark->angle - mark->basket_angle;
	}


	if ((abs(a_diff) < 0x5000) || (mark->shuffle) || (mark->last_speed == 0))
	{
		//standard
		dist = 0xc0000 + ((mark->basket_dist*5)/32);
	}
	else
	{
		//closer
		dist = 0x60000 + (mark->basket_dist/8);
		if (dist < 0xc0000)
		{
real_close:
			dist2 = MANHATTAN(mark->xco - plyr->xco, mark->yco - plyr->yco);
			//if closer already use current distance
			if (dist2 < 0xc0000)	dist = dist2;
			else					dist = 0xc0000;
		}
	}

	// Set player shuffling if he is close to markee
	if (!fast_break_flag && h_check && MANHATTAN(plyr->xco-mark->xco,plyr->yco-mark->yco)<0x200000 && plyr->basket_dist<player[plyr->markee].basket_dist)
	{
			dist=dist*3/4;
			current_ctrlr->ctrlr |= CTRL_SHUFFLE;
	}


got_dist:

	angle = LFPAtn(ball.xco-plyr->target_x, ball.yco-plyr->target_y);

	if (PLY(bhp)>FOUL_LINE && fast_break_flag)
		dist/=2;

	if (defend_home_in(plyr, mark, dist, angle))
	{
		if (plyr->last_speed == 0)
		{
			//face ball
			a_diff = (SW)(plyr->ball_angle - plyr->angle);
			//don't make small changes
			if (abs(a_diff) > 0x100)
			{
				if (a_diff > TURN_SPEED)	a_diff = TURN_SPEED;
				if (a_diff < -TURN_SPEED)	a_diff = -TURN_SPEED;
				plyr->angle += a_diff;
			}
		}
	}
}





void interception_check(playert *plyr)
{
int x,y,z,t;
SW  angle;

/*
	if (plyr->no == 6)
	{
		closest_approach(&ball, plyr, &x, &y, &t);

		if ((t>4) & (t<15))
		{
			get_future_ball_cos(t-1, &x, &y, &z);
//			ball.target_x = x;
//			ball.target_y = y;
//			ball.target_dist = z;

			follow_ball(plyr, x, y, z, t);
		}
	}
 */
 }



void rotate(teamt *t)
{
int base;
int i;
playert *plyr, *chosen_plyr, *bp;
int lowest_score;
int mark_count;
int score;


	bp = bhp;
	if (ball.main_routine == pass_ball_move)
		bp = player+int_recvr;

	t->helper=NULL;

	if (!possession_flag)
		return;
	if (bp->basket_dist > 0xa00000)
		return;
	if (covered3(bp, &player[bp->marker]))
		return;

	//if not, find best alternative marker
	//score based on position and position of own markee
	base = 5;
	plyr = t->plyr1;
	lowest_score = 0x7f000000;

	for (i=0; i<5; i++,plyr++)
	{
		SW a_diff;
		//less angle to cover the better
		//a_diff = bp->basket_angle - plyr->ball_angle - 0x8000;
		//score = abs(a_diff);

		if (plyr->no != bp->markee)
		{
			//closer to ball the better
			score = plyr->ball_dist>>9;

			//nearer own man is to basket the worse
			score -= player[plyr->markee].basket_dist>>9;

			if (plyr->basket_dist>bp->basket_dist)
				score += 0x4000;

			plyr->score = score;

			if (score < lowest_score)
			{
				lowest_score = score;
				chosen_plyr  = plyr;
			}
			//		player[plyr->def_markee].score = player[plyr->def_markee].basket_dist>>10;
		}
	}

	t->helper = chosen_plyr;
}
																		 


/*
 * temporarily leave own man to help gaurd bh
 */

void help(playert *plyr)
{
int save;

	if (!can_helper_d)
	{
		defend(plyr);
		return;
	}

	save		 = plyr->markee;
	plyr->markee = (ball.main_routine == pass_ball_move) ? int_recvr: ball_handler;
	defend(plyr);
	plyr->markee = save;
}



void reset_markers(void)
{
playert *plyr;

	for (plyr = &player[0] ;plyr < &ball; plyr++)
	{
		plyr->markee				= markee[plyr->no];
		player[plyr->markee].marker = plyr->no;
	}
}


int freezes[]={
10, 5, 0};



bool defend_home_in(playert *plyr, playert * mark, int dist, SW face_angle)
{
int x_diff, y_diff;
SW angle;
SW  target_direction;
SW  ball_direction;
SW  a_diff;
int run_cost, shuffle_cost, back_cost;
int target_dist;
int dist_cost;
int force;
bool covered_flag;
int	sx,sy,sd,ma;
int last_tx, last_ty, tv;
SW  tva;

	CallChainP(defend_home_in);

	if (mark->no == ball_handler)
	{
	 	plyr->look_at_ball_ctr = ONE_SEC/2;
	}

	//current_ctrlr->ctrlr = 0;
	current_ctrlr->force = 0;


	if (((plyr->last_speed) || (mark->basket_dist>0xa00000)) && (in_play_flag))
	{
		int diff;

		//don't suddenly change target when moving
		diff = dist-plyr->defense_dist;
		if (diff>0)
		{
			diff = diff/8;
			if (diff<0x4000)	diff=0x4000;
			dist = plyr->defense_dist + diff;
		}
		else
		{

		}
	}

	angle	= mark->basket_angle;


	//full court press

	if ((ai_team[plyr->team].press==1) || (ai_team[plyr->team].foul==1) || ((mark->no==ball_handler) && (possession_flag) && (pressures[plyr->no]==2)))
	{
		if (!half_flag)
		{
			if (mark->basket_dist > 0xc00000)
			{
				if ((mark->no == ball_handler) && ((possession_flag) || (!in_play_flag)) )
				{
					dist  = (in_play_flag) ? 0x100000: 0x300000;
				}
				else
				{
					angle = mark->ball_angle;
					dist  = 0x180000;
				}
			}
		}
	}

	if (((fronts[plyr->no]) || (!in_play_flag && mark->basket_dist<0x400000)) && mark->no!=bhp->no)
	{
		//if (mark->basket_dist<0x400000)
		{
			dist = 0x100000;
			angle= mark->ball_angle;
		}
	}

	last_tx = plyr->target_x;
	last_ty = plyr->target_y;


	if (possession_flag)
	{
		if (bhp == mark)
		{
			if (bhp->control)
			{
				int t;

				t = DIFFICULTY;
				t = freezes[t];




				if (lp_ctr-special_time <= t)
				{
					goto frozen;	
				}
			}
		}
	}


	//make defenders swing out to sideline when far away from mark
	if (dist > 0x280000)
	{
		int a;
		SW back_angle;

		back_angle = (plyr->no>4) ? 0x4000: 0xc000;

		if (dist < 0x400000)	a = (dist-0x280000)/0x2000;
		else					a = 0xc0;

		a_diff = angle-back_angle;
		a = (a_diff*a)>>8;

		angle  -= a;
	}

	plyr->defense_dist = dist;
	dist >>= 14;

	if (ArcadeMode && plyr->markee==ball_handler)
	{
		int	ld,fac;

		ld=dist*3/2;
		fac=bhp->basket_dist-0x400000;

		if (fac>0)
		{
			fac>>=16;
			if (fac>0x100)
				dist=ld;
			else
				dist=(ld*fac+dist*(0x100-fac))>>8;
		}
	}

frozen:
	plyr->target_x = mark->xco + (dist*LFPCos(angle));
	plyr->target_y = mark->yco + (dist*LFPSin(angle));

	if (!in_play_flag)
	{
		if (plyr->target_y > BASE_LINE)	plyr->target_y =  BASE_LINE-EDGE;
		if (plyr->target_y <-BASE_LINE)	plyr->target_y = -(BASE_LINE-EDGE);
	}
	
	tv			= MANHATTAN(last_tx-plyr->target_x, last_ty-plyr->target_y);
	tva			= LFPAtn(last_tx-plyr->target_x, last_ty-plyr->target_y);	
#if 1
	ma=LFPAtn(mark->xco-plyr->xco,mark->yco-mark->yco);
	sx=mark->xvel*2;
	sy=mark->yvel*2;
	sd=pythag(sy,sx);
	if (sd)
	{
		sd=(sx<<8)/sd*(LFPCos(ma)>>6)+(sy<<8)/sd*(LFPSin(ma)>>6);
		
		sx-=(sx>>8)*(sd>>8);
		sy-=(sx>>8)*(sd>>8);

		plyr->target_x+=sx;
		plyr->target_y+=sy;
	}
#endif

	x_diff			 = plyr->target_x - plyr->xco;
	y_diff			 = plyr->target_y - plyr->yco;
	target_direction = LFPAtn(x_diff, y_diff);
	target_dist      = MANHATTAN(x_diff, y_diff);

	ball_direction   = plyr->ball_angle;

	if (((plyr->last_speed==0) || (plyr->shuffle)) && (mark->basket_dist > 0xa00000))
	{
		if (target_dist<0x200000)
		{
			goto shuffle;
		}
	}
	else
	{
		if ((target_dist<0x80000) && (tv < 0x10000))
		{
			goto shuffle;
		}
	}

	dist_cost        = target_dist/((4096<<10)/0x10000);	//normalise target_dist so 4m = 360deg

//run cost
	run_cost     = dist_cost + abs((SW)(plyr->angle - target_direction)) + abs((SW)(target_direction - face_angle));

	//take into account cost of looking away from ball
	a_diff = target_direction - ball_direction;
	if	(a_diff > 0x4000)		run_cost += a_diff-0x4000;
	else if (a_diff < -0x4000)	run_cost -= (a_diff+0x4000);

	covered_flag = covered(mark,plyr);

	//is mark running?
	if ((mark->shuffle) || (mark->last_speed == 0))
	{
		//not running
		if (covered_flag)
		{
			goto shuffle;
		}
		else
		{
			//don't jog backwards for small distances unless mark running
			if (target_dist > 0x100000)
			{
				back_cost    = ((dist_cost*3)/2) + abs((SW)(plyr->angle - target_direction + 0x8000))
 					  		    				 + abs((SW)(target_direction - face_angle + 0x8000));

				a_diff = target_direction - ball_direction - 0x8000;
				if	(a_diff > 0x4000)		back_cost += (a_diff-0x4000) * 2;
				else if (a_diff < -0x4000)	back_cost -= (a_diff+0x4000) * 2;
			}
			else
			{
				back_cost =0x70000000;
			}

			run_cost += 0x3000;

			shuffle_cost = dist_cost*2;
			shuffle_cost += (plyr->shuffle) ? -0x1000: 0x1000;
		}
	}
	else
	{
		//running
		//don't jog backwards or shuffle to cover running players

		//unless they are running towards basket and already blocked
		if ((covered_flag) & (mark->basket_dist < 0x900000) && (!fast_break_flag))
		{
			a_diff = LFPAtn(plyr->xco - mark->xco,
							plyr->yco - mark->yco);
			a_diff = mark->d_angle - a_diff;

			if (abs(a_diff) < 0x2000)	goto shuffle;
		}
		goto run;
	}


	plyr->target_dist = target_dist;

	if ((run_cost < shuffle_cost) && (run_cost < back_cost))
	{
run:
		a_diff = target_direction - plyr->angle;

		if ((abs(a_diff) > 0x6000) && (target_dist<0x300000) && (target_dist > STOP_ZONE) && (mark->force))
		{
			//turn 180 (practically)
			//which way keeps me facing the mark
			a_diff	   = mark->d_angle - plyr->angle;
			target_direction = plyr->angle + ((a_diff>0) ? 0x6000: -0x6000);
		}

		//run home in
		if (target_dist > SLOW_ZONE)
		{
			current_ctrlr->d_angle = target_direction;
			current_ctrlr->force   = 0xf0;

			if (target_dist<0x300000)
			{
				a_diff = tva-target_direction;
				if (abs(a_diff) < 0x3000 && !fast_break_flag)
				{
					goto shuffle;
				}
			}

			if ((!fast_break_flag) && (plyr->no - cur_team->base > 2))
			{
				if (mark->basket_dist > 0x900000)
				{
					if ((mark->no != ball_handler) || (!possession_flag))
					{
//						current_ctrlr->force = 0xc0;
					}
				}
			}

			return FALSE;
		}
		else if (target_dist > STOP_ZONE)
		{
			force = target_dist >> 12;
			if (force <= 0x60)			force = 0x60;
			current_ctrlr->force   = force;
			current_ctrlr->d_angle = target_direction;
			return FALSE;
		}
		else
		{
			return TRUE;
		}
	}
	else if (shuffle_cost < back_cost)
	{
shuffle:
		//shuffle home in
		if (fast_break_flag)
			goto run;

		current_ctrlr->d_angle = target_direction;
		current_ctrlr->ctrlr  |= CTRL_SHUFFLE;

		if (target_dist > SHUFFLE_STOP_ZONE)
		{
			if ((plyr->last_speed == 0))
			{
				if (target_dist<0x80000)
					return TRUE;
				if (target_dist<0x100000)
				{
					current_ctrlr->force   = 0x80;
					return FALSE;
				}
			}

			if (mark->last_speed > 0x100)  // if the guy is moving use a slow shuffle
			{
				force = ((target_dist-SHUFFLE_STOP_ZONE) >> 11) + 0x20;
			}
			else
			{
				force = ((target_dist-SHUFFLE_STOP_ZONE) >> 8) + 0x40; // else come briskly to a stop
			}

			if (force > 0xf0) force  = 0xf0;
			current_ctrlr->force   = force;
			return FALSE;
		}
		else
		{
			current_ctrlr->force   = 0;
			return TRUE;
		}
	}
	else
	{
		if (target_dist < BACK_STOP_ZONE)
		{
			current_ctrlr->force   = 0;
			return TRUE;
		}
		else
		{
			current_ctrlr->ctrlr  |= CTRL_BACK;
			current_ctrlr->d_angle = target_direction;
			current_ctrlr->force   = 0xc0;
			return FALSE;
		}
/*
		else
		{
			//turn to face away from target
			current_ctrlr->d_angle = target_direction-0x8000;
			current_ctrlr->force   = 0x10;
			return FALSE;
		}
*/


/*
		if (abs((SW)(plyr->angle - target_direction - 0x8000)) < 0x1000)
		{
			if (target_dist < BACK_STOP_ZONE)
			{
				current_ctrlr->force   = 0;
				return TRUE;
			}
			else
			{
				current_ctrlr->d_angle = target_direction;
				current_ctrlr->force   = 0x70;
				return FALSE;
			}
		}
		else
		{
			//turn to face away from target
			current_ctrlr->d_angle = target_direction-0x8000;
			current_ctrlr->force   = 0x10;
			return FALSE;
		}
*/
	}
}



bool covered(playert *mark, playert *plyr)
{
int a_diff;
int dist_diff;

	dist_diff = mark->basket_dist - plyr->basket_dist;
 	if (dist_diff < 0)			return FALSE;
 	if (dist_diff > 0x300000)	return FALSE;

	a_diff = (SW)(mark->basket_angle-plyr->basket_angle);

	return ((abs(a_diff)*0x1800) < mark->basket_dist);
}



bool loose_covered(playert *mark, playert *plyr)
{
int a_diff;
int dist_diff;

	if ((mark->nearest_op == plyr->no) && (plyr->nearest_op == mark->no))	return TRUE;

	if (mark->basket_dist>0x900000)	return FALSE;

	dist_diff = mark->basket_dist - plyr->basket_dist;
 	if (dist_diff < 0)			return FALSE;

 	if (dist_diff > 0x300000)	return FALSE;

	a_diff = (SW)(mark->basket_angle-plyr->basket_angle);

	return ((abs(a_diff)*0x800) < mark->basket_dist);
}


void switch_markers(playert *p1, playert *p2)
{
int d1, d2;

	// If defender is not allowed to help, don't switch
	if (!can_helper_d && p1->team!=bhp->team)
		return;

	d1 = p1->marker;
	d2 = p2->marker;
	p1->marker = d2;
	p2->marker = d1;

	player[d1].markee = p2->no;
	player[d2].markee = p1->no;
}








bool covered3(playert *mark, playert *plyr)
{
int a_diff;
int dist_diff;

	dist_diff = mark->basket_dist - plyr->basket_dist;
 	if (dist_diff < 0)			return FALSE;
 	if (dist_diff > 0x300000)	return FALSE;

	a_diff = (SW)(mark->basket_angle-plyr->basket_angle);

	return ((abs(a_diff)*0x800) < mark->basket_dist);
}





int covered2(playert *mark, playert *plyr)
{
int x_diff, y_diff;
int dist;
SW a_diff;
int dist_diff;
int range;
SW a_range;

	dist_diff = mark->basket_dist - plyr->basket_dist;
 	if (dist_diff < 0)			return 0;
 	if (dist_diff > 0x300000)	return 0;

	if (mark->basket_dist > 0x600000)
	{
		range = 0x300000;
		a_range = 0x2000;
	}
	else if (mark->basket_dist > 0x200000)
	{
		range = mark->basket_dist/2;
		a_range = 0x3000;
	}
	else
	{
		range = 0x100000;
		a_range = 0x3800-(mark->basket_dist>>10);
	}

	x_diff = mark->xco-plyr->xco;
	y_diff = mark->yco-plyr->yco;

	dist   = MANHATTAN(x_diff, y_diff)-0xc0000;
	a_diff = LFPAtn(x_diff, y_diff);

	a_diff -= 0x8000 + mark->basket_angle;
	a_diff = abs(a_diff);


//	status_var2 = range;
//	status_var2 = dist;

	if (dist > range)		return 0;
	if (dist < (range/2))
	{
		if (a_diff*2 < a_range)	return 2;
		if (a_diff < a_range)	return 1;
	}

	dist = range-dist;

	if ( dist*(a_range>>8) > a_diff*(range>>9) )
	{
		return 1;
	}

	return 0;
}


void call_double_team(teamt *t)
{
playert *p, *dp;
int score;
int best;
SW a_diff;


	if (!can_helper_d)
	{
		t->dt=NULL;
		return;
	}

	best = 0x7fffffff;

	for (p=player; p<&ball; p++)
	{
		a_diff = bhp->ball_angle-p->ball_angle-0x8000; 

		if (p->markee != ball_handler)
		{
			p->score =
			score = p->ball_dist + (abs(a_diff)*0x80);
		}

		if (score<best)
		{
			best = score;
			dp   = p;
		}

		t->dt = dp;
	}
}



void double_team(playert *plyr)
{
SW angle;

	CallChainP(double_team);

	if (possession_flag && in_play_flag)
	{
		check_intentional_foul(plyr);
		if (CCTL_DOWN(CTRL_FOUL) && in_play_flag && DEFENSIVE_FOULS)
		{
				foul_start(plyr);
				return;
		}
	}

	if (!possession_flag)
	{
		cur_team->dt = NULL;
		defend(plyr);
	}

	angle = bhp->ball_angle;

	if (steal_test(plyr))
	{
		steal_start(plyr);
		return;
	}

	plyr->target_x = ball.xco + (LFPCos(angle)*0x30);
	plyr->target_y = ball.yco + (LFPSin(angle)*0x30);

	home_in4(plyr);
}







