bool RollAbsorptionChance(SpellAbsorption absorbEffect, DaggerfallEntity casterEntity) { int chance = absorbEffect.Settings.ChanceBase + absorbEffect.Settings.ChancePlus * (int)Mathf.Floor(casterEntity.Level / absorbEffect.Settings.ChancePerLevel); int roll = UnityEngine.Random.Range(1, 100); return(roll <= chance); }
/// <summary> /// Tests incoming effect for spell absorption. If absorption succeeds the entity will /// block effect and recover spell points equal to the casting cost of blocked effect. /// If target does not have enough spell points free to absorb effect cost then effect will NOT be absorbed. /// For example if player has 0 of 50 spell points available, they can absorb an incoming effect costing up to 50 spell points. /// An effect costing 51 spell points cannot be absorbed. It's "all or nothing". /// Notes: /// - There are two variants of spell absorption in Daggerfall. /// - Career-based: This is the "none / in light / in darkness / always" assigned to entity career kit. /// - Effect-based: Generated by having an active Spell Absorption effect from a spell or item. /// - In classic effect-based absorption from spells/items will override career-based absorption. Not sure if bug. /// - Career-based absorption will always succeed chance check. /// - Spell-based will roll for check on each absorb attempt. /// </summary> /// <param name="effect">Incoming effect.</param> /// <param name="targetType">Source bundle target type for spell cost calculation.</param> /// <param name="casterEntity">Source caster entity behaviour for spell cost calculation.</param> /// <param name="absorbSpellPointsOut">Number of spell points absorbed. Only valid when returning true.</param> /// <returns>True if absorbed.</returns> bool TryAbsorption(IEntityEffect effect, TargetTypes targetType, DaggerfallEntity casterEntity, out int absorbSpellPointsOut) { absorbSpellPointsOut = 0; // Effect cannot be null if (effect == null) { return(false); } // Currently only absorbing Destruction magic - not sure on status of absorbing other magic schools // This is to prevent something as benign as a self-heal from player being blocked and absorbed // With current design, absorption is checked for ALL incoming effects to entity so require some sanity checks if (effect.Properties.MagicSkill != DFCareer.MagicSkills.Destruction) { return(false); } // Get casting cost for this effect // Costs are calculated as if target cast the spell, not the actual caster // Note that if player self-absorbs a spell this will be equal anyway int effectCastingCost = GetEffectCastingCost(effect, targetType, entityBehaviour.Entity); // The entity must have enough spell points free to absorb incoming effect int availableSpellPoints = entityBehaviour.Entity.MaxMagicka - entityBehaviour.Entity.CurrentMagicka; if (effectCastingCost > availableSpellPoints) { return(false); } else { absorbSpellPointsOut = effectCastingCost; } // Check if entity has an absorb incumbent running SpellAbsorption absorbEffect = FindIncumbentEffect <SpellAbsorption>() as SpellAbsorption; if (absorbEffect != null) { return(TryEffectBasedAbsorption(effect, absorbEffect, casterEntity)); } // Handle career-based absorption if (entityBehaviour.Entity.Career.SpellAbsorption != DFCareer.SpellAbsorptionFlags.None) { return(TryCareerBasedAbsorption(effect, casterEntity)); } return(false); }
bool TryEffectBasedAbsorption(IEntityEffect effect, SpellAbsorption absorbEffect, DaggerfallEntity casterEntity) { return(RollAbsorptionChance(absorbEffect, casterEntity)); }