/*

  [BC] b_bot.h
  Last updated: 10/4/2000

  The bot class, prototypes and definitions be here!

*/

#ifndef __B_BOT_H__
#define __B_BOT_H__

#include "c_cvars.h"
#include "m_argv.h"
#include "tables.h"
#include "info.h"
#include "doomdef.h"
#include "d_ticcmd.h"
#include "r_defs.h"
#include "d_player.h"
#include "b_info.h"
#include "t_info.h"

#define FORWARDWALK		0x1900
#define FORWARDRUN		0x3200
#define SIDEWALK		0x1800
#define SIDERUN			0x2800

#define MAX_TRAVERSE_DIST			(1024*FRACUNIT)	//10 meters, used within b_func.c
#define AVOID_DIST					(512*FRACUNIT)	//Try avoid incoming missiles once they reached this close
#define SAFE_SELF_MISDIST			(128*FRACUNIT)	//Distance from self to target where it's safe to pull a rocket.
#define FRIEND_DIST					(128*FRACUNIT)	//To friend.
#define DARK_DIST					(256*FRACUNIT)	//Distance that bot can see enemies in the dark from.
#define WHATS_DARK					64				//light value thats classed as dark.
#define MAX_MONSTER_TARGET_DIST		(1024*FRACUNIT)	//Too high can slow down the performance, see P_mobj.c
#define ENEMY_SCAN_FOV				(120*ANGLE_1)
#define MAXMOVEHEIGHT				(32*FRACUNIT)	//MAXSTEPMOVE but with jumping counted in.
#define GETINCOMBAT					(512*FRACUNIT)	//Max distance to item. if it's due to be icked up in a combat situation.
#define SHOOTFOV					(60*ANGLE_1)
#define MAXROAM						(5*TICRATE)		//When this time is elapsed the bot will roam after something else.

class pos_t;
class skullb_s;
class player_s;
class teaminfo_s;

// Bot function prototypes
void B_AddBot (int bnum, char *info, char *team);
bool B_Spawn (char *name, char *team);
void B_Roam (skullb_s *bot);
BOOL B_CheckPath (AActor *mo, angle_t ang, int dist);
void B_Pitch (skullb_s *bot);
bool IsDangerous (sector_t *sec);
void ClearPlayer (int playernum);
bool Check_LOS (AActor *mobj1, AActor *mobj2, angle_t vangle);
void B_Main (skullb_s *bot);
void B_Think (skullb_s *bot);
AActor *B_SetAlly (skullb_s *bot);
AActor *B_FindEnemy (skullb_s *bot);
void B_SetEnemy (skullb_s *bot);
void B_SetGoal (skullb_s *bot);
void B_SetAction (skullb_s *bot);
void B_Scan (skullb_s *bot);
void B_Move (skullb_s *bot);
void B_Aim (skullb_s *bot);
void B_Attack (skullb_s *bot);
void B_Turn (skullb_s *bot);
void ActorToPos (AActor *mo, pos_t *pos);
bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y);
BOOL B_CheckItem (AActor *actor, AActor *item);
BOOL B_CheckName (char *name);
void B_CheckStuff (skullb_s *bot);
weapontype_t B_WeapFromItem (AActor *item);
ammotype_t B_AmmoFromItem (AActor *item);
void B_Remove (char *name);
void B_RemoveBots (void);
bool B_Chat (skullb_s *bot);
bool B_CheckTo (skullb_s *bot, pos_t *pos);

class pos_t
{
public:

	pos_t ();
	~pos_t ();

	fixed_t	x;
	fixed_t	y;
	fixed_t	z;
};

FArchive &operator<< (FArchive &arc, pos_t *pos);
FArchive &operator>> (FArchive &arc, pos_t *pos);

// For skirmish games
typedef struct
{
	char	*name;
	char	*team;
	int		tics;
} botspawn_t;

extern botspawn_t botspawn[MAXPLAYERS];

// The things the bot knows about their enemy
typedef struct
{
	int				health;
	weapontype_t	weap;
} enemyinfo_t;

//
// Bot states
//
typedef enum
{
	// Deciding what to do
	BST_NOTHING,
	// Bot is "fetching" something (skull, whatever)
	BST_OFFENSE,
	// Bot is defending something
	BST_DEFENSE,
	// Bot is heading to scoring place
	BST_RETURN
} botstate_t;

// Main bot class
class skullb_s
{
public:

	void Serialize (FArchive &arc);

	skullb_s (char *name);	// Constructor
	~skullb_s ();			// Destructor

	void LinkToPlayer (int playernum);
	void SetAngle (angle_t an);
	angle_t GetAngle ();

	player_s	*player;	// Points to reference player

	// Destinations
	AActor		*item;		// Item (roam towards weapon, etc)
	AActor		*goal;		// Teamgame goal spot
	line_t		*line;		// Line destination
	AActor		*node;		// Node we're heading towards
	AActor		*prev;		// Previous node we were at
	pos_t		*posdest;	// Position of our destination (doesn't have to be an actor)
	AActor		*enemy;		// The dead meat.
	pos_t		*lastpos;	// Last place we saw our enemy
	AActor		*missile;	// A threathing missile that got to be avoided.

	AActor		*ally;		// Ally to tag along with
	AActor		*last_mate;	// If bots mate dissapeared (not if died) that mate is
							// pointed to by this. Allows bot to roam to it if
							// necessary.

	enemyinfo_t	enemyinfo;	// Things we know about our enemy

	botstate_t	state;		// What we're doing in teamgame mode

	fixed_t		lastx;		// Last known x location of bot's enemy (go there if enemy goes out of sight)
	fixed_t		lasty;		// Last known y location of bot's enemy

	// Tickers

	int			t_respawn;
	int			t_strafe;
	int			t_react;
	int			t_fight;
	int			t_rocket;
	int			t_turn;
	int			t_pissed;
	int			t_frust;
	int			t_fire;		// Tics left until our gun will actually fire again
	int			t_anticip;	
	int			t_chat;		// Tics left until bots completes "typing" in what he's saying.
							// Bot also doesn't do anything during this time.

	short		forwardmove;	// For building ucmd
	short		sidemove;

	// Misc booleans
	bool		allround;


	chatline_t	*chatline;	// For when t_chat expires

	bottype_t	bottype;	// Bot type
	botinfo_t	info;		// Aiming, name, perfection, yadda yadda

	fixed_t		oldx;
	fixed_t		oldy;

	int			thingnum;
	int			angerlevel;

	AActor		*things[NUMMOBJTYPES];
	fixed_t		combatdist[NUMWEAPONS+1]; //different for each weapon.

private:
	angle_t		angle;		// The wanted angle that the bot tries to get every tic.
};
typedef skullb_s skullb_t;

FArchive &operator<< (FArchive &arc, skullb_s *bot);
FArchive &operator>> (FArchive &arc, skullb_s *bot);

#endif	// __B_BOT_H__