Пример #1
0
        private void GetTargetFromText(Action action, List <string> errors, int reachEnd)
        {
            var end = action.Text.IndexOf("Hit:", StringComparison.Ordinal);

            if (end != -1)
            {
                action.Attack.Target = action.Text.Substring(reachEnd, end - reachEnd).Trim(',').Trim(' ').Trim('.');
                return;
            }
            errors.Add("unable to find target in " + action.Text);
        }
Пример #2
0
        private void GetHitBonusFromText(Action action, List <string> errors)
        {
            var hitRegex = new Regex(@"\+( )*([0-9]*) to hit");
            var hit      = hitRegex.Match(action.Text);

            if (hit.Success)
            {
                action.Attack.AttackBonus = Convert.ToInt32(hit.Groups[2].Value);
                return;
            }
            errors.Add("unable to find hit bonus in " + action.Text);
        }
Пример #3
0
        public Action ParseAction(ActionRaw raw, List <string> errors, DynamicEnumProvider dep)
        {
            var action = new Action
            {
                Name = raw.Name,
                Text = new Regex("[ ]{2,}", RegexOptions.None).Replace(raw.Text.Replace("\r\n", " ").Replace("\n", " ").Replace("\r", " "), " "),
            };

            GetAttackTypeFromText(action, errors);
            if (action.Attack != null)
            {
                GetHitBonusFromText(action, errors);
                GetReachFromText(action, errors, out var reachEnd);
                GetTargetFromText(action, errors, reachEnd);
            }
            var pos = 0;

            FindHitEffects(action, errors, ref pos, dep);
            return(action);
        }
Пример #4
0
        private void GetAttackTypeFromText(Action action, List <string> errors)
        {
            var text = action.Text.ToLower();
            var t    = Enum.GetValues(typeof(AttackType));

            AttackType[] types = new AttackType[t.Length];
            t.CopyTo(types, 0);
            t = types.Reverse().ToArray();
            foreach (AttackType type in t)
            {
                if (text.Contains(type.ToString().Replace("_", " ").ToLower()))
                {
                    action.Attack = new Attack
                    {
                        Type = type
                    };
                    return;
                }
            }
            errors.Add("Unable to find AttackType in " + action.Text);
        }
Пример #5
0
        private void FindHitEffects(Action action, List <string> errors, ref int pos, DynamicEnumProvider dep)
        {
            var HitDieRegex    = new Regex(@"([0-9]*) \(([0-9]*)d([0-9]*)( [\+|\-] [0-9]*)*\) ([a-z]*) damage");
            var hitDies        = HitDieRegex.Matches(action.Text);
            var positions      = hitDies.ToDictionary(d => d.Index, d => d);
            var DCRegex        = new Regex(@"(DC ([0-9]*) ([A-Za-z]*) saving throw)|(\(escape DC ([0-9]*)\))|(DC ([0-9]*) [A-Za-z]* \(([A-Za-z]*)\)( or [A-Za-z]* \(([A-Za-z]*)\)*)* check)", RegexOptions.None);
            var dcs            = DCRegex.Matches(action.Text);
            var dcPositions    = dcs.ToDictionary(d => d.Index, d => d);
            var conditionRegex = new Regex(Enum.GetNames(typeof(Condition)).Select(c => "(" + c.ToLower() + ")").ToArray().Join("|"));
            var conditions     = conditionRegex.Matches(action.Text);
            var effects        = new Dictionary <int, HitEffect>();

            foreach (var hitDie in positions)
            {
                var hitEffect  = FindEffectForPosition(hitDie.Key, dep, effects, dcPositions);
                var damageDie  = new DieRoll(Convert.ToInt32(hitDie.Value.Groups[3].Value), Convert.ToInt32(hitDie.Value.Groups[2].Value), hitDie.Value.Groups[4].Value.Length > 0 ? Convert.ToInt32(hitDie.Value.Groups[4].Value.Replace(" ", "")) : 0);
                var damageType = Enum.Parse <DamageType>(hitDie.Value.Groups[5].Value, true);
                if (hitEffect.DamageDie != null)
                {
                    hitEffect = new HitEffect(hitEffect)
                    {
                        DamageDie  = damageDie,
                        DamageType = damageType
                    };
                    action.HitEffects.Add(hitEffect);
                }
                else
                {
                    hitEffect.DamageDie  = damageDie;
                    hitEffect.DamageType = damageType;
                }
            }
            foreach (var cond in conditions.ToArray())
            {
                var hitEffect = FindEffectForPosition(cond.Index, dep, effects, dcPositions);
                hitEffect.Condition.Add(Enum.Parse <Condition>(cond.Value, true));
            }

            action.HitEffects.AddRange(effects.Values);
        }
Пример #6
0
        private void GetReachFromText(Action action, List <string> errors, out int reachEnd)
        {
            var start = action.Text.IndexOf("reach", StringComparison.Ordinal);
            int end;

            reachEnd = 0;
            if (start != -1)
            {
                start += "reach".Length;
                end    = action.Text.IndexOf("ft.", start, StringComparison.Ordinal);
                if (end != -1)
                {
                    action.Attack.Reach = Convert.ToInt32(action.Text.Substring(start, end - start).Trim());
                    reachEnd            = end + 3;
                }
            }
            start = action.Text.IndexOf("range", StringComparison.Ordinal);
            if (start != -1)
            {
                start += "range".Length;
                end    = action.Text.IndexOf("ft.", start, StringComparison.Ordinal);
                if (end != -1)
                {
                    var range = action.Text.Substring(start, end - start).Trim().Split('/');
                    action.Attack.ShortRange = Convert.ToInt32(range[0]);
                    if (range.Length > 1)
                    {
                        action.Attack.LongRange = Convert.ToInt32(range[1]);
                    }
                    reachEnd = end + 3;
                }
            }
            if (action.Attack.Type == AttackType.Melee_Spell_Attack ||
                action.Attack.Type == AttackType.Melee_Weapon_Attack ||
                action.Attack.Type == AttackType.Melee_or_Ranged_Spell_Attack ||
                action.Attack.Type == AttackType.Melee_or_Ranged_Weapon_Attack)
            {
                if (action.Attack.Reach == 0)
                {
                    errors.Add("Unable to find Reach in " + action.Text);
                }
            }
            if (action.Attack.Type == AttackType.Ranged_Spell_Attack ||
                action.Attack.Type == AttackType.Ranged_Weapon_Attack ||
                action.Attack.Type == AttackType.Melee_or_Ranged_Spell_Attack ||
                action.Attack.Type == AttackType.Melee_or_Ranged_Weapon_Attack)
            {
                if (action.Attack.ShortRange == 0)
                {
                    errors.Add("Unable to find short range in " + action.Text);
                }
            }
            if (action.Attack.Type == AttackType.Ranged_Weapon_Attack ||
                action.Attack.Type == AttackType.Melee_or_Ranged_Weapon_Attack)
            {
                if (action.Attack.LongRange == 0)
                {
                    errors.Add("Unable to find long range in " + action.Text);
                }
            }
        }