1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
package game
import (
"fmt"
"thirdcollapse/internal/action"
"thirdcollapse/internal/engine"
"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: engine.ToTicks(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))
}
|