Ejemplo n.º 1
0
        public override void AddField(TextSpan field)
        {
            if (field.Value == "DONOTADD:HITDIE")
            {
                DoNotAddHitDie = true;
                return;
            }

            if (field.Value == "DONOTADD:SKILLPOINTS")
            {
                DoNotAddSkillPoints = true;
                return;
            }

            if (field.TryRemovePrefix("CAST:", out field))
            {
                SpellsPerDay.Clear();
                SpellsPerDay.AddRange(field.Split(',').Select(v => new Formula(v.Value)).ToList());
                return;
            }

            if (field.TryRemovePrefix("KNOWN:", out field))
            {
                SpellsKnown.Clear();
                SpellsKnown.AddRange(field.Split(',').Select(v => new Formula(v.Value)).ToList());
                return;
            }
            base.AddField(field);
        }
Ejemplo n.º 2
0
        public ServesAs(TextSpan value)
        {
            using var enumerator = value.Split('|').GetEnumerator();
            if (!enumerator.MoveNext())
            {
                throw new ParseFailedException(value, "Cannot parse SERVESAS");
            }

            if (enumerator.Current.TryRemovePrefix("ABILITY=", out var ability))
            {
                Ability = ability.Value;
            }
            else if (enumerator.Current.Value == "CLASS")
            {
                Class = true;
            }
            else if (enumerator.Current.Value == "RACE")
            {
                Race = true;
            }
            else if (enumerator.Current.Value == "SKILL")
            {
                Skill = true;
            }
            else
            {
                throw new ParseFailedException(enumerator.Current, "Cannot parse SERVESAS");
            }

            while (enumerator.MoveNext())
            {
                Names.Add(enumerator.Current.Value);
            }
        }
Ejemplo n.º 3
0
 public static IEnumerable <NaturalAttack> ParseAll(TextSpan value)
 {
     foreach (var part in value.Split('|'))
     {
         yield return(new NaturalAttack(part));
     }
 }
        public ContainerDefinition(TextSpan value)
        {
            bool first = true;

            foreach (var p in value.Split('|'))
            {
                var part = p;
                if (first)
                {
                    if (part.TryRemovePrefix("*", out part))
                    {
                        ContainedItemWeightDoesNotCount = true;
                    }
                    if (part.Value == "UNLIM")
                    {
                        Capacity = double.PositiveInfinity;
                    }
                    else if (part.TryRemoveInfix("%", out var percent, out var cap))
                    {
                        ContainedItemWeightModifier = Helpers.ParseDouble(percent) / 100;
                        Capacity = Helpers.ParseDouble(cap);
                    }
                    else
                    {
                        Capacity = Helpers.ParseDouble(part);
                    }
                    first = false;
                    continue;
                }

                if (!part.TryRemoveInfix("=", out var name, out var count))
                {
                    ItemLimits[part.Value] = null;
                }
Ejemplo n.º 5
0
        public static Bonus Parse(TextSpan value)
        {
            var parts = value.Split('|').ToArray();

            if (parts.Length < 3)
            {
                throw new ParseFailedException(value, "Unable to parse bonus.");
            }

            BonusType?       type       = null;
            List <Condition> conditions = new List <Condition>();

            foreach (var extra in parts.Skip(3))
            {
                if (BonusType.TryParse(extra, out type))
                {
                    continue;
                }

                if (Condition.TryParse(extra, out var condition))
                {
                    conditions.Add(condition);
                }
            }

            var variables = parts[1].Split(',').Select(t => t.Value).ToList();

            return(new Bonus(parts[0].Value, variables, type, parts[2].Value, conditions));
        }
Ejemplo n.º 6
0
 protected override void UnknownField(TextSpan field)
 {
     foreach (var subPart in field.Split(','))
     {
         if (subPart.TryRemovePrefix("RACETYPE=", out var raceType))
         {
             FollowerConditions.Add($"follower.RaceType == \"{raceType.Value}\"");
         }
         else if (subPart.TryRemovePrefix("RACESUBTYPE=", out var raceSubType))
         {
             FollowerConditions.Add($"follower.RaceSubType == \"{raceSubType.Value}\"");
         }
         else if (subPart.TryRemovePrefix("FOLLOWERADJUSTMENT:", out var adjustment))
         {
             FollowerLevelAdjustment = Helpers.ParseInt(adjustment);
         }
         else if (subPart.Value == "ANY")
         {
             FollowerConditions.Add("true");
         }
         else
         {
             FollowerConditions.Add($"follower.Name == \"{subPart.Value}\"");
         }
     }
 }
 public ChangeWeaponProficiencyCategory(TextSpan value)
 {
     foreach (var part in value.Split('|'))
     {
         var(weapons, category)  = part.SplitTuple('=');
         Changes[category.Value] = weapons.Value.Split(',').ToList();
     }
 }
Ejemplo n.º 8
0
        public static ProhibitedSpell Parse(TextSpan value)
        {
            string?          alignment  = null;
            string?          descriptor = null;
            string?          school     = null;
            string?          subschool  = null;
            List <string>    names      = new List <string>();
            List <Condition> conditions = new List <Condition>();
            var parts = value.Split('|').ToArray();

            if (parts.Length < 1)
            {
                throw new ParseFailedException(value, "Unable to parse PROHIBITSPELL");
            }

            var whatSpell = parts[0];

            if (whatSpell.StartsWith("ALIGNMENT."))
            {
                alignment = whatSpell.Substring("ALIGNMENT.".Length).Value;
            }
            else if (whatSpell.StartsWith("DESCRIPTOR."))
            {
                descriptor = whatSpell.Substring("DESCRIPTOR.".Length).Value;
            }
            else if (whatSpell.StartsWith("SCHOOL."))
            {
                school = whatSpell.Substring("SCHOOL.".Length).Value;
            }
            else if (whatSpell.StartsWith("SUBSCHOOL."))
            {
                subschool = whatSpell.Substring("SUBSCHOOL.".Length).Value;
            }
            else if (whatSpell.StartsWith("SPELL."))
            {
                var spells = whatSpell.Substring("SPELL.".Length);
                foreach (var spell in spells.Split(','))
                {
                    names.Add(spell.Value);
                }
            }
            else
            {
                throw new ParseFailedException(value, "Unable to parse PROHIBITSPELL");
            }
            foreach (var extra in parts.Skip(1))
            {
                if (!Condition.TryParse(extra, out var condition))
                {
                    throw new ParseFailedException(value, "Expected condition in PROHIBITSPELL definition.");
                }

                conditions.Add(condition);
            }

            return(new ProhibitedSpell(alignment, descriptor, school, subschool, names, conditions));
        }
Ejemplo n.º 9
0
 public FormattedString(TextSpan value)
 {
     AddPropertyDefinitions(() => new[]
     {
         CommonProperties.Conditions,
     });
     foreach (var part in value.Split('|'))
     {
         AddField(part);
     }
 }
Ejemplo n.º 10
0
 public Aspect(TextSpan value)
 {
     AddPropertyDefinitions(() => new []
     {
         CommonProperties.Conditions,
     });
     foreach (var f in value.Split('|'))
     {
         AddField(f);
     }
 }
Ejemplo n.º 11
0
 public AutomaticLanguage(TextSpan value)
 {
     AddPropertyDefinitions(() => new []
     {
         CommonProperties.Conditions,
     });
     foreach (var part in value.Split('|'))
     {
         AddField(part);
     }
 }
Ejemplo n.º 12
0
 public DomainReference(TextSpan value)
 {
     AddPropertyDefinitions(() => new[]
     {
         CommonProperties.Conditions,
     });
     foreach (var part in value.Split('|'))
     {
         AddField(part);
     }
 }
Ejemplo n.º 13
0
        public NaturalAttack(TextSpan value)
        {
            var parts = value.Split(',').ToList();

            if (parts.Count != 4 && parts.Count != 5)
            {
                throw new ParseFailedException(value, "Unable to parse NATURALATTACKS");
            }

            if (parts.Count == 5)
            {
                SpecialDescription = parts[4].Value;
            }
            Name   = parts[0].Value;
            Types  = parts[1].Value.Split('.');
            Count  = parts[2].Value;
            Damage = parts[3].Value;
        }
Ejemplo n.º 14
0
        public Bonus(TextSpan value)
        {
            AddPropertyDefinitions(() => new[]
            {
                IsEquipment?CommonProperties.ConditionForEquipment: CommonProperties.Conditions,
            });

            if (!value.TryRemoveInfix("|", out var category, out value))
            {
                throw new ParseFailedException(value, "Unable to parse bonus.");
            }
            if (!value.TryRemoveInfix("|", out var variableSpan, out value))
            {
                throw new ParseFailedException(value, "Unable to parse bonus.");
            }

            Category = category.Value;
            foreach (var part in value.Split('|'))
            {
                // This is fine, Provided that the only inheritor is EquipmentBonus
                // and it only overrides the IsEquipment property
                // ReSharper disable once VirtualMemberCallInConstructor
                AddField(part);
            }

            Formula ??= "%CHOICEVALUE";
            switch (Category)
            {
            case "ITEMCOST":
                Variables.Add("Cost");
                if (!variableSpan.TryRemovePrefix("TYPE.", out var types))
                {
                    throw new ParseFailedException(value, "Unable to parse bonus.");
                }
                var allTypes = types.Value.Split('.').Select(t => $"item.IsType(\"{t}\")").ToList();
                Properties.GetList <Condition>("Conditions")
                .Add(new EquipmentTypeCondition(false, allTypes.Count, allTypes));
                break;

            default:
                Variables.AddRange(variableSpan.Value.Split(','));
                break;
            }
        }
Ejemplo n.º 15
0
        public static DomainReference Parse(TextSpan value)
        {
            var conditions = new List <Condition>();
            var names      = new List <string>();

            foreach (var part in value.Split('|'))
            {
                if (Condition.TryParse(part, out var condition))
                {
                    conditions.Add(condition);
                }
                else
                {
                    names.Add(part.Value);
                }
            }

            return(new DomainReference(conditions, names));
        }
Ejemplo n.º 16
0
        public static List <SpellList> Parse(TextSpan textSpan)
        {
            var parts = textSpan.Split('|').ToArray();
            var kind  = parts[0].Value switch
            {
                "DOMAIN" => SpellListKind.Domain,
                "CLASS" => SpellListKind.Class,
                _ => throw new ParseFailedException(parts[0], "Unable to parse SPELLLEVEL or SPELLKNOWN"),
            };
            var       spellLists   = new Dictionary <string, SpellList>();
            SpellList?currentList  = null;
            int?      currentLevel = null;

            foreach (var part in parts.Skip(1))
            {
                if (part.Value.Contains("="))
                {
                    var(nameSpan, levelStr) = part.SplitTuple('=');
                    var name = nameSpan.Value;
                    currentList  = spellLists.GetOrAdd(name, () => new SpellList(kind, name));
                    currentLevel = Helpers.ParseInt(levelStr);
                }
                else if (part.StartsWith("PRE") && currentList != null)
                {
                    currentList.AddField(part);
                }
                else
                {
                    if (!currentLevel.HasValue || currentList == null)
                    {
                        throw new ParseFailedException(part, "Unable to parse SPELLLEVEL or SPELLKNOWN");
                    }
                    var spells = part.Split(',').Select(s => s.Value);
                    var level  = new SpellListLevel(currentLevel.Value);
                    level.Spells.AddRange(spells);
                    currentList.Levels.Add(level);
                }
            }

            return(spellLists.Values.ToList());
        }
        private EquipmentModifierReference(TextSpan value)
        {
            bool first = true;

            foreach (var p in value.Split('|'))
            {
                var part = p;
                if (first)
                {
                    Key   = part.Value;
                    first = false;
                    continue;
                }

                Parameters.Add(part.Value);
            }

            if (Key == null)
            {
                throw new ParseFailedException(value, "Unable to parse EQMOD:");
            }
        }
Ejemplo n.º 18
0
        public static AbilityReference Parse(TextSpan value)
        {
            var parts = value.Split('|').ToArray();

            if (parts.Length < 3)
            {
                throw new ParseFailedException(value, "Unable to parse AbilityReference");
            }

            var    category   = parts[0].Value;
            var    nature     = parts[1].Value;
            var    conditions = new List <Condition>();
            string?type       = null;
            string?name       = null;

            foreach (var part in parts.Skip(2))
            {
                if (Condition.TryParse(part, out var condition))
                {
                    conditions.Add(condition);
                }
                else if (part.StartsWith("TYPE="))
                {
                    type = part.Substring("TYPE=".Length).Value;
                }
                else
                {
                    name = part.Value;
                }
            }

            if (name != null && type != null)
            {
                throw new ParseFailedException(value, "AbilityReference cannot have both a name and type");
            }

            return(new AbilityReference(category, nature, name, type, conditions));
        }
        public static AddedSpellCasterLevel Parse(TextSpan field)
        {
            bool          any   = false;
            string?       type  = null;
            List <string>?names = null;

            switch (field.Value)
            {
            case "ANY":
                any = true;
                break;

            case "Divine":
            case "Arcane":
                type = field.Value;
                break;

            default:
                names = field.Split(',').Select(s => s.Value).ToList();
                break;
            }
            return(new AddedSpellCasterLevel(any, type, names));
        }
 public static IEnumerable <EquipmentModifierReference> ParseAll(TextSpan value)
 {
     return(value.Split('.').Select(s => new EquipmentModifierReference(s)));
 }
Ejemplo n.º 21
0
        public static IList <SpellLikeAbility> ParseAll(TextSpan value)
        {
            string?spellBookName = null;
            string times         = "1";
            string timeUnit      = "Day";
            string?casterLevel   = null;
            var    spells        = new List <(string spell, string?dc)>();
            var    conditions    = new List <Condition>();

            foreach (var part in value.Split('|'))
            {
                if (spellBookName == null)
                {
                    spellBookName = part.Value;
                    continue;
                }

                if (part.TryRemovePrefix("TIMES=", out var t))
                {
                    times = t.Value;
                    continue;
                }

                if (part.TryRemovePrefix("TIMEUNIT=", out var tu))
                {
                    timeUnit = tu.Value;
                    continue;
                }

                if (part.TryRemovePrefix("CASTERLEVEL=", out var cl))
                {
                    casterLevel = cl.Value;
                    continue;
                }

                if (Condition.TryParse(part, out var condition))
                {
                    conditions.Add(condition);
                    continue;
                }

                if (part.Value.Contains(","))
                {
                    var(name, dc) = part.SplitTuple(',');
                    spells.Add((name.Value, dc.Value));
                }
                else
                {
                    spells.Add((part.Value, null));
                }
            }

            if (spellBookName == null)
            {
                throw new ParseFailedException(value, "Unable to parse SPELLS:");
            }

            return(spells.Select(s =>
            {
                var result = new SpellLikeAbility(s.spell, s.dc, spellBookName, times, timeUnit, casterLevel, conditions);
                return result;
            }).ToList());
        }