diff options
| author | historia <[not public]> | 2026-07-01 18:36:21 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-01 18:36:21 -0400 |
| commit | 78b522d57a9ebc691e075523910d7cdaa06b6493 (patch) | |
| tree | b2a68397e0cecc5abb56e5ae451c05a9435cc5fe /internal/behavior/store.go | |
| parent | e6b4cb9f5816c6ee239233bc85f74ee446a161c2 (diff) | |
| download | thehouseoficarus-78b522d57a9ebc691e075523910d7cdaa06b6493.tar.gz | |
feat: shop system removed from talk system, added per-item restock and variable pricing
Diffstat (limited to 'internal/behavior/store.go')
| -rw-r--r-- | internal/behavior/store.go | 86 |
1 files changed, 64 insertions, 22 deletions
diff --git a/internal/behavior/store.go b/internal/behavior/store.go index 38cc72b..8112e1c 100644 --- a/internal/behavior/store.go +++ b/internal/behavior/store.go @@ -126,7 +126,9 @@ func LoadDropTable(dataDir, id string) (*DropTableDef, error) { return &dt, nil } -func ResolveDrop(dataDir string, drops []DropEntry) *DropEntry { +// pickWeighted returns a single entry chosen by weight, without resolving any +// table reference on it. Returns nil if the list is empty or has no weight. +func pickWeighted(drops []DropEntry) *DropEntry { if len(drops) == 0 { return nil } @@ -142,29 +144,69 @@ func ResolveDrop(dataDir string, drops []DropEntry) *DropEntry { for i := range drops { cumulative += drops[i].Weight if roll < cumulative { - if drops[i].Table != "" { - sub, err := LoadDropTable(dataDir, drops[i].Table) - if err == nil { - if resolved := ResolveDrop(dataDir, sub.Drops); resolved != nil { - qty := drops[i].Quantity - if qty <= 0 { - qty = resolved.Quantity - } - if qty <= 0 { - qty = 1 - } - return &DropEntry{ - ItemID: resolved.ItemID, - Quantity: qty, - Depletes: drops[i].Depletes, - SuccessMessage: drops[i].SuccessMessage, - } - } - } - return nil - } return &drops[i] } } return &drops[0] } + +func ResolveDrop(dataDir string, drops []DropEntry) *DropEntry { + picked := pickWeighted(drops) + if picked == nil { + return nil + } + if picked.Table != "" { + sub, err := LoadDropTable(dataDir, picked.Table) + if err != nil { + return nil + } + resolved := ResolveDrop(dataDir, sub.Drops) + if resolved == nil { + return nil + } + qty := picked.Quantity + if qty <= 0 { + qty = resolved.Quantity + } + if qty <= 0 { + qty = 1 + } + return &DropEntry{ + ItemID: resolved.ItemID, + Quantity: qty, + Depletes: picked.Depletes, + SuccessMessage: picked.SuccessMessage, + } + } + return picked +} + +// ResolveDropList performs one weighted pick from drops. A plain item entry +// yields a single result. When the picked entry references a sub-table, its +// Quantity is treated as the number of INDEPENDENT rolls against that sub-table +// (default 1) — each roll may produce a different item — and all results are +// returned. Tables are just weighted lists of items; this is skill-independent. +func ResolveDropList(dataDir string, drops []DropEntry) []DropEntry { + picked := pickWeighted(drops) + if picked == nil { + return nil + } + if picked.Table == "" { + return []DropEntry{*picked} + } + sub, err := LoadDropTable(dataDir, picked.Table) + if err != nil { + return nil + } + rolls := picked.Quantity + if rolls <= 0 { + rolls = 1 + } + var out []DropEntry + for i := 0; i < rolls; i++ { + if resolved := ResolveDrop(dataDir, sub.Drops); resolved != nil && resolved.ItemID != "" { + out = append(out, *resolved) + } + } + return out +} |
