/// <summary> /// Populates a given NarrativeEffect struct with all parsable stat changes found in a line. /// </summary> /// <param name="input">The data line to parse.</param> /// <param name="effect">The struct to populate.</param> private void PopulateStatChanges(string input, ref NarrativeEffect effect, List <int> lineNumbers) { var statMatches = StatRegex.Matches(input); foreach (Match match in statMatches) { // Check if a matched stat is invalid if (!StatMap.ContainsKey(match.Groups[1].Value)) { WarnInvalidStat(match.Groups[1].Value, lineNumbers); continue; } // Otherwise, process as normal var stat = StatMap[match.Groups[1].Value]; var operation = match.Groups[2].Value[0]; _ = int.TryParse(match.Groups[3].Value, out var value); switch (operation) { case Symbol.AddChar: effect.statChanges.Add(new StatChange(stat, value, true)); break; case Symbol.SubChar: effect.statChanges.Add(new StatChange(stat, -value, true)); break; case Symbol.SetChar: effect.statChanges.Add(new StatChange(stat, value, false)); break; } } }
/// <summary> /// Populates a given NarrativeEffect struct with all parsable trait changes found in a line. /// </summary> /// <param name="input">The data line to parse.</param> /// <param name="effect">The struct to populate.</param> private void PopulateTraitChanges(string input, ref NarrativeEffect effect, List <int> lineNumbers) { var traitMatches = TraitRegex.Matches(input); foreach (Match match in traitMatches) { var target = match.Groups[1].Value; var trait = match.Groups[2].Value; if (string.IsNullOrWhiteSpace(target)) { effect.characterTraits.Add(trait); } else if (Symbol.Encounter == target.ToLower()) { effect.encounterTraits.Add(trait); } else if (Symbol.Session == target.ToLower()) { effect.sessionTraits.Add(trait); } else { WarnInvalidTrait(target, lineNumbers); } } }
/// <summary>Update the list of effects that should be applied.</summary> /// <param name="narrativeEffect">Struct containing the new set of effects to apply.</param> public void Set(NarrativeEffect narrativeEffect) { applied = false; statChanges = narrativeEffect.statChanges ?? new List <StatChange>(); traits = narrativeEffect.characterTraits ?? new List <string>(); encounterTraits = narrativeEffect.encounterTraits ?? new List <string>(); sessionTraits = narrativeEffect.sessionTraits ?? new List <string>(); }
/// <summary> /// Attempt to create a NarrativePanelInfo from the next set of lines on the queue and /// a prepoulated property set. /// </summary> /// <param name="lines">The available lines to process.</param> /// <param name="properties">A set of prepopulated panel properties.</param> /// <returns>The info for a single NarrativePanel</returns> private NarrativePanelInfo ParseNarrativePanel(Queue <NumberedLine> lines, Dictionary <string, string> properties) { // Process lines var narrationLines = new List <string>(NarrationLines); while (lines.Count > 0 && narrationLines.Count < NarrationLines && lines.Peek().Text.StartsWith(Symbol.NarrativeLine) ) { var formattedLine = lines.Dequeue().Text.Substring(1).TrimStart(); narrationLines.Add(formattedLine); } var narration = string.Join("\n", narrationLines); // Process effects var effectBuilder = new StringBuilder(); var hasEffects = true; var lineNumbers = new List <int>(); // Check for any immediately adjacent effect lines and combine them. Ignore empty lines. while (lines.Count > 0 && hasEffects) { if (string.IsNullOrWhiteSpace(lines.Peek().Text)) { _ = lines.Dequeue(); } else if (lines.Peek().Text.StartsWith(Symbol.EffectLine)) { var next = lines.Dequeue(); _ = effectBuilder.Append(next.Text); lineNumbers.Add(next.Number); } else { hasEffects = false; } } var effectLine = effectBuilder.ToString(); var effect = new NarrativeEffect { statChanges = new List <StatChange>(), characterTraits = new List <string>(), encounterTraits = new List <string>(), sessionTraits = new List <string>() }; PopulateStatChanges(effectLine, ref effect, lineNumbers); PopulateTraitChanges(effectLine, ref effect, lineNumbers); return(new NarrativePanelInfo(properties, narration, effect)); }
public NarrativePanelInfo(Dictionary <string, string> properties, string text, NarrativeEffect effect) : base(properties) { Text = text; Effect = effect; }