Initial commit

This commit is contained in:
2026-03-14 00:32:26 +01:00
commit 70a35f3985
109 changed files with 62554 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
using Microsoft.EntityFrameworkCore;
using RolemasterDb.App.Data;
namespace RolemasterDb.App.Features;
public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbContextFactory)
{
public async Task<LookupReferenceData> GetReferenceDataAsync(CancellationToken cancellationToken = default)
{
await using var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
var attackTables = await dbContext.AttackTables
.AsNoTracking()
.OrderBy(item => item.DisplayName)
.Select(item => new LookupOption(item.Slug, item.DisplayName))
.ToListAsync(cancellationToken);
var armorTypes = await dbContext.ArmorTypes
.AsNoTracking()
.OrderBy(item => item.SortOrder)
.Select(item => new LookupOption(item.Code, item.Label))
.ToListAsync(cancellationToken);
var criticalTables = await dbContext.CriticalTables
.AsNoTracking()
.AsSplitQuery()
.Include(item => item.Columns)
.Include(item => item.Groups)
.OrderBy(item => item.DisplayName)
.ToListAsync(cancellationToken);
return new LookupReferenceData(
attackTables,
armorTypes,
criticalTables.Select(item => new CriticalTableReference(
item.Slug,
item.DisplayName,
item.Columns.OrderBy(column => column.SortOrder).Select(column => new LookupOption(column.ColumnKey, column.Label)).ToList(),
item.Groups.OrderBy(group => group.SortOrder).Select(group => new LookupOption(group.GroupKey, group.Label)).ToList()))
.ToList());
}
public async Task<AttackLookupResponse?> LookupAttackAsync(AttackLookupRequest request, CancellationToken cancellationToken = default)
{
await using var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
var attackTable = NormalizeSlug(request.AttackTable);
var armorType = request.ArmorType.Trim().ToUpperInvariant();
var attackResult = await dbContext.AttackResults
.AsNoTracking()
.Where(item =>
item.AttackTable.Slug == attackTable &&
item.ArmorType.Code == armorType &&
request.Roll >= item.AttackRollBand.MinRoll &&
(item.AttackRollBand.MaxRoll == null || request.Roll <= item.AttackRollBand.MaxRoll))
.Select(item => new AttackLookupResponse(
item.AttackTable.Slug,
item.AttackTable.DisplayName,
item.ArmorType.Code,
item.ArmorType.Label,
request.Roll,
item.AttackRollBand.Label,
item.Hits,
item.CriticalType,
item.CriticalSeverity,
item.RawNotation,
item.Notes,
null))
.SingleOrDefaultAsync(cancellationToken);
if (attackResult is null || attackResult.CriticalType is null || attackResult.CriticalSeverity is null || request.CriticalRoll is null)
{
return attackResult;
}
var autoCritical = await LookupCriticalAsync(
new CriticalLookupRequest(attackResult.CriticalType, attackResult.CriticalSeverity, request.CriticalRoll.Value, null),
cancellationToken);
return attackResult with { AutoCritical = autoCritical };
}
public async Task<CriticalLookupResponse?> LookupCriticalAsync(CriticalLookupRequest request, CancellationToken cancellationToken = default)
{
await using var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
var criticalType = NormalizeSlug(request.CriticalType);
var column = request.Column.Trim().ToUpperInvariant();
var group = string.IsNullOrWhiteSpace(request.Group) ? null : NormalizeSlug(request.Group);
return await dbContext.CriticalResults
.AsNoTracking()
.Where(item =>
item.CriticalTable.Slug == criticalType &&
item.CriticalColumn.ColumnKey == column &&
(group == null
? item.CriticalGroupId == null
: item.CriticalGroup != null && item.CriticalGroup.GroupKey == group) &&
request.Roll >= item.CriticalRollBand.MinRoll &&
(item.CriticalRollBand.MaxRoll == null || request.Roll <= item.CriticalRollBand.MaxRoll))
.Select(item => new CriticalLookupResponse(
item.CriticalTable.Slug,
item.CriticalTable.DisplayName,
item.CriticalGroup != null ? item.CriticalGroup.GroupKey : null,
item.CriticalColumn.ColumnKey,
request.Roll,
item.CriticalRollBand.Label,
item.DescriptionText,
item.RawAffixText))
.SingleOrDefaultAsync(cancellationToken);
}
private static string NormalizeSlug(string value) =>
value.Trim().Replace(' ', '_').ToLowerInvariant();
}