public AIState?StateUpdate() { if (!_agent.IsAlive()) { return(_fallbackState); } if (!_agent.HasTarget()) { return(_fallbackState); } if (!_agent.IsBetweenFearAndAggro()) { return(_fallbackState); } var distance = _agent.GetLineDistanceToTarget(); if (distance < _desiredRange) { return(_nextState); } var direction = (_agent.ActiveTarget.transform.position - _agent.Transform.position).normalized; var moveTo = _agent.ActiveTarget.transform.position - direction * (_desiredRange - 0.1f); _agent.Movement.ControlSetDestination(moveTo); _agent.Movement.ControlLookAt(moveTo); return(null); }
public AIState?StateUpdate() { if (!_agent.IsAlive()) { return(_fallbackState); } if (!_agent.HasTarget()) { return(_fallbackState); } if (!_agent.IsBetweenFearAndAggro()) { return(_fallbackState); } if (!_agent.CanCast()) { return(_fallbackState); } // If no intentions to choose from -> fallback if (_agent.Config.AI.SlotConfig == null || _agent.Config.AI.SlotConfig.Length == 0) { return(_fallbackState); } // Select a slot to cast that is ready; var readySlots = _agent.Config.AI.SlotConfig.Where(s => { var slotState = _agent.SpellBook.GetSpellSlotState(s.Slot); return(slotState.State == SpellbookState.SlotState.Ready); }).ToList(); // Find and randomly choose an active slot if (readySlots.Count >= 0) { var intention = RandomUtils.Choice(readySlots, s => s.Weight); _agent.IntendedSpell = intention; return(_nextState); } // No slots to cast _agent.Logger.Log("No active slots to cast"); return(_fallbackState); }
public AIState?StateUpdate() { if (!_agent.IsAlive()) { AbortIfCasting(); return(_fallbackState); } if (!_agent.HasTarget()) { AbortIfCasting(); return(_fallbackState); } if (!_agent.IsBetweenFearAndAggro()) { AbortIfCasting(); return(_fallbackState); } if (_agent.IntendedSpell == null) { AbortIfCasting(); return(_fallbackState); } var slotState = _agent.SpellBook.GetSpellSlotState(_agent.IntendedSpell.Slot); if (slotState.State == SpellbookState.SlotState.Ready) { if (_isCasting) { // If we are casting and ended up in ready state // then it means that the cast is completed _agent.LastSpellCastTime = Time.time; return(_nextState); } // If AI is not casting and the slot is ready // Cast the spell _agent.Movement.ControlLookAt(_agent.ActiveTarget.transform.position); _agent.Movement.ControlStop(); if (_agent.SpellBook.TryFireSpellToTarget(_agent.IntendedSpell.Slot, GetTarget(slotState.Spell.TargetType))) { _isCasting = true; return(null); } // Casting failed, fallback return(_fallbackState); } else if (slotState.State == SpellbookState.SlotState.Firing || slotState.State == SpellbookState.SlotState.Preparing) { // Update target while casting _targetProxy.Location = _agent.ActiveTarget.transform.position; // We are casting, we cool return(null); } // Failed to cast return(_fallbackState); }