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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }