按 code-conventions §1.4.1 第三轮定稿执行:core 22+schemas 18+presentation 根 14+views 28,全部头注 #→##、删日期/变更叙事/GDD 与架构反向链接/字段与域清单/机制描述,保留职责摘要+真实使用约束(防事故禁令/单一入口/信号契约每信号一行)。main.gd 31→5 行、save_manager 45→5 行、adventure_runner 37→5 行为最大单件。子代理分模块执行(波一 core+schemas、波二 presentation+views,并发≤2)。验收=tools/verify_comment_only_change.py 逐字节校验(82 文件头注区外逐行一致=零行为变更)+audit_file_headers 全绿;纯注释批免冒烟(先例 5843270)
46 lines
1.7 KiB
GDScript
46 lines
1.7 KiB
GDScript
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||
## 系统级设置独立存储(一安装一份、不进存档与生涯数据):音量(master bus)/全屏/减动效三件最小面,入口与持久化在此。
|
||
## 探针/冒烟必须经 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)
|