package game import ( "strings" "unicode/utf8" "thehouseoficarus/internal/casino" "thehouseoficarus/internal/net" ) // Wrap before Session.WriteLine: generic prose wrapping strips alignment from // overlong lines. Every casino menu uses the same two-space command indent and // hanging description column, capped at 80 even when prose wrapping is off. func (g *Game) casinoCommandColumns(sess *net.Session, commands []casino.MenuCommand) string { limit := 80 if sess.Player != nil { if wrap := sess.Player.OptionInt("wrap_width"); wrap > 0 { limit = min(limit, wrap) } } width := 0 for _, c := range commands { n := utf8.RuneCountInString(c.Command) // Unusually long commands get their own lines instead of squeezing every // other command's description into a tiny column. if n <= limit/2 { width = max(width, n) } } var lines []string for _, c := range commands { if sess.Player != nil && c.Cost > casinoAffordable(sess.Player) { continue } n := utf8.RuneCountInString(c.Command) if n > limit/2 { for _, line := range casinoWrapWords(c.Command, max(1, limit-2)) { lines = append(lines, " "+g.colorize(sess, "command", line)) } for _, line := range casinoWrapWords(c.Desc, max(1, limit-4)) { lines = append(lines, " "+line) } continue } if strings.TrimSpace(c.Desc) == "" { lines = append(lines, " "+g.colorize(sess, "command", c.Command)) continue } indent := width + 4 desc := casinoWrapWords(c.Desc, max(1, limit-indent)) cmd := c.Command + strings.Repeat(" ", width-n) lines = append(lines, " "+g.colorize(sess, "command", cmd)+" "+desc[0]) for _, line := range desc[1:] { lines = append(lines, strings.Repeat(" ", indent)+line) } } return strings.Join(lines, "\n") } // Input is uncolored command/description text; paint only after measuring. func casinoWrapWords(text string, width int) []string { var lines []string line := "" for _, word := range strings.Fields(text) { if line != "" && utf8.RuneCountInString(line)+1+utf8.RuneCountInString(word) > width { lines = append(lines, line) line = "" } runes := []rune(word) for len(runes) > width { lines = append(lines, string(runes[:width])) runes = runes[width:] } if line != "" { line += " " } line += string(runes) } if line != "" { lines = append(lines, line) } return lines }