diff options
Diffstat (limited to 'internal/game')
| -rw-r--r-- | internal/game/casino_test.go | 1 | ||||
| -rw-r--r-- | internal/game/cmd_bank.go | 13 | ||||
| -rw-r--r-- | internal/game/cmd_get.go | 14 | ||||
| -rw-r--r-- | internal/game/cmd_room_remove_test.go | 1 | ||||
| -rw-r--r-- | internal/game/correct_audit_fixes_test.go | 17 | ||||
| -rw-r--r-- | internal/game/credits_pickup_test.go | 2 | ||||
| -rw-r--r-- | internal/game/hardening_credit_cap_test.go | 4 | ||||
| -rw-r--r-- | internal/game/harness_test.go | 1 | ||||
| -rw-r--r-- | internal/game/sys_escape_test.go | 1 |
9 files changed, 43 insertions, 11 deletions
diff --git a/internal/game/casino_test.go b/internal/game/casino_test.go index 0b82945..a3c3d18 100644 --- a/internal/game/casino_test.go +++ b/internal/game/casino_test.go @@ -22,6 +22,7 @@ func (c *casinoTestConn) Write(b []byte) (int, error) { return len(b), nil } func (c *casinoTestConn) SetWriteDeadline(time.Time) error { return nil } +func (c *casinoTestConn) SetReadDeadline(time.Time) error { return nil } func (c *casinoTestConn) Close() error { return nil } func (c *casinoTestConn) SetEcho(bool) error { return nil } diff --git a/internal/game/cmd_bank.go b/internal/game/cmd_bank.go index bb03869..76fefb7 100644 --- a/internal/game/cmd_bank.go +++ b/internal/game/cmd_bank.go @@ -265,10 +265,15 @@ func (g *Game) doBankWithdraw(sess *net.Session, input string) { return } - for _, e := range entries { - def, _ := g.ItemStore.Load(e.id) - if def != nil && def.MatchesName(input) { - matches = append(matches, e) + // Only fall back to fuzzy MatchesName when the prefix pass found nothing; + // running it unconditionally appended the same entries twice and printed a + // duplicated ambiguity list. + if len(matches) == 0 { + for _, e := range entries { + def, _ := g.ItemStore.Load(e.id) + if def != nil && def.MatchesName(input) { + matches = append(matches, e) + } } } diff --git a/internal/game/cmd_get.go b/internal/game/cmd_get.go index a806ffa..d4742a5 100644 --- a/internal/game/cmd_get.go +++ b/internal/game/cmd_get.go @@ -40,7 +40,7 @@ func (g *Game) doGet(sess *net.Session, input string) { itemID := matches[0].ID if itemID == "credits" { - g.pickupCredits(sess, p, itemID) + g.pickupCredits(sess, p, itemID, qty) return } @@ -162,7 +162,7 @@ func (g *Game) doGetAllNamed(sess *net.Session, input string) { itemID := matches[0].ID if itemID == "credits" { - g.pickupCredits(sess, p, itemID) + g.pickupCredits(sess, p, itemID, 0) return } @@ -391,7 +391,7 @@ func (g *Game) doGetAll(sess *net.Session) { } } -func (g *Game) pickupCredits(sess *net.Session, p *player.Player, itemID string) { +func (g *Game) pickupCredits(sess *net.Session, p *player.Player, itemID string, want int) { // The balance cap is a hard limit: credits the purse cannot absorb must // stay on the ground instead of being removed and then clamped away by // grantCredits. Only the headroom below the cap is taken. @@ -400,7 +400,13 @@ func (g *Game) pickupCredits(sess *net.Session, p *player.Player, itemID string) sess.WriteLine(g.colorize(sess, "currency_pickup", "Your purse can't hold any more credits.")) return } - qty := g.World.RemoveAvailableItem(p.RoomID, itemID, room, p.Name) + // Honor an explicit quantity (get 5 credits) instead of always sweeping + // the whole purse headroom. + take := room + if want > 0 && want < take { + take = want + } + qty := g.World.RemoveAvailableItem(p.RoomID, itemID, take, p.Name) if qty <= 0 { return } diff --git a/internal/game/cmd_room_remove_test.go b/internal/game/cmd_room_remove_test.go index be2d917..dc5a397 100644 --- a/internal/game/cmd_room_remove_test.go +++ b/internal/game/cmd_room_remove_test.go @@ -23,6 +23,7 @@ func (c *removeTestConn) Write(b []byte) (int, error) { return len(b), nil } func (c *removeTestConn) SetWriteDeadline(time.Time) error { return nil } +func (c *removeTestConn) SetReadDeadline(time.Time) error { return nil } func (c *removeTestConn) Close() error { return nil } func (c *removeTestConn) SetEcho(bool) error { return nil } diff --git a/internal/game/correct_audit_fixes_test.go b/internal/game/correct_audit_fixes_test.go index 90fdc53..681843c 100644 --- a/internal/game/correct_audit_fixes_test.go +++ b/internal/game/correct_audit_fixes_test.go @@ -6,6 +6,7 @@ import ( "thehouseoficarus/internal/behavior" "thehouseoficarus/internal/casino" "thehouseoficarus/internal/item" + "thehouseoficarus/internal/net" "thehouseoficarus/internal/prediction" ) @@ -87,6 +88,22 @@ func TestGlobalCommandPreservesArgumentCase(t *testing.T) { } } +// Regression: `get 5 credits` used to sweep the whole purse headroom. +func TestPickupCreditsHonorsRequestedQuantity(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice") + p := h.seedCharacter("alice", "alice") + h.g.RunOnOwner(func() { + p.Credits = 0 + h.g.World.AddGroundItem(p.RoomID, "credits", 10) + sess := &net.Session{Player: p, Conn: newChanConn()} + h.g.pickupCredits(sess, p, "credits", 5) + if p.Credits != 5 { + t.Errorf("credits = %d, want 5 (output: %s)", p.Credits, sess.Conn.(*chanConn).Bytes()) + } + }) +} + // Regression: the player-file classifier must canonicalize repeated "/" and // "data/" prefixes so a raw-editor path cannot dodge the online check. func TestPlayerDataFileNameCanonicalizesPrefixes(t *testing.T) { diff --git a/internal/game/credits_pickup_test.go b/internal/game/credits_pickup_test.go index 721c550..4342ea8 100644 --- a/internal/game/credits_pickup_test.go +++ b/internal/game/credits_pickup_test.go @@ -19,7 +19,7 @@ func TestPickupCreditsSentinelQuantity(t *testing.T) { p.Credits = 100 h.g.World.AddGroundItem(p.RoomID, "credits", 10) sess := &net.Session{Player: p, Conn: newChanConn()} - h.g.pickupCredits(sess, p, "credits") + h.g.pickupCredits(sess, p, "credits", 0) if p.Credits != 110 { t.Errorf("credits after pickup = %d, want 110 (output: %s)", p.Credits, sess.Conn.(*chanConn).Bytes()) } diff --git a/internal/game/hardening_credit_cap_test.go b/internal/game/hardening_credit_cap_test.go index 872c746..05b0aeb 100644 --- a/internal/game/hardening_credit_cap_test.go +++ b/internal/game/hardening_credit_cap_test.go @@ -23,7 +23,7 @@ func TestPickupCreditsAtCapLeavesRemainderOnGround(t *testing.T) { sess := &net.Session{Conn: newChanConn(), Player: p} sess.SetState(net.StateGame) - h.g.pickupCredits(sess, p, "credits") + h.g.pickupCredits(sess, p, "credits", 0) if p.Credits != casino.MaxCredits { t.Errorf("balance = %d, want the cap %d", p.Credits, casino.MaxCredits) @@ -44,7 +44,7 @@ func TestPickupCreditsAtCapDestroysNothing(t *testing.T) { sess := &net.Session{Conn: newChanConn(), Player: p} sess.SetState(net.StateGame) - h.g.pickupCredits(sess, p, "credits") + h.g.pickupCredits(sess, p, "credits", 0) if p.Credits != casino.MaxCredits { t.Errorf("balance = %d, want the cap %d", p.Credits, casino.MaxCredits) diff --git a/internal/game/harness_test.go b/internal/game/harness_test.go index 1d3df10..ff5ac32 100644 --- a/internal/game/harness_test.go +++ b/internal/game/harness_test.go @@ -62,6 +62,7 @@ func (c *chanConn) Close() error { } func (c *chanConn) SetWriteDeadline(time.Time) error { return nil } +func (c *chanConn) SetReadDeadline(time.Time) error { return nil } func (c *chanConn) SetEcho(bool) error { return nil } diff --git a/internal/game/sys_escape_test.go b/internal/game/sys_escape_test.go index 61b50cd..fd4c9ab 100644 --- a/internal/game/sys_escape_test.go +++ b/internal/game/sys_escape_test.go @@ -24,6 +24,7 @@ func (c *escapeTestConn) Write(b []byte) (int, error) { return len(b), nil } func (c *escapeTestConn) SetWriteDeadline(time.Time) error { return nil } +func (c *escapeTestConn) SetReadDeadline(time.Time) error { return nil } func (c *escapeTestConn) Close() error { return nil } func (c *escapeTestConn) SetEcho(bool) error { return nil } |
