feat(stats): heals, repairs and restores count what they applied

Live sent TotalArmorRepaired / TotalImaginationRestored with what a repair
or restore applied, 0 included (1,050 and 2,148 zeros in the captures: a
power-up picked up at full), and never a TotalDamageHealed or
TotalDamageTaken of 0. DLU counted every change of the value instead, so
setting stats up (loading, respawning, level changes) counted as healing
and a heal at full health counted as 0 damage taken.

Now Heal, Repair and Imagine count what they applied; health lost and
imagination spent still count wherever they change.

Check in game: pick up an armor or imagination power-up when full; the
passport's Armor Repaired / Imagination Restored stay the same. Take damage
and heal; Damage Taken and Damage Healed go up by what the bar shows.
Respawn: Damage Healed doesn't jump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 02:19:43 -05:00
parent 1f29e9604a
commit fd10e19a06
4 changed files with 56 additions and 13 deletions

View File

@@ -174,3 +174,33 @@ TEST_F(PlayerStatisticTest, SmashingCountsEnemiesAndSmashables) {
EXPECT_TRUE(Statistics(smash(false, false)).empty());
killer->SetCharacter(nullptr);
}
// Live: what a heal, repair or restore applied, 0 included for armor and imagination (a power-up picked up when full);
// no TotalDamageHealed of 0
TEST_F(PlayerStatisticTest, HealsRepairsAndRestoresCountWhatTheyApplied) {
auto* destroyable = entity->AddComponent<DestroyableComponent>(-1);
destroyable->SetMaxHealth(10.0f);
destroyable->SetMaxArmor(10.0f);
destroyable->SetMaxImagination(10.0f);
destroyable->SetHealth(10);
destroyable->SetArmor(8);
destroyable->SetImagination(10);
const auto sent = [&](const std::function<void()>& action) {
std::vector<std::pair<int32_t, int64_t>> out;
for (const auto& statistic : Statistics(Capture(action))) out.emplace_back(statistic.updateID, statistic.updateValue);
return out;
};
using Sent = std::vector<std::pair<int32_t, int64_t>>;
EXPECT_EQ(sent([&] { destroyable->Heal(5); }), Sent{});
EXPECT_EQ(sent([&] { destroyable->Repair(5); }), (Sent{ { TotalArmorRepaired, 2 } }));
EXPECT_EQ(sent([&] { destroyable->Repair(5); }), (Sent{ { TotalArmorRepaired, 0 } }));
EXPECT_EQ(sent([&] { destroyable->Imagine(3); }), (Sent{ { TotalImaginationRestored, 0 } }));
EXPECT_EQ(sent([&] { destroyable->Imagine(-4); }), (Sent{ { TotalImaginationUsed, 4 } }));
EXPECT_EQ(sent([&] { destroyable->Imagine(6); }), (Sent{ { TotalImaginationRestored, 4 } }));
EXPECT_EQ(sent([&] { destroyable->SetHealth(7); }), (Sent{ { TotalDamageTaken, 3 } }));
EXPECT_EQ(sent([&] { destroyable->Heal(1); }), (Sent{ { TotalDamageHealed, 1 } }));
// Setting stats up (loading, respawning) isn't healing
EXPECT_EQ(sent([&] { destroyable->SetHealth(10); destroyable->SetArmor(10); destroyable->SetImagination(10); }), Sent{});
}