- Targetting tags can now hold more than one tag, keeping IsValidTarget, AlliesContains and HasSameTag checks available. - Added generic target tags for enemies and players - Optional specific targetting tags if needed for future enhanced targetting
270 lines
7.5 KiB
C#
270 lines
7.5 KiB
C#
using Photon.Pun;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class BossController : NPCController
|
|
{
|
|
[Header("Boss Related:")]
|
|
[SerializeField] protected GameEvent onBossDead;
|
|
[SerializeField] protected float bossRangedAttacksRange;
|
|
[SerializeField] protected float bossMeleeAttacksRange;
|
|
|
|
protected BossAbilityBinder bossAbilityBinder;
|
|
|
|
protected bool lockedInPhase = false;
|
|
|
|
protected float targetDistance = float.MaxValue;
|
|
protected float distance;
|
|
protected Taggable resultTarget;
|
|
|
|
protected float endSearchTime;
|
|
|
|
protected Collider[] hits;
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
bossAbilityBinder = GetComponent<BossAbilityBinder>();
|
|
}
|
|
|
|
[PunRPC]
|
|
protected override void RPC_OnDeath(bool lootDropped)
|
|
{
|
|
if (isDead) return;
|
|
|
|
onBossDead.Raise();
|
|
|
|
base.RPC_OnDeath(lootDropped);
|
|
}
|
|
|
|
protected override void Start()
|
|
{
|
|
base.Start();
|
|
|
|
if (!photonView.IsMine) return;
|
|
|
|
CheckSurroundings();
|
|
|
|
LockInTarget(CheckClosestTarget());
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
if (!photonView.IsMine) return;
|
|
if (isDead) return;
|
|
|
|
if (PrimaryMovementBehaviourCheck())
|
|
{
|
|
PerformPrimaryMovementBehaviour();
|
|
}
|
|
else if (agent.remainingDistance <= agent.stoppingDistance)
|
|
agent.isStopped = true;
|
|
|
|
counter += Time.deltaTime;
|
|
if (counter >= timeBetweenAttacks)
|
|
{
|
|
if (HighestPriorityCheck())
|
|
{
|
|
PerformHighestPriorityAction();
|
|
}
|
|
else if (SecondHighestPriorityCheck())
|
|
{
|
|
PerformSecondHighestPriorityAction();
|
|
}
|
|
else if (ThirdHighestPriorityCheck())
|
|
{
|
|
PerformThirdHighestPriorityAction();
|
|
}
|
|
else
|
|
{
|
|
agent.isStopped = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
agent.isStopped = false;
|
|
}
|
|
}
|
|
|
|
protected virtual bool PrimaryMovementBehaviourCheck()
|
|
{
|
|
return Vector3.Distance(agent.transform.position, currentTarget.transform.position) > (bossRangedAttacksRange * 0.8f);
|
|
}
|
|
|
|
protected virtual bool HighestPriorityCheck()
|
|
{
|
|
return bossAbilityBinder.CanCastUltimate();
|
|
}
|
|
protected virtual bool SecondHighestPriorityCheck()
|
|
{
|
|
return (bossAbilityBinder.CanCastCoreAbility() && agent.remainingDistance <= bossRangedAttacksRange);
|
|
}
|
|
protected virtual bool ThirdHighestPriorityCheck()
|
|
{
|
|
return agent.remainingDistance <= bossMeleeAttacksRange;
|
|
}
|
|
|
|
|
|
protected virtual void PerformPrimaryMovementBehaviour()
|
|
{
|
|
patrolDestination = currentTarget.transform.position;
|
|
patrolDestination.y = 0f;
|
|
agent.SetDestination(patrolDestination);
|
|
agent.isStopped = false;
|
|
}
|
|
|
|
protected virtual void PerformHighestPriorityAction()
|
|
{
|
|
PerformUltimate();
|
|
}
|
|
protected virtual void PerformSecondHighestPriorityAction()
|
|
{
|
|
PerformCoreAbility();
|
|
}
|
|
protected virtual void PerformThirdHighestPriorityAction()
|
|
{
|
|
PerformMeleeAbility();
|
|
}
|
|
|
|
protected virtual void PerformUltimate()
|
|
{
|
|
Debug.Log("INSIDE CAN CAST ULTIMATE: " + bossAbilityBinder.CanCastUltimate());
|
|
ResetValuesOnAbilityPerformed();
|
|
bossAbilityBinder.UseUltimateAbility(currentTarget.transform);
|
|
}
|
|
|
|
protected virtual void PerformCoreAbility()
|
|
{
|
|
ResetValuesOnAbilityPerformed();
|
|
bossAbilityBinder.UseCoreAbility(currentTarget.transform.position);
|
|
}
|
|
|
|
protected virtual void PerformMeleeAbility()
|
|
{
|
|
ResetValuesOnAbilityPerformed();
|
|
bossAbilityBinder.UseMeleeAbility();
|
|
}
|
|
|
|
protected virtual void ResetValuesOnAbilityPerformed()
|
|
{
|
|
agent.isStopped = true;
|
|
counter = 0f;
|
|
}
|
|
|
|
protected virtual Taggable CheckClosestTarget()
|
|
{
|
|
targetDistance = float.MaxValue;
|
|
Debug.Log("CLOSEST COUNT: " + possibleTargets.Count);
|
|
for (int i = 0; i < possibleTargets.Count; i++)
|
|
{
|
|
distance = Vector3.Distance(possibleTargets[i].transform.position, agent.transform.position);
|
|
if (distance < targetDistance)
|
|
{
|
|
targetDistance = distance;
|
|
resultTarget = possibleTargets[i];
|
|
}
|
|
}
|
|
|
|
return resultTarget;
|
|
}
|
|
|
|
protected virtual Taggable CheckFurthestAwayTarget()
|
|
{
|
|
targetDistance = 0f;
|
|
|
|
for (int i = 0; i < possibleTargets.Count; i++)
|
|
{
|
|
distance = Vector3.Distance(possibleTargets[i].transform.position, agent.transform.position);
|
|
if (distance > targetDistance)
|
|
{
|
|
targetDistance = distance;
|
|
resultTarget = possibleTargets[i];
|
|
}
|
|
}
|
|
|
|
return resultTarget;
|
|
}
|
|
|
|
protected virtual IEnumerator TargetLockedInPhaseDurationCoroutine()
|
|
{
|
|
yield return new WaitForSeconds(GameConstants.GameBalancing.BossTargetLockInPhaseDuration);
|
|
|
|
SearchForNewTargetToLockIn();
|
|
}
|
|
|
|
protected virtual IEnumerator SearchForNewTargetToLockInCoroutine()
|
|
{
|
|
endSearchTime = Time.time + GameConstants.GameBalancing.BossSearchForNewTargetLockInDuration;
|
|
|
|
while (Time.time < endSearchTime)
|
|
{
|
|
UpdateCurrentTarget(possibleTargets[Random.Range(0, possibleTargets.Count)]);
|
|
yield return new WaitForSeconds(GameConstants.GameBalancing.BossSearchForNewTargetLockInDuration / 3);
|
|
}
|
|
|
|
LockInTarget(CheckClosestTarget());
|
|
}
|
|
|
|
protected virtual void LockInTarget(Taggable target)
|
|
{
|
|
lockedInPhase = true;
|
|
|
|
UpdateCurrentTarget(target);
|
|
|
|
Debug.Log("Target Locked In: " + target.name);
|
|
StartCoroutine(TargetLockedInPhaseDurationCoroutine());
|
|
}
|
|
|
|
protected virtual void SearchForNewTargetToLockIn()
|
|
{
|
|
lockedInPhase = false;
|
|
|
|
Debug.Log("Searching for new lockin: ");
|
|
StartCoroutine(SearchForNewTargetToLockInCoroutine());
|
|
}
|
|
|
|
protected virtual void UpdateCurrentTarget(Taggable target)
|
|
{
|
|
currentTarget = target;
|
|
SetupAgentStats();
|
|
}
|
|
|
|
protected virtual void SetupAgentStats()
|
|
{
|
|
agent.speed = chasingAgentSpeed;
|
|
patrolDestination = currentTarget.transform.position;
|
|
patrolDestination.y = 0f;
|
|
agent.SetDestination(patrolDestination);
|
|
}
|
|
|
|
protected virtual void CheckSurroundings()
|
|
{
|
|
if (!photonView.IsMine) return;
|
|
|
|
hits = Physics.OverlapSphere(this.transform.position, sightRange);
|
|
Debug.Log("CHECK SURROUNDINGS COUNT: " + hits.Length);
|
|
foreach (Collider collider in hits)
|
|
{
|
|
Debug.Log("CHECKING COLLIDER: " + collider.name);
|
|
otherView = collider.GetComponentInParent<PhotonView>();
|
|
if (otherView != null)
|
|
{
|
|
if (otherView == photonView) continue;
|
|
}
|
|
|
|
possibleTarget = collider.GetComponentInParent<Taggable>();
|
|
|
|
if (possibleTarget == null) continue;
|
|
|
|
//if (possibleTarget.targetTag == myTag.targetTag || myTag.targetTag.AlliedTags.Contains(possibleTarget.targetTag)) continue;
|
|
if (possibleTarget.HasSameTag(myTag.targetTag) || myTag.AlliedTagsContains(possibleTarget.targetTag)) continue;
|
|
|
|
if (possibleTargets.Contains(possibleTarget)) continue;
|
|
|
|
Debug.Log("ADDING TARGET " + possibleTarget.name);
|
|
possibleTargets.Add(possibleTarget);
|
|
}
|
|
}
|
|
}
|