//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#include "cbase.h"
#include "hl2wars/npc/hlw_npc_stalker.h"
#include "ai_senses.h"

#include "hl2wars/util_hl2wars.h"
#include "hl2wars/rts_point_order.h"
#include "hl2wars/rts_globalresource.h"
#include "hl2wars/rts_basebuilding.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

LINK_ENTITY_TO_CLASS( hlw_npc_stalker, CHLW_NPC_Stalker );

#define	MAX_STALKER_FIRE_RANGE		1024 // 3600 feet.

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

BEGIN_DATADESC( CHLW_NPC_Stalker )

END_DATADESC()

//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CHLW_NPC_Stalker::Spawn( void )
{
	Precache( );

	SetModel( "models/stalker.mdl" );
	SetHullType(HULL_HUMAN);
	SetHullSizeNormal();

	SetSolid( SOLID_BBOX );
	AddSolidFlags( FSOLID_NOT_STANDABLE );
	SetMoveType( MOVETYPE_STEP );
	m_bloodColor		= DONT_BLEED;
	m_flFieldOfView		= 0.1;// indicates the width of this NPC's forward view cone ( as a dotproduct result )
	m_NPCState			= NPC_STATE_NONE;
	CapabilitiesAdd( bits_CAP_SQUAD | bits_CAP_MOVE_GROUND );
	CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1);
	CapabilitiesAdd( bits_CAP_NO_HIT_PLAYER | bits_CAP_NO_HIT_SQUADMATES | bits_CAP_FRIENDLY_DMG_IMMUNE );

	m_flNextAttackSoundTime		= 0;
	m_flNextBreatheSoundTime	= gpGlobals->curtime + random->RandomFloat( 0.0, 10.0 );
	m_flNextScrambleSoundTime	= 0;
	m_nextSmokeTime = 0;
	m_bPlayingHitWall			= false;
	m_bPlayingHitFlesh			= false;

	m_fBeamEndTime				= 0;
	m_fBeamRechargeTime			= 0;
	m_fNextDamageTime			= 0;

	NPCInit();

	m_flDistTooFar	= MAX_STALKER_FIRE_RANGE;

	m_iPlayerAggression = 0;

	GetSenses()->SetDistLook(MAX_STALKER_FIRE_RANGE - 1);
}

//=========================================================
// start task
//=========================================================
void CHLW_NPC_Stalker::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_STALKER_PLACE_BUILDING:
		{
			FileUnitInfo_t *pFUI = GetFileUnitInfoFromHandle( LookupUnitInfoSlot( STRING(GetUnitType() ) ) );
			if( !pFUI )
			{
				TaskFail(NO_TASK_FAILURE);
				break;
			}

			if( !AbilityTakeResources() )
			{
				TaskFail(NO_TASK_FAILURE);
				break;
			}

			// can we do this ability? ( ain't it recharging?)
			if( !CanDoAbility( m_iActiveAbilityButton ) )
			{
				TaskFail(NO_TASK_FAILURE);
				return;
			}

			CBaseBuildingModel *pBuilding = dynamic_cast<CBaseBuildingModel *>(GetCurrentOrder()->GetTarget());
			if( !pBuilding )
			{
				AbilityFailed();
				TaskFail(NO_TASK_FAILURE);
				break;
			}

			pBuilding->SetConstructionState(BS_UNDERCONSTRUCTION);

			AbilityCompleted();

			TaskComplete();

			break;
		}
	default: 
		BaseClass:: StartTask( pTask );
		break;
	}
}

//-----------------------------------------------------------------------------
// Purpose:
// Input  :
// Output :
//-----------------------------------------------------------------------------
int CHLW_NPC_Stalker::SelectSchedule( void )
{
	// First, check abilities
	if( GetCurrentOrder() )
	{
		if( GetCurrentOrder()->GetOrderType() == ORDER_DO_ABILITY && GetCurrentOrder()->GetAbility() != ABILITY_NONE )
		{
			if( !HasCondition(COND_CAN_DO_ABILITY) ) 
			{
				if( HasCondition(COND_TOO_FAR_FOR_ABILITY) )
				{
					return SCHED_MOVE_TO_ABILITY_RANGE;
				}
				else if( HasCondition(COND_TOO_CLOSE_FOR_ABILITY) )
				{
					return SCHED_STANDOFF_ABILITY_RANGE;
				}
			}

			m_iActiveAbilityButton = GetCurrentOrder()->GetAbilityButton();
			
			if( GetCurrentOrder()->GetAbility() == ABILITY_BUILDING)
			{
				return SCHED_STALKER_PLACE_BUILDING;
			}
		}
	}

	// no special cases here, call the base class
	return CAI_BaseStalker::SelectSchedule();
}

//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
CHLW_NPC_Stalker::CHLW_NPC_Stalker(void)
{

}

//-----------------------------------------------------------------------------
// Purpose: Hack to make the stalker move faster for gameplay purpose
//-----------------------------------------------------------------------------
float CHLW_NPC_Stalker::GetIdealSpeed() const
{
	//float baseSpeed = BaseClass::GetIdealSpeed();

	return 90.0f;
}

//-----------------------------------------------------------------------------
// Purpose: Our unit type depends on our weapons and flags
//-----------------------------------------------------------------------------
void CHLW_NPC_Stalker::InitUnitIndex()
{
	const char *m_sUnitType = "UNIT_STALKER";
	m_iUnitIndex = g_pRTSResource->GetUnitIndex( m_sUnitType );
}

//------------------------------------------------------------------------------
//
// Schedules
//
//------------------------------------------------------------------------------

AI_BEGIN_CUSTOM_NPC( hlw_npc_stalker, CHLW_NPC_Stalker )

	DECLARE_TASK(TASK_STALKER_PLACE_BUILDING)

	//=========================================================
	// > 
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_STALKER_PLACE_BUILDING,

		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_STALKER_PLACE_BUILDING	0"
		""
		"	Interrupts"
	)

AI_END_CUSTOM_NPC()
