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); }
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); } }
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; }
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)); }
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(); } }
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)); }
public FormattedString(TextSpan value) { AddPropertyDefinitions(() => new[] { CommonProperties.Conditions, }); foreach (var part in value.Split('|')) { AddField(part); } }
public Aspect(TextSpan value) { AddPropertyDefinitions(() => new [] { CommonProperties.Conditions, }); foreach (var f in value.Split('|')) { AddField(f); } }
public AutomaticLanguage(TextSpan value) { AddPropertyDefinitions(() => new [] { CommonProperties.Conditions, }); foreach (var part in value.Split('|')) { AddField(part); } }
public DomainReference(TextSpan value) { AddPropertyDefinitions(() => new[] { CommonProperties.Conditions, }); foreach (var part in value.Split('|')) { AddField(part); } }
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; }
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; } }
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)); }
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:"); } }
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))); }
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()); }