/*********************************************************************************************/
/*                                                                                           */
/* General AI Stuff					                                                            */
/*                                                                                           */
/*********************************************************************************************/

#ifndef BOX_H
#define BOX_H

#ifdef __cplusplus
extern "C" {
#endif

/********************************* TYPE DEFINITIONS ******************************************/

#define MAX_EXPANSION 5

#define NUM_SLOTS	5

#define NO_BOX -1
#define BOX_NUMBER  0x7fff

#define EXPAND_LEFT   0x1
#define EXPAND_RIGHT  0x2
#define EXPAND_TOP    0x4
#define EXPAND_BOTTOM 0x8

#define BLOCKABLE     0x8000
#define BLOCKED       0x4000
#define OVERLAP_INDEX 0x3fff

#define SEARCH_NUMBER  0x7fff
#define BLOCKED_SEARCH 0x8000

typedef struct box_info {
	uint8 left, right, top, bottom;
	sint16 height;
	sint16 overlap_index;
} BOX_INFO;

typedef struct box_node {
	sint16 exit_box;
	uint16 search_number;
	sint16 next_expansion;
	sint16 box_number;     // for storing zone box lists
} BOX_NODE;


typedef enum target_type {NO_TARGET, PRIME_TARGET, SECONDARY_TARGET} TARGET_TYPE;

typedef enum mood_type {BORED_MOOD, ATTACK_MOOD, ESCAPE_MOOD, STALK_MOOD} MOOD_TYPE;

#define TIMID   0
#define VIOLENT 1

typedef struct AI_info {
	sint16 zone_number, enemy_zone;
	sint32 distance, ahead, bite;
	sint16 angle, enemy_facing;
} AI_INFO;


#define NO_FLYING 0

typedef struct lot_info {
	BOX_NODE *node;
	sint16 head, tail;
	uint16 search_number, block_mask;
	sint16 step, drop, fly, zone_count;
	sint16 target_box, required_box;
	PHD_VECTOR target;
} LOT_INFO;


#define FRONT_ARC 0x4000
#define MAX_HEAD_CHANGE (ONE_DEGREE*5)
#define MAX_TILT			(ONE_DEGREE*3)

typedef struct creature_info {
	sint16 	head_rotation, neck_rotation; // up to 2 extra rotations in addition to normal animation
	sint16 	maximum_turn;
	sint16 	flags; // spare bits that can be used for any purpose by different types of creature
	sint16	item_num;
	MOOD_TYPE mood;
	LOT_INFO LOT;
	PHD_VECTOR target;
	ITEM_INFO *enemy;
} CREATURE_INFO;


typedef struct skidoo_info {
	sint16 track_mesh;
	int skidoo_turn;
	int left_fallspeed, right_fallspeed;
	sint16 momentum_angle, extra_rotation;
	int pitch;
} SKIDOO_INFO;

typedef struct boat_info {
	int boat_turn;
	int left_fallspeed, right_fallspeed;
	sint16 tilt_angle, extra_rotation;
	int water, pitch;
} BOAT_INFO;

/* Global structures */
extern int				number_boxes;
extern BOX_INFO 	  *boxes;
extern uint16		  *overlap;
extern sint16		  *ground_zone[4][2], *fly_zone[2];

// Get the correct zone from the allowed step height for the creature
#define ZONE(A) (((A) >> WALL_SHIFT-2) - 1)

extern int monks_attack_lara;

/******************************** FUNCTION PROTOTYPES ****************************************/

void		InitialiseCreature	(sint16 item_number);
int		CreatureActive			(sint16 item_number);
void		CreatureAIInfo			(ITEM_INFO *item, AI_INFO *info);

void 		CreateZone				(ITEM_INFO *item);
int 		SearchLOT				(LOT_INFO *LOT, int expansion);
int 		UpdateLOT				(LOT_INFO *LOT, int expansion);

void 		TargetBox				(LOT_INFO *LOT, sint16 box_number);
void		CreatureMood			(ITEM_INFO *item, AI_INFO *info, int violent);
TARGET_TYPE CalculateTarget	(PHD_VECTOR *target, ITEM_INFO *item, LOT_INFO *LOT);

int		CreatureAnimation		(sint16 item_number, sint16 angle, sint16 tilt);

sint16	CreatureTurn			(ITEM_INFO *item, sint16 maximum_turn);
void		CreatureTilt			(ITEM_INFO *item, sint16 angle);
void		CreatureHead			(ITEM_INFO *item, sint16 required);
void		CreatureNeck			(ITEM_INFO *item, sint16 required);
void		CreatureFloat			(sint16 item_number);
void		CreatureUnderwater	(ITEM_INFO *item, sint32 depth);
sint16	CreatureEffect			(ITEM_INFO *item, BITE_INFO *bite, sint16 (*generate)(sint32 x, sint32 y, sint32 z, sint16 speed, PHD_ANGLE yrot, sint16 room_number));
int		CreatureVault			(sint16 item_number, sint16 angle, int vault, int shift);
void		CreatureKill			(ITEM_INFO *item, int kill_anim, int kill_state, int lara_kill_state);
void		CreatureDie				(sint16 item_number, int explode);

void		GetBaddieTarget		(sint16 item_number, int goody);

void 		EarthQuake				(sint16 item_number);
void		DrawLightning			(ITEM_INFO *item);
void		InitialiseLightning	(sint16 item_number);
void		ControlLightning		(sint16 item_number);

int 		ExplodingDeath			(sint16 item_number, sint32 mesh_bits, sint16 damage);
void 		ControlBodyPart		(sint16 fx_number);
void		ControlNatlaGun		(sint16 fx_number);
void 		ControlMissile			(sint16 fx_number);
sint16 	ShardGun					(sint32 x, sint32 y, sint32 z, sint16 speed, PHD_ANGLE yrot, sint16 room_number);
sint16 	RocketGun				(sint32 x, sint32 y, sint32 z, sint16 speed, PHD_ANGLE yrot, sint16 room_number);
void		ShootAtLara			(FX_INFO* fx);

int 		Targetable				(ITEM_INFO *item, AI_INFO *info);
void		ControlGlow				(sint16 nFX);
void		ControlGunShot			(sint16 fx_number);
sint16	GunShot					(sint32 x, sint32 y, sint32 z, sint16 speed, PHD_ANGLE yrot, sint16 room_number);
sint16	GunHit					(sint32 x, sint32 y, sint32 z, sint16 speed, PHD_ANGLE yrot, sint16 room_number);
sint16	GunMiss					(sint32 x, sint32 y, sint32 z, sint16 speed, PHD_ANGLE yrot, sint16 room_number);
int		ShotLara					(ITEM_INFO *item, AI_INFO *info, BITE_INFO *gun, sint16 extra_rotation, int damage);

void		DrawSkidMan				(ITEM_INFO *item);
void		SkidmanCollision		(sint16 item_num, ITEM_INFO *laraitem, COLL_INFO *coll);

void		InitialiseCult3		(sint16 item_number);
void		InitialiseVulture		(sint16 item_number);
void		InitialiseCult1		(sint16 item_number);
void		InitialiseSkidman		(sint16 item_number);

void		DogControl				(sint16 item_number);
void		MouseControl			(sint16 item_number);
void		SharkControl			(sint16 item_number);
void		TigerControl			(sint16 item_number); // + snow leopard
void		BaracuddaControl		(sint16 item_number);
void		SpiderControl			(sint16 item_number);
void		BigSpiderControl		(sint16 item_number);
void		DiverControl			(sint16 item_number);
void		Worker1Control			(sint16 item_number);
void		Worker2Control			(sint16 item_number);
void		Worker3Control			(sint16 item_number);
void		Cult1Control			(sint16 item_number); // + cult1a and 1b
void		Cult2Control			(sint16 item_number);
void		Cult3Control			(sint16 item_number);
void		MonkControl				(sint16 item_number); // 2 monks
void		VultureControl			(sint16 item_number); // + crow
void		BanditControl			(sint16 item_number);
void		Bandit2Control			(sint16 item_number);
void		SkidManControl			(sint16 item_number);
void		SkidRiderControl		(sint16 item_number);
void		DinoControl				(sint16 item_number);
void		WinstonControl			(sint16 item_number);

#ifdef __cplusplus
}
#endif

#endif
