Esempio n. 1
0
        /// <summary>
        /// Selects a ranged spell from this enemy's list and returns true if it can be cast.
        /// </summary>
        bool CanCastRangedSpell()
        {
            if (entity.CurrentMagicka <= 0)
            {
                return(false);
            }

            EffectBundleSettings[]      spells      = entity.GetSpells();
            List <EffectBundleSettings> rangeSpells = new List <EffectBundleSettings>();
            int count = 0;

            foreach (EffectBundleSettings spell in spells)
            {
                if (spell.TargetType == TargetTypes.SingleTargetAtRange ||
                    spell.TargetType == TargetTypes.AreaAtRange)
                {
                    rangeSpells.Add(spell);
                    count++;
                }
            }

            if (count == 0)
            {
                return(false);
            }

            EffectBundleSettings selectedSpellSettings = rangeSpells[Random.Range(0, count)];

            selectedSpell = new EntityEffectBundle(selectedSpellSettings, entityBehaviour);

            int totalGoldCostUnused;
            int readySpellCastingCost;

            Formulas.FormulaHelper.CalculateTotalEffectCosts(selectedSpell.Settings.Effects, selectedSpell.Settings.TargetType, out totalGoldCostUnused, out readySpellCastingCost);
            if (entity.CurrentMagicka < readySpellCastingCost)
            {
                return(false);
            }

            if (EffectsAlreadyOnTarget(selectedSpell))
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Selects a ranged spell from this enemy's list and returns true if it can be cast.
        /// </summary>
        bool CanCastRangedSpell()
        {
            if (entity.CurrentMagicka <= 0)
            {
                return(false);
            }

            EffectBundleSettings[]      spells      = entity.GetSpells();
            List <EffectBundleSettings> rangeSpells = new List <EffectBundleSettings>();
            int count = 0;

            foreach (EffectBundleSettings spell in spells)
            {
                if (spell.TargetType == TargetTypes.SingleTargetAtRange ||
                    spell.TargetType == TargetTypes.AreaAtRange)
                {
                    rangeSpells.Add(spell);
                    count++;
                }
            }

            if (count == 0)
            {
                return(false);
            }

            EffectBundleSettings selectedSpellSettings = rangeSpells[Random.Range(0, count)];

            selectedSpell = new EntityEffectBundle(selectedSpellSettings, entityBehaviour);

            int totalGoldCostUnused;
            int readySpellCastingCost;

            Formulas.FormulaHelper.CalculateTotalEffectCosts(selectedSpell.Settings.Effects, selectedSpell.Settings.TargetType, out totalGoldCostUnused, out readySpellCastingCost);
            if (entity.CurrentMagicka < readySpellCastingCost)
            {
                return(false);
            }

            if (EffectsAlreadyOnTarget(selectedSpell))
            {
                return(false);
            }

            // Check that there is a clear path to shoot a spell
            float   spellMovementSpeed = 15; // All range spells are currently 15 speed
            Vector3 sphereCastDir      = senses.PredictNextTargetPos(spellMovementSpeed);

            if (sphereCastDir == EnemySenses.ResetPlayerPos)
            {
                return(false);
            }

            float sphereCastDist = (sphereCastDir - transform.position).magnitude;

            sphereCastDir = (sphereCastDir - transform.position).normalized;

            RaycastHit hit;

            if (Physics.SphereCast(transform.position, 0.45f, sphereCastDir, out hit, sphereCastDist))
            {
                DaggerfallEntityBehaviour hitTarget = hit.transform.GetComponent <DaggerfallEntityBehaviour>();

                // Clear path to target
                if (hitTarget == senses.Target)
                {
                    return(true);
                }

                // Something in the way
                return(false);
            }

            // Clear path to predicted target position
            return(true);
        }