

#ifndef __H_HAND
#define __H_HAND

typedef struct tagENEMYPOS *enemyhandle;

//TOM I've rem'd vars that arent used    ANO


typedef struct _GloveCtrl
{
	long		radius;
//	long		height;
	long		frontProbeHeight;
	enemyhandle	mount;
	VECTOR		move;
	VECTOR		slideData;
//	VECTOR		slideNormal;
	VECTOR		iceData;
	VECTOR		conveyerNormal;
	VECTOR		platformMove;
	LONG		freeVar;
	int			waterHeight;
	MATRIX		matrix;
	BOULDERDATA *attachedBoulder;
	USHORT		speed;
	USHORT		oldSpeed;
	USHORT		targetSpeed;
	USHORT		direction;
	USHORT		targetDirection;
	SHORT		directionSeekSpeed;
	USHORT		pushDirection;
	USHORT		action;
	USHORT		lastAction;
	USHORT		currentAnim;
	USHORT		active;
	USHORT		disableTimer;
	USHORT		throwDelay;
	USHORT		preDelay;
	SHORT		idleTimer;
	USHORT		actionTime;
	USHORT		spellActionTime;
	USHORT		walkType;
	USHORT		onGround;
	USHORT		onCeiling;
	USHORT		ballWithHand;
	USHORT		hitBall;
	USHORT		handOnBall;
	USHORT		dennisBounceCount;
	USHORT		tipNumber;
	USHORT		rotorSpinSpeed;
	SHORT		leftRight;
	SHORT		upDown;
	UBYTE		dennisJumpHit;		// Also used for swish
	UBYTE		dennisJump;
	UBYTE		dennisOnGround;
	UBYTE		ballCollision;
	UBYTE		flags;
	UBYTE		stopXZ;
	UBYTE		idleAction;
	UBYTE		idleSelection;
	UBYTE		frontProbeHit;
	UBYTE		ballHit;	// used for fist slam on ball
	UBYTE		tipFlag;	// set when close to tip
	UBYTE		clingFlag;
	UBYTE		pushFlag;
	UBYTE		lives;
	UBYTE		health;
	UBYTE		maxHealth;
	UBYTE		healthChange;
	UBYTE		currentDisplayedHealth;
	UBYTE		hurtFlag;
	UBYTE		hurtFlagBall;
	UBYTE		dieCount;
	UBYTE		handHurtTime;
	UBYTE		ballHurtTime;
	UBYTE		cameoDisableDamage;
	UBYTE		flash;
	UBYTE		deathType;
	UBYTE		deathTypeBall;
	UBYTE		shockFlag;
	UBYTE		inWaterFlag;
	UBYTE		enabled;	//if set, there's no glove in the level (eg - when respawning, before you come out of the teleport)
	UBYTE		forceSlide;	//if glove on steap slop make him slid down
	UBYTE		forceSlideDelay;
	UBYTE		onIce;		//if glove on ice
	UBYTE		onIceFlag;
	UBYTE		onConveyer;
	UBYTE		conveyerTimer;
	UBYTE		onTrampoline;
	UBYTE		jumpPressed;
	UBYTE		onWater;
	UBYTE		onSnow;
	UBYTE		insideBubble;
	UBYTE		insideSnowBall;
	UBYTE		whackAir;
	UBYTE		blinkTime;
	UBYTE		ballIdleAction;
	UBYTE		garibCollectState;
	UBYTE		allLevelGaribs;
	UBYTE		levelFinished;
	UBYTE		reHealthFlag;
	UBYTE		inWind;
	UBYTE		positionHold;
	USHORT		padIn;
	USHORT		padOld;
	USHORT		padInDB;
	UBYTE		padDisableTimer;
	UBYTE		pushingPlatform;
	UBYTE		onLava;
	UBYTE		spellCastOnBall;
	UBYTE		spellCastTimer;	// Yet another spell bodge this time for the ballwalk mode !!!
	UBYTE		spellCast;
	UBYTE		ballSpellBodge;
	UBYTE		onMovingPlat;
}GLOVECTRL;

typedef	struct	_INPUTSTATE
{
	UBYTE		aHeld;
	UBYTE		bHeld;
	UBYTE		cHeld;
	UBYTE		dHeld;
	UBYTE		eHeld;
	UBYTE		zHeld;
	UBYTE		aReleased;
	UBYTE		bReleased;
	UBYTE		cReleased;
	UBYTE		dReleased;
	UBYTE		eReleased;
	UBYTE		fReleased;
	UBYTE		aOnTime;
	UBYTE		bOnTime;
	UBYTE		cOnTime;
	UBYTE		dOnTime;
	UBYTE		eOnTime;
	UBYTE		zOnTime;
	UBYTE		aStateHoldTime;
	UBYTE		bStateHoldTime;
	UBYTE		cStateHoldTime;
	UBYTE		dStateHoldTime;
	UBYTE		eStateHoldTime;
	UBYTE		zStateHoldTime;
	UBYTE		aStateChange;
	UBYTE		bStateChange;
	UBYTE		cStateChange;
	UBYTE		dStateChange;
	UBYTE		eStateChange;
	UBYTE		zStateChange;
	UBYTE		whackWhenAble;
	UBYTE		throwWhenAble;
}INPUTSTATE;

extern	INPUTSTATE	InputState;
/*
typedef struct _BodgeCtrl
{
	DYNCOLLBOX	*carnivalPlat;
	UBYTE		platOn;
}BODGECTRL;

extern	BODGECTRL	BodgeCtrl;
*/
#define		CARDOK			1
#define		CARDGOINGDOWN	2
#define		CARDCOMEBACK	3

#define		BALLONFINGER		1
#define		BALLONFINGERSTOP	2
#define		BALLPEDDLE			3
#define		BALLPEDDLESTOP		4

typedef struct _CannonCtrl
{
	SHORT		direction;
	SHORT		lastDirection;
	SHORT		camDirection;
	SHORT		elevation;
	SHORT		ring1angle;
	SHORT		ring2angle;
	SHORT		ring3angle;
	SHORT		shotsFired;
	SHORT		cardsHit;
	VECTOR		bulletPos[10];
	VECTOR		bulletVel[10];
	VECTOR		bulletRot[10];
	VECTOR		bulletRotAdd[10];
	NEWMODEL	*bulletModel[10];
	UBYTE		alive[10];
	UBYTE		ring1CardTypes[20];
	UBYTE		ring2CardTypes[20];
	UBYTE		ring3CardTypes[20];
	UBYTE		ring1CardStatus[20];
	UBYTE		ring2CardStatus[20];
	UBYTE		ring3CardStatus[20];
	UBYTE		recedingCount1[20];
	UBYTE		recedingCount2[20];
	UBYTE		recedingCount3[20];
	UBYTE		bulletHit[10];
	UBYTE		nextFireCount;
	UBYTE		endOfBonusFlag;
	UBYTE		justFiredFlag;
	//UBYTE		receding[10];
}CANNONCTRL;

extern	CANNONCTRL	CannonCtrl;

typedef struct _SinCos
{
	long	sin;
	long	cos;
}SINCOSTABLE;

extern	SINCOSTABLE	*SinCosTable;

//#define		HURT				1
//#define		DEAD				2

// defines for die type
//#define		FALL_DEATH			1
//#define		HURT_DEATH			2
//#define		FALLOFFLEVEL_DEATH	3

extern	VECTOR	DennisPos,DennisVel;
extern	VECTOR	SwishPos,SwishVel;


extern	NEWOBJECT	*gloveShinR;
extern	NEWOBJECT	*gloveShinL;
extern	NEWOBJECT	*gloveArmR;
extern	NEWOBJECT	*gloveArmL;



// defines for death type
#define		HURTFALL			1
#define		HURTPAIN			2
#define		DEADFROMFALL		3
#define		DEADFROMPAIN		4
#define		DEADFROMSQUASH		5 /*????*/
#define		DEADFROMFALLOFF		6
#define		DEADFROMBALLFALLOFF	7
#define		DEADFROMBALLBURST	8 /*inculds shatterd crystal*/


#define		HURTJUMPSPEED		7*4096

#define		BLASTRADIUS			50*4096
#define		SLAMSPEED			20*4096
//#define	IDLE	0
//#define	WALK	1
//#define	RUN		2
//#define	SLIDE	3
//#define	JUMP	4

// Flag defines
#define GLOVEMOVE		(1<<0)
#define STOPGLOVEMOVE	(1<<1)
#define STOPAIRMOVE		(1<<2)

#define HAND_SNATCH_RANGE (60*4096)
#define	CRAWLSTARTDELAY	6
#define CRAWLSPEED		1

#define GLOVENORMALRADIUS	(25*4096*NORMAL_SCALE)
#define GLOVECRAWLRADIUS	(GLOVENORMALRADIUS/3)

//#define TOPSPEED	128/2

//#define TOPSPEED	128/2
extern int handpower_duration;
extern int handpower_timer;
extern int handpower_type;

extern USHORT	keyRecordCount;
// use for recording and saving
//extern USHORT	keyRecord[16384];
// use for loading and playback
//extern USHORT*	keyRecord;


#if RECORDKEYS == YES
extern USHORT	keyRecord[16384];
#else
extern USHORT*	keyRecord;
#endif

extern	USHORT		padState;
extern	SHORT		padX,padY;


//#define TOPSPEED ((handpower_timer != 0 && handpower_type == SPELL_SPEEDUP) ? 128:64)
#define TOPSPEED ((handpower_timer != 0 && handpower_type == SPELL_SPEEDUP) ? 192:96)

//#define	RUNSPEED	48*2 /*(TOPSPEED/2)*/
//#define WALKSPEED	24*2 /*(TOPSPEED/2)*/
#define	RUNSPEED	72
#define WALKSPEED	36


#define CARTWHEELSPEED 8
#define SKIDSPEED (TOPSPEED/8)
#define JUMPHEIGHT GRAVITY*10
#define DOUBLEJUMPHEIGHT GRAVITY*10

#define	RESTSPEED	2*4096

//#define	CATCHDISTANCE	10*4096
#define	LOBHEIGHT	GRAVITY*20
#define	LOBDISTANCE	4096*6

//#define	ROTATESPEED 	256
#define	ROTATESPEED 	384
#define	LEANANGLE		300/3
#define	BOUNCEFALLSPEED	GRAVITY*5

#define	GRAVITY	4096
//#define	GRAVITY	2048

#define	FRONTPROBEDIST	5
#define	FRONTPROBECHECK	90000
#define JOINEDFALLRATE	-4096*10

#define ABUTTON		(1<<0)
#define BBUTTON		(1<<1)

#define	DENNISHEIGHT	28
#define DENNISMOVESPEED 10

#define	SWISHDISTANCE	5*4096
#define SWISHWALKSPEED	-1*4096
#define SWISHRUNSPEED	-2*4096

#define ROTORMAXYSPEED	4*4096

#define	SPECIALACTION	99

typedef struct _GloverSeg
{
	USHORT	start;
	USHORT	end;
}GLOVERSEG;

//------------------------------------------------------
//Anim segments for Dennis
enum
{
	DENNIS_IDLE,
	DENNIS_IDLE2,
	DENNIS_STARTMOVE,
	DENNIS_WALK,
	DENNIS_RUN,
	DENNIS_STOPMOVE,
	DENNIS_JUMP,
	DENNIS_LAND,
	DENNIS_STARTATTACK,
	DENNIS_ENDATTACK,
	DENNIS_ACTION1,
	DENNIS_ACTION2,
	DENNIS_HURT,
	DENNIS_DEATH,
	DENNIS_SPECIAL1,
	DENNIS_SPECIAL2
};


//------------------------------------------------------
//hand animations needs to be reordered due to seg files being in different order
enum
{
	HANDANIM_TIPTOE,			//0  
	HANDANIM_JOG,				//1  
	HANDANIM_SKID,				//2  
	HANDANIM_IDLE,				//3  
	HANDANIM_JUMP,				//4  

	HANDANIM_SUPERJUMP,			//5
	HANDANIM_LAND,				//6
	HANDANIM_CARTWHEEL,			//7
	HANDANIM_DUCK,				//8
	HANDANIM_BORED,				//9

	HANDANIM_DUCK2STAND,		//10
	HANDANIM_SLAM,				//11
	HANDANIM_SLAM2STAND,		//12
	HANDANIM_ROLL,				//13
	HANDANIM_ROLL2BOUNCE,		//14

	HANDANIM_BOUNCE,			//15
	HANDANIM_BOUNCE2ROLL,		//16
	HANDANIM_RELEASE,			//17
	HANDANIM_THROWAIM,			//18
	HANDANIM_THROW,				//19

	HANDANIM_WHACKAIM,			//20
	HANDANIM_WHACK,				//21
	HANDANIM_RUN,				//22
	HANDANIM_SELFSPELL,			//23
	HANDANIM_BALLSPELL,			//24

	HANDANIM_NMESPELL,			//25
	HANDANIM_HURT,				//26
	HANDANIM_FALLDEATH,			//27
	HANDANIM_CARDIACDEATH,		//28
	HANDANIM_CRAWL,				//29

	HANDANIM_GETDOWN,			//30
	HANDANIM_GETUP,				//31
	HANDANIM_ROLLBLINK,			//32
	HANDANIM_ROLL2SPIN,			//33
	HANDANIM_SPIN,				//34

	HANDANIM_SPIN2ROLL,			//35
	HANDANIM_SIT,				//36
	HANDANIM_LOB,				//37
	HANDANIM_POINT,				//38
	HANDANIM_POINTCYCLE,		//39

	HANDANIM_CLING,				//40
	HANDANIM_CLINGDOWN,			//41
	HANDANIM_POINT2IDLE,		//42
	HANDANIM_CLINGUP,			//43
	HANDANIM_CLINGIDLE,			//44

	HANDANIM_WHACKIDLE,			//45
	HANDANIM_SITIDLE,			//46
	HANDANIM_GRABBALL,			//47
	HANDANIM_SITDOWN,			//48
	HANDANIM_SITUP,				//49

	HANDANIM_IDLE2PUSH,			//50
	HANDANIM_PUSH,				//51
	HANDANIM_PUSH2IDLE,			//52
	HANDANIM_BALLWALK,			//53
	HANDANIM_RIDEDENNIS,		//54

	HANDANIM_GRABSWISH,			//55
	HANDANIM_FALLOVER,			//56
	HANDANIM_EMPTYFIRE,			//57
	HANDANIM_THUMBSUP,			//58
	HANDANIM_OKAY,				//59

	HANDANIM_FALL,				//60
	HANDANIM_BALLWALK2,			//61
	HANDANIM_SQUASH,			//62
	HANDANIM_IDLE2STRETCH,		//63
	HANDANIM_STRETCH,			//64

	HANDANIM_STRETCH2IDLE,		//65
	HANDANIM_CELEBRATE,			//66
	HANDANIM_PEDDLE,			//67
	HANDANIM_ROLL2PEDDLE,		//68
	HANDANIM_VICTORY,			//69

	HANDANIM_CLICKFINGER,		//70
	HANDANIM_IDLE2WAVE,			//71
	HANDANIM_WAVE,				//72
	HANDANIM_BALLWALK2IDLE,		//73

	MAX_HANDANIMS			 

/*	HANDANIM_BALLWALK,			 //0  
	HANDANIM_MISFIRE,			 //1  
	HANDANIM_FALL,				 //2  
	HANDANIM_GETDOWN,			 //3  
	HANDANIM_GETUP,				 //4  
								  
	HANDANIM_SNATCH,			 //5  
	HANDANIM_SWISH,				 //6  
	HANDANIM_WALK,				 //7  
	HANDANIM_OKAY,				 //8  
	HANDANIM_DENIS,				 //9
								   
	HANDANIM_SIT2DOWN,			 //10 
	HANDANIM_SITIDLE,			 //11 
	HANDANIM_SITUP,				 //12 
	HANDANIM_THUMBSUP,			 //13 
	HANDANIM_TIPTOE,			 //14 
								  
	HANDANIM_BALLSPELL,			 //15 
	HANDANIM_IDLE1,				 //16 
	HANDANIM_BOUNCE2,			 //17 
	HANDANIM_BOUNCE2CUP,		 //18 
	HANDANIM_CARTWHEEL,			 //19 
								  
	HANDANIM_CLING,				 //20 
	HANDANIM_CLINGDOWN,			 //21 
	HANDANIM_CLINGIDLE,			 //22 
	HANDANIM_CLINGUP,			 //23 
	HANDANIM_CRAWL,				 //24 
								  
	HANDANIM_ST2DUCK,			 //25 
	HANDANIM_DUCK2ST,			 //26 
	HANDANIM_FALLDEATH,			 //27 
	HANDANIM_FALLOVER,			 //28 
	HANDANIM_CARDIACDEATH,		 //29 
								  
	HANDANIM_HURT,				 //30 
	HANDANIM_STAND,				 //31 
	HANDANIM_STAND2PUSH,		 //32 
	HANDANIM_JUMP,				 //33 
	HANDANIM_THROW2LAND,		 //34 
								  
	HANDANIM_LOB,				 //35 
	HANDANIM_NMESPELL,			 //36 
	HANDANIM_POINT,				 //37 
	HANDANIM_POINTCYCLE,		 //38 
	HANDANIM_POINT2IDLE,		 //39 
								      
	HANDANIM_PUSH,				 //40    
	HANDANIM_PUSH2STAND,		 //41    
	HANDANIM_CUP2ST,			 //42    
	HANDANIM_ST2CUP,			 //43    
	HANDANIM_CUP2BOUNCE,		 //44
								 
	HANDANIM_CUP2SPIN,			 //45
	HANDANIM_CUPIDLE,			 //46    
	HANDANIM_RUN,				 //47
	HANDANIM_HANDSPELL,			 //48
	HANDANIM_SIT,				 //49

	HANDANIM_SKID,				 //50
	HANDANIM_SLAM,				 //51
	HANDANIM_SLAM2ST,			 //52
	HANDANIM_SPIN,				 //53
	HANDANIM_SPIN2CUP,			 //54

	HANDANIM_LONGJUMP,			 //55
	HANDANIM_THROW,				 //56
	HANDANIM_THROWAIM,			 //57
	HANDANIM_WHACK2,			 //58
	HANDANIM_WHACK1,			 //59

	HANDANIM_WHACKIDLE,			 //60


	HANDANIM_BNCE2THROWAIM,		//61
	HANDANIM_THROW2CUP,			//62
	HANDANIM_BOUNCE3,			//63
	HANDANIM_IDLE3,				//64
	HANDANIM_SPECIAL1,			//65
	HANDANIM_SPECIAL2,			//66
	HANDANIM_STUN,				//67
	HANDANIM_PAT,				//68
	HANDANIM_CLIMBDOWN,			//69
	HANDANIM_CLIMBUP,			//70

	HANDANIM_CLIMBDOWNIDLE,		//71
	MAX_HANDANIMS
*/
};

//------------------------------------------------------
//hand actions
enum
{
	HAND_IDLE,			 	//0
	HAND_WALK,			 	//1
	HAND_JUMP,			 	//2
//	HAND_FRIG,				//3
	HAND_JOINED,		 	//4
	HAND_THROW,			 	//5
	HAND_PREWHACK,		 	//6
	HAND_WHACK,			 	//7
	HAND_SKIDDING,		 	//8
	HAND_DUCK,			 	//9
	HAND_RELEASE,		 	//10
	HAND_GETUP,			 	//11
	HAND_THROWAIM,		 	//12
	HAND_THROW2CUP,		 	//13
	HAND_FALLING,		 	//14
	HAND_BOUNCE,		 	//15
	HAND_BOUNCE2CUP,	 	//16
	HAND_AIRBOURNEWHACK, 	//17
	HAND_THROW2LAND,	 	//18
	HAND_SLAM,			 	//19
	HAND_SLAM2ST,		 	//20
	HAND_BALLWALK,		 	//21
	HAND_CRAWL,			 	//22
	HAND_CARTWHEEL,		 	//23
	HAND_CLIMBUP,		 	//24
	HAND_CLIMBDOWN,		 	//25
	HAND_CLING,			 	//26
	HAND_CLINGUP,		 	//27
	HAND_DROPDOWN,		 	//28
	HAND_HURT,			 	//29
	HAND_PUSH,			 	//30
	HAND_LOB,			 	//31
	HAND_CATCH,			 	//32
	HAND_CASTSPELL,		 	//33
	HAND_ROTOR,			 	//34
	HAND_SNATCH,		 	//35
	HAND_SLIDING,			//36
	HAND_HOPPING,			//37
	HAND_ALLGARIBS,			//38
	//HAND_FROG_IDLE,			//38
	HAND_LEVELCOMPLETE,		//39
	//HAND_FROG_JUMP,			//39
	HAND_FROG_WALK,			//40
	HAND_SWISH,				//41
	HAND_NOTHING,			//42
	HAND_LOCATE,			//43
	HAND_SPIN,				//44
	HAND_FROG_TONGUE,		//45
	HAND_NMESPELL,			//46
	//HAND_SUCTION,			//47 (added by Tom)
	MAX_HAND_ACTIONS	 	//48
};								
extern char handActionValidityTable[MAX_HAND_ACTIONS][MAX_HAND_ACTIONS];
enum
{
	BLANK,
	HANDWALK_TIPTOE,
	HANDWALK_WALK,
	HANDWALK_RUN,
	HANDWALK_ONBALL
};



extern	GLOVECTRL			GloveCtrl;
extern	BEHAVIOUR_PHYSICS	GloveBehaviour;
extern	LONG				ballStartRadius,ballEndRadius,spinSpeed;

void	Load_And_Init_Glove();
void	Control_Glove();
void	moveGlove();
void	MaintainAction();
int		GrabBallAllowed();
int		CatchBallAllowed();
int		HandOnBall();
void	HandCollision();
ULONG	HandToBallCollision();
void	resetGlove(void);
void	GloveDamage(void);
void	CheckForFistHits(void);
void	CheckForNmeHitsGlove(void);

void handRender();

void	objectPush( long nHits ) ;

void	handMountDenis(enemyhandle);
void	handMountSwish(enemyhandle);
// hand powerup routines
void handGivePlayerPower(int type, int time);
void handPowerUpdate();
void handPowerDraw();

//void handOverTip(ENEMYPOS *enemy, int tipno);
void	fixBadKeyFrames(void);


#define DISCONNECT_WHEN_JOINED		1
#define DISCONNECT_WHEN_BOUNCING	2
#define DISCONNECT_WHEN_WALKINGON	4
#define DISCONNECT_WHEN_WHATEVER	15

#define DISCONNECT_GENTLY 16

void DisconnectGloveFromBall(int when);

void handComeOutOfHoop(VECTOR *pos, int ya);
void handGoThroughTeleport(VECTOR *pos, int ya);	// it's assumed that your "connected-to-ball" status is preserved

//BOOL	ActionAllowed(int handAction, int requestedAction);
#define ActionAllowed(A,R) (handActionValidityTable[A][R])

void	GloveStatusReport();

void	HandOnCannon(void);
void	drawCards(void);
void	addBullet(void);
void	updateBullets(void);
void	miniCollision(void);
LONG	pointInBox(LONG	x,LONG z,VECTOR *p1,VECTOR *p2);
void	checkRing1(LONG height,LONG distance,LONG loop,VECTOR *tempVec);
void	checkRing2(LONG height,LONG distance,LONG loop,VECTOR *tempVec);
void	checkRing3(LONG height,LONG distance,LONG loop,VECTOR *tempVec);
void	checkCardRing1(LONG height,LONG distance,LONG loop);
void	checkCardRing2(LONG height,LONG distance,LONG loop);
void	checkCardRing3(LONG height,LONG distance,LONG loop);
LONG	endOfBonusCheck(void);

void	muzzelFlash(void);
void	caBonusDisplay(void);

void	cannonHandler(void);
void	fireShot(void);
void	updateShots(void);

void	handKillGlove();
void	handHurtGlove(int deathreason);

void handTidyGloveObject(void);

extern COLLDATA	DennisColl;
extern COLLDATA	handFrontProbe;
extern VECTOR	handFrontProbePos;


#endif 