Skip to content

Fix HUD visibility API and showhud/player map state conflicts#5027

Open
QueryOfficial wants to merge 5 commits into
multitheftauto:masterfrom
QueryOfficial:fix/isplayerhudcomponentvisible-showhud
Open

Fix HUD visibility API and showhud/player map state conflicts#5027
QueryOfficial wants to merge 5 commits into
multitheftauto:masterfrom
QueryOfficial:fix/isplayerhudcomponentvisible-showhud

Conversation

@QueryOfficial

@QueryOfficial QueryOfficial commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes two related HUD issues discovered while resolving #5026:

bool isPlayerHudComponentVisible(string component [, bool checkEnabled = true])
  • checkEnabled = true (default): unchanged behavior; reports the state requested through setPlayerHudComponentVisible, so no existing script breaks and scripts can still distinguish "disabled by script" from "hidden by showhud".
  • checkEnabled = false: reports the effective on-screen visibility, accounting for the global HUD state (showhud command, fullscreen player map) and every containing component in the draw path (radar_map, radar_blips and radar_altimeter inherit the radar's visibility).

Under the hood this introduces owner-aware HUD visibility state:

  • The persistent visibility requested through showhud is kept separate from temporary suppression, so showhud and the fullscreen player map no longer overwrite each other's state. Closing the map can no longer re-enable a HUD previously hidden with showhud 0.
  • The showhud toggle now flips only the user's own preference, so it behaves predictably while the map is open.
  • Game reset clears persistent state, temporary suppression and closes the player map, so no stale suppression or chat visibility state survives a reconnect.
  • GTA HUD draw instructions are only rewritten when the effective state actually changes, and SetComponentVisible skips the unprotect/write cycle when the component is already in the requested state.
  • New CHud virtual methods are added at the end of the interface to preserve existing virtual method positions across client modules.

There are no Lua function signature breaks, component ID, network protocol, or migration changes. The OOP variant (player.isHudComponentVisible) supports the new parameter automatically.

Motivation

Fixes #5026.
Fixes #547.

isPlayerHudComponentVisible("radar") returned true after showhud hid the HUD, because it only inspected the per-component state set by setPlayerHudComponentVisible and ignored the global HUD draw state.

This problem has a long history, and previous attempts were closed specifically because they changed the default return value:

This PR implements the solution the maintainers converged on in those discussions: the default stays fully compatible, and the effective visibility is available on request via checkEnabled = false.

While fixing the API, a second issue was found and fixed: showhud and the fullscreen player map both called Disable(bool) on a single global flag, so for example after showhud 0, opening and closing the F11 map unintentionally re-enabled the HUD. Persistent requested visibility and temporary suppression are now tracked separately, and each owner releases only its own suppression.

Test plan

Build:

  • Built Game SA (Release|Win32) successfully.
  • Compiled all touched Client Core / Client Deathmatch translation units successfully.
  • Ran utils/clang-format.ps1 after the C++ changes.

API behavior:

  1. isPlayerHudComponentVisible("radar") → true.
  2. showhud → isPlayerHudComponentVisible("radar") → still true (documented compatible default), isPlayerHudComponentVisible("radar", false) → false.
  3. showhud again → both return true.
  4. setPlayerHudComponentVisible("radar", false) → both variants return false.
  5. Hide parent radar only → "radar_map", "radar_blips", "radar_altimeter" with checkEnabled = false all return false; restoring radar restores them, while an explicitly hidden radar_blips stays false until restored.

State ownership:

  1. showhud 0 → HUD hidden.
  2. Open F11 map → HUD still hidden; close it → HUD still hidden (showhud state preserved).
  3. showhud (toggle) → HUD visible again.
  4. Open F11 map with HUD visible → HUD suppressed; showhud toggle while the map is open flips only the user preference.
  5. Reconnect with HUD hidden and map open → reset restores the HUD and closes the map with no stale suppression.

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

…state

#### Summary
Updated the IsPlayerHudComponentVisible function to accept an additional parameter, bCheckEnabled, which determines if the HUD's enabled state should be considered when checking component visibility.

#### Motivation
This change ensures that HUD components are reported as hidden when the HUD is globally disabled, even if they are still enabled by script. This improves the accuracy of visibility checks in various gameplay scenarios.

#### Test plan
Verify that HUD components behave correctly under different HUD enabled/disabled states, ensuring visibility reflects the actual on-screen status.
#### Summary
Introduced a new mechanism for managing HUD visibility through disable reasons, allowing for more granular control over HUD states. The `CHudSA` class now tracks multiple disable reasons, and methods have been added to set and reset these reasons. The `HUD` command function has been updated to respect user preferences without being affected by temporary HUD suppressions.

#### Motivation
This change improves the handling of HUD visibility, ensuring that temporary states (like player maps) do not interfere with user settings. It enhances the overall user experience by providing a more reliable HUD state management system.

#### Test plan
Verify that HUD visibility behaves correctly under various scenarios, including toggling the HUD with user commands and during temporary suppressions like player maps.
@TheCrazy17

Copy link
Copy Markdown
Contributor

You could also add Fixes #547 so both issues get closed by the same pull request. 😄

@QueryOfficial QueryOfficial changed the title Fix isPlayerHudComponentVisible not reflecting showhud state Fix HUD visibility API and showhud/player map state conflicts Jul 11, 2026
…hecks

#### Summary
This commit refines the HUD management system by introducing a more robust mechanism for handling visibility states. The `CHudSA` class now utilizes suppression reasons to manage temporary HUD states without affecting persistent user preferences. Additionally, new methods have been added to check component visibility more accurately, considering both the global HUD state and individual component states.

#### Motivation
These changes improve the reliability of HUD visibility, ensuring that temporary suppressions (like player maps) do not interfere with user settings. This enhances the overall user experience by providing clearer and more consistent HUD behavior.

#### Test plan
Verify that HUD visibility behaves correctly under various scenarios, including toggling the HUD with user commands and during temporary suppressions like player maps. Ensure that component visibility checks reflect the actual on-screen status accurately.
@QueryOfficial

Copy link
Copy Markdown
Contributor Author

You could also add Fixes #547 so both issues get closed by the same pull request. 😄

Thanks @crazy17 ! Good point — I've updated the PR description to also include "Fixes #547", so both issues get closed by this pull request. 🎉

@FileEX FileEX added the bugfix Solution to a bug of any kind label Jul 22, 2026
@FileEX

FileEX commented Jul 22, 2026

Copy link
Copy Markdown
Member

Conflict with #5028

Comment thread Client/game_sa/CHudSA.cpp Outdated
Comment thread Client/game_sa/CHudSA.cpp Outdated
Comment thread Client/game_sa/CHudSA.cpp Outdated
Comment thread Client/game_sa/CHudSA.h Outdated
Comment thread Client/sdk/game/CHud.h Outdated
Comment thread Client/game_sa/CHudSA.h Outdated
Comment thread Client/sdk/game/CHud.h Outdated
#### Summary
This commit simplifies the HUD suppression mechanism by removing the use of suppression reasons and directly managing the suppressed state within the `CHudSA` class. The `SetSuppressed` method has been updated to reflect this change, and visibility checks for HUD components have been enhanced to ensure accurate rendering based on the current HUD state.

#### Motivation
These changes streamline the HUD management system, making it easier to control visibility without the complexity of multiple suppression reasons. This improves the overall reliability of HUD behavior during gameplay.

#### Test plan
Verify that HUD visibility functions correctly under various scenarios, including toggling the HUD and during temporary suppressions like player maps. Ensure that component visibility checks accurately reflect the current state of the HUD.
@QueryOfficial

Copy link
Copy Markdown
Contributor Author

Thanks for the review @FileEX — applied your feedback:

  • IsDisabled() is now const noexcept
  • Replaced memcmp with std::memcmp
  • Switched member/default init to brace initialization (parent{HUD_ALL}, m_isEnabled{true}, m_isAppliedDisabled{false})
  • Removed the eHudSuppressionReason enum — agreed it wasn’t needed. Temporary map suppression is now a single bool via SetSuppressed(bool)
  • Dropped the virtual-method-order comment

Comment thread Client/game_sa/CHudSA.cpp Outdated
Comment thread Client/core/CCommandFuncs.cpp Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Solution to a bug of any kind

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isPlayerHudComponentVisible("radar") does not reflect showhud state isPlayerHudComponentVisible only works with setPlayerHudComponentVisible

3 participants