aboutsummaryrefslogtreecommitdiff
path: root/internal/game/casino.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/casino.go')
-rw-r--r--internal/game/casino.go27
1 files changed, 18 insertions, 9 deletions
diff --git a/internal/game/casino.go b/internal/game/casino.go
index 08695e7..e9334fc 100644
--- a/internal/game/casino.go
+++ b/internal/game/casino.go
@@ -6,6 +6,7 @@ import (
"os"
"strconv"
"strings"
+ "time"
"unicode/utf8"
"thehouseoficarus/internal/cardart"
@@ -431,10 +432,11 @@ func (g *Game) executeBet(sess *net.Session, args []string, rawInput string) {
// sets the wager and any other token is the bet target; AFTER "on", the
// next token is always the target. That makes numeric targets reachable
// ("bet 5 on 17"), which roulette, craps, and keno need.
- // Roulette combination bets need a multi-token target ("split 1 2",
- // "corner 1 2 4 5"), so a roulette table joins every extra target token.
- // Every other game keeps the stricter one-token target and its usage error.
- joinTarget := table.Config.Game == casino.GameRoulette
+ // Roulette combinations and craps bets need multi-token targets. Once
+ // an amount and target keyword exist, subsequent numbers belong to the
+ // target even without "on" (bet 10 split 1 2 / bet 10 buy 4).
+ // Other games keep the stricter one-token target.
+ joinTarget := table.Config.Game == casino.GameRoulette || table.Config.Game == casino.GameCraps
amount, spot, hasAmount, sawOn := 0, "", false, false
for i, arg := range args {
if strings.EqualFold(arg, "on") {
@@ -445,7 +447,7 @@ func (g *Game) executeBet(sess *net.Session, args []string, rawInput string) {
sawOn = true
continue
}
- if !sawOn {
+ if !sawOn && !(joinTarget && hasAmount && spot != "") {
if strings.EqualFold(arg, "min") {
if hasAmount {
sess.WriteLine("Use bet, bet <amount> [on <target>], bet min, or bet max.")
@@ -538,7 +540,11 @@ func (g *Game) executeTableAction(sess *net.Session, action string) {
func (g *Game) CasinoTick() {
if g.Casino != nil {
- g.emitCasinoEvents(g.Casino.Tick())
+ ms := 600
+ if g.Ticks != nil {
+ ms = g.Ticks.TickLengthMilliseconds()
+ }
+ g.emitCasinoEvents(g.Casino.TickElapsed(time.Duration(ms) * time.Millisecond))
}
}
@@ -608,18 +614,19 @@ func (g *Game) emitCasinoEvents(events []casino.Event) {
}
}
-// casinoBoardReminder splits a roulette menu so its wager instructions can be
+// casinoBoardReminder splits roulette and craps menus so instructions can be
// printed under the betting board, which is the table the reminder refers to.
// Every other game, and compact displays, keep their menu in one block.
func (g *Game) casinoBoardReminder(sess *net.Session, category string, menu *casino.MenuView, snapshot casino.Snapshot, message string) (header, reminder string, ok bool) {
if category != "casino_menu" || menu == nil || sess.Player == nil {
return "", "", false
}
+ _, isCraps := snapshot.(*casino.CrapsSnapshot)
s, isRoulette := snapshot.(*casino.RouletteSnapshot)
- if !isRoulette || s.Phase == "playing" || s.Phase == "result" {
+ if !isCraps && (!isRoulette || s.Phase == "playing" || s.Phase == "result") {
return "", "", false
}
- if sess.Player.OptionString("casino_display") == "compact" && (menu.Repeat || !menu.ShowBalance) {
+ if !isCraps && sess.Player.OptionString("casino_display") == "compact" && (menu.Repeat || !menu.ShowBalance) {
// The compact reminder is already a short block; leave it intact.
return "", "", false
}
@@ -741,6 +748,8 @@ func (g *Game) renderCasinoSnapshot(sess *net.Session, snapshot casino.Snapshot)
// how verbose the command menus are.
size := sess.Player.OptionInt("card_size")
switch s := snapshot.(type) {
+ case *casino.CrapsSnapshot:
+ return renderCrapsSnapshot(s, mode, unicode, sess.Player.OptionString("card_style"))
case *casino.RouletteSnapshot:
return renderRouletteSnapshot(s, mode, unicode, size)
case *casino.SlotSnapshot: