/*============================================================*/
/*============================================================*/
/*==														==*/
/*==			Human Player Specific Routines				==*/
/*==														==*/
/*============================================================*/
/*============================================================*/


/*========================================================  Includes  */

#include "Globals.h"
#include "UnivUtilities.h"
#include "Human.h"
#include "SoundUtils.h"
#include "Dynamics.h"


/*========================================================  Functions  */
/*========================================================  DetermineHumanFacing  */

void DetermineHumanFacing (playerType *who)

{
	#define kLoHThreshhold		-12
	#define kHiHThreshhold		12
	#define kLoVThreshhold		-8
	#define kHiVThreshhold		8
	
	if (who->hMouse < kLoHThreshhold)
	{
		if (who->vMouse < kLoVThreshhold)
			who->direction = kFacingSouthWest;
		else
		{
			if (who->vMouse > kHiVThreshhold)
				who->direction = kFacingNorthWest;
			else
				who->direction = kFacingWest;
		}
	}
	else
	{
		if (who->hMouse > kHiHThreshhold)
		{
			if (who->vMouse < kLoVThreshhold)
				who->direction = kFacingSouthEast;
			else
			{
				if (who->vMouse > kHiVThreshhold)
					who->direction = kFacingNorthEast;
				else
					who->direction = kFacingEast;
			}
		}
		else
		{
			if (who->vMouse < kLoVThreshhold)
				who->direction = kFacingSouth;
			else
			{
				if (who->vMouse > kHiVThreshhold)
					who->direction = kFacingNorth;
				else
					who->direction = kFacingRested;
			}
		}
	}
}


/*========================================================  GetHumanInput  */

void GetHumanInput (void)

{
	Point			mousePt;
	short			boardXForce, boardZForce;
	Boolean			brakeOn, bashOn;
	
	GetMouse(&mousePt);
	LocalToGlobal(&mousePt);
	if (ForcePointInRect(&mousePt, &mouseFrame))
		SetMouse(mousePt);
	
	thePlayer.hMouse = (mousePt.h - screenHCenter) / kPlayerInputSensitive;
	thePlayer.vMouse = (screenVCenter - mousePt.v) / kPlayerInputSensitive;
	thePlayer.buttonIs = Button();
	
	brakeOn = BitTst(&theKeyMap, kSpaceBarMap);
	bashOn = BitTst(&theKeyMap, kBKeyMap) || BitTst(&theKeyMap, kMKeyMap) || 
			BitTst(&theKeyMap, kNKeyMap);
	
	boardXForce = thePlayer.hMouse;
	boardZForce = thePlayer.vMouse;
	
	if (boardXForce > maxBoardForce)
		boardXForce = maxBoardForce;
	else if (boardXForce < -maxBoardForce)
		boardXForce = -maxBoardForce;
	if (boardZForce > maxBoardForce)
		boardZForce = maxBoardForce;
	else if (boardZForce < -maxBoardForce)
		boardZForce = -maxBoardForce;
	
	thePlayer.bashApplied = FALSE;
	if ((whosGotBall != kPlayerHasBall) && (bashOn) && (!brakeOn))
	{
		thePlayer.bashApplied = bashOn;
		boardXForce = boardForceTable[thePlayer.direction][kXComponent];
		boardZForce = boardForceTable[thePlayer.direction][kZComponent];
		boardXForce *= 3;							/* 150% increase in board force */
		boardZForce *= 3;
	}
	
	if ((thePlayer.buttonIs) && (!thePlayer.bashApplied))
	{
		boardXForce += boardXForce / kAddForceFract;	/* 25% increase in board force */
		boardZForce += boardZForce / kAddForceFract;	/* tried 50%, but it was harsh */
	}
	
	if (thePlayer.justHitWall == 0)
	{
		thePlayer.xVel += boardXForce;
		thePlayer.zVel += boardZForce;
	}
	
	if ((brakeOn == TRUE) && (thePlayer.brakeApplied == FALSE))
		PlaySoundSMS(kBrakeSound);
	thePlayer.brakeApplied = brakeOn;
	
	if (brakeOn)
	{
		thePlayer.xVel -= thePlayer.xVel / 10;	/* a 10% decrease in velocity */
		thePlayer.zVel -= thePlayer.zVel / 10;
	}
	
	if (thePlayer.buttonIs)
	{
		if ((theBall.modifier == kPlayerHolding) && (thePlayer.mouseWasLetUp))
			DoPersonBallParted(&thePlayer);
		
		thePlayer.posture = kCrouching;
	}
	else
	{
		thePlayer.mouseWasLetUp = TRUE;
		if (theBall.modifier == kPlayerHolding)
			thePlayer.posture = kCarrying;
		else
			thePlayer.posture = kStanding;
	}
}


/*========================================================  PrepareNetHumanInput  */

void PrepareNetHumanInput (void)

{
	Point			mousePt;
	
	GetMouse(&mousePt);
	LocalToGlobal(&mousePt);
	if (ForcePointInRect(&mousePt, &mouseFrame))
		SetMouse(mousePt);
	
	thePlayer.hMouse = (mousePt.h - screenHCenter) / kPlayerInputSensitive;
	thePlayer.vMouse = (screenVCenter - mousePt.v) / kPlayerInputSensitive;
	thePlayer.buttonIs = Button();
	thePlayer.brakeApplied = BitTst(&theKeyMap, kSpaceBarMap);
	thePlayer.bashApplied = BitTst(&theKeyMap, kBKeyMap) || BitTst(&theKeyMap, kMKeyMap) || 
			BitTst(&theKeyMap, kNKeyMap);
}


/*========================================================  ProcessNetPlayerInput  */

void ProcessNetPlayerInput (void)

{
	short			boardXForce, boardZForce;
	
	boardXForce = theOpponent.hMouse;
	boardZForce = theOpponent.vMouse;
	
	if (boardXForce > maxBoardForce)
		boardXForce = maxBoardForce;
	else if (boardXForce < -maxBoardForce)
		boardXForce = -maxBoardForce;
	if (boardZForce > maxBoardForce)
		boardZForce = maxBoardForce;
	else if (boardZForce < -maxBoardForce)
		boardZForce = -maxBoardForce;
	
	
	if ((theOpponent.bashApplied) && (whosGotBall != kOpponentHasBall) && 
			(!theOpponent.brakeApplied))
	{
		boardXForce = boardForceTable[theOpponent.direction][kXComponent];
		boardZForce = boardForceTable[theOpponent.direction][kZComponent];
		boardXForce *= 3;								/* 150% increase in board force */
		boardZForce *= 3;
	}
	
	if ((theOpponent.buttonIs) && (!theOpponent.bashApplied))
	{
		boardXForce += boardXForce / kAddForceFract;	/* 25% increase in board force */
		boardZForce += boardZForce / kAddForceFract;	/* tried 50%, but it was harsh */
	}
	
	if (theOpponent.justHitWall == 0)
	{
		theOpponent.xVel += boardXForce;
		theOpponent.zVel += boardZForce;
	}
	
	if ((wasBrakeOn == FALSE) && (theOpponent.brakeApplied == TRUE))
		PlaySoundSMS(kBrakeSound);
	wasBrakeOn = theOpponent.brakeApplied;
	
	if (wasBrakeOn)
	{
		theOpponent.bashApplied = FALSE;
		theOpponent.xVel -= theOpponent.xVel / 10;	/* a 10% decrease in velocity */
		theOpponent.zVel -= theOpponent.zVel / 10;
	}
	
	if (theOpponent.buttonIs)
	{
		if ((theBall.mode == kBallHeld) && (theBall.modifier == kOpponentHolding) && 
				(theOpponent.mouseWasLetUp))
			DoPersonBallParted(&theOpponent);
		
		theOpponent.posture = kCrouching;
	}
	else
	{
		theOpponent.mouseWasLetUp = TRUE;
		if (theBall.modifier == kOpponentHolding)
			theOpponent.posture = kCarrying;
		else
			theOpponent.posture = kStanding;
	}
}


/*========================================================  HandleBoardCursor  */

void HandleBoardCursor (void)

{
	short		rootHeight, actualHeight;
	short		indexX, absoluteX, fractionalX;
	short		indexZ, fractionalZ;
	
	if ((!showBoardCursor) || (disableBoardCursor))
		return;
	
	boardCursor.xPos = thePlayer.xPos + (thePlayer.hMouse * 16);
	boardCursor.zPos = thePlayer.zPos + (thePlayer.vMouse * 16);
	
	boardCursor.isRect.left = (boardCursor.xPos / 64) + displayHCenter - 5;
	
	if (boardCursor.isRect.left < 0)
		boardCursor.isRect.left = 0;
	else if (boardCursor.isRect.left + 16 > screenWide)
		boardCursor.isRect.left = screenWide - 16;
	
	boardCursor.isRect.right = boardCursor.isRect.left + 16;
	
	absoluteX = boardCursor.xPos;
	if (absoluteX < 0)
		absoluteX = -absoluteX;
	indexX = absoluteX / 512;
	fractionalX = absoluteX % 512;
	indexZ = (boardCursor.zPos / 512) + 40;
	fractionalZ = boardCursor.zPos % 512;
	
	rootHeight = vertTable[indexX][indexZ];
	actualHeight = rootHeight + (fractionalX * (vertTable[indexX + 1][indexZ] - rootHeight)) / 512;
	actualHeight += (fractionalZ * (vertTable[indexX][indexZ + 1] - rootHeight)) / 512;
	
	boardCursor.isRect.bottom = actualHeight + 4;
	
	if (boardCursor.isRect.bottom > screenHigh)
		boardCursor.isRect.bottom = screenHigh;
	else if (boardCursor.isRect.bottom < 12)
		boardCursor.isRect.bottom = 12;
	
	boardCursor.isRect.top = boardCursor.isRect.bottom - 8;
}



