Files
Papay-Shooter/globals/settings_manager.gd
T

223 lines
7.2 KiB
GDScript

extends Node
const SAVE_PATH = "user://settings.json"
var default_bindings = {
"jump": {"type": "key", "code": KEY_SPACE},
"crouch": {"type": "key", "code": KEY_CTRL},
"dash": {"type": "key", "code": KEY_SHIFT},
"fire": {"type": "mouse", "code": MOUSE_BUTTON_LEFT},
"fire_alt": {"type": "mouse", "code": MOUSE_BUTTON_RIGHT},
"grapple": {"type": "mouse", "code": MOUSE_BUTTON_MIDDLE},
"reload": {"type": "key", "code": KEY_R},
"interact": {"type": "key", "code": KEY_E},
"melee": {"type": "key", "code": KEY_F},
"move_forward": {"type": "key", "code": KEY_W},
"move_back": {"type": "key", "code": KEY_S},
"move_left": {"type": "key", "code": KEY_A},
"move_right": {"type": "key", "code": KEY_D},
"weapon_next": {"type": "mouse", "code": MOUSE_BUTTON_WHEEL_UP},
"weapon_prev": {"type": "mouse", "code": MOUSE_BUTTON_WHEEL_DOWN},
"weapon_1": {"type": "key", "code": KEY_1},
"weapon_2": {"type": "key", "code": KEY_2},
"weapon_3": {"type": "key", "code": KEY_3},
"weapon_4": {"type": "key", "code": KEY_4},
"toggle_flashlight": {"type": "key", "code": KEY_T},
}
var current_bindings = {}
var show_debug_ui: bool = false
var show_movement_speed: bool = false
var username: String = "Player"
var mouse_sensitivity: float = 0.002
var ads_sensitivity: float = 0.001
var world_fov: float = 90.0
# Video Settings
var display_mode: int = DisplayServer.WINDOW_MODE_WINDOWED
var resolution_index: int = 2 # Default to 1920x1080
var fps_cap: int = 0
var show_fps: bool = false
# Audio Settings
var vol_master: float = 100.0
var vol_sfx: float = 100.0
var vol_music: float = 100.0
var vol_wind: float = 100.0
var resolutions = [
Vector2i(640, 480), # 480p
Vector2i(1280, 720), # 720p
Vector2i(1920, 1080), # 1080p
Vector2i(2560, 1080), # UW-1080p
Vector2i(2560, 1440), # 1440p
Vector2i(3440, 1440), # UW-1440p
Vector2i(3840, 2160) # 4K
]
func _ready() -> void:
# Initialize defaults
current_bindings = default_bindings.duplicate(true)
# Load overrides
_load_settings()
# Apply to InputMap
_apply_all_bindings()
# Apply Video Settings
apply_video_settings()
# Setup & Apply Audio Settings
_setup_audio_buses()
apply_audio_settings()
func _setup_audio_buses() -> void:
if AudioServer.bus_count < 4:
# Assuming bus 0 is Master
if AudioServer.get_bus_name(0) != "Master":
AudioServer.set_bus_name(0, "Master")
# SFX
if AudioServer.bus_count <= 1:
AudioServer.add_bus(1)
AudioServer.set_bus_name(1, "SFX")
# Music
if AudioServer.bus_count <= 2:
AudioServer.add_bus(2)
AudioServer.set_bus_name(2, "Music")
# Wind
if AudioServer.bus_count <= 3:
AudioServer.add_bus(3)
AudioServer.set_bus_name(3, "Wind")
func _apply_all_bindings() -> void:
for action in current_bindings:
if not InputMap.has_action(action):
InputMap.add_action(action)
InputMap.action_erase_events(action)
var binding = current_bindings[action]
var ev: InputEvent
if binding["type"] == "key":
ev = InputEventKey.new()
ev.keycode = binding["code"]
elif binding["type"] == "mouse":
ev = InputEventMouseButton.new()
ev.button_index = binding["code"]
if ev:
InputMap.action_add_event(action, ev)
func rebind_action(action: String, event: InputEvent) -> void:
if not current_bindings.has(action):
return
if event is InputEventKey:
var code = event.physical_keycode if event.physical_keycode != 0 else event.keycode
current_bindings[action] = {"type": "key", "code": code}
elif event is InputEventMouseButton:
current_bindings[action] = {"type": "mouse", "code": event.button_index}
else:
return
_apply_all_bindings()
_save_settings()
func reset_to_defaults() -> void:
current_bindings = default_bindings.duplicate(true)
_apply_all_bindings()
_save_settings()
func _save_settings() -> void:
var save_data = {
"bindings": current_bindings,
"show_debug_ui": show_debug_ui,
"show_movement_speed": show_movement_speed,
"username": username,
"mouse_sensitivity": mouse_sensitivity,
"ads_sensitivity": ads_sensitivity,
"world_fov": world_fov,
"display_mode": display_mode,
"resolution_index": resolution_index,
"fps_cap": fps_cap,
"show_fps": show_fps,
"vol_master": vol_master,
"vol_sfx": vol_sfx,
"vol_music": vol_music,
"vol_wind": vol_wind
}
var json_string = JSON.stringify(save_data)
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
if file:
file.store_string(json_string)
file.close()
func _load_settings() -> void:
if FileAccess.file_exists(SAVE_PATH):
var file = FileAccess.open(SAVE_PATH, FileAccess.READ)
if file:
var json_string = file.get_as_text()
file.close()
var json = JSON.new()
var error = json.parse(json_string)
if error == OK:
var data = json.get_data()
if data is Dictionary:
if data.has("bindings"):
var loaded_bindings = data["bindings"]
for action in loaded_bindings:
if current_bindings.has(action):
current_bindings[action] = loaded_bindings[action]
if data.has("username"): username = data["username"]
if data.has("show_debug_ui"): show_debug_ui = data["show_debug_ui"]
if data.has("show_movement_speed"): show_movement_speed = data["show_movement_speed"]
if data.has("mouse_sensitivity"): mouse_sensitivity = data["mouse_sensitivity"]
if data.has("ads_sensitivity"): ads_sensitivity = data["ads_sensitivity"]
if data.has("world_fov"): world_fov = data["world_fov"]
if data.has("display_mode"): display_mode = data["display_mode"]
if data.has("resolution_index"): resolution_index = data["resolution_index"]
if data.has("fps_cap"): fps_cap = data["fps_cap"]
if data.has("show_fps"): show_fps = data["show_fps"]
if data.has("vol_master"): vol_master = data["vol_master"]
if data.has("vol_sfx"): vol_sfx = data["vol_sfx"]
if data.has("vol_music"): vol_music = data["vol_music"]
if data.has("vol_wind"): vol_wind = data["vol_wind"]
func apply_audio_settings() -> void:
_set_bus_volume("Master", vol_master)
_set_bus_volume("SFX", vol_sfx)
_set_bus_volume("Music", vol_music)
_set_bus_volume("Wind", vol_wind)
func _set_bus_volume(bus_name: String, vol_100: float) -> void:
var bus_idx = AudioServer.get_bus_index(bus_name)
if bus_idx >= 0:
var linear = clampf(vol_100 / 100.0, 0.0001, 1.0)
if vol_100 <= 0.1:
AudioServer.set_bus_mute(bus_idx, true)
else:
AudioServer.set_bus_mute(bus_idx, false)
AudioServer.set_bus_volume_db(bus_idx, linear_to_db(linear))
func apply_video_settings() -> void:
if display_mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN)
elif display_mode == DisplayServer.WINDOW_MODE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
if resolution_index >= 0 and resolution_index < resolutions.size():
DisplayServer.window_set_size(resolutions[resolution_index])
# Center window on primary screen
var screen = DisplayServer.window_get_current_screen()
var screen_size = DisplayServer.screen_get_size(screen)
var window_size = DisplayServer.window_get_size()
# Simple centering heuristic
DisplayServer.window_set_position(Vector2i((screen_size - window_size) / 2.0))
Engine.max_fps = fps_cap