package game import ( "fmt" "math/rand" "strconv" "strings" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" "thehouseoficarus/internal/world" ) 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 parseChoiceIndex(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 { base := float64(m.Defense+m.MaxHP) / 4.0 melee := float64(m.Attack+m.Strength) / 4.0 ranged := float64(m.Ranged) * 3.0 / 8.0 science := float64(m.Science) * 3.0 / 8.0 best := melee if ranged > best { best = ranged } if science > best { best = science } return int(base + best + 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 (g *Game) showWhichOne(sess *net.Session, matches []itemMatch) { sess.WriteLine("Which one?") seen := make(map[string]bool) for _, m := range matches { if seen[m.Name] { continue } seen[m.Name] = true def, _ := g.ItemStore.Load(m.ID) coloredName := g.itemColorize(sess, def, m.Name) sess.WriteLine(fmt.Sprintf(" - %s", coloredName)) } } func randInt(max int) int { if max <= 0 { return 0 } return rand.Intn(max) } func formatPickupList(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 (g *Game) newInventorySlot(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 }