/*
   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.
 */

#include "../g_local.h"
#include "ai_local.h"

//ACE

//==========================================
// AI_EnemyAdded
// Add the Player to our list
//==========================================
void AI_EnemyAdded( edict_t *ent )
{
	if( num_AIEnemies < MAX_EDICTS )
		AIEnemies[num_AIEnemies++] = ent;
}

//==========================================
// AI_EnemyRemoved
// Remove the Player from list
//==========================================
void AI_EnemyRemoved( edict_t *ent )
{
	int i;
	int pos = -1;

	// watch for 0 players
	if( num_AIEnemies < 1 )
		return;


	// special case for only one player
	if( num_AIEnemies == 1 )
	{
		num_AIEnemies = 0;
		return;
	}

	// Find the player
	for( i = 0; i < num_AIEnemies; i++ )
	{
		if( ent == AIEnemies[i] )
			pos = i;
	}

	if( pos == -1 )
		return;

	// decrement
	for( i = pos; i < num_AIEnemies-1; i++ )
		AIEnemies[i] = AIEnemies[i+1];

	num_AIEnemies--;
}

//==========================================
// AI_CanUseArmor
// Check if we can use the armor
//==========================================
qboolean AI_CanUseArmor( gitem_t *item, edict_t *other )
{
	edict_t	it_ent;
	if( !item )
		return qfalse;
	if( item->tag < ARMOR_GA || item->tag >= ARMOR_TOTAL )
		return qfalse;

	it_ent.item = item;
	return Add_Armor( &it_ent, other, qfalse );
}


//==========================================
// AI_CanPick_Ammo
// Check if we can use the Ammo
//==========================================
qboolean AI_CanPick_Ammo( edict_t *ent, gitem_t *item )
{
	int count;
	qboolean weapon;

	if( !ent->r.client )
		return qfalse;

	weapon = ( item->type & IT_WEAPON );
	if( ( weapon ) && ( dmflags->integer & DF_INFINITE_AMMO ) )
		count = 1000;
	//jalfixme: we are ignoring the ent->count here, and we shouldn't
	//else if (ent->count)
	//	count = ent->count;
	else
		count = item->quantity;

	return Add_Ammo( ent, item, count, qfalse );
}

//==========================================
// AI_ItemIsReachable
// Can we get there? Jalfixme: this needs better checks a lot
//==========================================
qboolean AI_ItemIsReachable( edict_t *self, vec3_t goal )
{
	trace_t trace;
	vec3_t v;

	VectorCopy( self->r.mins, v );
	v[2] += AI_STEPSIZE;

	G_Trace( &trace, self->s.origin, v, self->r.maxs, goal, self, MASK_NODESOLID );
	//trace = gi.trace ( self->s.origin, v, self->maxs, goal, self, MASK_NODESOLID );

	// Yes we can see it
	if( trace.fraction == 1.0 )
		return qtrue;
	else
		return qfalse;
}


//==========================================
// AI_ItemWeight
// Find out item weight
//==========================================
float AI_ItemWeight( edict_t *self, edict_t *it )
{
	float weight;

	if( !self->r.client )
		return 0;

	if( !it->item )
		return 0;

	//IT_WEAPON
	if( it->item->type & IT_WEAPON )
	{
		return self->ai.status.inventoryWeights[it->item->tag];
	}

	//IT_AMMO
	if( it->item->type & IT_AMMO )
	{
		return self->ai.status.inventoryWeights[it->item->tag];
	}

	//IT_ARMOR
	if( it->item->type & IT_ARMOR )
	{
		return self->ai.status.inventoryWeights[it->item->tag];
	}

	//IT_FLAG
	if( it->item->type & IT_FLAG )
	{
		return self->ai.status.inventoryWeights[it->item->tag];
	}

	//IT_HEALTH
	if( it->item->type & IT_HEALTH )
	{
		//CanPickup_Health
		if( !( it->style & 1 ) )
		{       //#define HEALTH_IGNORE_MAX	1
			if( HEALTH_TO_INT( self->health ) >= self->max_health )
				return 0;
		}
		if( self->health >= 250 && it->count > 25 )
			return 0;

		//find the weight
		weight = 0;
		if( self->health <= 250 && it->item->tag == HEALTH_MEGA )
		{
			weight = self->ai.status.inventoryWeights[HEALTH_MEGA];
			if( weight == 0.0f )
				return weight;
		}
		else if( self->health < 100 )
		{
			weight = ( ( 100 - self->health ) + it->count )*0.01;
			if( weight < 0.2f )
				weight = 0.2f;
		}

		weight += ( self->health < 35 ); //we just NEED IT!!!


		return weight;
	}

	//IT_POWERUP
	if( it->item->type & IT_POWERUP )
	{
		return self->ai.status.inventoryWeights[it->item->tag];
	}

	/*if( it->item->type & IT_CAPTURE_AREA )
	   {
	    return it->s.team == self->s.team ? 0.0 : self->ai.status.inventoryWeights[it->item->tag];
	   }*/

	//newgametypes[start]
	//IT_TECH
	//if (it->item->flags & IT_TECH)
	//{
	//	return self->ai.status.inventoryWeights[it->item->tag];
	//}//newgametypes[end]

	//item didn't have a recognizable item flag
	if( AIDevel.debugMode )
		G_PrintMsg( NULL, "(AI_ItemWeight) WARNING: Item with unhandled item flag:%s\n", it->classname );

	return 0;
}


//==========================================
//QUAKED item_botroam
//==========================================
void SP_item_botroam( edict_t *ent )
{
	float weight;

	//try to convert Q3 weights (doh)
	if( st.weight )
	{
		weight = st.weight;

		// item_botroam weights should go between 0 and 100.
		// to convert odd weights to this format:
		if( weight >= 1000 )
			weight = 100;
		else if( weight >= 100 )  //include 100, cause some q3 mappers use 100, 200, 300... etc
			weight *= 0.1f;
	}
	else
		weight = 30.0f; //default value

	ent->count = (int)weight;
}
