//////////////////////////////////////////////
//	Author: Drammel							//
//	Date: 4/5/2009							//
//	Title: gui_run_charge					//
//	Description: Activates charge attacks.	//
//////////////////////////////////////////////

#include "bot9s_inc_variables"
#include "bot9s_inc_maneuvers"
#include "bot9s_include"
#include "bot9s_inc_constants"

void ChargeRules(object oPC, object oTarget, float fStart, float fRange)
{	
	string sToB = GetFirstName(oPC) + "tob";
	object oToB = GetObjectByTag(sToB);
	
	location lPC = GetLocation(oPC);
	location lCharge = GetLocalLocation(oPC, "bot9s_pc_pos_charge");
	vector vCharge = GetPositionFromLocation(lCharge);
	float fCharge = GetZ(vCharge);
	
	effect eSpeed = EffectMovementSpeedIncrease(99);
	effect eAC = EffectACDecrease(2);
	effect eCharge = EffectLinkEffects(eAC, eSpeed);
	eCharge = SupernaturalEffect(eCharge);

	float fDist;

	if (fRange > FeetToMeters(8.0f))
	{
		fDist = fRange; // A check for reach weapons.
	}
	else fDist = FeetToMeters(8.0f); // Max distance the engine still lets you make attacks at.

	if ((GetLocalInt(oToB, "ChargeStatus") == 1) && (lPC != lCharge) && (GetLocalInt(oToB, "ChargeSpeedCheck") == 0))
	{
		ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCharge, oPC, 6.0f);
		SetLocalInt(oToB, "ChargeSpeedCheck", 1);
	}

	if ((lPC == lCharge) && (GetDistanceToObject(oTarget) <= fDist))
	{
		RemoveEffect(oPC, eCharge);
		SetLocalInt(oToB, "ChargeStatus", 0);
		SetLocalInt(oToB, "ChargeSpeedCheck", 0);
		ActionUseFeat(FEAT_STUDENT_OF_THE_SUBLIME_WAY, oPC);
	}
	else if ((fCharge < fStart - 0.25f) || (fCharge > fStart + 0.25f)) //Acounts for small bumps that aren't technically what you'd call 'rough terrain'.
	{	
		RemoveEffect(oPC, eCharge);
		SetLocalInt(oToB, "ChargeStatus", 0);
		SetLocalInt(oToB, "ChargeSpeedCheck", 0);
		ClearAllActions();
		SendMessageToPC(oPC, "<color=red>You cannot charge over uneven terrain.</color>");
	}
	
	if ((GetLocalInt(oToB, "ChargeStatus") == 1) && (lPC != lCharge))
	{
		DelayCommand(0.3f, ChargeRules(oPC, oTarget, fStart, fRange));
	}
	else SetLocalInt(oToB, "ChargeSpeedCheck", 0);
}

void RunPCChargePosition()
{
	object oPC = OBJECT_SELF;
	location lPC = GetLocation(oPC);
	string sToB = GetFirstName(oPC) + "tob";
	object oToB = GetObjectByTag(sToB);
	
	if (GetLocalInt(oToB, "ChargeStatus") == 1)
	{
		SetLocalLocation(oPC, "bot9s_pc_pos_charge", lPC);
		DelayCommand(0.3f, RunPCChargePosition());
	}
	else DeleteLocalLocation(oPC, "bot9s_pc_pos_charge");
}

void main(int nTarget)
{	
	object oOrigin = OBJECT_SELF;
	object oPC = GetControlledCharacter(oOrigin);
	string sToB = GetFirstName(oPC) + "tob";
	object oToB = GetObjectByTag(sToB);
	int nRow = 211;
	string sScript = GetLocalString(oToB, "maneuvers_Script" + IntToString(nRow));
	
	SetLocalInt(oToB, "Charge", nTarget);
	SetLocalInt(oToB, "Strike", nRow);
	
	if (NotMyFoe("Charge") == TRUE)
	{
		return;
	}
	
	object oTarget = IntToObject(GetLocalInt(oToB, "Charge"));
	object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
	int nWeapon = GetBaseItemType(oWeapon);
	float fRange = GetLocalFloat(oToB, "baseitems_PrefAttackDist" + IntToString(nWeapon));

	if ((GetDistanceBetween(oPC, oTarget) >= FeetToMeters(10.0f)) && (!GetWeaponRanged(oWeapon)))
	{
		if (LineOfSightObject(oPC, oTarget) == TRUE)
		{	
			vector vStart = GetPosition(oPC);
			float fStart = GetZ(vStart);

			ClearAllActions();
			ClearStrikes();
			SetLocalInt(oToB, "ChargeStatus", 1);
			DelayCommand(6.0f, SetLocalInt(oToB, "ChargeStatus", 0));
			DelayCommand(0.1f, RunPCChargePosition());
			DelayCommand(0.5f, ChargeRules(oPC, oTarget, fStart, fRange));
			ActionMoveToObject(oTarget, TRUE, fRange);
		}
		else SendMessageToPC(oPC, "<color=red>You do not have line of sight to the target.</color>");
	}
	else SendMessageToPC(oPC, "<color=red>You must be at least ten feet away from the target and equipped with a melee weapon to make a charge.</color>");
}