DIFF

bot_attack.c

#ifdef ROBOCLIENT
class BotAttack extends BotStateBase
{	
	private const int m_InputsDelayLoop = 200;
	
	private bool m_AimOverrideVertical = false;
	private bool m_AimOverrideHorizontal = false;
	
	private const float m_HorizontalTurnRate = 0.5;
	private const float m_VerticalTurnRate = 0.25;
	private const float m_InitialCheckTime = 1;
	private float m_InitialCheckTimeElapsed = 0;
	
	void BotAttack(Bot bot = NULL, BotStateBase parent = NULL)
	{
	}
	
	private void ActivateInputs()
	{
#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedOverride_ID(UAFire, 1, OverrideInputType.HOLD, false);
		g_Game.GetPlayer().GetInputInterface().SyncedOverride_ID(UADefaultAction, 1, OverrideInputType.HOLD, false);
#endif
	}
	
	private void DeactivateInputs()
	{
#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UAFire);
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UADefaultAction);
#endif
	}
	
	private void CallDeactivateInputs()
	{
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(DeactivateInputs, m_InputsDelayLoop, true);
	}
	
	private void RemoveHorizontalAim(bool Force = false)
	{
		if (!m_AimOverrideHorizontal && !Force)
			return;

#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UAAimLeft);
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UAAimRight);
#endif
		m_AimOverrideHorizontal = false;
	}
	
	private void RemoveVerticalAim(bool Force = false)
	{
		if (!m_AimOverrideVertical && !Force)
			return;
		
#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UAAimUp);
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UAAimDown);
#endif
		m_AimOverrideVertical = false;
	}
	
	private void HandleHorizontalAim()
	{
		bool hasTarget = m_Bot.m_Target && m_Bot.m_Target.IsAlive();
		if (!hasTarget)
		{
			RemoveHorizontalAim();
			return;
		}
		
		vector direction = vector.Direction(m_Owner.GetPosition(), m_Bot.m_Target.GetPosition());
		direction[1] = 0;
		direction.Normalize();
		float angle = Math.RAD2DEG * Math.Atan2(m_Owner.GetDirection()[0] * direction[2] - m_Owner.GetDirection()[2] * direction[0], vector.Dot(m_Owner.GetDirection(), direction));
		if (Math.AbsFloat(angle) < 3)
		{
			RemoveHorizontalAim();
			return;
		}
		
		int turnDirection = 1;
		if (angle > 0)
			turnDirection = -1;

		float slowDown = 1;
		if (Math.AbsFloat(angle) < 15)
			slowDown = Math.AbsFloat(angle) / 15;
		slowDown = Math.Clamp(slowDown, 0.2, 1);
		
		int overrideInput = UAAimRight;
		int removeOverrideInput = UAAimLeft;
		if (turnDirection < 0)
		{
			overrideInput = UAAimLeft;
			removeOverrideInput = UAAimRight;
		}
		
#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(removeOverrideInput);
		g_Game.GetPlayer().GetInputInterface().SyncedOverride_ID(overrideInput, m_HorizontalTurnRate * slowDown, OverrideInputType.HOLD, false);
#endif
		m_AimOverrideHorizontal = true;
	}

	private void HandleVerticalAim()
	{
		if (!m_Bot.m_Target || !m_Bot.m_Target.IsAlive())
			return;

		vector cameraPos, cameraDir, cameraRot;
		g_Game.GetPlayer().GetCurrentCameraTransform(cameraPos, cameraDir, cameraRot);
		
		vector cameraPos2D = cameraPos;
		cameraPos2D[1] = 0;
		
		vector targetPos2D = m_Bot.m_Target.GetPosition();
		targetPos2D[1] = 0;
		
		float distToTarget = vector.DistanceSq(cameraPos2D, targetPos2D);

		//Target is too far/ran away
		if (distToTarget > 4)
		{
			RemoveVerticalAim();
			return;
		}
		
		vector minTarget, maxTarget;
		m_Bot.m_Target.GetPhysics().GetGeomWorldBounds(0, minTarget, maxTarget);	
		
		//Distance from camera aim to target x/z
		float distAimToTarget = distToTarget / Math.Cos(g_Game.GetPlayer().GetCurrentCamera().GetCurrentPitch() * Math.DEG2RAD);

		vector cameraAimTargetPoint = distAimToTarget * cameraDir + cameraPos;
		
		//difference between camera aim y and target head
		float heightDiff = cameraAimTargetPoint[1] - maxTarget[1];
		
		if (0 < heightDiff && heightDiff < 0.15)
		{
			RemoveVerticalAim();
			return;
		}
		
		int overrideInput = UAAimUp;
		int removeOverrideInput = UAAimDown;
		float turnDirection = 1;
		
		if (heightDiff >= 0.15)
		{
			overrideInput = UAAimDown;
			removeOverrideInput = UAAimUp;
			turnDirection = -1;
		}
		
#ifdef INPUT_OVERRIDE
 		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(removeOverrideInput);
		g_Game.GetPlayer().GetInputInterface().SyncedOverride_ID(overrideInput, m_VerticalTurnRate, OverrideInputType.HOLD, false);
#endif
		m_AimOverrideVertical = true;
	}
	
	private void HandleAim()
	{
		HandleVerticalAim();
		HandleHorizontalAim();
		return;
	}
	
	override void OnEntry (BotEventBase e)
	{
		super.OnEntry(e);
			
		m_InitialCheckTimeElapsed = 0;
		m_AimOverrideVertical = false;
		m_AimOverrideHorizontal = false;
					
#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedOverride_ID(UATempRaiseWeapon, 1, OverrideInputType.CLICK, false);
#endif
		
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ActivateInputs, m_InputsDelayLoop, true);
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(CallDeactivateInputs, m_InputsDelayLoop - 100, false);
	}
	
	override void OnExit (BotEventBase e)
	{
		super.OnExit(e);
		
		if (m_Bot.m_Target && !m_Bot.m_Target.IsAlive())
			m_Bot.m_Target = null;
		
#ifdef INPUT_OVERRIDE
		g_Game.GetPlayer().GetInputInterface().SyncedRemoveOverride_ID(UATempRaiseWeapon);
#endif
		
		RemoveHorizontalAim(true);
		RemoveVerticalAim(true);
		DeactivateInputs();
		
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ActivateInputs);
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(DeactivateInputs);
	}
	
	override void OnUpdate (float dt)
	{
		super.OnUpdate(dt);
		
		HandleAim();
		m_InitialCheckTimeElapsed += dt;
		
		if (!m_Owner.GetMeleeCombat().GetTargetEntity() && m_InitialCheckTimeElapsed > m_InitialCheckTime)
		{	
			m_InitialCheckTimeElapsed = 0;
			m_Bot.CheckForEnemies(true);
		}
	}
}
#endif