2025-07-31 17:34:57 +00:00
|
|
|
extends Object
|
|
|
|
class_name AssetLoader
|
|
|
|
|
2025-07-31 23:40:57 +00:00
|
|
|
#region declaration
|
|
|
|
# === CONST ===
|
|
|
|
|
2025-07-31 17:34:57 +00:00
|
|
|
const DEFAULT_ASSETS_PATH = "res://mods"
|
|
|
|
|
2025-07-31 23:40:57 +00:00
|
|
|
## If you want to change the mod extension. Keep in mind that it's still a json under the hood
|
|
|
|
const MOD_INFOS_EXTENSION = "modinfo"
|
|
|
|
|
2025-07-31 17:34:57 +00:00
|
|
|
## Path to the mods folder : [param res://mods] by default
|
|
|
|
## [br]
|
|
|
|
## (is not a const but should be treated as such, so the uppercase)
|
|
|
|
var ASSETS_PATH
|
|
|
|
|
2025-07-31 23:40:57 +00:00
|
|
|
# === VAR ===
|
|
|
|
var dir:DirAccess
|
|
|
|
var mod_folders:PackedStringArray
|
2025-07-31 17:34:57 +00:00
|
|
|
var critical_error := false
|
|
|
|
|
2025-07-31 23:40:57 +00:00
|
|
|
var mod_paths : PackedStringArray
|
|
|
|
var mod_manifests : Dictionary[String]
|
|
|
|
|
|
|
|
# === SIGNALS ===
|
|
|
|
signal loading_finished
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2025-07-31 17:34:57 +00:00
|
|
|
|
|
|
|
func _init() -> void:
|
2025-07-31 23:40:57 +00:00
|
|
|
print_verbose("------ MOD LOADING STARTED ------")
|
2025-07-31 17:34:57 +00:00
|
|
|
ASSETS_PATH = ProjectSettings.get_setting("game/mods/mod_path", DEFAULT_ASSETS_PATH)
|
2025-07-31 23:40:57 +00:00
|
|
|
dir = DirAccess.open(ASSETS_PATH)
|
2025-07-31 17:34:57 +00:00
|
|
|
if not dir:
|
|
|
|
push_error("AssetLoader: Mods folder not found at '%s'" % ASSETS_PATH)
|
2025-07-31 23:40:57 +00:00
|
|
|
push_error("AssetLoader:",DirAccess.get_open_error())
|
2025-07-31 17:34:57 +00:00
|
|
|
_show_error_popup("Mods folder not found at '%s'" % ASSETS_PATH)
|
|
|
|
critical_error = true
|
|
|
|
return
|
2025-07-31 23:40:57 +00:00
|
|
|
mod_folders = dir.get_directories()
|
2025-07-31 17:34:57 +00:00
|
|
|
if mod_folders.is_empty():
|
|
|
|
push_error("AssetLoader: Mods folder '%s' is empty — no mods to load." % ASSETS_PATH)
|
|
|
|
_show_error_popup("Mods folder '%s' is empty — no mods to load." % ASSETS_PATH)
|
|
|
|
critical_error = true
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
## This will show a native MessageBox on Windows,
|
|
|
|
## a native dialog on macOS, and GTK/QT dialog on Linux.
|
|
|
|
func _show_error_popup(message: String) -> void:
|
|
|
|
OS.alert("AssetLoader:"+message, "AssetLoader:Error")
|
|
|
|
|
|
|
|
|
|
|
|
func load_all():
|
2025-07-31 23:40:57 +00:00
|
|
|
load_mods()
|
|
|
|
#load_mods_content()
|
|
|
|
|
|
|
|
|
|
|
|
func load_mods():
|
|
|
|
for mod in mod_folders:
|
|
|
|
var mod_name = mod
|
|
|
|
var mod_path = ASSETS_PATH + "/" + mod_name
|
|
|
|
var manifest_path = mod_path + "/" + mod_name + "." + MOD_INFOS_EXTENSION
|
|
|
|
if FileAccess.file_exists(manifest_path):
|
|
|
|
var manifest_file := FileAccess.open(manifest_path, FileAccess.READ)
|
|
|
|
var manifest: Dictionary = JSON.parse_string(manifest_file.get_as_text())
|
|
|
|
if typeof(manifest) == TYPE_DICTIONARY: # always true ?
|
|
|
|
mod_paths.append(mod_path)
|
|
|
|
if manifest["id"]:
|
|
|
|
mod_manifests[manifest["id"]] = manifest
|
|
|
|
print_verbose("Mod loaded: %s" % manifest["name"])
|
|
|
|
else:
|
|
|
|
mod_manifests[mod_name] = manifest
|
|
|
|
print_verbose("Mod loaded: %s" % manifest["name"])
|
|
|
|
|
|
|
|
print(dir.get_files())
|