From 90ad8c0c33b519d5830c69d4128bdc984b5e9de8 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 5 Oct 2026 14:22:14 -0400 Subject: feat: cryptocurrency exchange added to casino --- internal/game/cmd_bank.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'internal/game/cmd_bank.go') diff --git a/internal/game/cmd_bank.go b/internal/game/cmd_bank.go index deddf0b..15ce85f 100644 --- a/internal/game/cmd_bank.go +++ b/internal/game/cmd_bank.go @@ -102,6 +102,9 @@ func (g *Game) showBankBrowse(sess *net.Session) { entries = append(entries, bankEntry{slot: i, pos: len(entries) + 1, name: itemName, id: slot.ItemID, qty: slot.Quantity}) } + if p.Crypto.Balance < 0 { + sess.WriteLine(g.colorize(sess, "casino_result_loss", fmt.Sprintf("Crypto Exchange debt: %d credits. Future credit deposits repay this first.", -p.Crypto.Balance))) + } if len(entries) == 0 && p.BankedCredits <= 0 { sess.WriteLine("Your bank is empty.") return @@ -372,13 +375,26 @@ func (g *Game) doBankDepositCredits(sess *net.Session, parts []string) { sess.WriteLine("You don't have that many credits.") return } - creditsBefore, bankedBefore := p.Credits, p.BankedCredits - p.Credits -= amount - p.BankedCredits += amount - if !g.persistBankCredits(p, creditsBefore, bankedBefore) { + var seized int64 + if err := g.cryptoTransaction(p, func() error { + // Seize from the incoming deposit before the bank cap check. This also + // permits repayment when the bank itself is already at the balance cap. + seized = min(int64(amount), max(int64(0), -p.Crypto.Balance)) + bank, err := addCreditsChecked(p.BankedCredits, amount-int(seized)) + if err != nil { + return err + } + p.Credits -= amount + p.BankedCredits = bank + p.Crypto.Balance += seized + return nil + }); err != nil { sess.WriteLine("The bank terminal could not record the transfer; nothing was moved.") return } + if seized > 0 { + sess.WriteLine(fmt.Sprintf("The Crypto Exchange seized %d deposited credits to repay debt.", seized)) + } sess.WriteLine(g.colorize(sess, "currency_pickup", fmt.Sprintf("You deposit %s credits. (Banked: %s)", formatInt(amount), formatInt(p.BankedCredits)))) g.showBankBrowse(sess) } @@ -394,6 +410,10 @@ func (g *Game) doBankWithdrawCredits(sess *net.Session, parts []string) { sess.WriteLine("Invalid amount.") return } + if p.Crypto.Balance < 0 { + sess.WriteLine("Your bank credits are subject to Crypto Exchange debt. Repay the debt before withdrawing.") + return + } if p.BankedCredits < amount { sess.WriteLine("You don't have that many banked credits.") return @@ -421,7 +441,7 @@ func (g *Game) doBankWithdrawCredits(sess *net.Session, parts []string) { // a wager taken from that phantom balance would be charged against money the // player does not durably have. Reports whether the move may be announced. func (g *Game) persistBankCredits(p *player.Player, creditsBefore, bankedBefore int) bool { - if err := g.AccountStore.SaveCharacter(p); err != nil { + if err := (casinoWallet{g: g, p: p}).save("bank credit transfer"); err != nil { log.Printf("bank credit transfer %s: %v", p.Name, err) p.Credits = creditsBefore p.BankedCredits = bankedBefore -- cgit v1.2.3