package game import ( "fmt" "thehouseoficarus/internal/action" "thehouseoficarus/internal/engine" "thehouseoficarus/internal/net" "thehouseoficarus/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: engine.ToTicks(ticks), Data: map[string]any{ "item_id": itemID, "slot_idx": slotIdx, "started": false, }, } p.ActionState = &ActionState{Type: ActionSearching, TargetName: def.Name} if g.Hub != nil { for _, other := range g.Hub.PlayersInRoom(p.RoomID) { if other != sess && other.Player != nil { other.WriteLine(g.colorize(other, "broadcast", fmt.Sprintf("\n%s searches a %s.", p.Name, 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 lootDef, _ := g.ItemStore.Load(drop.ItemID) if lootDef != nil { name = lootDef.Name } if drop.ItemID == "credits" { p.Credits += qty sess.WriteLine(g.colorize(sess, "credits_pickup", 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.", g.itemColorize(sess, lootDef, name))) return } p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: drop.ItemID, Quantity: qty}) sess.WriteLine(fmt.Sprintf("You find %s.", g.itemColorize(sess, lootDef, name))) }