aboutsummaryrefslogtreecommitdiff
path: root/internal/game
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game')
-rw-r--r--internal/game/casino_test.go1
-rw-r--r--internal/game/cmd_bank.go13
-rw-r--r--internal/game/cmd_get.go14
-rw-r--r--internal/game/cmd_room_remove_test.go1
-rw-r--r--internal/game/correct_audit_fixes_test.go17
-rw-r--r--internal/game/credits_pickup_test.go2
-rw-r--r--internal/game/hardening_credit_cap_test.go4
-rw-r--r--internal/game/harness_test.go1
-rw-r--r--internal/game/sys_escape_test.go1
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 }