Add phase 1 critical import tool
This commit is contained in:
@@ -12,12 +12,12 @@ public static class RolemasterDbInitializer
|
||||
|
||||
await dbContext.Database.EnsureCreatedAsync(cancellationToken);
|
||||
|
||||
if (await dbContext.AttackTables.AnyAsync(cancellationToken) || await dbContext.CriticalTables.AnyAsync(cancellationToken))
|
||||
if (await dbContext.AttackTables.AnyAsync(cancellationToken))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RolemasterSeedData.Seed(dbContext);
|
||||
RolemasterSeedData.SeedAttackStarterData(dbContext);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,28 @@ namespace RolemasterDb.App.Data;
|
||||
|
||||
public static class RolemasterSeedData
|
||||
{
|
||||
public static void Seed(RolemasterDbContext dbContext)
|
||||
public static void SeedAttackStarterData(RolemasterDbContext dbContext)
|
||||
{
|
||||
var armorTypes = CreateArmorTypes();
|
||||
dbContext.ArmorTypes.AddRange(armorTypes);
|
||||
List<ArmorType> armorTypes;
|
||||
|
||||
if (dbContext.ArmorTypes.Any())
|
||||
{
|
||||
armorTypes = dbContext.ArmorTypes.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
armorTypes = CreateArmorTypes();
|
||||
dbContext.ArmorTypes.AddRange(armorTypes);
|
||||
}
|
||||
|
||||
if (dbContext.AttackTables.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var armorLookup = armorTypes.ToDictionary(item => item.Code, StringComparer.OrdinalIgnoreCase);
|
||||
var attackTables = CreateAttackTables(armorLookup);
|
||||
dbContext.AttackTables.AddRange(attackTables);
|
||||
|
||||
var criticalTables = CreateCriticalTables();
|
||||
dbContext.CriticalTables.AddRange(criticalTables);
|
||||
}
|
||||
|
||||
private static List<ArmorType> CreateArmorTypes() =>
|
||||
@@ -131,164 +142,6 @@ public static class RolemasterSeedData
|
||||
}
|
||||
}
|
||||
|
||||
private static List<CriticalTable> CreateCriticalTables()
|
||||
{
|
||||
return
|
||||
[
|
||||
CreateCriticalTable(
|
||||
slug: "slash",
|
||||
displayName: "Slash Critical",
|
||||
notes: "Starter subset derived from the critical-table schema design notes.",
|
||||
matrix: new Dictionary<string, (string Description, string Affix)[]>
|
||||
{
|
||||
["A"] =
|
||||
[
|
||||
("Glancing slash across the forearm.", "+2 hits, 1 bleed"),
|
||||
("Rib-level cut knocks the foe back a step.", "+4 hits, 1 stun, 2 bleed"),
|
||||
("Deep cut to the thigh unbalances the target.", "+6 hits, 2 stun, 3 bleed"),
|
||||
("Shoulder opened; guard collapses.", "+8 hits, 3 stun, 4 bleed"),
|
||||
("Neck line opened. The fight is over.", "Instant death")
|
||||
],
|
||||
["B"] =
|
||||
[
|
||||
("Slash cuts through the hand and weapon grip wavers.", "+4 hits, 1 stun, 2 bleed"),
|
||||
("Diagonal cut across the chest steals breath.", "+6 hits, 2 stun, 3 bleed"),
|
||||
("Hip strike drives the foe to one knee.", "+8 hits, 3 stun, 4 bleed"),
|
||||
("Sword arm carved deeply; weapon drops.", "+10 hits, 4 stun, 5 bleed"),
|
||||
("Throat opened in a full red arc.", "Instant death")
|
||||
],
|
||||
["C"] =
|
||||
[
|
||||
("Forearm split to the bone; parry ruined.", "+6 hits, 2 stun, 3 bleed"),
|
||||
("Wide cut over the ribs spins the foe.", "+8 hits, 3 stun, 4 bleed"),
|
||||
("Hamstring sliced; prone unless magically supported.", "+10 hits, 4 stun, 6 bleed"),
|
||||
("Slash rips across face and collar. Vision swims.", "+12 hits, 5 stun, 7 bleed"),
|
||||
("Head nearly severed.", "Instant death")
|
||||
],
|
||||
["D"] =
|
||||
[
|
||||
("Deep abdominal slice spills momentum and blood together.", "+8 hits, 3 stun, 5 bleed"),
|
||||
("Sword tracks from shoulder to sternum. Collapse likely.", "+10 hits, 4 stun, 6 bleed"),
|
||||
("Leg cut through muscle; foe falls hard.", "+12 hits, 5 stun, 8 bleed"),
|
||||
("Upper arm nearly removed; weapon arm useless.", "+14 hits, 6 stun, 10 bleed"),
|
||||
("Killing cut through the neck.", "Instant death")
|
||||
],
|
||||
["E"] =
|
||||
[
|
||||
("Massive slash opens chest and the foe staggers blindly.", "+10 hits, 4 stun, 6 bleed"),
|
||||
("Spine-grazing cut destroys posture and control.", "+12 hits, 5 stun, 8 bleed"),
|
||||
("Leg severed below the knee.", "+14 hits, 6 stun, 10 bleed"),
|
||||
("Torso opened from clavicle to hip.", "+16 hits, 8 stun, 12 bleed"),
|
||||
("Clean decapitation.", "Instant death")
|
||||
]
|
||||
}),
|
||||
CreateCriticalTable(
|
||||
slug: "puncture",
|
||||
displayName: "Puncture Critical",
|
||||
notes: "Starter subset seeded for missile and thrust attacks.",
|
||||
matrix: new Dictionary<string, (string Description, string Affix)[]>
|
||||
{
|
||||
["A"] =
|
||||
[
|
||||
("Point slips into the shoulder.", "+2 hits, 1 bleed"),
|
||||
("Stab bites into the upper arm.", "+4 hits, 1 stun, 2 bleed"),
|
||||
("Short thrust catches the ribs.", "+5 hits, 2 stun, 2 bleed"),
|
||||
("Point pierces the thigh. Movement slows.", "+7 hits, 2 stun, 3 bleed"),
|
||||
("Exact thrust to the throat.", "Instant death")
|
||||
],
|
||||
["B"] =
|
||||
[
|
||||
("Puncture through the palm forces a drop check.", "+4 hits, 1 stun, 2 bleed"),
|
||||
("Arrow buries in the flank.", "+6 hits, 2 stun, 3 bleed"),
|
||||
("Deep thrust into the belly doubles the foe over.", "+8 hits, 3 stun, 4 bleed"),
|
||||
("Point through the shoulder locks the arm.", "+10 hits, 4 stun, 5 bleed"),
|
||||
("Eye socket struck cleanly.", "Instant death")
|
||||
],
|
||||
["C"] =
|
||||
[
|
||||
("Stab through the bicep ruins the next parry.", "+6 hits, 2 stun, 3 bleed"),
|
||||
("Arrow punches through lung tissue.", "+8 hits, 3 stun, 5 bleed"),
|
||||
("Thrust under the ribs steals breath and footing.", "+10 hits, 4 stun, 6 bleed"),
|
||||
("Deep puncture pins the foe in place.", "+12 hits, 5 stun, 7 bleed"),
|
||||
("Heart strike.", "Instant death")
|
||||
],
|
||||
["D"] =
|
||||
[
|
||||
("Weapon point tears through the abdomen.", "+8 hits, 3 stun, 5 bleed"),
|
||||
("Arrow lodges near the spine; movement nearly gone.", "+10 hits, 4 stun, 6 bleed"),
|
||||
("Lance-like thrust through the torso.", "+12 hits, 5 stun, 8 bleed"),
|
||||
("Point enters the neck and exits behind the shoulder.", "+14 hits, 6 stun, 10 bleed"),
|
||||
("Brain pierced.", "Instant death")
|
||||
],
|
||||
["E"] =
|
||||
[
|
||||
("Massive puncture opens the chest cavity.", "+10 hits, 4 stun, 6 bleed"),
|
||||
("Shaft buries to the fletching; foe drops.", "+12 hits, 5 stun, 8 bleed"),
|
||||
("Groin-to-spine thrust destroys the body line.", "+14 hits, 6 stun, 10 bleed"),
|
||||
("Perfect impalement through the throat and neck.", "+16 hits, 8 stun, 12 bleed"),
|
||||
("Instantly fatal puncture.", "Instant death")
|
||||
]
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
private static CriticalTable CreateCriticalTable(
|
||||
string slug,
|
||||
string displayName,
|
||||
string notes,
|
||||
IReadOnlyDictionary<string, (string Description, string Affix)[]> matrix)
|
||||
{
|
||||
var table = new CriticalTable
|
||||
{
|
||||
Slug = slug,
|
||||
DisplayName = displayName,
|
||||
Family = "standard",
|
||||
SourceDocument = "Seeded starter data",
|
||||
Notes = notes
|
||||
};
|
||||
|
||||
table.Columns =
|
||||
[
|
||||
new CriticalColumn { ColumnKey = "A", Label = "A", SortOrder = 1 },
|
||||
new CriticalColumn { ColumnKey = "B", Label = "B", SortOrder = 2 },
|
||||
new CriticalColumn { ColumnKey = "C", Label = "C", SortOrder = 3 },
|
||||
new CriticalColumn { ColumnKey = "D", Label = "D", SortOrder = 4 },
|
||||
new CriticalColumn { ColumnKey = "E", Label = "E", SortOrder = 5 }
|
||||
];
|
||||
|
||||
table.RollBands =
|
||||
[
|
||||
new CriticalRollBand { Label = "01-20", MinRoll = 1, MaxRoll = 20, SortOrder = 1 },
|
||||
new CriticalRollBand { Label = "21-40", MinRoll = 21, MaxRoll = 40, SortOrder = 2 },
|
||||
new CriticalRollBand { Label = "41-60", MinRoll = 41, MaxRoll = 60, SortOrder = 3 },
|
||||
new CriticalRollBand { Label = "61-80", MinRoll = 61, MaxRoll = 80, SortOrder = 4 },
|
||||
new CriticalRollBand { Label = "81-100", MinRoll = 81, MaxRoll = 100, SortOrder = 5 }
|
||||
];
|
||||
|
||||
var columnsByKey = table.Columns.ToDictionary(item => item.ColumnKey, StringComparer.OrdinalIgnoreCase);
|
||||
var bandsByOrder = table.RollBands.ToDictionary(item => item.SortOrder);
|
||||
|
||||
foreach (var (columnKey, rows) in matrix)
|
||||
{
|
||||
for (var index = 0; index < rows.Length; index++)
|
||||
{
|
||||
var row = rows[index];
|
||||
table.Results.Add(new CriticalResult
|
||||
{
|
||||
CriticalColumn = columnsByKey[columnKey],
|
||||
CriticalRollBand = bandsByOrder[index + 1],
|
||||
DescriptionText = row.Description,
|
||||
RawAffixText = row.Affix,
|
||||
RawCellText = $"{row.Description} {row.Affix}",
|
||||
ParsedJson = "{}",
|
||||
ParseStatus = "verified"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private static string BuildAttackNotation(int hits, string? severity, string criticalType)
|
||||
{
|
||||
return severity is null
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user