From 9b2f28d9420752cf9acacc2006ff4e1118570fc4 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 08:00:22 +0200 Subject: [PATCH] fix(inventory-go): add Prodigal Spirit Drinker effect; document dmgMod key substitution; test wand mastery fallback Co-Authored-By: Claude Sonnet 5 --- go-services/inventory-go/od.go | 17 ++++++++++----- go-services/inventory-go/od_test.go | 32 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/go-services/inventory-go/od.go b/go-services/inventory-go/od.go index f39ebcc4..00aa18d2 100644 --- a/go-services/inventory-go/od.go +++ b/go-services/inventory-go/od.go @@ -416,6 +416,7 @@ var elemVsMonSpellEffects = map[int]odSpellEffect{ 3250: {.03, .03}, // Major Spirit Thirst 4670: {.05, .05}, // Epic Spirit Thirst 6098: {.07, .07}, // Legendary Spirit Thirst + 3735: {.15, 0}, // Prodigal Spirit Drinker } // buffedMaxDamage mirrors GetBuffedIntValueKey(218103842): base value minus @@ -497,11 +498,12 @@ func computeOD(raw map[string]any) (float64, bool) { } bv, ok := bestValues[key] if !ok && oc == 31 { - // Wands: our probe showed some wands lack key 353 (mastery), which - // defaults to 0 via ivI — but retry explicitly with mastery 0 so the - // void VR wand row (43,12,...) stays reachable while items that - // genuinely carry a different mastery value still fall back to the - // normal (34|43, 0, ...) rows. + // Mastery-0 retry for wands: an ADDITION over UB (UB's + // DataTable.Select has no retry; our captured wands may carry a + // mastery key 353 while the table's wand rows use mastery 0). + // Keeps the void VR wand row (43,12,...) reachable on the first + // exact-match attempt while other mastery-carrying wands fall back + // to the normal (34|43, 0, ...) rows. key.mastery = 0 bv, ok = bestValues[key] } @@ -550,6 +552,11 @@ func computeOD(raw map[string]any) (float64, bool) { remaining = 0 } + // NOTE: UB's literal CalcMissileDamage reads DoubleValues[63], but no + // DoubleValueKey ordinal 63 exists (verified against Decal.Adapter) — + // that line is a stale/bugged reference in the UB source. The correct + // populated key is 167772174 (DamageBonus), consistent with UB's own + // CalcedBuffedMissileDamage. Do NOT "fix" this back to 63. dmgMod := dvF(dv, "167772174", 0)*100 - 100 bDmg := float64(buffedMaxDamage(raw, iv)) if bDmg <= 10 { diff --git a/go-services/inventory-go/od_test.go b/go-services/inventory-go/od_test.go index 2acaf8a8..e725294d 100644 --- a/go-services/inventory-go/od_test.go +++ b/go-services/inventory-go/od_test.go @@ -23,6 +23,38 @@ func TestOD_Wand(t *testing.T) { } } +// Wand with an ACTIVE Prodigal Spirit Drinker (3735, change .15, bonus 0): +// shown ElemVsMonsters 1.55 un-buffs to 1.55 − .15 = 1.40 → OD +22, same +// underlying weapon as TestOD_Wand. +func TestOD_WandActiveProdigalSpiritDrinker(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.55, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{3735.0}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 22.0) { + t.Fatalf("wand w/ active Prodigal SD OD = %v ok=%v, want +22", od, ok) + } +} + +// Wand carrying a mastery value (353) with no matching wand table row: the +// exact-match lookup on (34,5,0,385) misses, and the mastery-0 retry must hit +// the (34,0,0,385) row → OD +22 as in TestOD_Wand. +func TestOD_WandMasteryFallback(t *testing.T) { + raw := map[string]any{ + "ObjectClass": 31.0, + "IntValues": map[string]any{"159": 34.0, "353": 5.0, "160": 385.0}, + "DoubleValues": map[string]any{"152": 1.40, "167772169": 8.0}, + "Spells": []any{}, "ActiveSpells": []any{}, + } + od, ok := computeOD(raw) + if !ok || !approx(od, 22.0) { + t.Fatalf("wand mastery-fallback OD = %v ok=%v, want +22", od, ok) + } +} + // Non-loot (no workmanship) → no OD. func TestOD_NonLootNull(t *testing.T) { raw := map[string]any{