Merge pull request #21 from dfgworm/main

DataManager refactor
This commit is contained in:
Antimundo 2024-04-18 18:08:26 +02:00 committed by GitHub
commit 0fdba00533
Signed by: github
GPG key ID: B5690EEEBB952194
22 changed files with 366 additions and 244 deletions

1
.gitignore vendored
View file

@ -4,7 +4,6 @@
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation

4
_exports/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
*
!.gitignore
!*.md

7
_exports/readme.md Normal file
View file

@ -0,0 +1,7 @@
# _builds
This folder is used to builds export.
The `export_path` of `/export_presets.cfg` will export any build here
Never commit any change to the `/export_presets.cfg`

31
default_data/settings.cfg Normal file
View file

@ -0,0 +1,31 @@
[user]
fps_overlay=false
sensitivity=1.0
sensitivity_game=0
sensitivity_game_value=0.022
[crosshair]
color=Color(0, 255, 0, 1)
outline_color=Color(0, 0, 0, 1)
enable_outline=false
dot_enable=false
dot_size=2.0
outline_width=1.0
thickness=1.0
length=10.0
gap=5.0
[world]
world_texture="checkerboard.png"
world_color=Color(0.361, 0.616, 1, 1)
target_color=Color(1, 0.749, 0, 1)
[video]
fov=80
window_mode="fullscreen"
resolution=1.0
fps_limit=120
[audio]
volume=1.0
hit_sound="beep"

62
export_presets.cfg Normal file
View file

@ -0,0 +1,62 @@
[preset.0]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*.cfg"
exclude_filter=""
export_path="_exports/LibreAim.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/bptc=true
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon="res://icon.svg"
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"

View file

@ -1,86 +1,113 @@
extends Node
const FILE_NAME: String = "settings.json"
const FILE_PATH: String = "user://" + FILE_NAME
## JSON file is divided in categories in order to keep things organized.
const CATEGORIES_ROUTES: Dictionary = {
categories.SETTINGS: "settings",
categories.CROSSHAIR: "crosshair",
categories.HIGH_SCORE: "high_score"
}
const USER_PATH: String = "user://data/"
const FORMAT: String = "cfg"
const DEFAULT_PATH :String = "res://default_data/"
enum categories { SETTINGS, CROSSHAIR, HIGH_SCORE }
const SETTINGS_FILE_PATH := "settings"
const HIGHSCORE_FILE_PATH := "highscores"
const HIGHSCORE_SECTION := "user"
const LOAD_ON_READY_PATHS := [SETTINGS_FILE_PATH, HIGHSCORE_FILE_PATH]
var game_data: Dictionary = {}
var default_data :Dictionary = {}
var file_data: Dictionary = {}
var pending_file_changes :Dictionary = {}
## save changes to disk at the end of current update frame
var auto_apply_changes := true
func _ready() -> void:
load_all_data()
for file_path in LOAD_ON_READY_PATHS:
_get_config(file_path)
func save_data(key, value, category: categories, file_directory = FILE_PATH) -> void:
var category_key = CATEGORIES_ROUTES[category]
if !game_data.has(category_key):
game_data[category_key] = {}
game_data[category_key][key] = value
var json = JSON.stringify(game_data, "\t")
var file = FileAccess.open(file_directory, FileAccess.WRITE)
file.store_line(json)
file.close()
func get_wrapper(file_path: String, section: String) -> SectionWrapper:
var wrapper := SectionWrapper.new()
wrapper.file_path = file_path
wrapper.section = section
return wrapper
func get_data(file_path: String, section: String, key :String, default :Variant = null) -> Variant:
var config := _get_config(file_path)
return config.get_value(section, key, default)
func set_data(file_path: String, section: String, key: String, value: Variant):
var config := _get_config(file_path)
config.set_value(section, key, value)
pending_file_changes[file_path] = true
if auto_apply_changes and not get_tree().process_frame.is_connected(_save_pending):
get_tree().process_frame.connect(_save_pending, CONNECT_ONE_SHOT)
func save_high_score(key: String, value) -> void:
if is_high_score(key, value):
DataManager.save_data(key, value, DataManager.categories.HIGH_SCORE)
set_data(HIGHSCORE_FILE_PATH, HIGHSCORE_SECTION, key, value)
func is_high_score(key: String, value) -> bool:
var category_key = CATEGORIES_ROUTES[DataManager.categories.HIGH_SCORE]
if game_data.has(category_key) \
and game_data[category_key].has(key):
return value > game_data[category_key][key]
else:
return true
return value > get_high_score(key)
func get_high_score(key: String) -> int:
var category_key = CATEGORIES_ROUTES[DataManager.categories.HIGH_SCORE]
if game_data.has(category_key) \
and game_data[category_key].has(key):
return game_data[category_key][key]
return 0
return get_data(HIGHSCORE_FILE_PATH, HIGHSCORE_SECTION, key, 0)
func save_all_data(file_directory: String = FILE_PATH) -> void:
var json = JSON.stringify(game_data, "\t")
var file = FileAccess.open(file_directory, FileAccess.WRITE)
file.store_line(json)
file.close()
func _get_config(file_path: String) -> ConfigFile:
if not file_data.has(file_path):
file_data[file_path] = _load_file(file_path)
return file_data[file_path]
func get_data(category: categories, key: String):
var result = null
if game_data != null \
and game_data.has(CATEGORIES_ROUTES[category]) \
and game_data.get(CATEGORIES_ROUTES[category]).has(key):
result = game_data.get(CATEGORIES_ROUTES[category]).get(key)
return result
# there's no reason to use this, but it's good to have it for completeness
func save_all_data() -> void:
for file_path in file_data:
_save_file(file_path)
pending_file_changes.clear()
func load_all_data(file_directory: String = FILE_PATH) -> void:
var json = JSON.new()
var result = {}
var file = FileAccess.open(file_directory, FileAccess.READ)
if file:
json.parse(file.get_as_text())
file.close()
else:
print("File not found.")
func _save_pending():
for file_path in pending_file_changes:
_save_file(file_path)
pending_file_changes.clear()
if json.data != null:
result = json.data
game_data = result
func _cancel_pending():
for file_path in pending_file_changes:
_load_file(file_path)
pending_file_changes.clear()
func set_parameter_if_exists(category: categories, parameter, key: String):
var new_value = DataManager.get_data(category, key)
if new_value != null:
return new_value
return parameter
func _save_file(file_path:String):
if not file_data.has(file_path):
push_error("Data file does not exist: %s"%file_path)
return
var config := _get_config(file_path)
var full_path := USER_PATH + file_path + "."+FORMAT
DirAccess.make_dir_recursive_absolute(full_path.get_base_dir())
var res := config.save(full_path)
assert(res == OK, "Error saving data: %s path: %s"%[res, full_path])
func set_color_if_exists(category: categories, parameter: Color, key: String) -> Color:
var new_color = set_parameter_if_exists(category, parameter, key)
if new_color != null and new_color is String:
new_color = Global.string_to_color(new_color)
return new_color
func _load_file(file_path: String) -> ConfigFile:
var config := ConfigFile.new()
config.load(USER_PATH + file_path + "."+FORMAT)
var default_config := _load_default_file(file_path)
if default_config != null:
_merge_config(config, default_config)
return config
func _load_default_file(file_path :String) -> ConfigFile:
var default_path := DEFAULT_PATH + file_path + ".cfg"
var config_file = ConfigFile.new()
config_file.load(default_path)
return config_file
func _merge_config(config: ConfigFile, to_merge: ConfigFile):
for section in to_merge.get_sections():
for key in to_merge.get_section_keys(section):
if config.has_section_key(section, key):
continue
var val = to_merge.get_value(section, key)
config.set_value(section, key, val)
class SectionWrapper:
var file_path:String
var section:String
func set_data(key: String, value: Variant):
DataManager.set_data(file_path, section, key, value)
func get_data(key: String, default: Variant = null) -> Variant:
return DataManager.get_data(file_path, section, key, default)
func get_keys() -> PackedStringArray:
return DataManager.get_config(file_path).get_section_keys(section)

View file

@ -2,15 +2,14 @@ extends Node
signal window_mode_updated(window_mode: DisplayServer.WindowMode)
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "video")
func _ready() -> void:
var category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "window_mode"):
var selected = DataManager.get_data(category, "window_mode")
set_window_mode(get_window_mode_from_string(selected))
var fps_limit = 120
if DataManager.get_data(category, "fps_limit"):
fps_limit = int(DataManager.get_data(category, "fps_limit"))
set_max_fps(fps_limit)
var selected = data_wrapper.get_data("window_mode")
set_window_mode(get_window_mode_from_string(selected))
set_max_fps( data_wrapper.get_data("fps_limit") )
func _input(event) -> void:
if event.is_action_pressed("fullscreen"):
@ -42,9 +41,9 @@ func set_window_mode(window_mode: DisplayServer.WindowMode) -> void:
window_mode_updated.emit(window_mode)
DisplayServer.window_set_mode(window_mode)
if window_mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
DataManager.save_data("window_mode", "fullscreen", DataManager.categories.SETTINGS)
data_wrapper.set_data("window_mode", "fullscreen")
elif window_mode == DisplayServer.WINDOW_MODE_MAXIMIZED:
DataManager.save_data("window_mode", "windowed", DataManager.categories.SETTINGS)
data_wrapper.set_data("window_mode", "windowed")
func set_max_fps(value) -> void:
Engine.set_max_fps(value)

View file

@ -55,27 +55,12 @@ func get_world_textures() -> Array:
return textures
func get_current_world_texture() -> Texture2D:
const CATEGORY = DataManager.categories.SETTINGS
var current_texture = DataManager.get_data(CATEGORY, "world_texture")
if !current_texture:
current_texture = "checkerboard.png"
var current_texture = DataManager.get_data(DataManager.SETTINGS_FILE_PATH, "world", "world_texture")
return load(get_world_textures_path() + current_texture)
func get_world_textures_path() -> String:
return "res://assets/images/world/"
func string_to_vector3d(string_vector: String) -> Vector3:
var components_str = string_vector.substr(1, string_vector.length() - 2)
var components = components_str.split(",")
# Convert each component from string to float
var x = components[0].to_float()
var y = components[1].to_float()
var z = components[2].to_float()
# Create the Vector3D object
return Vector3(x, y, z)
func string_to_color(string_vector: String) -> Color:
var components_str = string_vector.substr(1, string_vector.length() - 2)
var components = components_str.split(",")

View file

@ -1,7 +1,7 @@
extends Label
func _process(_delta: float) -> void:
if DataManager.get_data(DataManager.categories.SETTINGS, "fps_overlay"):
if DataManager.get_data(DataManager.SETTINGS_FILE_PATH, "user", "fps_overlay"):
set_text("FPS " + str(Engine.get_frames_per_second()))
else:
set_text("")

View file

@ -45,9 +45,8 @@ func _set_health_slider() -> void:
$HealthSlider.enable()
func _set_target_material() -> void:
var category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "target_color") != null:
var material_override = _mesh_instance.get_mesh().get_material()
material_override.set_albedo(Global.string_to_color(DataManager.get_data(category, "target_color")))
material_override.set_emission(Global.string_to_color(DataManager.get_data(category, "target_color")))
_mesh_instance.material_override = material_override
var material_override = _mesh_instance.get_mesh().get_material()
var col = DataManager.get_data(DataManager.SETTINGS_FILE_PATH, "world", "target_color")
material_override.set_albedo(col)
material_override.set_emission(col)
_mesh_instance.material_override = material_override

View file

@ -1,17 +1,17 @@
extends Control
## Renders the user crosshair
var _color := Color(0, 255, 255, 1)
var _outline_color := Color(0,0,0)
var _color :Color
var _outline_color :Color
var _enable_outline := true
var _dot_enable := false
var _enable_outline :bool
var _dot_enable :bool
var _dot_size: float = 6.0
var _outline_width: float = 1.0
var _thickness: float = 2.0
var _length: float = 12.0
var _gap: float = 5.0
var _dot_size: float
var _outline_width: float
var _thickness: float
var _length: float
var _gap: float
var current_crosshair: Dictionary = {
"top": [],
@ -36,16 +36,16 @@ func _on_options_refresh_crosshair() -> void:
queue_redraw()
func _load_save() -> void:
var category = DataManager.categories.CROSSHAIR
_dot_enable = DataManager.set_parameter_if_exists(category, _dot_enable, "dot")
_dot_size = DataManager.set_parameter_if_exists(category, _dot_size, "dot_size")
_length = DataManager.set_parameter_if_exists(category, _length, "length")
_thickness = DataManager.set_parameter_if_exists(category, _thickness, "thickness")
_gap = DataManager.set_parameter_if_exists(category, _gap, "gap")
_enable_outline = DataManager.set_parameter_if_exists(category, _enable_outline, "outline_enable")
_outline_width = DataManager.set_parameter_if_exists(category, _outline_width, "outline_width")
_color = DataManager.set_color_if_exists(category, _color, "color")
_outline_color = DataManager.set_color_if_exists(category, _outline_color, "outline_color")
var wrapper := DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "crosshair")
_dot_enable = wrapper.get_data("dot_enable")
_dot_size = wrapper.get_data("dot_size")
_length = wrapper.get_data("length")
_thickness = wrapper.get_data("thickness")
_gap = wrapper.get_data("gap")
_enable_outline = wrapper.get_data("enable_outline")
_outline_width = wrapper.get_data("outline_width")
_color = wrapper.get_data("color")
_outline_color = wrapper.get_data("outline_color")
func _load_crosshair() -> void:
current_crosshair["dot"] = [

View file

@ -7,13 +7,15 @@ func _ready() -> void:
func _on_volume_updated(_value: float) -> void:
update_hit_sound()
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "audio")
func update_hit_sound() -> void:
var volume = DataManager.get_data(DataManager.categories.SETTINGS, "volume")
var volume = data_wrapper.get_data("volume")
if volume != null:
var this_bus := AudioServer.get_bus_index("Master")
AudioServer.set_bus_volume_db(this_bus, lerpf(-20, 0, volume))
AudioServer.set_bus_mute(this_bus, volume == 0)
var category := DataManager.categories.SETTINGS
if DataManager.get_data(category, "hit_sound") != null:
var selected = DataManager.get_data(category, "hit_sound")
stream = load(Audio.hit_sounds[selected])
var selected = data_wrapper.get_data("hit_sound")
stream = load(Audio.hit_sounds[selected])

View file

@ -89,6 +89,5 @@ func _spawn_initial_targets():
func _update_world_appareance() -> void:
var world_material: StandardMaterial3D = preload("res://assets/material_default.tres")
world_material.albedo_texture = Global.get_current_world_texture()
const CATEGORY = DataManager.categories.SETTINGS
$DirectionalLight3D.light_color = DataManager.set_color_if_exists(CATEGORY, \
$DirectionalLight3D.light_color, "world_color")
var wrapper = DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "world")
$DirectionalLight3D.light_color = wrapper.get_data("world_color")

View file

@ -20,8 +20,7 @@ var current_shoot_cooldown: float
@onready var bullet_hole = preload("res://scenes/game_world/bullet_hole.tscn")
func _ready() -> void:
const CATEGORY := DataManager.categories.SETTINGS
camera.fov = DataManager.set_parameter_if_exists(CATEGORY, camera.fov, "camera_fov")
camera.fov = DataManager.get_data("settings", "video", "fov")
mouse_sensitivity = _get_mouse_sensitivity()
func _input(event: InputEvent) -> void:
@ -61,11 +60,8 @@ func _physics_process(delta: float) -> void:
move_and_slide()
func _get_mouse_sensitivity() -> float:
const CATEGORY := DataManager.categories.SETTINGS
var user_sensitivity: float = 1
var conversion_sensitivity: float = 0.022
conversion_sensitivity = DataManager.set_parameter_if_exists(CATEGORY, conversion_sensitivity, "sensitivity_game_value")
user_sensitivity = DataManager.set_parameter_if_exists(CATEGORY, user_sensitivity, "sensitivity")
var user_sensitivity: float = DataManager.get_data("settings", "user", "sensitivity")
var conversion_sensitivity: float = DataManager.get_data("settings", "user", "sensitivity_game_value")
return user_sensitivity * conversion_sensitivity
func _handle_joypad_rotation(delta: float) -> void:

View file

@ -8,33 +8,32 @@ const hit_sounds: Dictionary = {
"kalimba": "res://scenes/enemies/kalimba.ogg",
}
var category := DataManager.categories.SETTINGS
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "audio")
func _ready() -> void:
category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "volume") != null:
_set_volume_label()
_set_volume_label()
var option_button := $OptionButton
for sound in hit_sounds:
option_button.add_item(sound)
if DataManager.get_data(category, "hit_sound") != null:
var selected = DataManager.get_data(category, "hit_sound")
for i in range(option_button.item_count):
if selected == option_button.get_item_text(i):
option_button.select(i)
var selected = data_wrapper.get_data("hit_sound")
for i in range(option_button.item_count):
if selected == option_button.get_item_text(i):
option_button.select(i)
func _on_volume_slider_value_changed(value) -> void:
DataManager.save_data("volume", value, category)
data_wrapper.set_data("volume", value)
_set_volume_label()
func _set_volume_label() -> void:
var volume_label := $VolumeLabel
volume_label.text = "Volume " + str(DataManager.get_data(category, "volume"))
volume_label.text = "Volume " + str(data_wrapper.get_data("volume"))
var volume_slider := $VolumeSlider
volume_slider.value = DataManager.get_data(category, "volume")
volume_slider.value = data_wrapper.get_data("volume")
func _on_option_button_item_selected(index: int) -> void:
DataManager.save_data("hit_sound", hit_sounds.keys()[index], category)
data_wrapper.set_data("hit_sound", hit_sounds.keys()[index])
$Preview/AudioStreamPlayer.update_hit_sound()
func _on_preview_pressed() -> void:

View file

@ -11,25 +11,22 @@ const games_sensitivities: Dictionary = {
@onready var game = $Game
@onready var sensitivity = $Sensitivity
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "user")
func _ready() -> void:
for sens in games_sensitivities:
game.add_item(sens)
var category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "sensitivity"):
sensitivity.value = DataManager.get_data(category, "sensitivity")
if DataManager.get_data(category, "sensitivity_game"):
game.selected = DataManager.get_data(category, "sensitivity_game")
sensitivity.value = data_wrapper.get_data("sensitivity")
game.selected = data_wrapper.get_data("sensitivity_game")
func _on_sensitivity_change_value(value) -> void:
DataManager.save_data("sensitivity_game", game.get_selected_id(), \
DataManager.categories.SETTINGS)
DataManager.save_data("sensitivity_game_value", games_sensitivities.get(game.get_item_text(game.get_selected_id())), \
DataManager.categories.SETTINGS)
DataManager.save_data("sensitivity", float(value), \
DataManager.categories.SETTINGS)
data_wrapper.set_data("sensitivity_game", game.get_selected_id(), )
data_wrapper.set_data("sensitivity_game_value", games_sensitivities.get(game.get_item_text(game.get_selected_id())) )
data_wrapper.set_data("sensitivity", float(value))
func _on_game_item_selected(index: int) -> void:
DataManager.save_data("sensitivity_game", index, \
DataManager.categories.SETTINGS)
DataManager.save_data("sensitivity_game_value", games_sensitivities.get(game.get_item_text(index)), \
DataManager.categories.SETTINGS)
data_wrapper.set_data("sensitivity_game", index)
data_wrapper.set_data("sensitivity_game_value", games_sensitivities.get(game.get_item_text(index)) )

View file

@ -3,6 +3,7 @@ extends Control
signal refresh_crosshair
@onready var crosshair := $CrosshairSettings/Preview/Crosshair
@onready var file_export := $ExportFileDialog
@onready var file_import := $ImportFileDialog
@ -21,19 +22,29 @@ func _on_import_pressed() -> void:
file_import.visible = true
func _on_export_file_dialog_file_selected(path: String) -> void:
DataManager.save_all_data(path)
var cfg := ConfigFile.new()
var wrapper := DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "crosshair")
for key in wrapper.get_keys():
cfg.set_value(wrapper.section, key, wrapper.get_data(key))
cfg.save(path)
func _on_import_file_dialog_file_selected(path: String) -> void:
DataManager.load_all_data(path)
DataManager.save_all_data()
emit_signal("refresh_crosshair")
var cfg := ConfigFile.new()
var err := cfg.load(path)
if err != OK:
push_warning("Could not import crosshair %s"%path)
return
var wrapper := DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "crosshair")
for key in cfg.get_section_keys(wrapper.section):
wrapper.set_data(key, cfg.get_value(wrapper.section, key))
load_saved()
queue_refresh_crosshair()
func _on_dot_change_value(value: float) -> void:
change_value("dot_size", float(value))
func _on_dot_toggle_checkbox(value: bool) -> void:
change_value("dot", value)
change_value("dot_enable", value)
func _on_length_change_value(value: float) -> void:
change_value("length", float(value))
@ -42,7 +53,7 @@ func _on_thickness_change_value(value: float) -> void:
change_value("thickness", float(value))
func _on_outline_toggle_checkbox(value: bool) -> void:
change_value("outline_enable", value)
change_value("enable_outline", value)
func _on_outline_change_value(value: float) -> void:
change_value("outline_width", float(value))
@ -51,31 +62,26 @@ func _on_gap_change_value(value: float) -> void:
change_value("gap", float(value))
func _on_crosshair_color_color_changed(color: Color) -> void:
change_value("color", str(color))
change_value("color", color)
func _on_outline_color_color_changed(color: Color) -> void:
change_value("outline_color", str(color))
change_value("outline_color", color)
func change_value(key: String, value) -> void:
DataManager.save_data(key, value, DataManager.categories.CROSSHAIR)
emit_signal("refresh_crosshair")
DataManager.set_data(DataManager.SETTINGS_FILE_PATH, "crosshair", key, value)
queue_refresh_crosshair()
func queue_refresh_crosshair():
# delay changes so we do not spam this event in load_saved()
if not get_tree().process_frame.is_connected(emit_signal.bind("refresh_crosshair")):
get_tree().process_frame.connect(emit_signal.bind("refresh_crosshair"), CONNECT_ONE_SHOT)
func load_saved() -> void:
const CATEGORY := DataManager.categories.CROSSHAIR
var container := $CrosshairSettings
var dot := container.get_node("Dot")
dot.checkbox_value = DataManager.set_parameter_if_exists(CATEGORY, dot.checkbox_value, "dot")
dot.value = DataManager.set_parameter_if_exists(CATEGORY, dot.value, "dot_size")
var length := container.get_node("Length")
length.value = DataManager.set_parameter_if_exists(CATEGORY, length.value, "length")
var thickness := container.get_node("Thickness")
thickness.value = DataManager.set_parameter_if_exists(CATEGORY, thickness.value, "thickness")
var gap := container.get_node("Gap")
gap.value = DataManager.set_parameter_if_exists(CATEGORY, gap.value, "gap")
var outline := container.get_node("Outline")
outline.checkbox_value = DataManager.set_parameter_if_exists(CATEGORY, outline.checkbox_value, "outline_enable")
outline.value = DataManager.set_parameter_if_exists(CATEGORY, outline.value, "outline_width")
var crosshair_color := container.get_node("Color/CrosshairColor")
crosshair_color.color = DataManager.set_color_if_exists(CATEGORY, crosshair_color.color, "color")
var outline_color := container.get_node("OutlineColor/OutlineColor")
outline_color.color = DataManager.set_color_if_exists(CATEGORY, outline_color.color, "outline_color")
crosshair._load_save()
const plainValueChanges := ["dot_size", "length", "thickness", "gap", "outline_width"]
for param in plainValueChanges:
get_node("%"+param).value = crosshair.get("_"+param)
%dot_size.checkbox_value = crosshair._dot_enable
%outline_width.checkbox_value = crosshair._enable_outline
%crosshair_color.color = crosshair._color
%outline_color.color = crosshair._outline_color

View file

@ -101,34 +101,39 @@ size_flags_horizontal = 4
size_flags_vertical = 4
script = ExtResource("3_uw2kl")
[node name="Dot" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
[node name="dot_size" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
unique_name_in_owner = true
layout_mode = 2
label_text = "Dot"
max_value = 10.0
value = 10.0
[node name="Length" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
[node name="length" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
unique_name_in_owner = true
layout_mode = 2
label_text = "Length"
max_value = 50.0
value = 20.0
has_checkbox = false
[node name="Thickness" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
[node name="thickness" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
unique_name_in_owner = true
layout_mode = 2
label_text = "Thickness"
max_value = 10.0
value = 10.0
has_checkbox = false
[node name="Gap" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
[node name="gap" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
unique_name_in_owner = true
layout_mode = 2
label_text = "Gap"
max_value = 25.0
value = 25.0
has_checkbox = false
[node name="Outline" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
[node name="outline_width" parent="CrosshairSettings" instance=ExtResource("4_2iwqj")]
unique_name_in_owner = true
layout_mode = 2
label_text = "Outline"
max_value = 10.0
@ -142,7 +147,8 @@ layout_mode = 2
size_flags_horizontal = 3
text = "Color"
[node name="CrosshairColor" type="ColorPickerButton" parent="CrosshairSettings/Color" groups=["Persist", "PutLabel"]]
[node name="crosshair_color" type="ColorPickerButton" parent="CrosshairSettings/Color" groups=["Persist", "PutLabel"]]
unique_name_in_owner = true
custom_minimum_size = Vector2(220, 0)
layout_mode = 2
color = Color(0, 1, 1, 1)
@ -155,7 +161,8 @@ layout_mode = 2
size_flags_horizontal = 3
text = "Outline color"
[node name="OutlineColor" type="ColorPickerButton" parent="CrosshairSettings/OutlineColor" groups=["Persist", "PutLabel"]]
[node name="outline_color" type="ColorPickerButton" parent="CrosshairSettings/OutlineColor" groups=["Persist", "PutLabel"]]
unique_name_in_owner = true
custom_minimum_size = Vector2(220, 0)
layout_mode = 2
@ -189,15 +196,15 @@ access = 2
use_native_dialog = true
[connection signal="refresh_crosshair" from="." to="CrosshairSettings/Preview/Crosshair" method="_on_options_refresh_crosshair"]
[connection signal="change_value" from="CrosshairSettings/Dot" to="." method="_on_dot_change_value"]
[connection signal="toggle_checkbox" from="CrosshairSettings/Dot" to="." method="_on_dot_toggle_checkbox"]
[connection signal="change_value" from="CrosshairSettings/Length" to="." method="_on_length_change_value"]
[connection signal="change_value" from="CrosshairSettings/Thickness" to="." method="_on_thickness_change_value"]
[connection signal="change_value" from="CrosshairSettings/Gap" to="." method="_on_gap_change_value"]
[connection signal="change_value" from="CrosshairSettings/Outline" to="." method="_on_outline_change_value"]
[connection signal="toggle_checkbox" from="CrosshairSettings/Outline" to="." method="_on_outline_toggle_checkbox"]
[connection signal="color_changed" from="CrosshairSettings/Color/CrosshairColor" to="." method="_on_crosshair_color_color_changed"]
[connection signal="color_changed" from="CrosshairSettings/OutlineColor/OutlineColor" to="." method="_on_outline_color_color_changed"]
[connection signal="change_value" from="CrosshairSettings/dot_size" to="." method="_on_dot_change_value"]
[connection signal="toggle_checkbox" from="CrosshairSettings/dot_size" to="." method="_on_dot_toggle_checkbox"]
[connection signal="change_value" from="CrosshairSettings/length" to="." method="_on_length_change_value"]
[connection signal="change_value" from="CrosshairSettings/thickness" to="." method="_on_thickness_change_value"]
[connection signal="change_value" from="CrosshairSettings/gap" to="." method="_on_gap_change_value"]
[connection signal="change_value" from="CrosshairSettings/outline_width" to="." method="_on_outline_change_value"]
[connection signal="toggle_checkbox" from="CrosshairSettings/outline_width" to="." method="_on_outline_toggle_checkbox"]
[connection signal="color_changed" from="CrosshairSettings/Color/crosshair_color" to="." method="_on_crosshair_color_color_changed"]
[connection signal="color_changed" from="CrosshairSettings/OutlineColor/outline_color" to="." method="_on_outline_color_color_changed"]
[connection signal="pressed" from="Export" to="." method="_on_export_pressed"]
[connection signal="file_selected" from="ExportFileDialog" to="." method="_on_export_file_dialog_file_selected"]
[connection signal="pressed" from="Import" to="." method="_on_import_pressed"]

View file

@ -4,16 +4,17 @@ extends VBoxContainer
@onready var fps_limit_slider = $FPSLimitSlider
@onready var fps_limit_label = $FPSLimitLabel
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "video")
func _on_fps_limit_slider_value_changed(value):
DataManager.save_data("fps_limit", value, DataManager.categories.SETTINGS)
data_wrapper.set_data("fps_limit", value)
DisplayManager.set_max_fps(value)
update_label()
func _ready():
var category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "fps_limit"):
fps_limit_slider.value = DataManager.get_data(category, "fps_limit")
fps_limit_slider.value = data_wrapper.get_data("fps_limit")
update_label()

View file

@ -3,11 +3,12 @@ extends HBoxContainer
@onready var fps_overlay_checkbox = $FPSOverlayCheckBox
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "user")
func _on_fps_overlay_check_box_toggled(value: bool) -> void:
DataManager.save_data("fps_overlay", value, DataManager.categories.SETTINGS)
data_wrapper.set_data("fps_overlay", value)
func _ready() -> void:
var category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "fps_overlay"):
fps_overlay_checkbox.button_pressed = DataManager.get_data(category, "fps_overlay")
fps_overlay_checkbox.set_pressed_no_signal(data_wrapper.get_data("fps_overlay"))

View file

@ -6,36 +6,36 @@ extends Control
@onready var fov_slider = $FovSlider
@onready var window_mode_options = $WindowModeOptions
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "video")
func _ready() -> void:
DisplayManager.window_mode_updated.connect(_on_display_manager_window_mode_updated)
_update_fov_label()
_update_resolution_label()
get_viewport().size_changed.connect(self._update_resolution_label)
var category = DataManager.categories.SETTINGS
if DataManager.get_data(category, "resolution"):
resolution_slider.value = DataManager.get_data(category, "resolution")
if DataManager.get_data(category, "camera_fov"):
fov_slider.value = DataManager.get_data(category, "camera_fov")
if DataManager.get_data(category, "window_mode"):
var selected = DataManager.get_data(category, "window_mode")
for i in range(window_mode_options.item_count):
if selected == window_mode_options.get_item_text(i):
window_mode_options.select(i)
resolution_slider.value = data_wrapper.get_data("resolution")
fov_slider.value = data_wrapper.get_data("fov")
var selected = data_wrapper.get_data("window_mode")
for i in range(window_mode_options.item_count):
if selected == window_mode_options.get_item_text(i):
window_mode_options.select(i)
func _on_resolution_slider_value_changed(value: float) -> void:
get_viewport().scaling_3d_scale = value
_update_resolution_label()
DataManager.save_data("resolution", value, DataManager.categories.SETTINGS)
data_wrapper.set_data("resolution", value)
func _on_fov_slider_value_changed(value: float) -> void:
_update_fov_label()
DataManager.save_data("camera_fov", value, DataManager.categories.SETTINGS)
data_wrapper.set_data("fov", value)
func _on_window_mode_options_item_selected(index: int) -> void:
var option = window_mode_options.get_item_text(index)
DisplayManager.set_window_mode_from_string(option)
DataManager.save_data("window_mode", option, DataManager.categories.SETTINGS)
data_wrapper.set_data("window_mode", option)
func _on_display_manager_window_mode_updated(window_mode):
var selected = DisplayManager.get_string_from_window_mode(window_mode)

View file

@ -1,24 +1,26 @@
extends VBoxContainer
## World appareance settings
const CATEGORY = DataManager.categories.SETTINGS
@onready var world_color = $WorldColor/Color
@onready var world_texture = $WorldTexture
@onready var target_color = $TargetColor/TargetColor
@onready var preview = $Preview
@onready var target_preview = $Preview/TargetPreview
var data_wrapper:DataManager.SectionWrapper:
get:
return DataManager.get_wrapper(DataManager.SETTINGS_FILE_PATH, "world")
func _on_color_color_changed(color: Color) -> void:
DataManager.save_data("world_color", str(color), CATEGORY)
data_wrapper.set_data("world_color", color)
update_preview()
func _on_target_color_color_changed(color: Color) -> void:
DataManager.save_data("target_color", str(color), CATEGORY)
data_wrapper.set_data("target_color", color)
update_preview()
func _on_world_texture_item_selected(index) -> void:
DataManager.save_data("world_texture", world_texture.get_item_text(index), CATEGORY)
data_wrapper.set_data("world_texture", world_texture.get_item_text(index))
update_preview()
func _ready() -> void:
@ -26,20 +28,19 @@ func _ready() -> void:
for texture in Global.get_world_textures():
world_texture.add_icon_item(load(Global.get_world_textures_path() + texture), texture, i)
i+=1
world_color.color = DataManager.set_color_if_exists(CATEGORY, world_color.color, "world_color")
target_color.color = DataManager.set_color_if_exists(CATEGORY, target_color.color, "target_color")
world_color.color = data_wrapper.get_data("world_color")
target_color.color = data_wrapper.get_data("target_color")
get_selected_texture_index()
update_preview()
func get_selected_texture_index() -> void:
if DataManager.get_data(CATEGORY, "world_texture"):
var selected = DataManager.get_data(CATEGORY, "world_texture")
for i in range(world_texture.item_count):
if selected == world_texture.get_item_text(i):
world_texture.select(i)
var selected = data_wrapper.get_data("world_texture")
for i in range(world_texture.item_count):
if selected == world_texture.get_item_text(i):
world_texture.select(i)
update_preview()
func update_preview() -> void:
preview.texture = Global.get_current_world_texture()
preview.self_modulate = DataManager.set_color_if_exists(CATEGORY, preview.self_modulate, "world_color")
target_preview.color = DataManager.set_color_if_exists(CATEGORY, target_preview.color, "target_color")
preview.self_modulate = data_wrapper.get_data("world_color")
target_preview.color = data_wrapper.get_data("target_color")