Implant apps use hierarchical groups: implant/map, implant/wiki, implant/journal, etc. Apps are mutually exclusive with each other and with gameplay. Opening implant/map hides gameplay + any other implant app. Closing returns to gameplay. API: open_app(), close_app(), toggle_app(), is_app_active(). Star map uses implant/map. Future apps register their own group. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
109 lines
3.3 KiB
GDScript
109 lines
3.3 KiB
GDScript
extends Node
|
|
## HUD visibility group manager (D-170).
|
|
##
|
|
## Nodes register into hierarchical groups. Groups control show/hide as a unit.
|
|
##
|
|
## Hierarchy:
|
|
## "gameplay" — stance, minimap, health, prompts, cursor, inventory
|
|
## "implant/map" — star map
|
|
## "implant/wiki" — GTTR reader
|
|
## "implant/journal" — knowledge journal
|
|
## "implant/travel" — travel planner
|
|
## "implant/station" — station profile
|
|
## "implant/cargo" — cargo manifest
|
|
## "modal" — settings, bug report, loading (independent layer)
|
|
## "debug" — debug overlay, gauntlet HUD (independent layer)
|
|
##
|
|
## Rules:
|
|
## - "gameplay" and any "implant/*" are mutually exclusive.
|
|
## Opening an implant app hides gameplay.
|
|
## - "implant/*" apps are mutually exclusive with each other.
|
|
## Opening implant/map hides implant/wiki.
|
|
## - "modal" and "debug" are independent — overlay on anything.
|
|
##
|
|
## Usage:
|
|
## HudGroups.register(self, "gameplay")
|
|
## HudGroups.register(self, "implant/map")
|
|
## HudGroups.open_app("implant/map") # hides gameplay + other implant apps
|
|
## HudGroups.close_app() # returns to gameplay
|
|
## HudGroups.toggle_app("implant/map") # open if closed, close if open
|
|
|
|
var _groups: Dictionary = {} # group_name -> Array[Control]
|
|
var _active_app: String = "" # currently open implant/* app ("" = none)
|
|
|
|
|
|
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
|
|
if group == "gameplay":
|
|
node.visible = _active_app.is_empty()
|
|
elif group.begins_with("implant/"):
|
|
node.visible = (group == _active_app)
|
|
|
|
|
|
func unregister(node: Control, group: String) -> void:
|
|
if _groups.has(group):
|
|
_groups[group].erase(node)
|
|
|
|
|
|
## Open an implant app. Hides gameplay and any other implant app.
|
|
func open_app(app: String) -> void:
|
|
if not app.begins_with("implant/"):
|
|
push_warning("HudGroups.open_app: expected implant/* group, got: " + app)
|
|
return
|
|
|
|
# Hide previous app if different
|
|
if not _active_app.is_empty() and _active_app != app:
|
|
_set_group_visible(_active_app, false)
|
|
|
|
_active_app = app
|
|
_set_group_visible("gameplay", false)
|
|
_set_group_visible(app, true)
|
|
|
|
|
|
## Close the current implant app. Returns to gameplay.
|
|
func close_app() -> void:
|
|
if not _active_app.is_empty():
|
|
_set_group_visible(_active_app, false)
|
|
_active_app = ""
|
|
_set_group_visible("gameplay", true)
|
|
|
|
|
|
## Toggle an implant app. If it's open, close it. If another is open, switch.
|
|
func toggle_app(app: String) -> void:
|
|
if _active_app == app:
|
|
close_app()
|
|
else:
|
|
open_app(app)
|
|
|
|
|
|
## Check if a specific app is currently open.
|
|
func is_app_active(app: String) -> bool:
|
|
return _active_app == app
|
|
|
|
|
|
## Check if any implant app is open.
|
|
func is_implant_active() -> bool:
|
|
return not _active_app.is_empty()
|
|
|
|
|
|
## Get the currently active app name, or "" if none.
|
|
func get_active_app() -> String:
|
|
return _active_app
|
|
|
|
|
|
## Show/hide an independent group (modal, debug). Does not affect gameplay/implant.
|
|
func show_group(group: String, vis: bool = true) -> void:
|
|
_set_group_visible(group, vis)
|
|
|
|
|
|
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
|