H5 follow-up: short-rest at full HP can still refresh slots

handleDnDShortRest early-returned when HPCurrent >= HPMax, which dates
from when short rest was HP-only. After H5 (1cd53eb) added the partial
slot refresh, that gate left casters who hadn't been hit unable to
recover slots between fights — the most common slot-attrition scenario.

Loosen the gate: short rest is allowed when HP can heal OR any spell
slot has used > 0. New helper casterHasUsedSlots gates the slot branch.
Martial behavior unchanged (still bails at full HP). Two new tests.
This commit is contained in:
prosolis
2026-05-17 16:06:46 -07:00
parent f2c2d774d4
commit dd25de71f0
3 changed files with 99 additions and 18 deletions

View File

@@ -543,6 +543,18 @@ func refundSpellSlot(userID id.UserID, slotLevel int) error {
return err
}
// casterHasUsedSlots reports whether any spell slot for userID has used>0.
// Used by the short-rest gate so casters at full HP can still rest to
// recover slots (partialRefreshSpellSlots is otherwise unreachable for
// them).
func casterHasUsedSlots(userID id.UserID) (bool, error) {
var n int
err := db.Get().QueryRow(
`SELECT COUNT(*) FROM dnd_spell_slots WHERE user_id = ? AND used > 0`,
string(userID)).Scan(&n)
return n > 0, err
}
// refreshSpellSlots resets used=0 across all of a player's slots. Called
// on long rest.
func refreshSpellSlots(userID id.UserID) error {