Add ui_LifebarOnlyDamaged toggle to hide full-HP lifebars#151
Add ui_LifebarOnlyDamaged toggle to hide full-HP lifebars#151M3RT1N99 wants to merge 1 commit intoFAForever:masterfrom
Conversation
When ui_LifebarOnlyDamaged is set to 1, the engine skips lifebar enqueue for units at full HP, only showing lifebars once a unit has taken damage. Default 0 (vanilla behaviour). Mirrors Warcraft 3's 'Show Lifebars Only When Damaged' option. Hooks the call sub_85EED0 at 0x85C09F inside Moho::CWldSession::RenderStrategicIcons. The custom calling convention of sub_85EED0 (eax = lifebar entry buffer ptr, ecx = batch vec) is preserved by a small asm filter that either ret's (suppress) or tail-calls the original (render). The filter reads the same HP fields the actual lifebar drawing function sub_85CD40 uses for the bar fill fraction: v18 = *(float **)eax0; // entry[0] -> unit data ptr v19 = v18[26] / v18[27]; // current HP / max HP so we read offsets 104/108 from the unit data pointer at entry[0] and suppress when the two are equal. Provides a noticeable FPS gain in dense crowds where most units are undamaged, since the lifebar batch never receives the redundant entries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThese changes implement a "show lifebars only when damaged" feature controlled by a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@section/LifebarFilter.cpp`:
- Around line 14-17: Update the comment block documenting HP offsets to match
the actual implementation and include/moho.h: change the mapped offsets so
UserEntity_base.mVarData @ +0x4C plus SSTIEntityVariableData.mHealth @ +0x18 ->
UserEntity +0x68, and SSTIEntityVariableData.mMaxHealth @ +0x1C -> UserEntity
+0x6C (this aligns with the reads in LifebarFilter where the code uses +0x68 and
+0x6C for health and max health). Mention include/moho.h as the corroborating
source and remove the incorrect +0x64/+0x68 mapping from the comment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a9adef0b-ccff-41ab-abdf-1f8975dcf956
📒 Files selected for processing (4)
Info.txtchangelog.mdhooks/LifebarFilter.hooksection/LifebarFilter.cpp
| // HP/MaxHealth offsets in Moho::UserEntity verified via IDA struct DB: | ||
| // UserEntity_base.mVarData @ +0x4C | ||
| // SSTIEntityVariableData.mHealth @ +0x18 -> UserEntity +0x64 | ||
| // SSTIEntityVariableData.mMaxHealth @ +0x1C -> UserEntity +0x68 |
There was a problem hiding this comment.
Fix the documented HP offsets.
These comments say mHealth / mMaxHealth resolve to UserEntity +0x64 / +0x68, but the implementation reads +0x68 / +0x6C at Lines 76-77, which also matches include/moho.h. Please correct the comment so future maintenance does not “fix” the asm to the wrong fields.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@section/LifebarFilter.cpp` around lines 14 - 17, Update the comment block
documenting HP offsets to match the actual implementation and include/moho.h:
change the mapped offsets so UserEntity_base.mVarData @ +0x4C plus
SSTIEntityVariableData.mHealth @ +0x18 -> UserEntity +0x68, and
SSTIEntityVariableData.mMaxHealth @ +0x1C -> UserEntity +0x6C (this aligns with
the reads in LifebarFilter where the code uses +0x68 and +0x6C for health and
max health). Mention include/moho.h as the corroborating source and remove the
incorrect +0x64/+0x68 mapping from the comment.
Adds a new HUD setting that hides lifebars on units at full HP. Bars only appear once a unit has taken damage. Provides a noticeable FPS gain in dense crowds where most units are undamaged. Requires the matching binary patch (FAForever/FA-Binary-Patches#151) which exposes the ui_LifebarOnlyDamaged ConVar this option drives via ConExecute. Without that patch the option toggle is a no-op (the ConVar is unrecognised). - lua/options/options.lua: new toggle in the HUD section - lua/ui/help/tooltips.lua: tooltip entry options_gui_lifebar_only_damaged - loc/US/strings_db.lua: OPTIONS_0287 / OPTIONS_0288 strings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
ui_LifebarOnlyDamaged. When set to 1, lifebars only appear once a unit takes damage; full-HP units skip the lifebar batch entirely. Default 0 (vanilla behaviour).https://discord.com/channels/197033481883222026/1492294267492634674
Companion PR
The matching settings UI option lives in FAForever/fa#7085 — adds a HUD toggle that drives this ConVar via
ConExecute. The two PRs should land together: this binary patch alone makes the ConVar available in the in-game console, the Lua PR alone is a no-op without this patch.How it works
Hooks the
call sub_85EED0at 0x85C09F insideMoho::CWldSession::RenderStrategicIcons(the lifebar enqueue inside the per-unit loop). The 5-byte CALL is replaced withcall LifebarFilter(same encoding length, no padding).LifebarFilteris a small asm filter that:Saves caller state with
pushadReads the
ui_LifebarOnlyDamagedflag — if 0, falls through to the originalReads the same HP fields the actual lifebar drawing function
sub_85CD40uses for the bar fill fraction:So we dereference
entry[0]and read offsets 104 / 108 from the unit data pointer.If
current HP < max HP→ tail-callssub_85EED0(render)If
current HP >= max HP→ returns without enqueueing (suppress)The custom calling convention of
sub_85EED0(eax = lifebar entry buffer pointer, ecx = batch vec pointer) is preserved on both paths viapushad/popad.Files
hooks/LifebarFilter.hook— 5-byte CALL replacement at 0x85C09Fsection/LifebarFilter.cpp— ConVar registration + asm filterchangelog.md— entry under AdditionsInfo.txt— documentssub_85EED0,sub_85CD40, and the entry HP layoutTest plan
ui_LifebarOnlyDamaged 1— verify lifebars disappear for all of themui_LifebarOnlyDamaged 0— verify all lifebars come back (vanilla behaviour)🤖 Generated with Claude Code