168 lines
5.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasicEnemyNPCController : NPCControllerBase
{
[Header("Events:")]
[SerializeField] protected GameEvent_Float experienceOnDeath;
protected DropTable dropTable;
protected override void Awake()
{
dropTable = GetComponentInChildren<DropTable>();
base.Awake();
}
protected override void OnDeath()
{
RPC_OnDeath(dropTable.CalculateLootDrop());
}
protected override void RPC_OnDeath(bool lootDropped)
{
if (isDead) return;
//Debug.Log($"{this.gameObject.name} died!");
isDead = true;
agent.enabled = false;
experienceOnDeath.Raise(health.GetMaxValue() * GameConstants.GameBalancing.HealthIntoExperienceMultiplier);
dropTable.DropLoot(lootDropped);
animatorController.SetDead();
}
protected override void OnNewTargetIdentifiedAndHasTarget()
{
//someone entered sight, npc already has a target
//Debug.Log("New Target available, current target = " + currentTarget.name);
}
protected override void OnNewTargetIdentifiedAndNoCurrentTarget()
{
//someone entered sight, npc does not have a target yet
//Debug.Log("New Target available, current target = null, updating target with closest");
UpdateCurrentTarget(GetClosestTarget());
}
protected override void OnPossibleTargetLostAndHasTargetAndVision()
{
//someone exited sight, npc already has target and vision
}
protected override void OnPossibleTargetLostAndHasTargetButNoVision()
{
//someone exited sight, npc already has target but no vision of it (possibly his target was the one getting out of sight)
base.OnPossibleTargetLostAndHasTargetButNoVision();
UpdateCurrentTarget(GetClosestTarget());
}
protected override void OnPossibleTargetLostAndHasNoCurrentTargetButHasAvailableTargets()
{
//someone exited sight, npc has no target yet, there are available targets to pick
UpdateCurrentTarget(GetClosestTarget());
}
protected override void OnPossibleTargetLostAndHasNoCurrentTargetAndNoAvailableTargets()
{
//someone exited sight, npc has no target yet, there are NO available targets
PatrolNewPosition();
}
protected override void ChasingUpdate()
{
base.ChasingUpdate();
}
protected override void PatrollingUpdate()
{
base.PatrollingUpdate();
}
protected int failedTryAttackCounter = 0;
protected int failedTryAttackLimitToChangeTarget = 3;
protected override void TryAttack()
{
if (waitingForAttackAnimation) return;
if (maintainsDistance) UpdateCurrentTarget(GetClosestTarget());
possibleTargetHealth = currentTarget.GetComponent<Health>();
if (possibleTargetHealth.GetCurrentValue() <= 0)
{
UpdateCurrentTarget(GetClosestTarget());
return;
}
GetHighestPriorityAvailableAbility();
if (ability == null)
{
failedTryAttackCounter++;
if(failedTryAttackCounter >= failedTryAttackLimitToChangeTarget && possibleTargets.Count > 1)
{
failedTryAttackCounter = 0;
UpdateCurrentTarget(GetClosestTarget());
Debug.Log("RESETTING TARGET AFTER 3 FAIL ATTACK ATTEMPTS");
}
//Debug.Log("No abilities available for current conditional state");
SetupAgentStats(currentTarget.transform.position, true);
SetAgentMoving(true);
return;
}
//Debug.Log(this.name + " Ability with highest priority = " + ability.name);
waitingForAttackAnimation = true;
ForceFaceTarget();
SetAgentMoving(false);
animatorController.SetTriggerBasedOnAbility(ability.animationType);
}
protected virtual void GetHighestPriorityAvailableAbility()
{
ability = abilityPriorityManager.GetHighestPriorityAvailableAbility();
}
public override void OnAttackAnimationEventTriggered()
{
//Debug.Log(this.name + " Controller on attack animation event triggered, executing ability = ");
if(ability is AreaOfEffectOverTimeAbility && !((AreaOfEffectOverTimeAbility)ability).spawnUnderUser)
{
if (currentTarget != null)
ability.Execute(myTag, currentTarget.transform);
else
ability.Execute(myTag, this.transform.position + this.transform.forward);
}
else if (ability is AreaOfEffectAbility && !((AreaOfEffectAbility)ability).spawnUnderUser)
{
if (currentTarget != null)
ability.Execute(myTag, currentTarget.transform);
else
ability.Execute(myTag, this.transform.position + this.transform.forward);
}
else
{
ability.Execute(myTag);
}
if (ability.cooldown > 0)
abilityCooldownTracker.StartAbilityCooldown(ability);
ResetCounterOnAttackPerformed();
waitingForAttackAnimation = false;
SetAgentMoving(true);
//Debug.Log("Attack cycle done");
}
}