Files
alpacaman edc40f9008 Initial commit — Godot space roguelite source
- Touch controls: direct InputEventScreenTouch in shop_ui (bypass relay)
- ItemDB: static preload list instead of DirAccess scan (export fix)
- All 18 items with EN localisation (name_en, desc_en, category_en)
- Ship playstyles: NOVA-1 shield, INFERNO ram, AURORA agile/tank
- Quasar: SMBH visual, jet boost, merge, push, BH-eating
- Atlas & UI text updated EN+DE

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:38:09 +02:00

98 lines
3.5 KiB
GDScript

extends Node
var master_volume: float = 1.0
var sfx_muted: bool = false
var music_volume: float = 0.8
var fullscreen: bool = false
var nebula_enabled: bool = true
var star_density: int = 1 # 0=low 1=mid 2=high
var language: String = "de" # "de" or "en"
var touch_mode: int = 0 # 0=auto, 1=always on, 2=always off
# Runtime-only — not saved. Set by input detection in main.gd / touch_controls.gd.
var last_input_device: String = "keyboard" # "keyboard" | "pad" | "touch"
# Rebindable gameplay actions (P1 only).
const REBIND_ACTIONS: Array[String] = ["p1_thrust", "p1_left", "p1_right", "p1_shoot", "p1_wipe"]
# Stores physical keycodes (int) for rebound keys. Empty = use project defaults.
var key_bindings: Dictionary = {}
const PATH := "user://settings.cfg"
func _ready() -> void:
load_settings()
apply_all()
func apply_all() -> void:
apply_volume()
apply_key_bindings()
# Mobile always runs fullscreen — ignore the saved setting.
if OS.has_feature("android") or OS.has_feature("ios"):
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
elif fullscreen:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
func apply_volume() -> void:
var db := linear_to_db(master_volume) if not sfx_muted else -80.0
AudioServer.set_bus_volume_db(0, db)
func apply_music_volume() -> void:
var bus_idx := AudioServer.get_bus_index("Music")
if bus_idx != -1:
AudioServer.set_bus_volume_db(bus_idx,
linear_to_db(music_volume) if music_volume > 0.0 else -80.0)
func apply_key_bindings() -> void:
for action: String in key_bindings:
var keycode: int = key_bindings[action]
if keycode > 0 and InputMap.has_action(action):
# Remove existing keyboard events for this action
var events := InputMap.action_get_events(action)
for ev in events:
if ev is InputEventKey:
InputMap.action_erase_event(action, ev)
# Add the custom key
var new_ev := InputEventKey.new()
new_ev.physical_keycode = keycode as Key
InputMap.action_add_event(action, new_ev)
func reset_key_bindings() -> void:
InputMap.load_from_project_settings()
key_bindings.clear()
save_settings()
func save_settings() -> void:
var cfg := ConfigFile.new()
cfg.set_value("sound", "volume", master_volume)
cfg.set_value("sound", "muted", sfx_muted)
cfg.set_value("sound", "music", music_volume)
cfg.set_value("graphics", "fullscreen", fullscreen)
cfg.set_value("graphics", "nebula", nebula_enabled)
cfg.set_value("graphics", "stars", star_density)
cfg.set_value("game", "language", language)
cfg.set_value("game", "touch_mode", touch_mode)
for action: String in REBIND_ACTIONS:
if key_bindings.has(action):
cfg.set_value("bindings", action, key_bindings[action])
cfg.save(PATH)
func load_settings() -> void:
var cfg := ConfigFile.new()
if cfg.load(PATH) != OK:
return
master_volume = cfg.get_value("sound", "volume", 1.0)
sfx_muted = cfg.get_value("sound", "muted", false)
music_volume = cfg.get_value("sound", "music", 0.8)
fullscreen = cfg.get_value("graphics", "fullscreen", false)
nebula_enabled = cfg.get_value("graphics", "nebula", true)
star_density = cfg.get_value("graphics", "stars", 1)
language = cfg.get_value("game", "language", "de")
touch_mode = cfg.get_value("game", "touch_mode", 0)
key_bindings.clear()
for action: String in REBIND_ACTIONS:
if cfg.has_section_key("bindings", action):
key_bindings[action] = cfg.get_value("bindings", action)