diff options
| author | historia <[not public]> | 2026-09-30 16:16:17 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-30 16:16:17 -0400 |
| commit | a4c09c2d38d1f3bc1d3ad4bdb0234bdea7c37e73 (patch) | |
| tree | 00c9567e620f331a59dd44f1f1fa779ecd94a845 /internal/game/casino_commands.go | |
| parent | 724079f8de1ae69965c6267dca3d7fc3cc86afa2 (diff) | |
| download | thehouseoficarus-a4c09c2d38d1f3bc1d3ad4bdb0234bdea7c37e73.tar.gz | |
feat: additional craps variants added, standardizard casino command hints
Diffstat (limited to 'internal/game/casino_commands.go')
| -rw-r--r-- | internal/game/casino_commands.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/internal/game/casino_commands.go b/internal/game/casino_commands.go new file mode 100644 index 0000000..f4ca79f --- /dev/null +++ b/internal/game/casino_commands.go @@ -0,0 +1,83 @@ +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 +} |
