using AIMachineTools; using System; using System.Collections; using UnityEngine; public class AttackState : State { private static AttackState _instance; //only declared once private AttackState() //set instance to itself { if (_instance != null) { return; } _instance = this; } public static AttackState instance //creates the instance of the first state if it does not exist { get { if (_instance == null) { new AttackState(); } return _instance; } } public override IEnumerator InState(AIMachine owner) { float timeWaitingToShoot = 0; float timeSinceFiring = 0; bool shotFired = false; bool movingCloserToEnemy = false; owner.RemoveMarker(); while (owner.botMachine.currentState == AttackState.instance) { if (!owner.disabled) { if (owner.enemyObject == null) { owner.canSeeEnemy = false; owner.enemyHealth = null; LeaveState(owner); yield break; } else { if (shotFired == true) { timeSinceFiring += Time.deltaTime; if (!owner.animator.GetCurrentAnimatorStateInfo(0).IsName("BarrelLightFade")) { owner.laserLine.enabled = false; owner.barrelLight.enabled = false; } if (timeSinceFiring >= owner.fireRate) { timeSinceFiring = 0.0f; shotFired = false; } } if (owner.additionalEnemies.Count >= 2 && owner.nearbyFriendlies.Count <= 1) { for (int i = 0; i < owner.friendlyBots.Count; i++) { if (Vector3.Distance(owner.friendlyBots[i].transform.position, owner.transform.position) <= owner.retreatRadius && Vector3.Distance(owner.friendlyBots[i].transform.position, owner.transform.position) >= 50) { owner.laserLine.enabled = false; owner.barrelLight.enabled = false; owner.botMachine.ChangeState(RetreatState.instance); yield break; } } } int numberOfBotsCalled = 0; for (int i = 0; i < owner.friendlyBots.Count; i++) //if there are any friendly bots within the reinforcementRadius, give them this bots target { if (Vector3.Distance(owner.transform.position, owner.friendlyBots[i].transform.position) <= owner.ReinforcementRadius) { if (owner.friendlyBots[i].GetComponent<AIMachine>().enemyObject == null) //if the current bot doesnt already have a target, set it { owner.friendlyBots[i].GetComponent<AIMachine>().enemyObject = owner.enemyObject; owner.friendlyBots[i].GetComponent<AIMachine>().canSeeEnemy = true; numberOfBotsCalled++; } } } if (numberOfBotsCalled != 0) { owner.logD.RecieveLog(owner.displayName + " called " + numberOfBotsCalled + " bot(s) for help!"); numberOfBotsCalled = 0; } if (movingCloserToEnemy == false) owner.thisAgent.SetDestination(owner.transform.position); if (Vector3.Distance(owner.transform.position, owner.enemyObject.transform.position) <= owner.attackDistance && owner.canSeeEnemy) { MoveTurret(owner, owner.enemyObject.GetComponentInChildren<HighlightObject>().gameObject.transform.position); timeWaitingToShoot += Time.deltaTime; if (timeWaitingToShoot >= 5f) { owner.thisAgent.SetDestination(owner.enemyObject.transform.position); movingCloserToEnemy = true; if (Vector3.Distance(owner.transform.position, owner.enemyObject.transform.position) <= 20 || owner.onTarget) { owner.thisAgent.SetDestination(owner.transform.position); movingCloserToEnemy = false; } } if (owner.onTarget == true) { timeWaitingToShoot = 0; if (!shotFired) { timeSinceFiring = 0.0f; shotFired = true; Shoot(owner); } bool removing = false; for (int i = 0; i < owner.friendlyBots.Count; i++) { if (owner.friendlyBots[i].GetComponent<AIMachine>().removingEnemy == true) { removing = true; break; } } if (removing == false) { if (owner.enemyObject != null) { try { if (owner.enemyHealth.health <= 0) { owner.removingEnemy = true; OnEnemyDeath(owner); } } catch (Exception e) { Debug.LogError(e.StackTrace); } } } } } else { LeaveState(owner); yield break; } } } else { owner.thisAgent.SetDestination(owner.transform.position); } yield return null; } } private void Shoot(AIMachine _owner) { _owner.soundMgr.StartMusicCouroutine(); int randomHitChance = UnityEngine.Random.Range(0, 100); float pitchVariance = UnityEngine.Random.Range(0.80f, 1.20f); _owner.audioS.pitch = pitchVariance; _owner.audioS.PlayOneShot(_owner.GetComponent<MultipleAudioClips>().clips[1]); int randomLaserMat = UnityEngine.Random.Range(0, 5); _owner.laserLine.material = _owner.lasers[randomLaserMat]; _owner.laserLine.SetPosition(0, _owner.barrelEnd.position); _owner.laserLine.SetPosition(1, _owner.contactPoint); _owner.laserLine.enabled = true; _owner.barrelLight.enabled = true; float adjustedAnimSpeed = 1; for (float i = 2f; i > _owner.fireRate; i -= 0.1f) { adjustedAnimSpeed += 0.01f; } _owner.animator.SetFloat("shootSpeed", adjustedAnimSpeed); _owner.animator.Play("BarrelLightFade", 0); _owner.animator.Play("BarrelMove", 2); _owner.animator.Play("LaserFade", 1); _owner.laserParticles.Play(); if (randomHitChance <= _owner.hitChance && _owner.enemyObject != null) { _owner.CreateImpactParticles(); int randomCritChance = UnityEngine.Random.Range(0, 100); int randomHeavyHitChance = UnityEngine.Random.Range(0, 100); _owner.enemyObject.GetComponent<AudioSource>().PlayOneShot(_owner.enemyObject.GetComponent<MultipleAudioClips>().clips[0]); if (randomCritChance <= _owner.critChance) { int damageAmt = 2; if (randomHeavyHitChance <= _owner.heavyHitChance) damageAmt += _owner.heavyHitModifier; try { _owner.enemyHealth.HealthReduce(damageAmt); } catch (Exception e) { Debug.LogError(e.StackTrace); } } else { int damageAmt = 1; if (randomHeavyHitChance <= _owner.heavyHitChance) damageAmt += _owner.heavyHitModifier; try { _owner.enemyHealth.HealthReduce(damageAmt); } catch (Exception e) { Debug.LogError(e.StackTrace); } } if (!_owner.enemyObject.GetComponent<StructureInfo>()) { if (_owner.enemyObject.GetComponent<EnemyAIMachine>().enemyObject == null) { _owner.enemyObject.GetComponent<EnemyAIMachine>().enemyObject = _owner.gameObject; _owner.enemyObject.GetComponent<EnemyAIMachine>().canSeeEnemy = true; } } } else { _owner.logD.RecieveLog(_owner.displayName + " missed."); } } private void OnEnemyDeath(AIMachine _owner) { var tempEnemyHolder = _owner.enemyObject; _owner.enemyObject = null; _owner.canSeeEnemy = false; _owner.enemyHealth = null; if (tempEnemyHolder.GetComponent<StructureInfo>()) { _owner.logD.RecieveLog(tempEnemyHolder.GetComponent<StructureInfo>().displayName + " was destroyed", Color.red); _owner.gameManager.OnStructureDestroy(tempEnemyHolder); tempEnemyHolder.SetActive(false); _owner.botStats.KillExpIncrease(tempEnemyHolder); } else { _owner.logD.RecieveLog(tempEnemyHolder.GetComponent<EnemyAIMachine>().displayName + " was destroyed", Color.red); tempEnemyHolder.SetActive(false); if (tempEnemyHolder.GetComponent<EnemyAIMachine>().turretBot) _owner.gameManager.OnTurretKill(tempEnemyHolder); else _owner.gameManager.OnKill(tempEnemyHolder); _owner.botStats.KillExpIncrease(tempEnemyHolder); } for (int i = 0; i < _owner.friendlyBots.Count; i++) { AIMachine targetBot = null; AIAllyMachine targetAlly = null; if (_owner.friendlyBots[i].GetComponent<BotStats>()) targetBot = _owner.friendlyBots[i].GetComponent<AIMachine>(); else targetAlly = _owner.friendlyBots[i].GetComponent<AIAllyMachine>(); if (targetAlly == null) { if (targetBot.enemyObject == tempEnemyHolder && targetBot.gameObject.activeSelf == true) { targetBot.enemyObject = null; targetBot.enemyHealth = null; targetBot.canSeeEnemy = false; targetBot.laserLine.enabled = false; targetBot.barrelLight.enabled = false; var currentState = targetBot.botMachine.baseState; if (currentState == SearchState.instance) targetBot.botMachine.ChangeState(ChaseState.instance); else if (currentState == CaptureAreaState.instance) targetBot.botMachine.ChangeState(ChaseState.instance); else if (currentState == FollowState.instance) targetBot.botMachine.ChangeState(FollowState.instance); else if (currentState == PartnerState.instance) targetBot.botMachine.ChangeState(ChaseState.instance); else if (currentState == MoveToState.instance) targetBot.botMachine.ChangeState(ChaseState.instance); else if (currentState == SentryState.instance) targetBot.botMachine.ChangeState(SentryState.instance); } } else { if (targetAlly.enemyObject == tempEnemyHolder && targetAlly.gameObject.activeSelf == true) { targetAlly.enemyObject = null; targetAlly.enemyHealth = null; targetAlly.canSeeEnemy = false; targetAlly.laserLine.enabled = false; targetAlly.barrelLight.enabled = false; var currentState = targetAlly.botMachine.currentState; if (currentState != AllyRetreatState.instance) targetAlly.botMachine.ChangeState(AllyRetreatState.instance); } } } GameObject playerEnemy = _owner.playerObject.GetComponent<PlayerCallForHelp>().GetEnemy(); if (playerEnemy == tempEnemyHolder) _owner.playerObject.GetComponent<PlayerCallForHelp>().SetEnemyNull(); _owner.removingEnemy = false; } private void MoveTurret(AIMachine _owner, Vector3 hitPos) { Quaternion turretRot = Quaternion.LookRotation(hitPos - _owner.turretPos.transform.position); if (Vector3.Angle(_owner.turretPos.transform.forward, _owner.enemyObject.transform.position - _owner.turretPos.transform.position) > 5) { _owner.turretPos.transform.rotation = Quaternion.RotateTowards(_owner.turretPos.transform.rotation, turretRot, Time.deltaTime * _owner.turretRotateSpeed); _owner.turretPos.transform.localEulerAngles = new Vector3(0, _owner.turretPos.transform.localEulerAngles.y, 0); } _owner.barrelPos.transform.rotation = Quaternion.RotateTowards(_owner.barrelPos.transform.rotation, turretRot, Time.deltaTime * _owner.barrelMoveSpeed); _owner.barrelPos.transform.localEulerAngles = new Vector3(0, _owner.barrelPos.transform.localEulerAngles.y, 0); } private void LeaveState(AIMachine _owner) { _owner.laserLine.enabled = false; _owner.barrelLight.enabled = false; if (_owner.botMachine.baseState == SearchState.instance) _owner.botMachine.ChangeState(ChaseState.instance); else if (_owner.botMachine.baseState == CaptureAreaState.instance) _owner.botMachine.ChangeState(ChaseState.instance); else if (_owner.botMachine.baseState == FollowState.instance) _owner.botMachine.ChangeState(FollowState.instance); else if (_owner.botMachine.baseState == PartnerState.instance) _owner.botMachine.ChangeState(ChaseState.instance); else if (_owner.botMachine.baseState == MoveToState.instance) _owner.botMachine.ChangeState(ChaseState.instance); else if (_owner.botMachine.baseState == SentryState.instance) _owner.botMachine.ChangeState(SentryState.instance); } }