aboutsummaryrefslogtreecommitdiff
path: root/internal/behavior/store.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-01 18:36:21 -0400
committerhistoria <[not public]>2026-07-01 18:36:21 -0400
commit78b522d57a9ebc691e075523910d7cdaa06b6493 (patch)
treeb2a68397e0cecc5abb56e5ae451c05a9435cc5fe /internal/behavior/store.go
parente6b4cb9f5816c6ee239233bc85f74ee446a161c2 (diff)
downloadthehouseoficarus-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.go86
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
+}