diff options
Diffstat (limited to 'internal/casino/machine.go')
| -rw-r--r-- | internal/casino/machine.go | 34 |
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 { |
