diff options
m--------- | extension/deps/openvic-simulation | 0 | ||||
-rw-r--r-- | extension/src/openvic-extension/GameSingleton.cpp | 33 | ||||
-rw-r--r-- | extension/src/openvic-extension/GameSingleton.hpp | 3 | ||||
-rw-r--r-- | extension/src/openvic-extension/LoadLocalisation.cpp | 4 | ||||
-rw-r--r-- | extension/src/openvic-extension/Utilities.cpp | 10 | ||||
-rw-r--r-- | extension/src/openvic-extension/Utilities.hpp | 11 | ||||
-rw-r--r-- | game/src/Game/Autoload/Argument/ArgumentParser.tscn | 18 | ||||
-rw-r--r-- | game/src/Game/GameStart.gd | 58 | ||||
-rw-r--r-- | game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd | 2 | ||||
m--------- | scripts | 0 |
10 files changed, 103 insertions, 36 deletions
diff --git a/extension/deps/openvic-simulation b/extension/deps/openvic-simulation -Subproject 04795924456062db1631686a90f13d963791ad3 +Subproject 19e5829e47e9d823f1f979d1f2c95fdb9aae5bb diff --git a/extension/src/openvic-extension/GameSingleton.cpp b/extension/src/openvic-extension/GameSingleton.cpp index ade6ec9..b294691 100644 --- a/extension/src/openvic-extension/GameSingleton.cpp +++ b/extension/src/openvic-extension/GameSingleton.cpp @@ -10,11 +10,16 @@ using namespace godot; using namespace OpenVic; +using OpenVic::Utilities::std_to_godot_string; +using OpenVic::Utilities::std_view_to_godot_string; +using OpenVic::Utilities::godot_to_std_string; + GameSingleton* GameSingleton::singleton = nullptr; void GameSingleton::_bind_methods() { ClassDB::bind_static_method("GameSingleton", D_METHOD("setup_logger"), &GameSingleton::setup_logger); ClassDB::bind_method(D_METHOD("load_defines_compatibility_mode", "file_paths"), &GameSingleton::load_defines_compatibility_mode); + ClassDB::bind_static_method("GameSingleton", D_METHOD("search_for_game_path", "hint_path"), &GameSingleton::search_for_game_path, DEFVAL(String{})); ClassDB::bind_method(D_METHOD("lookup_file", "path"), &GameSingleton::lookup_file); ClassDB::bind_method(D_METHOD("setup_game"), &GameSingleton::setup_game); @@ -83,13 +88,13 @@ void GameSingleton::draw_pie_chart(Ref<Image> image, Color trim_colour, float trim_size, float gradient_falloff, float gradient_base, bool donut, bool donut_inner_trim, float donut_inner_radius) { - OpenVic::draw_pie_chart(image, stopAngles, colours, radius, shadow_displacement, shadow_tightness, shadow_radius, shadow_thickness, + Utilities::draw_pie_chart(image, stopAngles, colours, radius, shadow_displacement, shadow_tightness, shadow_radius, shadow_thickness, trim_colour, trim_size, gradient_falloff, gradient_base, donut, donut_inner_trim, donut_inner_radius); } Ref<Image> GameSingleton::load_image(String const& path) { - return load_godot_image(path); + return Utilities::load_godot_image(path); } GameSingleton* GameSingleton::get_singleton() { @@ -211,9 +216,9 @@ Dictionary GameSingleton::_distribution_to_dictionary(distribution_t const& dist Dictionary dict; for (distribution_t::value_type const& p : dist) { Dictionary sub_dict; - sub_dict[get_piechart_info_size_key()] = p.second; - sub_dict[get_piechart_info_colour_key()] = to_godot_color(p.first->get_colour()); - dict[std_to_godot_string(p.first->get_identifier())] = sub_dict; + sub_dict[get_piechart_info_size_key()] = p.second.to_float(); + sub_dict[get_piechart_info_colour_key()] = Utilities::to_godot_color(p.first->get_colour()); + dict[std_view_to_godot_string(p.first->get_identifier())] = sub_dict; } return dict; } @@ -223,18 +228,18 @@ Dictionary GameSingleton::get_province_info_from_index(int32_t index) const { if (province == nullptr) return {}; Dictionary ret; - ret[get_province_info_province_key()] = std_to_godot_string(province->get_identifier()); + ret[get_province_info_province_key()] = std_view_to_godot_string(province->get_identifier()); Region const* region = province->get_region(); - if (region != nullptr) ret[get_province_info_region_key()] = std_to_godot_string(region->get_identifier()); + if (region != nullptr) ret[get_province_info_region_key()] = std_view_to_godot_string(region->get_identifier()); Good const* rgo = province->get_rgo(); - if (rgo != nullptr) ret[get_province_info_rgo_key()] = std_to_godot_string(rgo->get_identifier()); + if (rgo != nullptr) ret[get_province_info_rgo_key()] = std_view_to_godot_string(rgo->get_identifier()); ret[get_province_info_life_rating_key()] = province->get_life_rating(); TerrainType const* terrain_type = province->get_terrain_type(); - if (terrain_type != nullptr) ret[get_province_info_terrain_type_key()] = std_to_godot_string(terrain_type->get_identifier()); + if (terrain_type != nullptr) ret[get_province_info_terrain_type_key()] = std_view_to_godot_string(terrain_type->get_identifier()); ret[get_province_info_total_population_key()] = province->get_total_population(); distribution_t const& pop_types = province->get_pop_type_distribution(); @@ -252,7 +257,7 @@ Dictionary GameSingleton::get_province_info_from_index(int32_t index) const { BuildingInstance const& building = buildings[idx]; Dictionary building_dict; - building_dict[get_building_info_building_key()] = std_to_godot_string(building.get_identifier()); + building_dict[get_building_info_building_key()] = std_view_to_godot_string(building.get_identifier()); building_dict[get_building_info_level_key()] = static_cast<int32_t>(building.get_current_level()); building_dict[get_building_info_expansion_state_key()] = static_cast<int32_t>(building.get_expansion_state()); building_dict[get_building_info_start_date_key()] = std_to_godot_string(building.get_start_date().to_string()); @@ -325,7 +330,7 @@ int32_t GameSingleton::get_mapmode_count() const { String GameSingleton::get_mapmode_identifier(int32_t index) const { Mapmode const* mapmode = game_manager.get_map().get_mapmode_by_index(index); - if (mapmode != nullptr) return std_to_godot_string(mapmode->get_identifier()); + if (mapmode != nullptr) return std_view_to_godot_string(mapmode->get_identifier()); return String {}; } @@ -450,7 +455,7 @@ Error GameSingleton::_load_terrain_variants_compatibility_mode(String const& ter static constexpr int32_t SHEET_DIMS = 8, SHEET_SIZE = SHEET_DIMS * SHEET_DIMS; // Load the terrain texture sheet and prepare to slice it up - Ref<Image> terrain_sheet = load_godot_image(terrain_texturesheet_path); + Ref<Image> terrain_sheet = Utilities::load_godot_image(terrain_texturesheet_path); if (terrain_sheet.is_null()) { UtilityFunctions::push_error("Failed to load terrain texture sheet: ", terrain_texturesheet_path); return FAILED; @@ -530,6 +535,10 @@ Error GameSingleton::load_defines_compatibility_mode(PackedStringArray const& fi return err; } +String GameSingleton::search_for_game_path(String hint_path) { + return std_to_godot_string(Dataloader::search_for_game_path(godot_to_std_string(hint_path)).string()); +} + String GameSingleton::lookup_file(String const& path) const { return std_to_godot_string(dataloader.lookup_file(godot_to_std_string(path)).string()); } diff --git a/extension/src/openvic-extension/GameSingleton.hpp b/extension/src/openvic-extension/GameSingleton.hpp index 56c9e88..8145a39 100644 --- a/extension/src/openvic-extension/GameSingleton.hpp +++ b/extension/src/openvic-extension/GameSingleton.hpp @@ -44,6 +44,7 @@ namespace OpenVic { godot::Vector2 shadow_displacement, float shadow_tightness, float shadow_radius, float shadow_thickness, godot::Color trim_colour, float trim_size, float gradient_falloff, float gradient_base, bool donut, bool donut_inner_trim, float donut_inner_radius); + static godot::Ref<godot::Image> load_image(godot::String const& path); static GameSingleton* get_singleton(); @@ -58,6 +59,8 @@ namespace OpenVic { */ godot::Error load_defines_compatibility_mode(godot::PackedStringArray const& file_paths); + static godot::String search_for_game_path(godot::String hint_path = {}); + godot::String lookup_file(godot::String const& path) const; /* Post-load/restart game setup - reset the game to post-load state diff --git a/extension/src/openvic-extension/LoadLocalisation.cpp b/extension/src/openvic-extension/LoadLocalisation.cpp index 9ab7298..418f01c 100644 --- a/extension/src/openvic-extension/LoadLocalisation.cpp +++ b/extension/src/openvic-extension/LoadLocalisation.cpp @@ -146,8 +146,8 @@ bool LoadLocalisation::add_message(std::string_view key, Dataloader::locale_t lo return false; } } - const StringName godot_key = std_to_godot_string(std::string { key }); - const StringName godot_localisation = std_to_godot_string(std::string { localisation }); + const StringName godot_key = Utilities::std_view_to_godot_string(key); + const StringName godot_localisation = Utilities::std_view_to_godot_string(localisation); if (0) { const StringName old_localisation = translation->get_message(godot_key); if (!old_localisation.is_empty()) { diff --git a/extension/src/openvic-extension/Utilities.cpp b/extension/src/openvic-extension/Utilities.cpp index 649550f..ea7e888 100644 --- a/extension/src/openvic-extension/Utilities.cpp +++ b/extension/src/openvic-extension/Utilities.cpp @@ -13,10 +13,10 @@ using namespace godot; using namespace OpenVic; static Ref<Image> load_dds_image(String const& path) { - gli::texture2d texture { gli::load_dds(godot_to_std_string(path)) }; + gli::texture2d texture { gli::load_dds(Utilities::godot_to_std_string(path)) }; if (texture.empty()) { UtilityFunctions::push_error("Failed to load DDS file: ", path); - return {}; + return nullptr; } static constexpr gli::format expected_format = gli::FORMAT_BGRA8_UNORM_PACK8; @@ -25,7 +25,7 @@ static Ref<Image> load_dds_image(String const& path) { texture = gli::convert(texture, expected_format); if (texture.empty()) { UtilityFunctions::push_error("Failed to convert DDS file: ", path); - return {}; + return nullptr; } } @@ -43,7 +43,7 @@ static Ref<Image> load_dds_image(String const& path) { return Image::create_from_data(extent.x, extent.y, false, Image::FORMAT_RGBA8, pixels); } -Ref<Image> OpenVic::load_godot_image(String const& path) { +Ref<Image> Utilities::load_godot_image(String const& path) { if (path.begins_with("res://")) { ResourceLoader* loader = ResourceLoader::get_singleton(); return loader ? loader->load(path) : nullptr; @@ -116,7 +116,7 @@ static Color pie_chart_fragment(Vector2 UV, float radius, Array const& stopAngle } } -void OpenVic::draw_pie_chart(Ref<Image> image, +void Utilities::draw_pie_chart(Ref<Image> image, Array const& stopAngles, Array const& colours, float radius, Vector2 shadow_displacement, float shadow_tightness, float shadow_radius, float shadow_thickness, Color trim_colour, float trim_size, float gradient_falloff, float gradient_base, diff --git a/extension/src/openvic-extension/Utilities.hpp b/extension/src/openvic-extension/Utilities.hpp index 32e7cb5..68e72d2 100644 --- a/extension/src/openvic-extension/Utilities.hpp +++ b/extension/src/openvic-extension/Utilities.hpp @@ -3,10 +3,11 @@ #include <godot_cpp/classes/image.hpp> #include <openvic-simulation/types/Colour.hpp> +#include <openvic-simulation/types/Vector.hpp> #define ERR(x) ((x) ? OK : FAILED) -namespace OpenVic { +namespace OpenVic::Utilities { inline std::string godot_to_std_string(godot::String const& str) { return str.ascii().get_data(); @@ -16,10 +17,18 @@ namespace OpenVic { return str.c_str(); } + inline godot::String std_view_to_godot_string(std::string_view str) { + return std_to_godot_string(static_cast<std::string>(str)); + } + inline godot::Color to_godot_color(colour_t colour) { return { colour_byte_to_float((colour >> 16) & 0xFF), colour_byte_to_float((colour >> 8) & 0xFF), colour_byte_to_float(colour & 0xFF) }; } + inline godot::Vector2i to_godot_ivec2(ivec2_t vec) { + return { vec.x, vec.y }; + } + godot::Ref<godot::Image> load_godot_image(godot::String const& path); void draw_pie_chart(godot::Ref<godot::Image> image, diff --git a/game/src/Game/Autoload/Argument/ArgumentParser.tscn b/game/src/Game/Autoload/Argument/ArgumentParser.tscn index 84ebd50..32339ec 100644 --- a/game/src/Game/Autoload/Argument/ArgumentParser.tscn +++ b/game/src/Game/Autoload/Argument/ArgumentParser.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=6 format=3 uid="uid://dayjmgc34tqo6"] +[gd_scene load_steps=7 format=3 uid="uid://dayjmgc34tqo6"] [ext_resource type="Script" path="res://src/Game/Autoload/Argument/ArgumentParser.gd" id="1_pc7xr"] [ext_resource type="Script" path="res://src/Game/Autoload/Argument/ArgumentOption.gd" id="2_4hguj"] @@ -21,13 +21,21 @@ default_value = false [sub_resource type="Resource" id="Resource_tiax1"] script = ExtResource("2_4hguj") -name = &"compatibility-mode" -aliases = Array[StringName]([&"compat"]) +name = &"base-path" +aliases = Array[StringName]([]) type = 4 -description = "Load Victoria 2 assets from this path." +description = "Load Victoria 2 assets from this exact path." +default_value = "" + +[sub_resource type="Resource" id="Resource_sh3m3"] +script = ExtResource("2_4hguj") +name = &"search-path" +aliases = Array[StringName]([]) +type = 4 +description = "Search for Victoria 2 assets at this path." default_value = "" [node name="ArgumentParser" type="Node"] editor_description = "SS-56" script = ExtResource("1_pc7xr") -option_array = Array[ExtResource("2_4hguj")]([SubResource("Resource_tq3y4"), SubResource("Resource_j1to4"), SubResource("Resource_tiax1")]) +option_array = Array[ExtResource("2_4hguj")]([SubResource("Resource_tq3y4"), SubResource("Resource_j1to4"), SubResource("Resource_tiax1"), SubResource("Resource_sh3m3")]) diff --git a/game/src/Game/GameStart.gd b/game/src/Game/GameStart.gd index 422a42a..1c230d1 100644 --- a/game/src/Game/GameStart.gd +++ b/game/src/Game/GameStart.gd @@ -6,6 +6,10 @@ const SoundTabScene = preload("res://src/Game/Menu/OptionMenu/SoundTab.tscn") @export_subgroup("Nodes") @export var loading_screen : LoadingScreen +@export var section_name : String = "general" +@export var setting_name : String = "base_defines_path" +var _settings_base_path : String = "" + func _ready() -> void: if ArgumentParser.get_argument(&"help"): ArgumentParser._print_help() @@ -20,30 +24,64 @@ func _ready() -> void: var sound_tab := SoundTabScene.instantiate() sound_tab.visible = false add_child(sound_tab) + Events.Options.load_settings.connect(_load_setting) + Events.Options.save_settings.connect(_save_setting) Events.Options.load_settings_from_file() sound_tab.queue_free() loading_screen.start_loading_screen(_initialize_game) +func _load_setting(file : ConfigFile) -> void: + if file == null: return + _settings_base_path = file.get_value(section_name, setting_name, "") + +func _save_setting(file : ConfigFile) -> void: + if file == null: return + file.set_value(section_name, setting_name, _settings_base_path) + func _load_compatibility_mode(): # Set this to your Vic2 install dir or a mod's dir to enable compatibility mode # (this won't work for mods which rely on vanilla map assets, copy missing assets # into the mod's dir for a temporary fix) # Usage: OpenVic --compatibility-mode <path> - var compatibility_mode_path : String = ArgumentParser.get_argument(&"compatibility-mode", "") - - if not compatibility_mode_path: - # TODO - non-Windows default paths - const default_path : String = "C:/Program Files (x86)/Steam/steamapps/common/Victoria 2" - compatibility_mode_path = default_path - - var compatibility_mode_paths : PackedStringArray = [compatibility_mode_path] + var arg_base_path : String = ArgumentParser.get_argument(&"base-path", "") + var arg_search_path : String = ArgumentParser.get_argument(&"search-path", "") + + var actual_base_path : String = "" + + if arg_base_path: + if arg_search_path: + push_warning("Exact base path and search base path arguments both used:\nBase: ", arg_base_path, "\nSearch: ", arg_search_path) + actual_base_path = arg_base_path + elif arg_search_path: + actual_base_path = GameSingleton.search_for_game_path(arg_search_path) + if not actual_base_path: + push_warning("Failed to find assets using search hint: ", arg_search_path) + + if not actual_base_path: + if _settings_base_path: + actual_base_path = _settings_base_path + else: + actual_base_path = GameSingleton.search_for_game_path() + if not actual_base_path: + var title : String = "Failed to find game asset path!" + var msg : String = "The path can be specified with the \"base-path\" command line option." + OS.alert(msg, title) + get_tree().quit() + return + + if not _settings_base_path: + _settings_base_path = actual_base_path + # Save the path found in the search + Events.Options.save_settings_to_file() + + var paths : PackedStringArray = [actual_base_path] # Example for adding mod paths - #compatibility_mode_paths.push_back("C:/Program Files (x86)/Steam/steamapps/common/Victoria 2/mod/TGC") + #paths.push_back(actual_base_path + "/mod/TGC") - if GameSingleton.load_defines_compatibility_mode(compatibility_mode_paths) != OK: + if GameSingleton.load_defines_compatibility_mode(paths) != OK: push_error("Errors loading game defines!") # REQUIREMENTS diff --git a/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd b/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd index cb7566f..0d1836c 100644 --- a/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd +++ b/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd @@ -12,7 +12,7 @@ func get_screen_mode_from_window_mode(window_mode : Window.Mode) -> ScreenMode: return ScreenMode.Fullscreen Window.MODE_FULLSCREEN: return ScreenMode.Borderless - Window.MODE_WINDOWED: + Window.MODE_WINDOWED, Window.MODE_MINIMIZED: return ScreenMode.Windowed _: return ScreenMode.Unknown diff --git a/scripts b/scripts -Subproject 3060e56388ac00d90deb6693ec19d47bad52deb +Subproject accb77a0af7d200818d4521b12492c078e4b7f4 |