New HudGroups autoload manages show/hide of related HUD elements as groups. Exclusive groups (gameplay, implant) are mutually exclusive — opening the star map hides stance indicator, minimap, interaction prompts, etc. Closing it restores them. Gameplay nodes registered in main.gd _ready(). Star map registers as implant group and uses toggle_group() instead of direct visibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
89 lines
2.8 KiB
GDScript
89 lines
2.8 KiB
GDScript
extends Node
|
|
## HUD visibility group manager (D-170).
|
|
##
|
|
## Nodes register themselves into groups. When a group's visibility changes,
|
|
## all registered nodes show/hide together. This replaces per-panel manual
|
|
## hide/show of individual HUD elements.
|
|
##
|
|
## Groups:
|
|
## "gameplay" — stance indicator, minimap, health/time, interaction prompts,
|
|
## cursor renderer, inventory, news ticker, examine display
|
|
## "implant" — star map, travel planner, GTTR reader, station profile
|
|
## "modal" — settings, bug report, loading screen, debug console
|
|
## "debug" — debug overlay, gauntlet HUD, checklist
|
|
## "always" — nodes that never hide (reserved for future use)
|
|
##
|
|
## Usage from any node:
|
|
## HudGroups.register(self, "gameplay")
|
|
## HudGroups.show_group("implant") # shows implant, hides gameplay
|
|
## HudGroups.show_group("gameplay") # shows gameplay, hides implant
|
|
## HudGroups.toggle_group("implant") # toggle between gameplay and implant
|
|
|
|
## Which groups are mutually exclusive — showing one hides the others.
|
|
## Modal and debug are independent (they overlay on top of anything).
|
|
const EXCLUSIVE_GROUPS: Array[String] = ["gameplay", "implant"]
|
|
|
|
var _groups: Dictionary = {} # group_name -> Array[Control]
|
|
var _active_exclusive: String = "gameplay"
|
|
|
|
|
|
func register(node: Control, group: String) -> void:
|
|
if not _groups.has(group):
|
|
_groups[group] = []
|
|
if node not in _groups[group]:
|
|
_groups[group].append(node)
|
|
# Apply current visibility state
|
|
if group in EXCLUSIVE_GROUPS:
|
|
node.visible = (group == _active_exclusive)
|
|
|
|
|
|
func unregister(node: Control, group: String) -> void:
|
|
if _groups.has(group):
|
|
_groups[group].erase(node)
|
|
|
|
|
|
## Show a group. If it's exclusive, hide the other exclusive groups.
|
|
func show_group(group: String) -> void:
|
|
if group in EXCLUSIVE_GROUPS:
|
|
_active_exclusive = group
|
|
for g: String in EXCLUSIVE_GROUPS:
|
|
_set_group_visible(g, g == group)
|
|
else:
|
|
_set_group_visible(group, true)
|
|
|
|
|
|
## Hide a group. If exclusive, falls back to "gameplay".
|
|
func hide_group(group: String) -> void:
|
|
if group in EXCLUSIVE_GROUPS:
|
|
show_group("gameplay")
|
|
else:
|
|
_set_group_visible(group, false)
|
|
|
|
|
|
## Toggle between gameplay and the specified group.
|
|
func toggle_group(group: String) -> void:
|
|
if _active_exclusive == group:
|
|
show_group("gameplay")
|
|
else:
|
|
show_group(group)
|
|
|
|
|
|
## Check if a group is currently active.
|
|
func is_group_active(group: String) -> bool:
|
|
if group in EXCLUSIVE_GROUPS:
|
|
return _active_exclusive == group
|
|
# Non-exclusive: check if any member is visible
|
|
if _groups.has(group):
|
|
for node: Control in _groups[group]:
|
|
if is_instance_valid(node) and node.visible:
|
|
return true
|
|
return false
|
|
|
|
|
|
func _set_group_visible(group: String, vis: bool) -> void:
|
|
if not _groups.has(group):
|
|
return
|
|
for node: Control in _groups[group]:
|
|
if is_instance_valid(node):
|
|
node.visible = vis
|