124 lines
3.6 KiB
GDScript
124 lines
3.6 KiB
GDScript
extends Control
|
|
## Einstieg: hält den Spielstand und wechselt zwischen den Bildschirmen.
|
|
|
|
var profile: Profile
|
|
var screen: Control
|
|
var save_path: String = Profile.SAVE_PATH
|
|
var sfx: Sfx
|
|
var net: Net
|
|
|
|
|
|
func _ready() -> void:
|
|
_map_gamepad()
|
|
theme = Style.make_theme()
|
|
var bg := Style.Backdrop.new()
|
|
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(bg)
|
|
sfx = Sfx.new()
|
|
add_child(sfx)
|
|
# Fester Pfad /root/Net: Netzwerkaufrufe werden über den Knotenpfad zugestellt,
|
|
# der bei Host und Mitspielern gleich sein muss.
|
|
net = Net.new()
|
|
net.name = "Net"
|
|
get_tree().root.add_child.call_deferred(net)
|
|
profile = Profile.load_or_new(save_path)
|
|
apply_settings()
|
|
show_screen(MenuScreen.new())
|
|
|
|
|
|
func apply_settings() -> void:
|
|
sfx.set_volume(profile.settings.volume)
|
|
sfx.set_music_volume(profile.settings.music)
|
|
set_language(profile.settings.language)
|
|
Style.font_scale = 1.2 if profile.settings.get("big_font", false) else 1.0
|
|
theme = Style.make_theme()
|
|
|
|
|
|
## Neues Profil: Sammlung und Fortschritt werden verworfen.
|
|
func reset_profile() -> void:
|
|
profile = Profile.starter()
|
|
clear_battle_save()
|
|
save()
|
|
apply_settings()
|
|
|
|
|
|
func set_language(code: String) -> void:
|
|
TranslationServer.set_locale(code)
|
|
|
|
|
|
func show_screen(s: Control) -> void:
|
|
if screen != null:
|
|
screen.queue_free()
|
|
screen = s
|
|
s.app = self
|
|
s.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
add_child(s)
|
|
if pad_mode:
|
|
focus_first_button.call_deferred()
|
|
|
|
|
|
var pad_mode := false # zuletzt Gamepad benutzt: Fokusrahmen sichtbar, Steuerkreuz wechselt Knöpfe
|
|
|
|
|
|
## Gamepad in Menüs: erster Tastendruck setzt den Fokus, Maus nimmt ihn wieder weg.
|
|
func _input(event: InputEvent) -> void:
|
|
if event is InputEventJoypadButton or (event is InputEventJoypadMotion and absf(event.axis_value) > 0.5):
|
|
if not pad_mode:
|
|
pad_mode = true
|
|
if get_viewport().gui_get_focus_owner() == null:
|
|
focus_first_button()
|
|
elif event is InputEventMouseMotion and pad_mode:
|
|
pad_mode = false
|
|
get_viewport().gui_release_focus()
|
|
|
|
|
|
## Gamepad-Tasten für die Menünavigation: A bestätigt, B bricht ab (falls nicht schon zugeordnet).
|
|
func _map_gamepad() -> void:
|
|
for pair in [["ui_accept", JOY_BUTTON_A], ["ui_cancel", JOY_BUTTON_B]]:
|
|
var action: String = pair[0]
|
|
if not InputMap.has_action(action):
|
|
InputMap.add_action(action)
|
|
if not InputMap.action_get_events(action).any(func(e): return e is InputEventJoypadButton):
|
|
var ev := InputEventJoypadButton.new()
|
|
ev.button_index = pair[1]
|
|
InputMap.action_add_event(action, ev)
|
|
|
|
|
|
func focus_first_button() -> void:
|
|
if screen == null or screen is BattleScreen:
|
|
return
|
|
var b := _first_button(screen)
|
|
if b != null:
|
|
b.grab_focus()
|
|
|
|
|
|
func _first_button(node: Node) -> Button:
|
|
for c in node.get_children():
|
|
if c is Button and not c.disabled and c.is_visible_in_tree():
|
|
return c
|
|
var found := _first_button(c)
|
|
if found != null:
|
|
return found
|
|
return null
|
|
|
|
|
|
func save() -> void:
|
|
profile.save(save_path)
|
|
|
|
|
|
## Datei für einen unterbrochenen Kampf (neben dem Spielstand).
|
|
func battle_save_path() -> String:
|
|
return save_path.get_basename() + "_kampf.json"
|
|
|
|
|
|
func clear_battle_save() -> void:
|
|
if FileAccess.file_exists(battle_save_path()):
|
|
DirAccess.remove_absolute(ProjectSettings.globalize_path(battle_save_path()))
|
|
|
|
|
|
func _exit_tree() -> void:
|
|
if net != null and net.is_inside_tree():
|
|
net.leave()
|
|
net.queue_free()
|