
#ifndef __H_ENEMIES
#define __H_ENEMIES

#define MAX_ENEMIES 30


/*
// playstation order
	NMEANIM_IDLE,			//0
	NMEANIM_IDLE2,			//1

	NMEANIM_STARTMOVE,		//2
	NMEANIM_WALK,			//3
	NMEANIM_RUN,			//4
	NMEANIM_STOPMOVE,		//5

	NMEANIM_JUMP,			//6
	NMEANIM_LAND,			//7

	NMEANIM_STARTATTACK,	//8
	NMEANIM_ENDATTACK,		//9

	NMEANIM_ACTION1,		//10
	NMEANIM_ACTION2,		//11

	NMEANIM_HURT,			//12
	NMEANIM_DEATH,			//13
	NMEANIM_SPECIAL1,		//14
	NMEANIM_SPECIAL2,		//15
// ---

// n64 order
	NMEANIM_ACTION1,		//0
	NMEANIM_ACTION2,		//1
	NMEANIM_DEATH,			//2
	NMEANIM_ENDATTACK,		//3
	NMEANIM_HURT,			//4

	NMEANIM_IDLE,			//5
	NMEANIM_IDLE2,			//6

	NMEANIM_JUMP,			//7
	NMEANIM_LAND,			//8
	NMEANIM_RUN,			//9
	NMEANIM_SPECIAL1,		//10
	NMEANIM_SPECIAL2,		//11
	NMEANIM_STARTATTACK,	//12
	NMEANIM_STARTMOVE,		//13
	NMEANIM_STOPMOVE,		//14
	NMEANIM_WALK,			//15

*/


/*

//ACTOR & PLATFORM flags
#define GRAVITY_FLAG	(1<<0) 
#define DESTROYED		(1<<1)
#define BACKGROUND_OBJ	(1<<2)

//ACTOR flags
#define COLLISION_ACTOR		(1<<3)  
#define COLLISION_LAND		(1<<4)  
#define ROLLING				(1<<5)  
#define LO_GRAVITY			(1<<6)  
#define DIESONCONTACT		(1<<7)  
#define SHADOW				(1<<8)  
#define DESTROYER			(1<<9)  
#define MAGNETIC			(1<<10) 
#define BLOWN_BY_WIND		(1<<11) 
#define BEING_BLOWN			(1<<12) 
#define CATAPULTING			(1<<13) 
#define QUAT_ROTATION		(1<<14) 
#define SUCTION_ON			(1<<15) 
#define LANDSCAPE_OBJ		(1<<16) 
#define HURT_HAND			(1<<17) 
#define HURT_BALL			(1<<18) 
#define KILL_HAND			(1<<19) 
#define KILL_BALL			(1<<20)
#define FLOATS				(1<<21) 
#define HURT_BY_LAVA		(1<<22) 
#define NO_UPDATE			(1<<23) 
#define NO_MAX_SPEED		(1<<24) 
#define DISABLE_SQUASH		(1<<25) 
#define TOUCHED_BALL		(1<<26) 
#define RELEASE_BALL		(1<<27)
#define NO_CURRENT			(1<<28)
#define NO_CAM_COLLISION	(1<<29)
#define NO_MASS				(1<<30)
#define SQUASH_HAND			(1<<31)


*/



// Instruction notes:-
// instr Special time (i,j,f, string,c1,c2) -> )i,j,c1,c2,f,cond)







//enemy flags
/*
// ** N64 ** low 2 digits
#define	NMEFLAGS_MOVE_ACCEL				(1<<0)	//1	signals to accellerate enemies
#define NMEFLAGS_MOVE_VEL				(1<<1)	//2	signals to add to velocity
#define NMEFLAGS_DONT_SLOW_WHEN_NEAR	(1<<2)	//4	used with moveto's
#define NMEFLAGS_USE_X_AXIS				(1<<3)	//8	used for circling

#define NMEFLAGS_USE_Y_AXIS				(1<<4)	//16	used for circling
#define NMEFLAGS_USE_Z_AXIS				(1<<5)	//32	used for circling
#define NMEFLAGS_SPECIFY_HAND			(1<<6)	//64	used for follow, flee, face
#define NMEFLAGS_SPECIFY_BALL			(1<<7)	//128	used for follow, flee, face
*/
/*
// ** N64 **   word 2 digits
#define NMEFLAGS_SPECIFY_CLOSEST		(1<<8)	//256	used for follow, flee, face
#define NMEFLAGS_DONT_CHANGE_ROT		(1<<9)	//512	used for circling
#define NMEFLAGS_ANTICLOCKWISE			(1<<10)	//1024	used to specify circling direction
#define NMEFLAGS_DONT_INTERUPT			(1<<11)	//2048	if a conditional instruction is al
lowed to happen
												//	act on it, but dont interupt normal instr list.
#define NMEFLAGS_DONT_FACE_DIR			(1<<12)	//4096	dont face in the direction of travel
#define NMEFLAGS_BANK					(1<<13)	//8192	allow enemy to bank when he turns
#define NMEFLAGS_DONTANIMATE			(1<<14) //16384 dont animate action

#define NMEFLAGS_NONEW					(1<<15) //32768 don't get a new action when done if condition still true - used for conditionals


*/

/*
// ** N64 **  above-word two digits
#define NMEFLAGS_ONLYATANIMSTART		(1<<16) //65536
#define NMEFLAGS_HOLDCOLLSPHERE			(1<<17) //131072
#define NMEFLAGS_RUN					(1<<18) //262144 use run animation
#define NMEFLAGS_NOMOVE					(1<<19) //524288 don't move in STARTMOVE animation

#define NMEFLAGS_FACEHAND				(1<<20) //1048576
#define NMEFLAGS_FACEBALL				(1<<21) //2097152
#define NMEFLAGS_FACECLOSEST			(1<<22)	//4194304
#define NMEFLAGS_LAND_ON_PLAYER			(1<<23) //8388608
*/

/*
// ** N64 ** wait flags
#define NMEFLAGS_SKID					(1<<0)	
#define NMEFLAGS_STOPMOVE				(1<<1)
#define NMEFLAGS_WAITFOREND				(1<<2) //queue the wait anim

// ** N64 ** special flags
#define ANIM_LOOP						(1<<0)	//1 loop animation
#define ANIM_QUEUE						(1<<1)	//2	queue animation
#define ANIM_KILLQ						(1<<2)	//4 kill anim queue
*/
//enemy action flags
//enum
/*
#define		ATTACK_BALL_IF_NEAR		(1 << 0)
#define 	ATTACK_HAND_IF_NEAR		(1 << 1)
#define 	ATTACK_NME_IF_NEAR		(1 << 2)
#define 	RETREAT_BALL_IF_NEAR	(1 << 3)
#define 	RETREAT_HAND_IF_NEAR	(1 << 4)
#define 	RETREAT_NME_IF_NEAR		(1 << 5)

#define 	DEFEND_BALL_IF_NEAR		(1 << 6)
#define 	DEFEND_HAND_IF_NEAR		(1 << 7)
#define 	DEFEND_NME_IF_NEAR		(1 << 8)

#define 	DROP_BALL_ON_ARRIVAL	(1 << 9)
#define 	DONT_PICK_UP_BALL		(1 << 10)

#define 	DONT_ATTACK				(1 << 11)

#define 	FACE_DIRECTION			(1 << 12)
#define 	FACE_POSITION			(1 << 13)

#define 	DONT_FACE_DIR			(1 << 14)
*/















#define NMEFLAG_VISIBLE 1
#define NMEFLAG_ACTIVE  2

#define NMEFLAG_STUNNED 4
#define NMEFLAG_FROGGED 8
#define NMEFLAG_DEAD    16
#define NMEFLAG_GARIB_DROPPED    32
// non-enabled enemies won't be spawned except by puzzles
// There's an assumption that if "enabled" is zero, "active" is also zero,
// Enabled	Active
//	0		0		Not onscreen, and won't respawn. The normal state for a puzzle-disabled bad guy till he's turned on
//	0		1		(Not a valid flagsettings)
//	1		0		Enemy will respawn, but has been splatted for the moment
//	1		1		Enemy is alive & kicking

#define NMEFLAG_ENABLED 64

// defines for nmes hitting glove 

//#define	GENERALWUATTACKRADIUS	30*4096
//#define	MALLETATTACKRADIUS		30*4096
#define BUGLE_SPHERE_RAD 30


#define NME_MAX_PATHVECTORS 40

// Enemy PathVector usage...
// 0 - Kirk bubble scales (created nme)
// 0,1 - Willy walking path
// 0,1 - Frank dynamically created path
// 0,1,2 - Spank (confine box, and a goto point)
// 0,1,2,3 - Evil Robot (3 positions & a fall-rotate)
// 0:- Robot Missiles midpoint (created nme)
// 0:- Robot Electrobolt midpoint (created nme)
// 0 - Robot Spiders droppoint (created nme)
// 0 - Boss fragment rotations
// 0,1 - pickups use it for the regen time & duration
// 0 - Teleport destination

// 0,1,2 - Any box-confined enemy: box plus current target
// 0,1,2 - And randommove enemy (including the hubcritters. denis, cluck, bovva, robes)

// 0,1,2,3,... moveto (or samtex faceto) points
// (2-point-only:- Mallet, Lionfish, Willy)



// This is rapidly turning into an "actor" type structure, and should probably be transferred/renamed as such
typedef struct tagENEMYPOS
{
// NB - assumption that this is the first one!
// (FindFreeNme zeroes from 4 upwards)

	struct tagENEMYPOS *next;

	SVECTOR init_pos;
	SHORT	init_ya;

//	USHORT num;  //set top bit of num if collected 
//	SHORT shadowheight;

// replace this with a "*4096" VECTOR
// (ummm, will stuff like homing in on the player be ok with 4096-scaled vecs?)
//	SHORT x,y,z;
	VECTOR pos;	// stored*4096
//	VECTOR smPos; // not stored *4096
	VECTOR vel;

	SHORT xa,ya,za;
	NEWMODEL *psa;

	SHORT type;
	SHORT flags;
	SHORT tag;	// for puzzles

	AnimType animinfo;
	ACTOR_ANIMATION anim;

	SHORT doing;	// position in instruction list (I'm thinking of hardcoding this rather than parsing)
	SHORT ticker;	// time left on this instruction

	char n_points;
	char stuntime;
//	VECTOR pathvectors[NME_MAX_PATHVECTORS];
	VECTOR *pathvectors;
	void *extras;	// eg - collision/physics pointer for those enemies that use it
}ENEMYPOS;

extern ENEMYPOS *nme_list;
extern ENEMYPOS *nme_list_tail;

/******************************************************************************/
// the segs we've got on the playstation appear to be in a different order, dude...
enum								
{									
	NMEANIM_IDLE,			//0
	NMEANIM_IDLE2,			//1

	NMEANIM_STARTMOVE,		//2
	NMEANIM_WALK,			//3
	NMEANIM_RUN,			//4
	NMEANIM_STOPMOVE,		//5

	NMEANIM_JUMP,			//6
	NMEANIM_LAND,			//7

	NMEANIM_STARTATTACK,	//8
	NMEANIM_ENDATTACK,		//9

	NMEANIM_ACTION1,		//10
	NMEANIM_ACTION2,		//11

	NMEANIM_HURT,			//12
	NMEANIM_DEATH,			//13
	NMEANIM_SPECIAL1,		//14
	NMEANIM_SPECIAL2,		//15
};									


//actor types

// Scripted list
//						"CAMERA","HAND","BALL","DEBRIS","BULLET", "SNEEZY","MOOCOW","BOVVA",
//						"CANNONBALL","SAMTEX","MALLET","GENERALWU","LIONFISH","CHESTER",
//						"KEG","REGGIE", "SWISH","KNIGHT", "ROBES", "FUMBLE", "MIKE",
//						"RAPTOR", "CRUMPET", "TRACEY","YOOFOW", "OPEC", "CYMON",
//						"SUCKER", "BUGLE", "DENIS", "CHUCK","HUBCHICKEN","FRANKIE",
//						"KLOSET","FLANNEL","SELWYN_WHALE","SELWYN_CRAB","SELWYN_FISH",
//						"ROBOT","EVIL_ROBOT","SPANK","BABY_SPANK","EVIL_GLOVE","DIBBER","FLY","SNAIL",
//						"BIGFISH","LITTLEFISH","LADYBIRD","WEEVIL","CATERPILLAR","BUTTERFLY",
//						"SPIDER","BAT","FROG","DRAGFLY","BOXTHING","BUG","NME_FROG","MR_TIP","*"};


enum
{
	CAMERA,				//0		(used as "free enemy" for bullets)
// In the N64 source, these are "HAND" and "BALL",
// but "ball" conflicted with something on the PSX. Luv, Fred
	BLANK_ENEMY,		//	non-spawning enemy to be filled in by the program on demand (eg - dynamically created pickups)
	ACTORTYPE_BALL,				//2      
	DEBRIS,				//3      
	BULLET,				//4      
	SNEEZY,				//5      
	MOOCOW,				//6 
	BOVVA,				//7      

	CANNONBALL,			//8      
	SAMTEX,				//9      
	MALLET,				//10     
	GENERALWU,			//11     
	LIONFISH,			//12     
	CHESTER,			//13     
	KEG,				//14     
	REGGIE,				//15     

	SWISH,				//16     
	KNIGHT,				//17     
	ROBES,				//18     
	FUMBLE,				//19     
	MIKE,				//20     
	RAPTOR,				//21     
	CRUMPET,			//22     
	TRACEY,				//23     

	YOOFOW,				//24     
	OPEC,				//25     
	CYMON,				//26     
	SUCKER,				//27     
	BUGLE,				//28     
	DENNIS,				//29     
	CHUCK,				//30     
	HUBCHICKEN,			//31

	FRANKIE,			//32
	KLOSET,				//33
	FLANNEL,			//34
	SELWYN_WHALE,		//35
	SELWYN_CRAB,		//36
	SELWYN_FISH,		//37
	ROBOT,				//38
	EVIL_ROBOT,			//39

	SPANK,				//40
	BABY_SPANK,			//41
	EVIL_GLOVE,			//42
	DIBBER,				//43
	FLY,				//44
	SNAIL,				//45
	BIGFISH,			//46
	LITTLEFISH,			//47

	LADYBIRD,			//48
	WEEVIL,				//49
	CATERPILLAR,		//50
	BUTTERFLY,			//51
	SPIDER,				//52
	BAT,				//53
	FROG,				//54
	DRAGFLY,			//55

	BOXTHING,			//56
	BUG,				// 57
	NME_FROG,			// 58
	PICKUP_ENEMY_MRTIP,	// 59



	PICKUP_ENEMY_STUN,
	PICKUP_ENEMY_DEATH,
	PICKUP_ENEMY_FROGGY,
	PICKUP_ENEMY_SUCTION,
	PICKUP_ENEMY_HERCULES,
	PICKUP_ENEMY_SPEEDUP,
	PICKUP_ENEMY_ROTORBLADES,
	PICKUP_ENEMY_BOWLINGBALL,
	PICKUP_ENEMY_POWERBALL,
	PICKUP_ENEMY_BALLBEARING,
	PICKUP_ENEMY_BEACHBALL,
	PICKUP_ENEMY_SNOWBALL,
	PICKUP_ENEMY_CRYSTALBALL,
	PICKUP_ENEMY_BOOMERANGBALL,
	PICKUP_ENEMY_VANISHBALL,

	PORTAL_ENEMY,
	HOOP_ENEMY,
	VENT_ENEMY,
	TELEPORT_ENEMY,
	BULLET_ENEMY_STING,
	BULLET_ENEMY_EGG,
	BULLET_ENEMY_FLAMES,
	BULLET_ENEMY_STEAM,
	BULLET_ENEMY_UFOZAP,
	BULLET_ENEMY_SPRAY,
	BULLET_ENEMY_CLAW,
	KIRK_BUBBLE1_ENEMY,
	KIRK_BUBBLE2_ENEMY,
	WILLY_FIREBALL_ENEMY,

	ROBOT_LARM_ENEMY,
	ROBOT_RARM_ENEMY,
	ROBOT_GUN_ENEMY,
	SPIDERBOMB,
	ROBOT_MISSILE,
	ROBOT_BOLT,
	ROBOT_FRAGMENT,

	CA_PIE,
	CA_GLOVE,
	CA_BOMB,
	CA_PIANO,

	CAMEO_ENEMY
};							    
	

// flags for the teleport platform/enemy token


// (FLAGS)%i{BALL-HAND-BALLANDHAND-BALLANDHANDJOINED-SWAPHANDBALL--}
//          {17-   18-     19-        24-                64--} Delays[(DISAPPEAR)%i (APPEAR)%i]
//          b+stop h+stop b+h+stop  +joined+stop        swap

#define TELEPORT_BALL			(1<<0)
#define TELEPORT_HAND			(1<<1)
#define TELEPORT_NME			(1<<2)
#define TELEPORT_JOINED			(1<<3)
#define TELEPORT_ZEROVEL		(1<<4)
#define TELEPORT_GOTOPLATFORM	(1<<5)
#define TELEPORT_SWAP			(1<<6)

typedef struct TELEPORTDEFSTR
{
	short flags;
	short platform_tag;
	short disappear_delay;
	short appear_delay;
	short x,dummy,y,dummy2,z,dummy3;
}TELEPORTDEFSTR;




//extern ENEMYPOS *enemies;
//extern ULONG numberofenemies;

//extern	ENEMYPOS *current_enemy;

void enemiesBeginFile();
void enemiesLoadShapes();

int enemiesParseTokenEnemy(short token,UBYTE **data);

void enemiesParseTokenTip(UBYTE **data);

void enemiesEndFile();

void enemiesFreeEnemies();
void enemiesFreeTempEnemies();

void enemiesAddExitPortal(int x, int y, int z, int tag);
void enemiesAddHoop(int x, int y, int z, int ya);
void enemiesAddTeleport(VECTOR *pos, TELEPORTDEFSTR *def, int tag);

// call when glover dies (and, indeed, post load)
void Spawn_Enemies(int again);
void Respawn_Enemies();
#define Respawn_Enemies() Spawn_Enemies(1);


void Update_Enemies();

void Draw_Enemies();

// Funtions for enemies hitting the glove (will also need to hit ball as well)

void	CheckGeneralHit(ENEMYPOS *nme);
void	CheckMalletHitGlove(ENEMYPOS *nme);
void	CheckMalletHitBall(ENEMYPOS *nme);


void nmeDismountDenis(ENEMYPOS *nme);
void nmeDismountSwish(ENEMYPOS *nme);

ENEMYPOS * nmeFindEnemyToShootAt();


void EnemyStun(ENEMYPOS *enemy);
void EnemyKill(ENEMYPOS *enemy);
void EnemyFroggify(ENEMYPOS *enemy);

void CheckForNmeHitsBlast(VECTOR *pos, int radius, int height);

extern VECTOR nmeGlovePushVector;
extern VECTOR nmeBallPushVector;

extern int numberofhoops;
extern int lasthoopused;
extern char ball_at_hoop;


// nextprev = 0 to find the 1st that's available, +/- 1 to find the next in that dirn from "hoop_number"
int nextHoopAvailable(int hoop_number, int nextprev);
void Use_Hoop(int hoop_number);



// the enemy structure stores
// pos, tag
typedef struct VENTHEADER
{
	short n_patterns;
	short tag;
	short plat_tag;
	short type;
	VECTOR pos;
	VECTOR vel;
//
//	DYNCOLLBOX *platform;	// filled in post-load from "plat_tag"
	struct tagDYNCOLLBOX *platform;
}VENTHEADER;
typedef struct VENTPATTERN
{
	short delay;
	short duration;
}VENTPATTERN;

typedef struct VENT
{
	VENTHEADER head;
	VENTPATTERN pat[1];
}VENT;

void enemiesAddVent(VENT *vent);

extern SPRITEX  *tracy_heart_sprite;

extern char cheat_any_ball_powerwhacks;






typedef void NME_UPDATEROU(ENEMYPOS *enemy);

typedef void NME_INTERACTROU(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);

void FeebleRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void HarmlessRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void PushableRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void SplatRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void HardBastRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);

void DenisTintRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void DenisBintRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void SwishIntRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void SwordIntRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void BovIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void CluckIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void OpecIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void FumbIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);

void PortIntRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void HoopIntRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void TeleIntRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);
void StingIntRou(int with, ENEMYPOS *nme, VECTOR *dpos, int sphererad);
void FBallIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void UZapIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void EggIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void TipIntRou(int with, ENEMYPOS *enemy, VECTOR *dpos, int sphererad);

void BugleIntRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad);

void VeryPushableRou(int with, ENEMYPOS *nme, VECTOR *dvec, int sphererad, int amount);

ULONG	NMEPushesBall(ENEMYPOS *nme, VECTOR *dvec, int sphererad);
ULONG	NMEShovesBall(ENEMYPOS *nme, VECTOR *dvec, int sphererad, int amount);
void NMEHurtsGlove(ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void NMEPushesGlove(ENEMYPOS *nme, VECTOR *dvec, int sphererad);
void NMEHurtsGloveDirect();

void GetPointingAngles(VECTOR *us, VECTOR *targ, int *xa, int *ya);

void enemy_ShootFlames(VECTOR *org, VECTOR *vel, int type);
void enemy_ShootUfoZap(VECTOR *org, VECTOR *vel, int type);
void ForceExplosion(VECTOR *vec, int rad, int power);

ENEMYPOS * enemy_FindFreeEnemy();

// Call here AFTER (or during) parselandscapefile
//create a single enemy at load time (but keeps it's "active" flag set to zero)
// set type to "BLANK_ENEMY" if it's to be a spawning type of enemy that you don't want spawned (eg - spells)
ENEMYPOS *enemies_ReserveEnemy(int type);

// note - type = "SPELL_", which is internally converted to a "PICKUP_ENEMY_"
void enemyCreatePickup(ENEMYPOS *nme, int type, VECTOR *pos, int regen, int duration);


typedef struct NME_SPHERE
{
	struct NME_SPHERE *next;
	NME_INTERACTROU *interact;
	VECTOR pos;
	int r;
	int seg;
}NME_SPHERE;

typedef struct ENEMYBEHAVIOUR
{
	char *fname;
	SHORT scale;

	int radius;	// visibility radius taken from the object's position. May be considerably larger than the object
	int hag;	// height-above-ground correction
	int visdist;

	signed char n_paths;	// -1 for variable, 0 up for number required at create time. 4 for any unknowns
	short flags;

	NME_SPHERE *spheres;
	NME_INTERACTROU *interact;
	NME_UPDATEROU *update;
}ENEMYBEHAVIOUR;


typedef struct NMEAccelStr
{
	LONG acceleration;
	LONG maxspeed;
	SHORT turnrate;
	LONG dsquared;
}NMEAccelStr;

extern ENEMYBEHAVIOUR nmeinfo[];

// velue subtracted from an enemies Y position when finding ground height
#define NME_H_FRIG (4096 * 50)

int IsBallShield(VECTOR *dvec);	// dvec = hand-nmesphere
int NMECheckInRange(ENEMYPOS *enemy, VECTOR *vec,LONG range, int boxed_enemy);
int NMECheckInRange2D(ENEMYPOS *enemy, VECTOR *vec,LONG range, int boxed_enemy);
int NME_FaceTo(ENEMYPOS *enemy, VECTOR *target, SHORT rate);
void NME_GoForwards(ENEMYPOS *enemy, int speed);
BOOL NME_AccelTo3D(ENEMYPOS *enemy, VECTOR *dest,const NMEAccelStr *accel);
int NME_GoTo2D(ENEMYPOS *enemy, VECTOR *target, int speed);
int NME_GoTo3D(ENEMYPOS *enemy, VECTOR *target, int speed);
void EnemyRotatePoint(ENEMYPOS *enemy,VECTOR *in, VECTOR *out, int segment);
int NMECheckVisible(ENEMYPOS *enemy, VECTOR *vec, LONG range, SHORT angrange);
void NMEChooseRandomPoint(ENEMYPOS *enemy, int in2d);
void NME_KeepInBox(ENEMYPOS *enemy);

int teleportTrigger(int which,VECTOR *dest,int flags,int diss,int app, int ya);


#define NME_GoTo2D(enemy, target, speed) VectorMoveTo2D((&(enemy)->pos), (target), (speed))
#define NME_GoTo3D(enemy, target, speed) VectorMoveTo((&(enemy)->pos), (target), (speed))


void	CheckForNmeHitsGlove(void);
void	CheckForNmeHitsBall(void);
void	CheckForNmeHitsSphere(VECTOR *pos, int radius, int id);


extern BEHAVIOUR_PHYSICS	EnemyHeavyPhysics;
extern BEHAVIOUR_PHYSICS	EnemyDefaultPhysics;

// the enemy is expected to add gravity to it's yvel, and add yvel to ypos itself
int enemy_UsePhysics(ENEMYPOS *nme, BEHAVIOUR_PHYSICS *physics, VECTOR *oldpos, int radius);

void StunDebris(VECTOR *refpos, int h, int rad);

// Set to 2 when bugle/cluck/cymon/babyspank has the ball, and decreased when non zero
extern int enemy_has_ball;

void NextLevelBasics();

extern VECTOR caveballpos;

extern SPRITEX *SPR_mrtipbase;

void Update_NMEFrog(ENEMYPOS *nme);
extern  struct tagLOADEDMODEL *babySpankModel;

extern ENEMYPOS *ca_pickup_nme[2];

void enemyDimTip(int number);
int MrTipDimmed(int number);

#endif
