fix(topdata): encode spell radial feat IDs (#37)
test / test (push) Successful in 1m21s
build-binaries / build-binaries (push) Successful in 2m3s
build-image / publish (push) Successful in 13s

## Summary
- add explicit `{"spellradial": {"id": "feat:key"}}` authoring syntax for `spells.2da` `FeatID`
- resolve spell and feat rows dynamically and emit NWN:EE packed subradial values
- reject malformed or misplaced spell-radial references

## Verification
- `go test ./internal/topdata`

Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Reviewed-on: #37
Reviewed-by: archvillainette <vickydotbat@tutamail.com>
Reviewed-by: xtul <mpiasecki720@protonmail.com>
Co-authored-by: gitea-bot <gitea-bot@noreply.git.westgate.pw>
Co-committed-by: gitea-bot <gitea-bot@noreply.git.westgate.pw>
This commit was merged in pull request #37.
This commit is contained in:
2026-07-11 15:10:10 +00:00
committed by archvillainette
co-authored by archvillainette
parent 825fff8b67
commit e9860c12c6
2 changed files with 20 additions and 2 deletions
+18
View File
@@ -4712,6 +4712,24 @@ func (r *valueResolver) resolveValue(row map[string]any, field string, value any
switch typed := value.(type) {
case map[string]any:
if radial, ok := typed["spellradial"].(map[string]any); ok && len(typed) == 1 {
if r.dataset.Name != "spells" || field != "FeatID" {
return tlkCompiledValue{}, fmt.Errorf("spellradial reference is only valid for spells.FeatID")
}
radialKey, ok := radial["id"].(string)
if !ok || len(radial) != 1 {
return tlkCompiledValue{}, fmt.Errorf("spellradial reference requires exactly one id")
}
featID, ok := r.keyToID[radialKey]
if !ok {
return tlkCompiledValue{}, fmt.Errorf("unknown spellradial feat reference: %s", radialKey)
}
spellID, ok := row["id"].(int)
if !ok {
return tlkCompiledValue{}, fmt.Errorf("spellradial reference requires a numeric spell row id")
}
return tlkCompiledValue{Value: spellID<<16 + featID}, nil
}
if encoding, ok := r.valueEncodingForField(field); ok {
mode := strings.TrimSpace(encoding.Mode)
_, hasList := typed["list"]
+2 -2
View File
@@ -11887,7 +11887,7 @@ func TestBuildSupportsCanonicalSpells(t *testing.T) {
"spells:disarm": {
"Label": "Disarm",
"Name": "501",
"FeatID": {"id": "feat:disarm"},
"FeatID": {"spellradial": {"id": "feat:specialattacks"}},
"Master": {"id": "spells:specialattacks"},
"Category": {"ref": "spells:specialattacks", "field": "Category"}
}
@@ -11939,7 +11939,7 @@ func TestBuildSupportsCanonicalSpells(t *testing.T) {
!strings.Contains(text, "\t1000\t") ||
!strings.Contains(text, "841\tDisarm\t501") ||
!strings.Contains(text, "\t840\t") ||
!strings.Contains(text, "\t1001\t") ||
!strings.Contains(text, "\t55116776\t") ||
!strings.Contains(text, "849\tBard_Fascinate\t600") ||
!strings.Contains(text, "\t601\t") ||
!strings.Contains(text, "\t602\t") ||