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.go34
1 files changed, 33 insertions, 1 deletions
diff --git a/internal/casino/machine.go b/internal/casino/machine.go
index cf0ccb9..83e018f 100644
--- a/internal/casino/machine.go
+++ b/internal/casino/machine.go
@@ -380,15 +380,47 @@ func (m *Machine) resetSeat() {
// markDisconnected removes the player from the machine, forfeiting any
// in-flight wager, so the seat is immediately free for someone else.
+//
+// Already-landed free-spin winnings (featureBank) are NOT part of the
+// in-flight wager: they are settled after resetSeat resolves the triggering
+// stake, so the unlinked settlement cannot be read at recovery as covering
+// that stake. If the round's payout could not be persisted (stakeFailed), the
+// stake is left open for recovery and the bank is reported as forfeited
+// rather than silently destroyed.
func (m *Machine) markDisconnected(name string) []Event {
m.mu.Lock()
defer m.mu.Unlock()
if !m.owns(name) {
return nil
}
+ bank := int(m.featureBank)
+ wallet := m.player.Wallet
+ stakeFailed := m.stakeFailed
m.resetSeat()
- return []Event{{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventLeft, Player: name,
+ events := []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}}
+ if bank <= 0 || wallet == nil {
+ return events
+ }
+ switch {
+ case stakeFailed:
+ events = append(events, Event{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventResult,
+ PrivateTo: name, Player: name,
+ PrivateMessage: fmt.Sprintf("Your %d credits of banked free-spin winnings were forfeited because the round could not be persisted.", bank),
+ Color: "casino_action", Public: false})
+ case wallet.PayCredits(bank) != nil:
+ events = append(events, Event{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventResult,
+ PrivateTo: name, Player: name,
+ PrivateMessage: fmt.Sprintf("Your %d credits of free-spin winnings could not be persisted; they are recorded for recovery.", bank),
+ Color: "casino_action", Public: false})
+ default:
+ events = append(events, Event{RoomID: m.RoomID, TableID: m.Config.ID, Type: EventResult,
+ PrivateTo: name, Player: name,
+ Message: fmt.Sprintf("%s's %d banked free-spin credits pay out on disconnect.", name, bank),
+ PrivateMessage: fmt.Sprintf("The house settles your %d banked free-spin winnings.", bank),
+ Color: "casino_action", Public: true})
+ }
+ return events
}
func (m *Machine) hasParticipant(name string) bool {