public void DetectedEnemy(Creature target) { if (!CombatManager.Instance.CombatMode) { _creature.SetTargetCreature(target); _instigator = true; _creature.InitiateCombat(); } else { CombatManager.AddToCombat(_creature); } }
protected virtual IEnumerator RunCombatLogicTree() { switch (_currentState) { case State.Fleeing: GetPath(); yield return(_creature.AIMoveCreature()); _creature.EndTurn(); yield break; case State.Dead: yield break; /*case State.Idle: * case State.Wander: * case State.Patrol: * case State.Guard: * case State.Chase: * default: * break;*/ } if (WantsToHeal()) { var healed = TryToHeal(); if (!healed && HealthVeryLow()) { _currentState = State.Fleeing; GetPath(); yield return(_creature.AIMoveCreature()); _creature.EndTurn(); } else if (healed) { yield return(_creature.AnimController.UseAnimWait); } } if (_aggression == Aggression.Hostile) { var chanceToHit = _creature.GetChanceToHit(1, Player.Instance); if (chanceToHit < MINCHANCETOHIT) { _currentState = State.Fleeing; GetPath(); yield return(_creature.AIMoveCreature()); _creature.EndTurn(); yield break; } } var foundTarget = false; var distToTarget = 0; if (_instigator) { _targetCreature = _creature.TargetCreature; distToTarget = HexMaker.Instance.GetDistanceToCoord(_creature.Coord, _targetCreature.Coord, _creature.TargetPath, wantToMove: false); CombatManager.AddToCombat(_targetCreature); foundTarget = true; } else { foundTarget = TryGetTarget(out distToTarget); } if (!foundTarget) { _creature.EndTurn(); yield break; } //If not possible for AI to get to target if (distToTarget < 0) { _currentState = State.Fleeing; GetPath(); yield return(_creature.AIMoveCreature()); _creature.EndTurn(); yield break; } var weaponInfo = _creature.GetAttackTypeInfo(); var path = _creature.TargetPath.ToArray(); _creature.TargetPath.Clear(); var dist = distToTarget - weaponInfo.Range; for (var i = 0; i < path.Length; i++) { _creature.TargetPath.Add(path[i]); if (dist > 1) { yield return(_creature.AIMoveCreature()); } else { if (CombatManager.ViewUnobscured(_creature, _targetCreature)) { break; } yield return(_creature.AIMoveCreature()); } dist--; distToTarget--; _creature.TargetPath.Remove(path[i]); if (_creature.MaxCanMoveDist <= 0) { _creature.TargetPath.Clear(); _creature.EndTurn(); yield break; } } _creature.TargetPath.Clear(); if (_creature.MaxCanMoveDist <= 0) { _creature.EndTurn(); yield break; } if (_creature.TargetCreature != null) { var chanceToHit = _creature.GetChanceToHit(distToTarget, _targetCreature); var attackSuccess = _creature.TryAttackCreature(); var firstAttack = true; var tryAgain = attackSuccess != AttackSuccess.NotEnoutAP; while (firstAttack || tryAgain) { switch (attackSuccess) { case AttackSuccess.None: case AttackSuccess.NoTarget: case AttackSuccess.NoChanceToHit: tryAgain = false; break; case AttackSuccess.NotEnoutAP: if (firstAttack) { var inactiveNull = _creature.InactiveItem == null || _creature.InactiveItem.Info == null; if (inactiveNull || _creature.InactiveItem.Info is WeaponInfo) { var attackInfo = _creature.GetAttackTypeInfo(false); if (!attackInfo.IsValidWeapon || _creature.MaxCanMoveDist < attackInfo.ActionPointCost || (!inactiveNull && !_creature.InactiveItem.CanUseItem())) { yield return(null); tryAgain = false; break; } yield return(_creature.SwapQuickbarItems()); tryAgain = true; break; } } tryAgain = false; break; case AttackSuccess.NoAmmo: var canReload = _creature.TryReloadWeapon(_creature.ActiveItem); if (canReload) { //wait for anim to finish yield return(null); tryAgain = true; } else { tryAgain = false; } break; case AttackSuccess.AttackMissed: //wait for anim to finish yield return(null); break; case AttackSuccess.AttackHit: case AttackSuccess.AttackCritical: //wait for anim to finish yield return(null); break; default: throw new ArgumentOutOfRangeException(); } firstAttack = false; if (tryAgain) { attackSuccess = _creature.TryAttackCreature(); } } yield return(null); } yield return(null); _creature.EndTurn(); }