aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/machine.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/machine.go')
-rw-r--r--internal/casino/machine.go57
1 files changed, 31 insertions, 26 deletions
diff --git a/internal/casino/machine.go b/internal/casino/machine.go
index 79e4cb6..c1e93fe 100644
--- a/internal/casino/machine.go
+++ b/internal/casino/machine.go
@@ -47,21 +47,14 @@ func newMachine(roomID int, cfg MachineConfig, rng *rand.Rand) *Machine {
func (m *Machine) join(name string) []Event {
m.mu.Lock()
defer m.mu.Unlock()
- if m.player != nil && m.player.Name != name {
+ if m.player != nil {
return []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventResult, PrivateTo: name, Message: "That slot machine is occupied."}}
}
- if m.player == nil {
- m.player = &Participant{Name: name, Connected: true}
- events := []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventJoined, Player: name,
- Message: fmt.Sprintf("%s sits down at the slots machine.", name),
- PrivateMessage: "You sit down at the slot machine.", PrivateTo: name, Color: "casino_action", Public: true}}
- return append(events, m.privateMenu("You sit down at the slot machine.")...)
- }
- m.player.Connected = true
- if m.autoBet {
- return m.private("Autobet is active. Type \"stop\" to stop playing.")
- }
- return m.menuEvents("You resume your place at the slot machine.")
+ m.player = &Participant{Name: name, Connected: true}
+ events := []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventJoined, Player: name,
+ Message: fmt.Sprintf("%s sits down at the slots machine.", name),
+ PrivateMessage: "You sit down at the slot machine.", PrivateTo: name, Color: "casino_action", Public: true}}
+ return append(events, m.privateMenu("You sit down at the slot machine.")...)
}
func (m *Machine) setBet(name string, amount int, wallet Wallet) []Event {
@@ -152,6 +145,10 @@ func (m *Machine) stopAutoBet(name string) ([]Event, bool) {
func (m *Machine) tick() []Event {
m.mu.Lock()
defer m.mu.Unlock()
+ if m.autoBet && m.player == nil {
+ // Defensive: autobet can never run without a seated player.
+ m.autoBet, m.autoCountdown = false, 0
+ }
if m.phase == machineReady && m.autoBet {
return m.autoBetTick()
}
@@ -264,28 +261,36 @@ func (m *Machine) leave(name string) []Event {
if m.phase != machineReady {
return m.private("You're in the middle of a spin!")
}
- m.player = nil
- m.bet = 0
- m.payoutRemainder = 0
+ m.resetSeat()
return []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventLeft, Player: name,
Message: fmt.Sprintf("%s stands up from the slots machine.", name), PrivateMessage: "You stand up from the slot machine.", PrivateTo: name, Color: "casino_action", Public: true}}
}
-func (m *Machine) markDisconnected(name string) []Event {
- m.mu.Lock()
- defer m.mu.Unlock()
- if m.owns(name) {
- m.player.Connected = false
- }
- return nil
+// resetSeat frees the machine, discarding any in-flight spin and autobet
+// state. A wager already taken for a spin in progress is forfeited.
+func (m *Machine) resetSeat() {
+ m.player = nil
+ m.bet = 0
+ m.spin = nil
+ m.spinBet = 0
+ m.phase = machineReady
+ m.reel, m.clock, m.suspense = 0, 0, false
+ m.freeSpins = 0
+ m.payoutRemainder = 0
+ m.autoBet, m.autoCountdown = false, 0
}
-func (m *Machine) markConnected(name string) {
+// markDisconnected removes the player from the machine, forfeiting any
+// in-flight wager, so the seat is immediately free for someone else.
+func (m *Machine) markDisconnected(name string) []Event {
m.mu.Lock()
defer m.mu.Unlock()
- if m.owns(name) {
- m.player.Connected = true
+ if !m.owns(name) {
+ return nil
}
+ m.resetSeat()
+ return []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventLeft, Player: name,
+ Message: fmt.Sprintf("%s stands up from the slots machine.", name), Color: "casino_action", Public: true}}
}
func (m *Machine) hasParticipant(name string) bool {