Nicht abgenommen: Nach dem ersten Spieltest wurde entschieden, Champions of Luneraria nach Unity 6 zu portieren. Dieser Stand ist die Referenz für das HUD im Unity-Projekt (../luneraria-unity). - HUD neu aus Komponenten mit eigenem Theme, Porträts aus den echten Modellen (einmal gerendert, zwischengespeichert), Lane-Übersicht mit deterministischer Bedrohung aus öffentlichem Zustand, Bossgrotte, nächste Welle, Ereignisse, Minimap mit zusammengefassten Armeen, Held/Items/Talente, Einheitendetails, Angriffschampions, Bereit-Sperre, UI-Größe, Team-Formen statt nur Farben - Privatsphäre über LuneHudModel: fremdes Gold und fremde Entwürfe erscheinen nie - Keine Regeländerung: Regeln 91/91, M2 73/73, Netz 43/43; verify_g3 715/715; verify_m1 38/38 und verify_m2 14/14 mit angepassten UI-Treibern - Spieltest bis Welle 8 über die echte Oberfläche, Befunde in G3-HUD.md - HELDEN-KONZEPT.md: vom Projektinhaber vorgegebene Helden (nicht umgesetzt) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
5.2 KiB
GDScript
121 lines
5.2 KiB
GDScript
class_name LuneSettings
|
||
extends ColorRect
|
||
## Options and controls for Champions of Luneraria; the same Preferences as before plus the
|
||
## HUD size. The key list is the one place where every shortcut is shown.
|
||
|
||
signal closed
|
||
|
||
const SCALES: Array[float] = [.9, 1.0, 1.15, 1.3]
|
||
const KEYS: Array = [
|
||
["Planung", [["1–5", "Truppe kaufen"], ["Leertaste", "Bereit"], ["Klick auf Einheit", "Details, Aufwerten, Einsatz"], ["Esc", "Auswahl oder Fenster schließen"]]],
|
||
["Kampf", [["Leertaste / P", "Pause (offline)"], ["Tempo-Knopf", "1× · 2× · 4×"]]],
|
||
["Kamera", [["F2 · F3 · F4", "Top · Mid · Bottom"], ["G", "Bossgrotte"], ["B", "eigener Ancient"], ["H", "eigener Held"],
|
||
["Tab", "nächste Lane"], ["O", "Übersicht"], ["R", "zurücksetzen"], ["Q / E", "drehen"], ["WASD · Pfeile · mittlere Maustaste", "verschieben"],
|
||
["Mausrad", "Zoom"], ["Minimap", "klicken oder ziehen"]]],
|
||
["Allgemein", [["F1", "Optionen"], ["M", "Ton an/aus"], ["F11", "Vollbild"]]],
|
||
]
|
||
|
||
var _volume: HSlider
|
||
var _checks: Dictionary = {}
|
||
var _scale: ChoiceGroup
|
||
|
||
func _ready() -> void:
|
||
theme = LuneUiTheme.shared()
|
||
color = Color(.02, .03, .04, .9)
|
||
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
mouse_filter = Control.MOUSE_FILTER_STOP
|
||
var center := CenterContainer.new()
|
||
center.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
add_child(center)
|
||
var panel := PanelContainer.new()
|
||
panel.theme_type_variation = "MenuPanel"
|
||
panel.custom_minimum_size.x = 900
|
||
center.add_child(panel)
|
||
var column := VBoxContainer.new()
|
||
column.add_theme_constant_override("separation", 10)
|
||
panel.add_child(column)
|
||
var heading := _label("Optionen & Steuerung", "HeadingLabel", column)
|
||
heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||
_label("Ein laufender Kampf pausiert offline, solange dieses Fenster geöffnet ist.", "MutedLabel", column).horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||
var top := HBoxContainer.new()
|
||
top.add_theme_constant_override("separation", 30)
|
||
column.add_child(top)
|
||
var left := VBoxContainer.new()
|
||
left.add_theme_constant_override("separation", 8)
|
||
left.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
top.add_child(left)
|
||
_label("LAUTSTÄRKE", "SectionLabel", left)
|
||
_volume = HSlider.new()
|
||
_volume.max_value = 100
|
||
_volume.custom_minimum_size.y = 28
|
||
left.add_child(_volume)
|
||
_volume.value_changed.connect(func(value: float) -> void:
|
||
Preferences.volume = value / 100.0
|
||
Preferences.commit())
|
||
for entry: Array in [["muted", "Ton stumm [M]"], ["fullscreen", "Vollbild [F11]"], ["reduced_motion", "Bewegung reduzieren"]]:
|
||
var check := CheckButton.new()
|
||
check.text = entry[1]
|
||
left.add_child(check)
|
||
var key: String = entry[0]
|
||
check.toggled.connect(func(value: bool) -> void:
|
||
Preferences.set(key, value)
|
||
Preferences.commit())
|
||
_checks[key] = check
|
||
var right := VBoxContainer.new()
|
||
right.add_theme_constant_override("separation", 8)
|
||
right.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
top.add_child(right)
|
||
_label("UI-GRÖSSE IM SPIEL", "SectionLabel", right)
|
||
_scale = ChoiceGroup.new(true)
|
||
for value: float in SCALES:
|
||
_scale.add_option("%d %%" % int(round(value * 100.0)))
|
||
right.add_child(_scale)
|
||
_scale.item_selected.connect(func(index: int) -> void:
|
||
Preferences.ui_scale = SCALES[index]
|
||
Preferences.commit())
|
||
var note := _label("Größer für hochauflösende oder weit entfernte Bildschirme. Das HUD begrenzt die Größe selbst, sodass nichts aus dem Fenster ragt.", "MutedLabel", right)
|
||
note.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||
column.add_child(HSeparator.new())
|
||
_label("STEUERUNG", "SectionLabel", column)
|
||
var keys := HBoxContainer.new()
|
||
keys.add_theme_constant_override("separation", 26)
|
||
column.add_child(keys)
|
||
for index: int in range(2):
|
||
var list := GridContainer.new()
|
||
list.columns = 2
|
||
list.add_theme_constant_override("h_separation", 14)
|
||
list.add_theme_constant_override("v_separation", 2)
|
||
list.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
keys.add_child(list)
|
||
for group: Array in (KEYS.slice(0, 2) + [KEYS[3]] if index == 0 else [KEYS[2]]):
|
||
var caption := _label(str(group[0]).to_upper(), "EyebrowLabel", list)
|
||
caption.add_theme_font_size_override("font_size", 14)
|
||
list.add_child(Control.new())
|
||
for pair: Array in group[1]:
|
||
var key_label := _label(str(pair[0]), "CardFactLabel", list)
|
||
key_label.add_theme_font_size_override("font_size", 15)
|
||
key_label.add_theme_color_override("font_color", LuneUiTheme.BRONZE_LIGHT)
|
||
var action := _label(str(pair[1]), "MutedLabel", list)
|
||
action.add_theme_font_size_override("font_size", 15)
|
||
var back := Button.new()
|
||
back.text = "ZURÜCK [Esc]"
|
||
back.theme_type_variation = "PrimaryButton"
|
||
back.pressed.connect(func() -> void: closed.emit())
|
||
column.add_child(back)
|
||
|
||
func _label(text_value: String, variation: String, parent: Node) -> Label:
|
||
var label := Label.new()
|
||
label.text = text_value
|
||
label.theme_type_variation = variation
|
||
parent.add_child(label)
|
||
return label
|
||
|
||
func sync() -> void:
|
||
_volume.set_value_no_signal(Preferences.volume * 100.0)
|
||
for key: String in _checks:
|
||
(_checks[key] as CheckButton).set_pressed_no_signal(bool(Preferences.get(key)))
|
||
var best: int = 1
|
||
for index: int in range(SCALES.size()):
|
||
if absf(SCALES[index] - Preferences.ui_scale) < absf(SCALES[best] - Preferences.ui_scale):
|
||
best = index
|
||
_scale.select(best)
|