diff options
Diffstat (limited to 'internal/game/act_search.go')
| -rw-r--r-- | internal/game/act_search.go | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/internal/game/act_search.go b/internal/game/act_search.go new file mode 100644 index 0000000..6af15ca --- /dev/null +++ b/internal/game/act_search.go @@ -0,0 +1,126 @@ +package game + +import ( + "fmt" + + "thehouseoficarus/internal/behavior" + "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 = &behavior.Action{ + Type: "search", + TargetID: itemID, + TargetName: def.Name, + WaitLeft: engine.ToTicks(ticks), + Data: &behavior.SearchData{ + ItemID: itemID, + SlotIdx: slotIdx, + Started: false, + }, + } + + g.broadcastAction(sess, "\n%s searches a %s.", p.Name, def.Name) +} + +func (g *Game) advanceSearch(sess *net.Session, p *player.Player) { + d, ok := p.Action.Data.(*behavior.SearchData) + if !ok || d == nil { + sess.WriteLine("Something went wrong.") + g.cancelAction(p) + return + } + + def, err := g.ItemStore.Load(d.ItemID) + if err != nil { + sess.WriteLine("Something went wrong.") + g.cancelAction(p) + return + } + + if !d.Started { + msg := def.SearchMessage + if msg == "" { + msg = fmt.Sprintf("digging through the %s", def.Name) + } + sess.WriteLine(fmt.Sprintf("You begin %s.", msg)) + d.Started = true + return + } + + slot := p.InvSlot(d.SlotIdx) + if slot == nil || slot.ItemID != d.ItemID || slot.Quantity <= 0 { + sess.WriteLine("The item is gone.") + g.cancelAction(p) + return + } + + if slot.Quantity > 1 { + slot.Quantity-- + } else { + p.SetInvSlot(d.SlotIdx, nil) + } + + dt, err := behavior.LoadDropTable(g.DataDir, def.SearchTable) + if err == nil && len(dt.Drops) > 0 { + drop := behavior.ResolveDrop(g.DataDir, dt.Drops) + if drop != nil && drop.ItemID != "" { + g.giveSearchLoot(sess, p, drop) + } + } + + if def.SearchMiscTable != "" { + dt2, err := behavior.LoadDropTable(g.DataDir, def.SearchMiscTable) + if err == nil && len(dt2.Drops) > 0 { + drop := behavior.ResolveDrop(g.DataDir, 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 *behavior.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))) +} |
