270 lines
9 KiB
C#
270 lines
9 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Chronicle-voice templates. Hook = fact (<see cref="ChronicleEntry.Line"/>);
|
|
/// sentence = optional poetry (<see cref="ChronicleEntry.LoreLine"/>). Never invents facts.
|
|
/// </summary>
|
|
public static class LoreProse
|
|
{
|
|
private static readonly Regex KillPattern =
|
|
new Regex(@"^Killed (.+) \(([^)]+)\)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex KilledByPattern =
|
|
new Regex(@"^Killed by (.+) \(([^)]+)\)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex EatenByPattern =
|
|
new Regex(@"^Eaten by (.+) \(([^)]+)\)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex LoversPattern =
|
|
new Regex(@"^Became lovers with (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex FriendPattern =
|
|
new Regex(@"^Befriended (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex WarVsPattern =
|
|
new Regex(@"^War: (.+) vs (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex TotalWarPattern =
|
|
new Regex(@"^Total war: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex KingdomFellPattern =
|
|
new Regex(@"^Kingdom fell: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex KingdomNewPattern =
|
|
new Regex(@"^New kingdom: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex CityDestroyedPattern =
|
|
new Regex(@"^City destroyed: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex CityNewPattern =
|
|
new Regex(@"^New city: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex NewKingPattern =
|
|
new Regex(@"^New king: (.+) \((.+)\)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex KingDiedPattern =
|
|
new Regex(@"^King died: (.+) \((.+)\)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex KingKilledPattern =
|
|
new Regex(@"^King killed: (.+) \((.+)\)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex AlliancePattern =
|
|
new Regex(@"^Alliance: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex AllianceDissolvedPattern =
|
|
new Regex(@"^Alliance dissolved: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex WarEndedPattern =
|
|
new Regex(@"^War ended: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex RevoltPattern =
|
|
new Regex(@"^Revolt: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex ExtinctPattern =
|
|
new Regex(@"^Species extinct: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex FavoriteFellPattern =
|
|
new Regex(@"^Favorite fell: (.+)$", RegexOptions.CultureInvariant);
|
|
private static readonly Regex DisasterHint =
|
|
new Regex(@"disaster", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
|
|
|
/// <summary>Rewrite a raw history/world fact line into short legendary prose.</summary>
|
|
public static string Rewrite(ChronicleKind kind, string rawLine, string assetId = null)
|
|
{
|
|
if (string.IsNullOrEmpty(rawLine))
|
|
{
|
|
return rawLine ?? "";
|
|
}
|
|
|
|
// Long free-form harness / player lines stay as written.
|
|
if (rawLine.Length > 96)
|
|
{
|
|
return rawLine;
|
|
}
|
|
|
|
switch (kind)
|
|
{
|
|
case ChronicleKind.Kill:
|
|
return RewriteKill(rawLine);
|
|
case ChronicleKind.Death:
|
|
return RewriteDeath(rawLine);
|
|
case ChronicleKind.Lover:
|
|
return RewriteLovers(rawLine);
|
|
case ChronicleKind.Friend:
|
|
return RewriteFriend(rawLine);
|
|
case ChronicleKind.World:
|
|
return RewriteWorld(rawLine, assetId);
|
|
default:
|
|
return rawLine;
|
|
}
|
|
}
|
|
|
|
private static string RewriteKill(string raw)
|
|
{
|
|
Match m = KillPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Slew " + m.Groups[1].Value + " of the " + m.Groups[2].Value + "s";
|
|
}
|
|
|
|
return raw;
|
|
}
|
|
|
|
private static string RewriteDeath(string raw)
|
|
{
|
|
Match by = KilledByPattern.Match(raw);
|
|
if (by.Success)
|
|
{
|
|
return "Fell at " + by.Groups[1].Value + "'s hand";
|
|
}
|
|
|
|
Match eaten = EatenByPattern.Match(raw);
|
|
if (eaten.Success)
|
|
{
|
|
return "Devoured by " + eaten.Groups[1].Value;
|
|
}
|
|
|
|
switch (raw)
|
|
{
|
|
case "Died of old age":
|
|
return "Passed from old age";
|
|
case "Starved to death":
|
|
return "Starved in lean seasons";
|
|
case "Burned to death":
|
|
return "Burned to ash";
|
|
case "Burned in lava":
|
|
return "Claimed by lava";
|
|
case "Drowned":
|
|
return "Drowned beneath the waves";
|
|
case "Died of poison":
|
|
return "Succumbed to poison";
|
|
case "Died of plague":
|
|
return "Taken by plague";
|
|
case "Died of infection":
|
|
return "Taken by infection";
|
|
case "Died of a tumor":
|
|
return "Claimed by a tumor";
|
|
case "Dissolved in acid":
|
|
return "Dissolved in acid";
|
|
case "Died of ash fever":
|
|
return "Taken by ash fever";
|
|
case "Fell to their death":
|
|
return "Fell to their death";
|
|
case "Died in an explosion":
|
|
return "Perished in an explosion";
|
|
case "Struck down by divine power":
|
|
return "Struck down by divine power";
|
|
case "Was eaten":
|
|
return "Was eaten";
|
|
case "Killed in combat":
|
|
return "Fell in combat";
|
|
case "Transformed away":
|
|
return "Transformed away";
|
|
case "Died":
|
|
return "Met their end";
|
|
default:
|
|
return raw;
|
|
}
|
|
}
|
|
|
|
private static string RewriteLovers(string raw)
|
|
{
|
|
Match m = LoversPattern.Match(raw);
|
|
return m.Success ? "Heartbound to " + m.Groups[1].Value : raw;
|
|
}
|
|
|
|
private static string RewriteFriend(string raw)
|
|
{
|
|
Match m = FriendPattern.Match(raw);
|
|
return m.Success ? "Bound in friendship with " + m.Groups[1].Value : raw;
|
|
}
|
|
|
|
private static string RewriteWorld(string raw, string assetId)
|
|
{
|
|
Match m;
|
|
m = WarVsPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "War kindled: " + m.Groups[1].Value + " and " + m.Groups[2].Value;
|
|
}
|
|
|
|
m = TotalWarPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Total war engulfed " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = KingdomFellPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Kingdom fell: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = KingdomNewPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "A kingdom rose: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = CityDestroyedPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "City razed: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = CityNewPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "City founded: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = NewKingPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Crowned: " + m.Groups[1].Value + " of " + m.Groups[2].Value;
|
|
}
|
|
|
|
m = KingDiedPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "A king passed: " + m.Groups[1].Value + " of " + m.Groups[2].Value;
|
|
}
|
|
|
|
m = KingKilledPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "A king slain: " + m.Groups[1].Value + " of " + m.Groups[2].Value;
|
|
}
|
|
|
|
m = AlliancePattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Alliance forged: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = AllianceDissolvedPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Alliance broken: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = WarEndedPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "War ended: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = RevoltPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Revolt in " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = ExtinctPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "Extinct: " + m.Groups[1].Value;
|
|
}
|
|
|
|
m = FavoriteFellPattern.Match(raw);
|
|
if (m.Success)
|
|
{
|
|
return "A favorite fell: " + m.Groups[1].Value;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(assetId) && DisasterHint.IsMatch(assetId))
|
|
{
|
|
return "Disaster struck: " + raw;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(assetId) && assetId.IndexOf("shattered", System.StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
return raw.Replace("Kingdom shattered:", "Kingdom shattered:");
|
|
}
|
|
|
|
return raw;
|
|
}
|
|
}
|