private void AddCreatureFactors(Dictionary <FactorType, List <FactorInfo> > dict
                                        , CreatureRef creatureRef
                                        , Fight fight
                                        , Creature attacker
                                        , Creature defender
                                        , AttackType attackType
                                        , CreatureRef attackerRef
                                        , CreatureRef defenderRef)
        {
            Dictionary <string, Param> abilityParams = new Dictionary <string, Param> ();

            if (creatureRef.Items != null)
            {
                foreach (object item in creatureRef.Items)
                {
                    if (item is Spell)
                    {
                        Reference refSpell = (Reference)item;
                        Spell     spell    = World.Spells[refSpell.Name];
                        //AddFactor(dict, spell.Items, fight, attacker, defender, attackerRef, defenderRef);
                    }
                    if (item is Param)
                    {
                        abilityParams.Add(((Param)item).Name, (Param)item);
                    }
                }
            }

            Creature creature = World.Creatures[creatureRef.Name];

            if (creature.Items != null)
            {
                foreach (Reference abilityRef in creature.Items)
                {
                    CreatureAbility ability = World.CreatureAbilities[abilityRef.Name];
                    AddFactor(dict, ability.Items, fight, attacker, defender, attackType, attackerRef, defenderRef, ability, abilityRef, abilityParams);
                }
            }
        }
        private decimal EvalModificator(object modificator, FactorInfo factorInfo, Dictionary <FactorType, List <FactorInfo> > defenderFactors, Hero hero, Creature creature, TextWriter log, decimal i2, decimal r2 = 1)
        {
            // %HeroLevel%
            // %CreatureLevel%
            // %Immunity%
            // %CreatureAttack%
            // %CreatureDefense%
            // %I2%
            // %R2%
            // PARAMS

            string    value    = string.Empty;
            decimal   retValue = 0;
            RoundType round    = RoundType.None;

            // get value from modificator
            if (modificator is Modificator)
            {
                value = ((Modificator)modificator).Value;
                round = ((Modificator)modificator).RoundType;
            }
            else if (modificator is LevelModificator)
            {
                LevelModificator levelModificator = (LevelModificator)modificator;
                string           level            = string.Empty;
                if (factorInfo.ParentRef != null)
                {
                    level = factorInfo.ParentRef.Level;
                }
                if (string.IsNullOrEmpty(level) || level == "0")
                {
                    value = levelModificator.Level_0.Value;
                }
                else if (level == "1")
                {
                    value = levelModificator.Level_1.Value;
                }
                else if (level == "2")
                {
                    value = levelModificator.Level_2.Value;
                }
                else if (level == "3")
                {
                    value = levelModificator.Level_3.Value;
                }

                round = levelModificator.RoundType;
            }
            log.WriteLine("Evaluating value '{0}' for {1}", value, creature.Name);

            // replace standard values
            value = value.Replace("%HeroLevel%", hero.Level.ToString());
            value = value.Replace("%CreatureLevel%", creature.Level.ToString());
            value = value.Replace("%CreatureAttack%", creature.Attack.ToString());
            value = value.Replace("%CreatureDefense%", creature.Defense.ToString());

            System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
            nfi.NumberDecimalSeparator = ".";
            value = value.Replace("%I2%", i2.ToString(nfi));

            value = value.Replace("%R2%", i2.ToString(nfi));

            // check immunity
            if (factorInfo.Parent is CreatureAbility)
            {
                string          immunity = "0";
                CreatureAbility ability  = (CreatureAbility)factorInfo.Parent;
                if (defenderFactors.ContainsKey(FactorType.ImmuneToCreatureAbility))
                {
                    List <FactorInfo> immunityFactors = defenderFactors[FactorType.ImmuneToCreatureAbility];
                    foreach (FactorInfo immunityFactor in immunityFactors)
                    {
                        if (ability.Name == immunityFactor.Factor.CreatureAbility)
                        {
                            immunity = "1";
                        }
                    }
                }
                value = value.Replace("%Immunity%", immunity);
            }

            // params
            if (factorInfo.Parent is CreatureAbility)
            {
                CreatureAbility ability = (CreatureAbility)factorInfo.Parent;
                if (!string.IsNullOrEmpty(ability.Params))
                {
                    string [] abilityParams = ability.Params.Split(' ');
                    foreach (string param in abilityParams)
                    {
                        string val = "0";
                        if (factorInfo.Params != null && factorInfo.Params.ContainsKey(param))
                        {
                            Param refParam = factorInfo.Params[param];
                            val = refParam.Value.ToString();
                        }
                        value = value.Replace("%" + param + "%", val);
                    }
                }
            }

            // evaluate string
            log.WriteLine("Evaluating direct value '{0}' for {1}", value, creature.Name);

            DataTable dt = new DataTable();

            retValue = System.Convert.ToDecimal(dt.Compute(value, string.Empty));
            if (round == RoundType.Down)
            {
                retValue = System.Math.Floor(retValue);
            }
            else if (round == RoundType.Up)
            {
                retValue = System.Math.Ceiling(retValue);
            }
            else if (round == RoundType.Normal)
            {
                retValue = System.Math.Round(retValue);
            }

            log.WriteLine("Counted value '{0}' for {1}", retValue, creature.Name);

            return(retValue);
        }