223 lines
7.2 KiB
GDScript
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
|