forked from xiangwang25/whale-town-front-v2
137 lines
4.2 KiB
GDScript
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()
|