コード例 #1
0
        private HitEffect FindEffectForPosition(int position, DynamicEnumProvider dep, Dictionary <int, HitEffect> effects, Dictionary <int, Match> dcPositions)
        {
            HitEffect effect;
            var       dc = dcPositions.LastOrDefault(d => d.Key < position || d.Key - 20 < position && d.Value.Value.Contains("escape"));

            if (!dc.Equals(default(KeyValuePair <int, Match>)))
            {
                if (!effects.ContainsKey(dc.Key))
                {
                    effects[dc.Key] = new HitEffect();
                    if (dc.Value.Value.Contains("escape"))
                    {
                        effects[dc.Key].DC = new SkillCheck
                        {
                            Skill = Skill.Acrobatics | Skill.Athletics,
                            Value = Convert.ToInt32(dc.Value.Groups[5].Value)
                        };
                    }
                    else if (dc.Value.Value.Contains("check"))
                    {
                        effects[dc.Key].DC = new SkillCheck
                        {
                            Value = Convert.ToInt32(dc.Value.Groups[7].Value)
                        };
                        var reg = new Regex(@"\([A-Za-z]*\)");
                        foreach (var s in reg.Matches(dc.Value.Value).Select(s => Enum.Parse <Skill>(s.Value.Trim('(', ')'), true)))
                        {
                            ((SkillCheck)effects[dc.Key].DC).Skill |= s;
                        }
                    }
                    else if (dc.Value.Value.Contains("saving throw"))
                    {
                        var str = dc.Value.Value.Replace("saving throw", "").Replace("DC " + dc.Value.Groups[2].Value, "").Trim();
                        effects[dc.Key].DC = new SavingThrow()
                        {
                            Value   = Convert.ToInt32(dc.Value.Groups[2].Value),
                            Ability = dep.GetEnumValues("Ability").Parse(str)
                        };
                    }
                }
                effect = effects[dc.Key];
            }
            else
            {
                if (!effects.ContainsKey(0))
                {
                    effects[0] = new HitEffect();
                }
                effect = effects[0];
            }
            return(effect);
        }
コード例 #2
0
        public void Test1()
        {
            var           ap     = new ActionParser();
            var           dep    = new DynamicEnumProvider(null);
            List <string> errors = new List <string>();
            var           action = ap.ParseAction(new ActionRaw()
            {
                Name = "Bite",
                Text = @"Melee Weapon Attack: +4 to hit, reach 5 ft., one target.
                Hit: 7 (1d10 + 2) piercing damage plus 5 (1d10) poison
                damage, and the target is grappled (escape DC 13). Until this
                grapple ends, the target is restrained, and the toad can't bite
                another target. "
            }, errors, dep);

            Assert.Equal(new Attack
            {
                AttackBonus = 4,
                LongRange   = 0,
                ShortRange  = 0,
                Reach       = 5,
                Target      = "one target",
                Type        = AttackType.Melee_Weapon_Attack
            }, action.Attack);
            Assert.Contains(new HitEffect
            {
                Condition  = null,
                DamageType = DamageType.Piercing,
                DC         = null,
                DamageDie  = new DieRoll(10, 1, 2)
            }, action.HitEffects);
            Assert.Contains(new HitEffect
            {
                Condition  = null,
                DamageType = DamageType.Poison,
                DC         = null,
                DamageDie  = new DieRoll(10, 1, 0)
            }, action.HitEffects);
            Assert.Contains(new HitEffect
            {
                Condition = new List <Condition> {
                    Condition.Grappled, Condition.Restrained
                },
                DamageType = null,
                DC         = new SkillCheck {
                    Skill = Skill.Acrobatics | Skill.Athletics, Value = 13
                },
                DamageDie = null
            }, action.HitEffects);
        }
コード例 #3
0
 public Spellcasting CheckForSpellcasting(List <Spell> spells, MonsterRaw raw, ref List <string> errors,
                                          DynamicEnumProvider dep)
 {
     for (var i = 0; i < raw.Traits.Count; i++)
     {
         var trait = raw.Traits[i];
         if (trait.Name.Equals("Spellcasting"))
         {
             var spellcasting = _spellParser.ParseSpellcasting(trait.Text, spells, ref errors, dep);
             raw.Traits.RemoveAt(i);
             return(spellcasting);
         }
     }
     return(null);
 }
コード例 #4
0
        private string TryFindSpellcastingAbility(string spellcastingDescription, DynamicEnumProvider dep, ref List <String> errors)
        {
            var desc = spellcastingDescription.ToLower();

            foreach (var attr in dep.GetEnumValues("Ability").Data)
            {
                if (desc.Contains("ability is " + attr.ToLower()))
                {
                    return(attr);
                }
                if (desc.Contains("that uses " + attr.ToLower() + " as "))
                {
                    return(attr);
                }
            }
            errors.Add("Unable to find spellcasting ability in description: " + spellcastingDescription);
            return("Strength");
        }
コード例 #5
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);
        }
コード例 #6
0
 public Monster(DynamicEnumProvider dep)
 {
     Abilities = new Dictionary <string, AbilityScore>();
     foreach (var ability in dep.GetEnumValues("Ability").Data)
     {
         Abilities.Add(ability, new AbilityScore()
         {
             Value = 10
         });
     }
     Race            = new();
     Senses          = new();
     ChallengeRating = new();
     HitDie          = new();
     Skillmodifiers  = new();
     SavingThrows    = new();
     Alignment       = new();
     Speed           = new();
     ArmorInfo       = new();
 }
コード例 #7
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);
        }
コード例 #8
0
 public DefaultController(DataProvider dataProvider, DynamicEnumProvider dep)
 {
     _dataProvider = dataProvider;
     this.dep      = dep;
 }
コード例 #9
0
        public Spellcasting ParseSpellcasting(string spellcastingDescription, List <Spell> spells, ref List <string> errors, DynamicEnumProvider dep)
        {
            spellcastingDescription = spellcastingDescription
                                      .Replace("spell caster", "spellcaster")
                                      .Replace("level-spellcaster", "level spellcaster")
                                      .Replace(": ", ":")
                                      .Replace(":", ": ")
                                      .Replace("th-level", "th level")
                                      .Replace("th level spellcaster", "th-level spellcaster")
                                      .Replace("th level slot", "th-level slot")
                                      .Replace("Save DC", "save DC")
                                      .Replace(" Level", " level")
                                      .Replace("st—", "st-");
            var SpellcastingLevel   = TryFindLevel(spellcastingDescription, ref errors);
            var SpellListClass      = TryFindSpellListClass(spellcastingDescription, ref errors);
            var SpellcastingAbility = TryFindSpellcastingAbility(spellcastingDescription, dep, ref errors);
            var SpellslotsByLevel   = GetSpellslotByLevel(SpellcastingLevel, SpellListClass);
            var Spellslots          = CheckSpellslotsByDescription(SpellslotsByLevel, SpellListClass, spellcastingDescription);

            if (!Spellslots.SequenceEqual(SpellslotsByLevel))
            {
                var levelBySlots = FindSpellCastingLevelBySlots(Spellslots, SpellListClass);
                if (levelBySlots != -1)
                {
                    spellcastingDescription = FixDescription(SpellcastingLevel, levelBySlots, spellcastingDescription);
                    SpellcastingLevel       = levelBySlots;
                }
            }
            var SpellDC = TryFindSpellsaveDC(spellcastingDescription, ref errors);
            var SpellcastingModifier = TryFindSpellcastingModifier(spellcastingDescription, SpellDC, ref errors);
            var Spells = TryFindSpells(Spellslots, spellcastingDescription, SpellListClass, spells, ref errors, out var _spellTableStart, out var _spellTableEnd);

            var(before, _, after) = RemoveSpellTable(_spellTableStart, _spellTableEnd, spellcastingDescription);
            return(new Spellcasting
            {
                Name = "Spellcasting",
                Text = spellcastingDescription,
                SpellcastingLevel = SpellcastingLevel,
                SpellListClass = SpellListClass,
                SpellcastingAbility = SpellcastingAbility,
                Spellslots = Spellslots,
                SpellDC = SpellDC,
                SpellcastingModifier = SpellcastingModifier,
                Spells = Spells,
                TextBeforeTable = before,
                TextAfterTable = after
            });
        }
コード例 #10
0
 public string GetAbility(DynamicEnumProvider dep)
 {
     return(dep.GetEnumValues("Ability").GetFromInt(AbilityId));
 }
コード例 #11
0
 private List <Action> ParseActions(List <ActionRaw> raw, List <string> errors, DynamicEnumProvider dep)
 {
     return(raw.Select(r => _actionParser.ParseAction(r, errors, dep)).ToList());
 }
コード例 #12
0
 public MonsterParser(SpellcastingParser spellParser, ActionParser actionParser, DynamicEnumProvider dep)
 {
     _spellParser  = spellParser;
     _actionParser = actionParser;
     _dep          = dep;
 }