Files
whale-town-front-v2/_Core/managers/SettingsManager.gd

137 lines
4.2 KiB
GDScript

extends Node
# ============================================================================
# SettingsManager.gd - 游戏设置偏好管理器
# ============================================================================
# 统一应用账号级设置,并向运行中的 UI、聊天和角色系统广播变更。
# 设置持久化以后端账号 profile 为准,本管理器不再读写 user:// 配置文件。
# ============================================================================
const BASE_VIEWPORT_SIZE: Vector2i = Vector2i(1920, 1440)
const DEFAULT_SETTINGS: Dictionary = {
"master_volume": 0.80,
"music_volume": 0.60,
"effects_volume": 0.90,
"ui_scale": 1.00,
"fullscreen": false,
"show_interaction_hints": false,
"show_name_always": false,
"show_chat_bubbles": true,
"world_notifications": true,
"private_notifications": true,
"friend_request_notifications": true,
"allow_nearby_private": true,
"allow_nearby_friend_requests": true,
"mute_ui_sfx": false,
}
var _settings: Dictionary = DEFAULT_SETTINGS.duplicate(true)
func _ready() -> void:
_connect_auth_events()
reset_to_defaults(false)
apply_all_settings()
func load_settings() -> void:
_settings = DEFAULT_SETTINGS.duplicate(true)
apply_all_settings()
_emit_settings_changed()
func save_settings() -> bool:
_emit_settings_changed()
return true
func get_default_settings() -> Dictionary:
return DEFAULT_SETTINGS.duplicate(true)
func get_settings() -> Dictionary:
return _settings.duplicate(true)
func set_settings(settings: Dictionary, saveImmediately: bool = true) -> void:
for key in DEFAULT_SETTINGS.keys():
if settings.has(key):
_settings[key] = settings[key]
apply_all_settings()
if saveImmediately:
save_settings()
else:
_emit_settings_changed()
func apply_account_settings(settings: Dictionary) -> void:
set_settings(settings, false)
func reset_to_defaults(emitChanged: bool = true) -> void:
_settings = DEFAULT_SETTINGS.duplicate(true)
apply_all_settings()
if emitChanged:
_emit_settings_changed()
func set_setting(key: String, value: Variant, saveImmediately: bool = true) -> void:
if not DEFAULT_SETTINGS.has(key):
return
_settings[key] = value
apply_all_settings()
if saveImmediately:
save_settings()
else:
_emit_settings_changed()
func get_setting(key: String, fallback: Variant = null) -> Variant:
return _settings.get(key, fallback if fallback != null else DEFAULT_SETTINGS.get(key))
func get_bool(key: String) -> bool:
return bool(_settings.get(key, DEFAULT_SETTINGS.get(key, false)))
func get_float(key: String) -> float:
return float(_settings.get(key, DEFAULT_SETTINGS.get(key, 0.0)))
func apply_all_settings() -> void:
_apply_fullscreen_setting()
_apply_audio_settings()
_apply_ui_scale_setting()
func _apply_audio_settings() -> void:
_apply_bus_volume("Master", get_float("master_volume"))
_apply_bus_volume("Music", get_float("music_volume"))
_apply_bus_volume("SFX", get_float("effects_volume"))
func _apply_bus_volume(busName: String, value: float) -> void:
var busIndex := AudioServer.get_bus_index(busName)
if busIndex < 0:
return
var clamped := clampf(value, 0.0, 1.0)
AudioServer.set_bus_mute(busIndex, clamped <= 0.001)
if clamped > 0.001:
AudioServer.set_bus_volume_db(busIndex, linear_to_db(clamped))
func _apply_fullscreen_setting() -> void:
if DisplayServer.get_name() == "headless":
return
var fullscreen := get_bool("fullscreen")
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN if fullscreen else DisplayServer.WINDOW_MODE_WINDOWED)
func _apply_ui_scale_setting() -> void:
var viewport := get_tree().root
if viewport == null:
return
var scale := clampf(get_float("ui_scale"), 0.8, 1.2)
viewport.content_scale_size = Vector2i(
int(round(float(BASE_VIEWPORT_SIZE.x) / scale)),
int(round(float(BASE_VIEWPORT_SIZE.y) / scale))
)
func _emit_settings_changed() -> void:
var eventSystem := get_node_or_null("/root/EventSystem")
if eventSystem != null:
eventSystem.call("emit_event", EventNames.SETTINGS_CHANGED, get_settings())
func _connect_auth_events() -> void:
var eventSystem := get_node_or_null("/root/EventSystem")
if eventSystem == null:
return
eventSystem.call("connect_event", EventNames.AUTH_LOGOUT, _on_auth_logout, self)
func _on_auth_logout(_data: Variant = null) -> void:
reset_to_defaults()