package spells import ( "sort" "gitea.maximumdirect.net/eric/notarius/internal/core/source" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared" ) type orderedSpellResponse struct { value spellCastResponse earliest int hasEvidence bool } func canonicalizeResponse(response *extractionResponse, order shared.SourceRefOrder, sourceID string) { if response == nil { return } ordered := make([]orderedSpellResponse, len(response.SpellCasts)) for index := range response.SpellCasts { earliest, hasEvidence := canonicalizeSpellCast(&response.SpellCasts[index], order, sourceID) ordered[index] = orderedSpellResponse{ value: response.SpellCasts[index], earliest: earliest, hasEvidence: hasEvidence, } } sort.SliceStable(ordered, func(i, j int) bool { if ordered[i].hasEvidence != ordered[j].hasEvidence { return ordered[i].hasEvidence } if !ordered[i].hasEvidence { return false } return ordered[i].earliest < ordered[j].earliest }) for index := range ordered { response.SpellCasts[index] = ordered[index].value } } func canonicalizeSpellCast(spell *spellCastResponse, order shared.SourceRefOrder, sourceID string) (int, bool) { if spell == nil { return 0, false } refs := order.Canonicalize(spellSourceRefs(spell.SourceRefs, sourceID)) spell.SourceRefs = spellResponseRefs(refs) return order.EarliestValid(refs) } func spellSourceRefs(refs []spellSourceRefResponse, sourceID string) []source.SourceRef { if refs == nil { return nil } values := make([]source.SourceRef, len(refs)) for index, ref := range refs { values[index] = source.SourceRef{SourceID: sourceID, StartUnitID: ref.StartUnitID, EndUnitID: ref.EndUnitID} } return values } func spellResponseRefs(refs []source.SourceRef) []spellSourceRefResponse { if refs == nil { return nil } values := make([]spellSourceRefResponse, len(refs)) for index, ref := range refs { values[index] = spellSourceRefResponse{StartUnitID: ref.StartUnitID, EndUnitID: ref.EndUnitID} } return values } func canonicalSpellList(response extractionResponse, sourceID string) dnd.SpellList { spellCasts := make([]dnd.SpellCast, len(response.SpellCasts)) for index, spell := range response.SpellCasts { refs := make([]source.SourceRef, len(spell.SourceRefs)) for refIndex, ref := range spell.SourceRefs { refs[refIndex] = source.SourceRef{ SourceID: sourceID, StartUnitID: ref.StartUnitID, EndUnitID: ref.EndUnitID, } } spellCasts[index] = dnd.SpellCast{ Caster: spell.Caster, Spell: spell.Spell, SourceRefs: refs, } } if response.SpellCasts == nil { spellCasts = nil } return dnd.SpellList{SpellCasts: spellCasts} }