//=============================================================================
// KFAIPluginRage_Fleshpound
//=============================================================================
// AICommand executing while Fleshpound is enraged
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFAIPluginRage_Fleshpound extends AITickablePlugin
	within KFAIController_ZedFleshpound
	native(AI)
	config(AI);

`include(KFGame\KFGameAnalytics.uci);

var vector	StartLocation;

/** Track damage taken over the past AccumulatedDOTDuration seconds */
var int				AccumulatedDOT;
/**	The time when we found an enemy */
var float			RageFrustrationStartTime;
/**	The max time we can stay in rage mode*/
var float	MaxEnemyNotVisibleRageTime;
/**	The base time to wait before becoming frustrated and raging anyways */
var float	RageFrustrationBaseTime;
/** The (randomized) final time to wait before becoming frustrated */
var float 	RageFrustrationTime;
/**	The amount of damage we need to accumulate before entering rage */
var float	RageDamageThreshold;

var bool bIsEnraged;

/** Ticked to determine when we should start and end rage mode */
event TickRage()
{
	if( bIsEnraged && !bEnemyIsVisible && `TimeSince(LastEnemySightedTime) > MaxEnemyNotVisibleRageTime )
	{
		EndRage();
	}
	else if( CanDoRage() )
	{
		AIActionStatus = "Enraged!";
		GotoState( 'Enraged' );
	}
}

function DoSpawnRage()
{
	AIActionStatus = "Enraged!";
	GotoState( 'Enraged' );
}

/** Checks if it's possible to enter rage */
function bool CanDoRage()
{
	if( bIsEnraged || !MyKFPawn.IsCombatCapable() )
	{
		return false;
	}

	// If it's been longer than RageFrustrationTime since we've had an enemy, rage anyways
	if( Enemy != none && RageFrustrationStartTime > 0 && `TimeSince(RageFrustrationStartTime) > RageFrustrationTime )
	{
		return true;
	}

	// If we've taken more than the RageDamageThreshold in damage, begin rage
	if( AccumulatedDOT >= RageDamageThreshold )
	{
		return true;
	}

	return false;
}

/** Begins the timer until the FleshPound can rage */
function StartRageTimer(optional bool bJustSawEnemy)
{
	// Already raging!
	if( bIsEnraged )
	{
		return;		
	}

	RageFrustrationStartTime = WorldInfo.TimeSeconds;
	SetRageTime();

	// If the FP hasn't seen its enemy for a long time, rage (almost) immediately
	if( bJustSawEnemy && `TimeSince(LastEnemySightedTime) > MaxEnemyNotVisibleRageTime )
	{
		RageFrustrationStartTime += RageFrustrationTime - 0.5f;
	}
}

/** Sets our rage timer (RageFrustrationBaseTime + RandRange(1,5)) */
function SetRageTime()
{
	RageFrustrationTime = RageFrustrationBaseTime + RandRange(1.f,5.f);
}

/** Leave Rage Mode */
function EndRage()
{
	// Any time we end call end rage, we are no longer frustrated
	if( bIsEnraged )
	{
		GotoState( InitialState );	
		StartRageTimer();
	}
}

/*********************************************************************************************
* Enraged state
********************************************************************************************* */

state Enraged
{
	function BeginState( name PreviousStateName )
	{
		bIsEnraged = true;
		MyKFPawn.SetEnraged( true );

		`AILog( GetStateName()$" "$GetFuncName()$"() Prev: "$PreviousStateName, 'Charging' );
		SetFocalPoint(vect(0,0,0));
		Focus = none;
		//bAdjustFromWalls = false;   // Experimenting **NOTE this prevented FP from jumping when raging - Matt
		AIZeroMovementVariables();

		/** Rotate to enemy - state code will resume execution after RotateToFocus is popped */
		PushState( 'RotateToFocus' );
		/** Finished rotating - see if I need to taunt first */

		if( !MyKFPawn.IsDoingSpecialMove() )
 		{
			// Start the rage-taunt command - no more state code will execute below until the taunt is finished
			DoRageTauntAt( KFPawn(Enemy) );
			// Finished taunting 
			LastTauntTime = WorldInfo.TimeSeconds;
		}
	}

	function EndState( name NextStateName )
	{	
		bIsEnraged = false;
		MyKFPawn.SetEnraged( false );
		
		AccumulatedDOT = 0;

		if( Enemy == none || VSize(Enemy.Location - Pawn.Location) > 1024.f || !CanSee(Enemy) )
		{
			SetEnemy(GetClosestEnemy());
		}
		AIActionStatus = "No longer engraged";
		EnableMeleeRangeEventProbing();

		MyKFPawn.bForceMaxAccel	= false;
		bPreciseDestination		= false;
		//bAdjustFromWalls		= true;
	}

	function ContinuedState()
	{
		AIActionStatus = "Enraged, and preparing to charge";
	}

Finished:
	UnlockPawnRotation();
	AIZeroMovementVariables();
	SetDestinationPosition( Pawn.Location );
	Pawn.ResetDesiredRotation();
	RotationRateMultiplier = 1.f;
	PushState( 'RotateToFocus' );
}

/*********************************************************************************************
* RotateToFocus state
********************************************************************************************* */

state RotateToFocus `DEBUGSTATE
{
Begin:
	AIActionStatus = "Rotating to focus";
	SetFocalPoint( vect(0,0,0) );
	Focus = Enemy;
	FinishRotation();
	PopState();
}

/*********************************************************************************************
* Debugging
********************************************************************************************* */


DefaultProperties
{
	// ---------------------------------------------
	// Settings
	RageFrustrationBaseTime=9
	RageDamageThreshold=276
	MaxEnemyNotVisibleRageTime=30
}
