51 lines
2.2 KiB
GDScript
51 lines
2.2 KiB
GDScript
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||
# Date: 2026-09-29(迭代 8 卡④ 最小设置面——设置与本地化.md P1 两项兑现:音量入口+减动效开关)
|
||
# 系统级设置独立存储(设置与本地化.md——2026-09-19 用户拍板:一安装一份、删游戏才消失,
|
||
# 不进存档与生涯数据两分)。三件最小面:音量(master bus)/全屏/减动效。
|
||
# 生效侧分工:入口与持久化归本类;音量对声音的生效口径归 音频.md(master bus 单点);
|
||
# 减动效对动画的分档兑现归 battle.md §Transitions(UiKit.motion_scale 既有承载,结算逐行
|
||
# 兑现=信息载体只降速不跳过)。
|
||
# 探针隔离:path 可注入(冒烟/探针禁碰真实 user://settings.cfg——同存档隔离纪律)。
|
||
class_name SettingsStore
|
||
extends RefCounted
|
||
|
||
const DEFAULT_PATH := "user://settings.cfg"
|
||
|
||
var path: String = DEFAULT_PATH
|
||
var volume_linear := 1.0 # master bus 线性 0-1(0=静音)
|
||
var fullscreen := false
|
||
var reduced_motion := false
|
||
|
||
|
||
func _init(path_override: String = "") -> void:
|
||
if path_override != "":
|
||
path = path_override
|
||
|
||
|
||
func load_settings() -> void:
|
||
var cf := ConfigFile.new()
|
||
if cf.load(path) != OK:
|
||
return # 缺文件 = 出厂默认(合法态——非损坏不兜底)
|
||
volume_linear = clampf(float(cf.get_value("audio", "volume_linear", 1.0)), 0.0, 1.0)
|
||
fullscreen = bool(cf.get_value("display", "fullscreen", false))
|
||
reduced_motion = bool(cf.get_value("motion", "reduced", false))
|
||
|
||
|
||
func save_settings() -> bool:
|
||
var cf := ConfigFile.new()
|
||
cf.set_value("audio", "volume_linear", volume_linear)
|
||
cf.set_value("display", "fullscreen", fullscreen)
|
||
cf.set_value("motion", "reduced", reduced_motion)
|
||
return cf.save(path) == OK
|
||
|
||
|
||
# 应用到引擎态(启动恢复与实时调节同一口——headless 下窗口面跳过)
|
||
func apply() -> void:
|
||
var master := AudioServer.get_bus_index("Master")
|
||
AudioServer.set_bus_mute(master, volume_linear <= 0.001)
|
||
AudioServer.set_bus_volume_db(master, linear_to_db(maxf(volume_linear, 0.001)))
|
||
UiKit.motion_scale = 0.5 if reduced_motion else 1.0
|
||
if DisplayServer.get_name() != "headless":
|
||
DisplayServer.window_set_mode(
|
||
DisplayServer.WINDOW_MODE_FULLSCREEN if fullscreen else DisplayServer.WINDOW_MODE_WINDOWED)
|