/*
   Copyright (C) 1997-2001 Id Software, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

   See the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   --------------------------------------------------------------
   The ACE Bot is a product of Steve Yeager, and is available from
   the ACE Bot homepage, at http://www.axionfx.com/ace.

   This program is a modification of the ACE Bot, and is therefore
   in NO WAY supported by Steve Yeager.
 */

//	local to acebot files
//==========================================================

#include "ai_nodes_local.h"
#include "ai_weapons.h"
#include "../g_gametypes.h"


#define AI_VERSION_STRING "A0058"

//bot debug_chase options
extern cvar_t *bot_showpath;
extern cvar_t *bot_showcombat;
extern cvar_t *bot_showsrgoal;
extern cvar_t *bot_showlrgoal;
extern cvar_t *bot_debugmonster;
extern cvar_t *bot_dummy;

//----------------------------------------------------------

#define MAX_BOTS 64
#define AI_GOAL_SR_RADIUS	150
#define AI_DEFAULT_YAW_SPEED	650
#define AI_WATERJUMP_HEIGHT	24
#define AI_REACTION_TIME	((self->ai.pers.skillLevel < 0.33f) ? 1500 : ((self->ai.pers.skillLevel < 0.66f) ? 500 : 250 ))
#define AI_COMBATMOVE_TIMEOUT	((self->ai.pers.skillLevel < 0.33f) ? 800 : ((self->ai.pers.skillLevel < 0.66f) ? 500 : 300 ))
#define AI_NODE_TOUCH_RADIUS	75
#define AI_MOVE_ACCEL		50*FRAMETIME
#define AI_TIMEDITEM_CAMPTIME	5000

// Platform states:
#define	STATE_TOP	    0
#define	STATE_BOTTOM	    1
#define STATE_UP	    2
#define STATE_DOWN	    3

// Bot state types
#define BOT_STATE_STAND		0
#define BOT_STATE_MOVE		1
#define BOT_STATE_WANDER	2
#define BOT_STATE_ATTACK	3
#define BOT_STATE_DEFEND	4


#define BOT_MOVE_LEFT		0
#define BOT_MOVE_RIGHT		1
#define BOT_MOVE_FORWARD	2
#define BOT_MOVE_BACK		3


//acebot_items.c players table
//----------------------------------------------------------
int num_AIEnemies;
edict_t *AIEnemies[MAX_EDICTS];     // pointers to all players in the game


//Debug & creating and linking nodes
//----------------------------------------------------------
typedef struct
{

	qboolean debugMode;

	qboolean showPLinks;
	edict_t	*plinkguy;

	qboolean debugChased;
	edict_t	*chaseguy;

} ai_devel_t;
ai_devel_t AIDevel;



//----------------------------------------------------------

//game
//----------------------------------------------------------
void	    Use_Plat( edict_t *ent, edict_t *other, edict_t *activator );


// ai_main.c
//----------------------------------------------------------
void	    AI_Think( edict_t *ent );
void	    AI_PickLongRangeGoal( edict_t *ent );
void	    AI_Frame( edict_t *self, usercmd_t *ucmd );
void	    AI_SetUpMoveWander( edict_t *ent );
void	    AI_ResetNavigation( edict_t *ent );
void	    AI_ResetWeights( edict_t *ent );
void	    AI_CategorizePosition( edict_t *ent );


// ai_items.c
//----------------------------------------------------------
float	    AI_ItemWeight( edict_t *ent, edict_t *item );
qboolean    AI_ItemIsReachable( edict_t *self, vec3_t goal );


// ai_movement.c
//----------------------------------------------------------
int	AI_ChangeAngle( edict_t *ent );
qboolean    AI_MoveToGoalEntity( edict_t *self, usercmd_t *ucmd );
qboolean    AI_SpecialMove( edict_t *self, usercmd_t *ucmd );
qboolean    AI_CanMove( edict_t *self, int direction );
qboolean    AI_IsLadder( vec3_t origin, vec3_t v_angle, vec3_t mins, vec3_t maxs, edict_t *passent );
qboolean    AI_IsStep( edict_t *ent );
//qboolean	AI_IsLadder(vec3_t origin, vec3_t v_angle, vec3_t mins, vec3_t maxs, edict_t *passent);


// ai_navigation.c
//----------------------------------------------------------
int	    AI_FindCost( int from, int to, int movetypes );
int	    AI_FindClosestReachableNode( vec3_t origin, edict_t *passent, int range, int flagsmask );
int	    AI_FindClosestNode( vec3_t origin, float mindist, int range, int flagsmask );
void	    AI_SetGoal( edict_t *self, int goal_node );
qboolean    AI_FollowPath( edict_t *self );
qboolean    AI_IsTimedItem( edict_t *item );


// ai_nodes.c
//----------------------------------------------------------
qboolean    AI_DropNodeOriginToFloor( vec3_t origin, edict_t *passent );
void	    AI_InitNavigationData( void );
int	    AI_FlagsForNode( vec3_t origin, edict_t *passent );
qboolean    AI_LoadPLKFile( char *mapname );
void AI_DeleteNode( int node );


// ai_tools.c
//----------------------------------------------------------
void	    AIDebug_SetChased( edict_t *ent );
void	    AITools_DrawPath( edict_t *self, int node_to );
void	    AITools_DrawLine( vec3_t origin, vec3_t dest );
void	    AITools_DrawColorLine( vec3_t origin, vec3_t dest, int color, int parm );
void	    AITools_InitEditnodes( void );
void	    AITools_InitMakenodes( void );
void	    AITools_SaveNodes( void );

// ai_links.c
//----------------------------------------------------------
qboolean    AI_VisibleOrigins( vec3_t spot1, vec3_t spot2 );
int	    AI_LinkCloseNodes( void );
int	    AI_FindLinkType( int n1, int n2 );
qboolean    AI_AddLink( int n1, int n2, int linkType );
qboolean    AI_PlinkExists( int n1, int n2 );
int	    AI_PlinkMoveType( int n1, int n2 );
int	    AI_findNodeInRadius( int from, vec3_t org, float rad, qboolean ignoreHeight );
char *AI_LinkString( int linktype );
int	    AI_GravityBoxToLink( int n1, int n2 );
int	    AI_LinkCloseNodes_JumpPass( int start );

//bot_status.c
//----------------------------------------------------------
qboolean    AI_CanPick_Ammo( edict_t *ent, gitem_t *item );
qboolean    AI_CanUseArmor( gitem_t *item, edict_t *other );
void	    AI_BotRoamFinishTimeouts( edict_t *self );


//bot_classes
//----------------------------------------------------------
void	    BOT_DMclass_InitPersistant( edict_t *self );
qboolean    BOT_ChangeWeapon( edict_t *ent, gitem_t *item );
void	    M_default_Spawn( void );

//ai_weapons.c
//----------------------------------------------------------
void	    AI_InitAIWeapons( void );

//ai_common.c
//----------------------------------------------------------
qboolean    AI_visible( edict_t *self, edict_t *other );
qboolean    AI_infront( edict_t *self, edict_t *other );
void	    AI_NewEnemyInView( edict_t *self, edict_t *enemy );

//ai_npc_phys.c
//----------------------------------------------------------
void M_Phys_Momentum_AddPush( vec3_t accel, vec3_t pushdir, float push, float mass, float timestep );
void M_Phys_Momentum_AddFriction( float classfriction, float class_stopspeed, vec3_t origin, vec3_t vel, float timestep, vec3_t mins, vec3_t maxs, edict_t *passent, int solidmask );

//ai_class_dmbot.c
//----------------------------------------------------------
void BOT_DMclass_FindEnemy( edict_t *self );
void BOT_DMclass_CombatMovement( edict_t *self, usercmd_t *ucmd );
void BOT_DMclass_Wander( edict_t *self, usercmd_t *ucmd );
void BOT_DMclass_Move( edict_t *self, usercmd_t *ucmd );
