Hauptszene scenes/luneraria.tscn, Saumwacht bleibt über --legacy und die alten QA-Schalter erreichbar. Karte aus Bestandsassets plus neuem Turm, HUD mit Planung, Lanes und Minimap, Menü umbenannt, Einstellungen werden aus dem alten Benutzerordner übernommen. Simulation 6,6x schneller (Raster, Caches, faire Staffelung) und exakt spiegelsymmetrisch. Regeln 91/91, echte Anwendung 38/38, Legacy unverändert grün. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.3 KiB
GDScript
59 lines
2.3 KiB
GDScript
extends Node
|
|
## Local preferences only. Match rules and ownership are never saved here.
|
|
|
|
signal changed
|
|
var volume: float = .65
|
|
var muted: bool = false
|
|
var follow_camera: bool = true
|
|
var fullscreen: bool = false
|
|
## Menu camera travel, idle drift, particles and fades are skipped when set.
|
|
var reduced_motion: bool = false
|
|
var storage_path: String = "user://preferences.cfg"
|
|
|
|
func _ready() -> void:
|
|
read_settings()
|
|
apply()
|
|
|
|
## The project was renamed from "Saumwacht · Glutpakt"; its user folder changed with it.
|
|
const LEGACY_FOLDER := "Saumwacht · Glutpakt"
|
|
var migrated_from: String = ""
|
|
|
|
func _legacy_path() -> String:
|
|
var own: String = ProjectSettings.globalize_path("user://")
|
|
var parent: String = own.trim_suffix("/").get_base_dir()
|
|
return parent.path_join(LEGACY_FOLDER).path_join("preferences.cfg")
|
|
|
|
func read_settings() -> void:
|
|
var config := ConfigFile.new()
|
|
if storage_path == "user://preferences.cfg" and not FileAccess.file_exists(storage_path) and FileAccess.file_exists(_legacy_path()):
|
|
# One-time copy of the old options; the old file stays untouched.
|
|
if config.load(_legacy_path()) == OK and config.save(storage_path) == OK:
|
|
migrated_from = _legacy_path()
|
|
print("PREFERENCES: übernommen aus ", migrated_from)
|
|
if config.load(storage_path) != OK:
|
|
return
|
|
volume = clampf(float(config.get_value("audio", "volume", .65)), 0.0, 1.0)
|
|
muted = bool(config.get_value("audio", "muted", false))
|
|
follow_camera = bool(config.get_value("camera", "follow", true))
|
|
fullscreen = bool(config.get_value("display", "fullscreen", false))
|
|
reduced_motion = bool(config.get_value("display", "reduced_motion", false))
|
|
|
|
func apply() -> void:
|
|
AudioServer.set_bus_volume_db(0, linear_to_db(maxf(.001, volume)))
|
|
AudioServer.set_bus_mute(0, muted or volume <= 0.0)
|
|
if DisplayServer.get_name() != "headless":
|
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN if fullscreen else DisplayServer.WINDOW_MODE_WINDOWED)
|
|
changed.emit()
|
|
|
|
func save_settings() -> Error:
|
|
var config := ConfigFile.new()
|
|
config.set_value("audio", "volume", volume)
|
|
config.set_value("audio", "muted", muted)
|
|
config.set_value("camera", "follow", follow_camera)
|
|
config.set_value("display", "fullscreen", fullscreen)
|
|
config.set_value("display", "reduced_motion", reduced_motion)
|
|
return config.save(storage_path)
|
|
|
|
func commit() -> void:
|
|
apply()
|
|
save_settings()
|