diff options
| author | historia <[not public]> | 2026-06-14 22:38:23 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-14 22:38:23 -0400 |
| commit | a6f0ad79e2e3a5b7c11eef1ffc3233f3a2766f77 (patch) | |
| tree | 89601a502bbfcb50302cf03f09b6febc6040eeb0 /internal/game/action_search.go | |
| parent | 1aba2bdd23aebed4032333e74aa553c40a31fcbd (diff) | |
| download | thehouseoficarus-a6f0ad79e2e3a5b7c11eef1ffc3233f3a2766f77.tar.gz | |
feat: fractional ticks and server game_speed implemented. potentially insanely janky.
Diffstat (limited to 'internal/game/action_search.go')
| -rw-r--r-- | internal/game/action_search.go | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/internal/game/action_search.go b/internal/game/action_search.go new file mode 100644 index 0000000..07bae44 --- /dev/null +++ b/internal/game/action_search.go @@ -0,0 +1,122 @@ +package game + +import ( + "fmt" + + "thirdcollapse/internal/action" + "thirdcollapse/internal/net" + "thirdcollapse/internal/player" +) + +func (g *Game) startSearch(sess *net.Session, p *player.Player, itemID string, slotIdx int) { + def, err := g.ItemStore.Load(itemID) + if err != nil || def.SearchTable == "" { + sess.WriteLine("You can't search that.") + return + } + + ticks := def.SearchTicks + if ticks <= 0 { + ticks = 3 + } + + p.Action = &action.Action{ + Type: "search", + TargetID: itemID, + TargetName: def.Name, + WaitLeft: g.computeTicks(ticks), + Data: map[string]any{ + "item_id": itemID, + "slot_idx": slotIdx, + "started": false, + }, + } + + p.ActionState = &ActionState{Type: ActionSearching, TargetName: def.Name} +} + +func (g *Game) advanceSearch(sess *net.Session, p *player.Player) { + data := p.Action.Data + itemID := data["item_id"].(string) + slotIdx := data["slot_idx"].(int) + started := data["started"].(bool) + + def, err := g.ItemStore.Load(itemID) + if err != nil { + sess.WriteLine("Something went wrong.") + g.CancelAction(p) + return + } + + if !started { + msg := def.SearchMessage + if msg == "" { + msg = fmt.Sprintf("digging through the %s", def.Name) + } + sess.WriteLine(fmt.Sprintf("You begin %s.", msg)) + data["started"] = true + return + } + + slot := p.InvSlot(slotIdx) + if slot == nil || slot.ItemID != itemID || slot.Quantity <= 0 { + sess.WriteLine("The item is gone.") + g.CancelAction(p) + return + } + + if slot.Quantity > 1 { + slot.Quantity-- + } else { + p.SetInvSlot(slotIdx, nil) + } + + dt, err := g.BehaviorStore.LoadDropTable(def.SearchTable) + if err == nil && len(dt.Drops) > 0 { + drop := g.BehaviorStore.ResolveDrop(dt.Drops) + if drop != nil && drop.ItemID != "" { + g.giveSearchLoot(sess, p, drop) + } + } + + if def.SearchMiscTable != "" { + dt2, err := g.BehaviorStore.LoadDropTable(def.SearchMiscTable) + if err == nil && len(dt2.Drops) > 0 { + drop := g.BehaviorStore.ResolveDrop(dt2.Drops) + if drop != nil && drop.ItemID != "" { + g.giveSearchLoot(sess, p, drop) + } + } + } + + g.AccountStore.SaveCharacter(p) + g.CancelAction(p) +} + +func (g *Game) giveSearchLoot(sess *net.Session, p *player.Player, drop *action.DropEntry) { + qty := drop.Quantity + if qty <= 0 { + qty = 1 + } + + name := drop.ItemID + if def, err := g.ItemStore.Load(drop.ItemID); err == nil { + name = def.Name + } + + if drop.ItemID == "credits" { + p.Credits += qty + sess.WriteLine(fmt.Sprintf("You find %d credits.", qty)) + return + } + + freeSlot := p.FirstFreeSlot() + if freeSlot == -1 { + g.World.AddGroundItem(p.RoomID, drop.ItemID, qty) + sess.WriteLine(fmt.Sprintf("You find %s. It falls to the ground.", name)) + return + } + + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: drop.ItemID, Quantity: qty}) + sess.WriteLine(fmt.Sprintf("You find %s.", name)) +} |
