// Fast function that says how big is the area covered by effects from a given category public uint GetArea(SpellCategory?category = SpellCategory.Damages) { uint area = 0; foreach (var effect in GetEffects()) { if ((Spell.GetEffectCategories((uint)effect.Id, LevelTemplate.id) & category) > 0) { area = Math.Max(area, effect.Surface); } } return(area); }
// Precise compute efficiency of a spell for a given category (beware to remove pc from friend and friendcells lists before calling this !) // Returns -1 if it would hit friends (todo : optimize if needed) public int GetFullAreaEffect(PlayedFighter pc, Cell source, Cell dest, IEnumerable <Fighter> actors, Spell.SpellCategory category, ref string comment) { SpellImpact spellImpact = new SpellImpact(); foreach (EffectInstanceDice effect in LevelTemplate.effects) { if ((Spell.GetEffectCategories((uint)effect.effectId, LevelTemplate.id) & category) > 0) { comment += " Effect " + (EffectsEnum)(effect.effectId) + " : "; EffectDice effectCl = new EffectDice(effect); IEnumerable <Cell> cells = effectCl.GetArea(source, dest); SpellTargetType targetType = (SpellTargetType)effect.targetId; int nbAffectedTargets = 0; if (EffectBase.canAffectTarget(effectCl, this, pc, pc) && cells.Contains(source)) { // Caster would be affected DamageType efficiency = Spell.CumulEffects(effect, ref spellImpact, pc, pc /*, category*/, this); if (efficiency != 0) { comment += string.Format("{0} on {1} => {2}, ", (decimal)efficiency, pc, (decimal)spellImpact.Damage); } nbAffectedTargets++; if (efficiency < 0) { return(0); // The caster would be affected by a bad spell => give up } } foreach (var actor in actors.Where(act => cells.Contains(act.Cell))) // All actors within the area covered by the spell { if (!EffectBase.canAffectTarget(effectCl, this, pc, actor)) { continue; // This actor is not affected by the spell } DamageType damage = Spell.CumulEffects(effect, ref spellImpact, pc, actor /*, category*/, this); if (damage != 0) { comment += string.Format(" - {0} on {1} => {2}", (decimal)damage, actor, (decimal)spellImpact.Damage); } nbAffectedTargets++; //if (damage > 0 && actor.Team == pc.Team) return 0; // Harmful on a friend => give up } //if (nbAffectedTargets > 1) //{ // pc.Character.SendWarning("Spell {0} : {1} targets affected for {2} damage - {3}", this, nbAffectedTargets, spellImpact.Damage, comment); //} } } if (Template.id == 139) // Mot d'altruisme : only use near end of fight or if lot of spellImpact to heal { int hpLeftOnFoes = actors.Where(actor => actor.Team.Id != pc.Team.Id).Sum(actor => actor.Stats.Health); comment += string.Format(" - special \"Mot d'altruisme\" processing : hpLeftOnFoes = {0}, efficiency = {1}", hpLeftOnFoes, (int)spellImpact.Damage); if (hpLeftOnFoes > 500) // Not the end of the fight { if (spellImpact.Damage < 300) { return(0); // Do not cast it if less than 300 hp of healing } else { return((int)spellImpact.Damage / 3); // Otherwise, far from the end of the fight, divide efficiency by 3 } } // if close to the end of the fight, then returns full result. } return((int)spellImpact.Damage); }