mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Combat: round half-up on HP wound persistence to fix 101→100 drift
Wound carry-over went through three integer truncations across the legacy combat scale (123 max) and the dndChar scale (78 max). 101/123 persisted as int(64.04)=64, then restored as int(100.92)=100 — losing 0.92 HP every fight. Switching both sides to math.Round means most HPs round-trip exactly; the residual error is bounded by ±1 HP from the inherent scale mismatch (1 dndChar HP ≈ 1.58 legacy HP, so some pairs collide on the smaller scale). Acceptable; the prior always-truncate behavior was directionally biased against the player. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package plugin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gogobee/internal/db"
|
"gogobee/internal/db"
|
||||||
@@ -429,7 +430,11 @@ func applyDnDHPScaling(stats *CombatStats, c *DnDCharacter) {
|
|||||||
if pct < dndWoundFloor {
|
if pct < dndWoundFloor {
|
||||||
pct = dndWoundFloor
|
pct = dndWoundFloor
|
||||||
}
|
}
|
||||||
scaled := int(float64(stats.MaxHP) * pct)
|
// Round half-up. Naive int truncation loses up to 1 HP on every
|
||||||
|
// round-trip through the dndChar scale (which is coarser than the
|
||||||
|
// legacy combat scale): 101/123 → persist as 64/78 → restore as
|
||||||
|
// int(100.92) = 100, silently dropping a HP between fights.
|
||||||
|
scaled := int(math.Round(float64(stats.MaxHP) * pct))
|
||||||
if scaled < 1 {
|
if scaled < 1 {
|
||||||
scaled = 1
|
scaled = 1
|
||||||
}
|
}
|
||||||
@@ -470,7 +475,10 @@ func persistDnDHPAfterCombat(userID id.UserID, legacyStartHP, legacyEndHP int) {
|
|||||||
pct = 1
|
pct = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
newHP := int(float64(c.HPMax) * pct)
|
// Round half-up to mirror applyDnDHPScaling — a fight that ends at
|
||||||
|
// 101/123 should round-trip cleanly through the dndChar (78-scale)
|
||||||
|
// store and come back as 101, not 100.
|
||||||
|
newHP := int(math.Round(float64(c.HPMax) * pct))
|
||||||
if newHP < 0 {
|
if newHP < 0 {
|
||||||
newHP = 0
|
newHP = 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user