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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
package game
import (
"fmt"
"math/rand"
"strconv"
"strings"
"thirdcollapse/internal/net"
"thirdcollapse/internal/object"
"thirdcollapse/internal/player"
"thirdcollapse/internal/world"
)
var EquipSlots = []object.EquipSlot{
object.SlotHead, object.SlotNeck, object.SlotTorso, object.SlotLegs,
object.SlotHands, object.SlotFeet, object.SlotBack, object.SlotAmmo,
object.SlotMainHand, object.SlotOffHand, object.SlotRing,
}
type itemMatch struct {
ID string
Name string
Slot int
}
type xpGain struct {
Skill string
XP int
}
type deathDrop struct {
itemID string
quantity int
totalVal int
isEquip bool
equipSlot object.EquipSlot
invSlot int
}
func plural(n int) string {
if n == 1 {
return ""
}
return "s"
}
func parseQty(input string) (int, string) {
parts := strings.Fields(input)
if len(parts) > 1 {
if n, err := strconv.Atoi(parts[0]); err == nil && n > 0 {
return n, strings.Join(parts[1:], " ")
}
}
return 0, input
}
func parseIndex(s string) (int, error) {
var idx int
_, err := fmt.Sscanf(s, "%d", &idx)
return idx, err
}
func mobDisplayName(m *world.MobInstance, definite bool) string {
if m.Unique {
return m.Name
}
if definite {
return "the " + m.Name
}
return "a " + m.Name
}
func mobCombatLevel(m *world.MobInstance) int {
return int(0.25*float64(m.Attack+m.Strength+m.Defense+m.MaxHP) + 0.5)
}
func uniqueItemNames(matches []itemMatch) []string {
seen := make(map[string]bool)
var out []string
for _, m := range matches {
if !seen[m.Name] {
seen[m.Name] = true
out = append(out, m.Name)
}
}
return out
}
func randInt(max int) int {
if max <= 0 {
return 0
}
return rand.Intn(max)
}
func innerPickupReport(sess *net.Session, picked []string) {
for i, name := range picked {
if i == len(picked)-1 {
sess.WriteLine(name)
} else if i == len(picked)-2 {
sess.Write(name + " and ")
} else {
sess.Write(name + ", ")
}
}
}
func actionDesc(p *player.Player) string {
if p.Action == nil {
return ""
}
target := p.Action.TargetName
if idx, ok := p.Action.Data["instance_idx"]; ok {
target += fmt.Sprintf(" [%d]", idx)
}
switch p.Action.Type {
case "gather":
return "mining a " + target
case "talk":
return "talking to " + target
case "use":
return "using a " + target
case "burn":
return "trying to start a fire"
case "stoke":
return "tending to a fire"
}
return ""
}
func (g *Game) newInvSlot(itemID string, qty int) *player.InventorySlot {
slot := &player.InventorySlot{ItemID: itemID, Quantity: qty}
if def, err := g.ItemStore.Load(itemID); err == nil && def.MaxQuality > 0 {
slot.Quality = def.Quality
slot.MaxQuality = def.MaxQuality
}
return slot
}
|