aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/craps_clock.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/craps_clock.go')
-rw-r--r--internal/casino/craps_clock.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/casino/craps_clock.go b/internal/casino/craps_clock.go
index f5cb690..bbba19e 100644
--- a/internal/casino/craps_clock.go
+++ b/internal/casino/craps_clock.go
@@ -9,6 +9,10 @@ const (
crapsBetDelay = 10 * time.Second
crapsDealerDelay = 60 * time.Second
crapsAutoDelay = 3 * time.Second
+
+ // Simplified craps has no manual roll: one shared automatic countdown
+ // starts with the first live bet and resolves every wager.
+ crapsSimplifiedDelay = 3 * time.Second
)
func crapsSeconds(d time.Duration) int {
@@ -46,6 +50,29 @@ func (t *crapsTable) activePlayers() int {
// extends it. A solo player has no forced deadline at all.
func (t *crapsTable) syncRoundClock() []Event {
multi := t.activePlayers() > 1
+ if t.Config.Craps.variant() == "simplified" {
+ // Simplified craps never opens a manual shooting window; the first
+ // live bet starts one shared automatic countdown for everyone.
+ if !t.hasLiveBets() {
+ t.phase = phaseWaiting
+ t.roundElapsed = 0
+ t.countdown = 0
+ t.lastCall = false
+ t.multiplayer = multi
+ return nil
+ }
+ fresh := t.phase == phaseWaiting
+ t.multiplayer = multi
+ if fresh {
+ t.roundElapsed = 0
+ t.countdown = 0
+ }
+ t.phase = phasePlaying
+ if fresh && multi {
+ return []Event{t.event("{casino_emphasis}Bets open{/} — the dice roll in 3 seconds.", true)}
+ }
+ return nil
+ }
if !t.hasLiveBets() {
t.phase = phaseWaiting
t.roundElapsed = 0
@@ -73,6 +100,24 @@ func (t *crapsTable) tickElapsed(elapsed time.Duration) []Event {
t.mu.Lock()
defer t.mu.Unlock()
events := t.syncRoundClock()
+ if t.Config.Craps.variant() == "simplified" {
+ if elapsed <= 0 || !t.hasLiveBets() {
+ return events
+ }
+ t.roundElapsed += elapsed
+ shooter := t.shooter()
+ if shooter == nil {
+ return events
+ }
+ for t.countdown < len(crapsCountdownFlavor) && t.roundElapsed >= time.Duration(t.countdown+1)*time.Second {
+ events = append(events, crapsCountdownEvent(t, shooter.Name, t.countdown))
+ t.countdown++
+ }
+ if t.roundElapsed >= crapsSimplifiedDelay {
+ events = append(events, t.roll()...)
+ }
+ return events
+ }
if elapsed <= 0 || !t.hasLiveBets() {
return events
}
@@ -101,6 +146,32 @@ func (t *crapsTable) tickElapsed(elapsed time.Duration) []Event {
return events
}
+// crapsCountdownFlavor broadcasts one line per second before the automatic
+// simplified roll. Each step carries a few variants: the public line names
+// the shooter, the private line speaks to them.
+var crapsCountdownFlavor = [][3][2]string{
+ {
+ {"{casino_emphasis}%s grabs the dice...{/}", "{casino_emphasis}You grab the dice...{/}"},
+ {"{casino_emphasis}%s scoops up the dice...{/}", "{casino_emphasis}You scoop up the dice...{/}"},
+ {"{casino_emphasis}%s weighs the dice in one hand...{/}", "{casino_emphasis}You weigh the dice in one hand...{/}"},
+ },
+ {
+ {"{casino_emphasis}%s blows on them for luck...{/}", "{casino_emphasis}You blow on them for luck...{/}"},
+ {"{casino_emphasis}%s blows on the dice for luck...{/}", "{casino_emphasis}You blow on the dice for luck...{/}"},
+ {"{casino_emphasis}%s rubs them for luck...{/}", "{casino_emphasis}You rub them for luck...{/}"},
+ },
+ {
+ {"{casino_emphasis}%s shakes, shakes, shakes the dice...{/}", "{casino_emphasis}Shake, shake, shake...{/}"},
+ {"{casino_emphasis}%s rattles the dice... shake, shake...{/}", "{casino_emphasis}Shake, shake... here they come!{/}"},
+ {"{casino_emphasis}%s gives the dice one last shake...{/}", "{casino_emphasis}You shake them hard... here they come!{/}"},
+ },
+}
+
+func crapsCountdownEvent(t *crapsTable, shooter string, step int) Event {
+ line := crapsCountdownFlavor[step][t.rng.Intn(3)]
+ return t.playerAction(shooter, fmt.Sprintf(line[0], shooter), line[1])
+}
+
// StopAutoRoll is atomic with ticking and does not queue a departure or touch
// any wager. A second stop, in manual mode, retains normal casino leave behavior.
func (t *Table) StopAutoRoll(name string) ([]Event, bool) {