diff options
Diffstat (limited to 'internal/game')
| -rw-r--r-- | internal/game/casino.go | 24 | ||||
| -rw-r--r-- | internal/game/casino_test.go | 6 | ||||
| -rw-r--r-- | internal/game/cmd_quit.go | 1 | ||||
| -rw-r--r-- | internal/game/core_login_char.go | 1 |
4 files changed, 28 insertions, 4 deletions
diff --git a/internal/game/casino.go b/internal/game/casino.go index 785666e..9f3b524 100644 --- a/internal/game/casino.go +++ b/internal/game/casino.go @@ -43,6 +43,10 @@ func (w casinoWallet) PayCredits(amount int) { w.g.AccountStore.SaveCharacter(w.p) } +// casinoAffordable is the most a player can wager: chips are spent first, +// then credits. +func casinoAffordable(p *player.Player) int { return p.Credits + countChips(p) } + func (g *Game) casinoTable(roomID int, gameName string) (*casino.Table, bool) { room, err := g.World.LoadRoom(roomID) if err != nil { @@ -50,7 +54,11 @@ func (g *Game) casinoTable(roomID int, gameName string) (*casino.Table, bool) { } for _, cfg := range room.CasinoTables { if strings.EqualFold(string(cfg.Game), gameName) { - return g.Casino.EnsureTable(roomID, cfg), true + table := g.Casino.EnsureTable(roomID, cfg) + if table == nil { + return nil, false + } + return table, true } } return nil, false @@ -126,7 +134,12 @@ func (g *Game) executeBet(sess *net.Session, args []string, rawInput string) { } if len(args) == 1 { if args[0] == "max" { - g.emitCasinoEvents(g.Casino.SetMachineBet(machine.RoomID, machine.Config.ID, p.Name, machine.Config.MaxBet, casinoWallet{g: g, p: p})) + amount := min(machine.Config.MaxBet, casinoAffordable(p)) + if amount < 1 { + sess.WriteLine("You don't have any chips or credits to bet.") + return + } + g.emitCasinoEvents(g.Casino.SetMachineBet(machine.RoomID, machine.Config.ID, p.Name, amount, casinoWallet{g: g, p: p})) return } if amount, err := strconv.Atoi(args[0]); err == nil && amount > 0 { @@ -163,7 +176,12 @@ func (g *Game) executeBet(sess *net.Session, args []string, rawInput string) { sess.WriteLine("Use bet, bet <amount> [on <target>], bet min, or bet max.") return } - amount, hasAmount = table.Config.MaxBet, true + amount = min(table.Config.MaxBet, casinoAffordable(p)) + if amount < 1 { + sess.WriteLine("You don't have any chips or credits to bet.") + return + } + hasAmount = true continue } if value, err := strconv.Atoi(arg); err == nil && value > 0 { diff --git a/internal/game/casino_test.go b/internal/game/casino_test.go index 8affe29..9f31a37 100644 --- a/internal/game/casino_test.go +++ b/internal/game/casino_test.go @@ -42,6 +42,12 @@ func TestExecuteBetRejectsInvalidMachineArgs(t *testing.T) { if !strings.Contains(string(conn.data), "You don't have enough chips and credits") { t.Fatalf("bet 10 should attempt an auto-spin and fail at the empty wallet, got %q", string(conn.data)) } + // Bet max with an empty wallet is rejected before any wager is attempted. + conn.data = nil + g.executeBet(sess, []string{"max"}, "bet max") + if !strings.Contains(string(conn.data), "You don't have any chips or credits to bet.") { + t.Fatalf("bet max with empty wallet: expected no-funds message, got %q", string(conn.data)) + } } func TestExecuteBetParsesBaccaratSpots(t *testing.T) { diff --git a/internal/game/cmd_quit.go b/internal/game/cmd_quit.go index b7ec972..fa4038b 100644 --- a/internal/game/cmd_quit.go +++ b/internal/game/cmd_quit.go @@ -38,6 +38,7 @@ func (g *Game) doQuit(sess *net.Session) { case 0: g.cancelRest(p.Name) g.restoreGodPlayer(p) + g.emitCasinoEvents(g.Casino.MarkDisconnected(p.Name)) g.AccountStore.SaveCharacter(p) g.charsMu.Lock() delete(g.loggedInChars, p.Name) diff --git a/internal/game/core_login_char.go b/internal/game/core_login_char.go index 4f59f1b..38499e2 100644 --- a/internal/game/core_login_char.go +++ b/internal/game/core_login_char.go @@ -108,7 +108,6 @@ func (g *Game) connectCharacter(sess *net.Session, name string) { if g.Hub != nil { g.Hub.EnterRoom(sess, p.RoomID) } - g.Casino.MarkConnected(name) g.doLook(sess) g.checkAggro(sess) |
