From aa49dbbb3cf9dbff18c08245b0e46a9943df9b15 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Thu, 24 Aug 2023 00:33:21 +0100 Subject: Big Dataloader Commit (openvic) Default compat path + formatting + bits+bobs --- .gitmodules | 3 - SConstruct | 11 +- extension/deps/openvic-dataloader | 1 - extension/deps/openvic-simulation | 2 +- extension/src/GameSingleton.cpp | 109 +--------- extension/src/GameSingleton.hpp | 35 +--- extension/src/LoadGameCompatibility.cpp | 47 +++-- extension/src/LoadGameOpenVic.cpp | 342 +------------------------------- extension/src/Utilities.cpp | 12 +- extension/src/Utilities.hpp | 2 +- game/src/Game/Autoload/GameLoader.gd | 12 -- game/src/Game/GameStart.gd | 21 +- 12 files changed, 79 insertions(+), 518 deletions(-) delete mode 160000 extension/deps/openvic-dataloader diff --git a/.gitmodules b/.gitmodules index 5e462da..26eca85 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "extension/deps/openvic-simulation"] path = extension/deps/openvic-simulation url = https://github.com/OpenVicProject/OpenVic-Simulation -[submodule "extension/deps/openvic-dataloader"] - path = extension/deps/openvic-dataloader - url = https://github.com/OpenVicProject/OpenVic-Dataloader diff --git a/SConstruct b/SConstruct index eefd99d..2d34e01 100644 --- a/SConstruct +++ b/SConstruct @@ -2,7 +2,6 @@ import os import sys from glob import glob -from pathlib import Path # Local from scripts.build.option_handler import OptionsClass @@ -60,9 +59,15 @@ if env["compiledb"]: # - CPPDEFINES are for pre-processor defines # - LINKFLAGS are for linking flags +ovsim_env = SConscript("extension/deps/openvic-simulation/SConstruct") + +env.Append(LIBPATH=ovsim_env.openvic_simulation["LIBPATH"]) +env.Append(LIBS=ovsim_env.openvic_simulation["LIBS"]) +env.Append(CPPPATH=ovsim_env.openvic_simulation["INCPATH"]) + # tweak this if you want to use different folders, or more folders, to store your source code in. -paths = ["extension/src/", "extension/deps/openvic-simulation/src/"] -env.Append(CPPPATH=paths) +paths = ["extension/src/"] +env.Append(CPPPATH=[[env.Dir(p) for p in paths]]) sources = GlobRecursive("*.cpp", paths) env.extension_sources = sources diff --git a/extension/deps/openvic-dataloader b/extension/deps/openvic-dataloader deleted file mode 160000 index 65443ef..0000000 --- a/extension/deps/openvic-dataloader +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 65443efcc2f4c7d687b2bd9c631f6bb426688bbf diff --git a/extension/deps/openvic-simulation b/extension/deps/openvic-simulation index 419e58e..d204599 160000 --- a/extension/deps/openvic-simulation +++ b/extension/deps/openvic-simulation @@ -1 +1 @@ -Subproject commit 419e58e8de977d7a619b7451bb6d4242af4569f2 +Subproject commit d20459988118dc18ddc9feb12b09f5e65ad03b23 diff --git a/extension/src/GameSingleton.cpp b/extension/src/GameSingleton.cpp index 25f7195..07be9aa 100644 --- a/extension/src/GameSingleton.cpp +++ b/extension/src/GameSingleton.cpp @@ -22,8 +22,7 @@ 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", "file_dict"), &GameSingleton::load_defines); - ClassDB::bind_method(D_METHOD("load_defines_compatibility_mode", "file_path"), &GameSingleton::load_defines_compatibility_mode); + ClassDB::bind_method(D_METHOD("load_defines_compatibility_mode", "file_paths"), &GameSingleton::load_defines_compatibility_mode); ClassDB::bind_method(D_METHOD("setup_game"), &GameSingleton::setup_game); ClassDB::bind_method(D_METHOD("get_province_index_from_uv_coords", "coords"), &GameSingleton::get_province_index_from_uv_coords); @@ -58,16 +57,6 @@ void GameSingleton::_bind_methods() { ADD_SIGNAL(MethodInfo("state_updated")); ADD_SIGNAL(MethodInfo("province_selected", PropertyInfo(Variant::INT, "index"))); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_province_identifier_file_key"), &GameSingleton::get_province_identifier_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_water_province_file_key"), &GameSingleton::get_water_province_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_region_file_key"), &GameSingleton::get_region_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_terrain_variant_file_key"), &GameSingleton::get_terrain_variant_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_terrain_texture_dir_key"), &GameSingleton::get_terrain_texture_dir_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_province_image_file_key"), &GameSingleton::get_province_image_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_terrain_image_file_key"), &GameSingleton::get_terrain_image_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_goods_file_key"), &GameSingleton::get_goods_file_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_good_icons_dir_key"), &GameSingleton::get_good_icons_dir_key); - ClassDB::bind_static_method("GameSingleton", D_METHOD("get_province_info_province_key"), &GameSingleton::get_province_info_province_key); ClassDB::bind_static_method("GameSingleton", D_METHOD("get_province_info_region_key"), &GameSingleton::get_province_info_region_key); ClassDB::bind_static_method("GameSingleton", D_METHOD("get_province_info_life_rating_key"), &GameSingleton::get_province_info_life_rating_key); @@ -95,7 +84,7 @@ void GameSingleton::_bind_methods() { } void GameSingleton::draw_pie_chart(Ref image, - Array const& stopAngles, Array const& colours, float radius, + 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, bool donut, bool donut_inner_trim, float donut_inner_radius) { @@ -128,95 +117,17 @@ void GameSingleton::setup_logger() { Logger::set_error_func([](std::string&& str) { UtilityFunctions::push_error(std_to_godot_string(str)); }); } -Error GameSingleton::_load_hardcoded_defines() { - Error err = OK; - - static constexpr colour_t LOW_ALPHA_VALUE = float_to_alpha_value(0.4f); - static constexpr colour_t HIGH_ALPHA_VALUE = float_to_alpha_value(0.7f); - using mapmode_t = std::pair; - const std::vector mapmodes { - { "mapmode_terrain", - [](Map const&, Province const& province) -> colour_t { - return LOW_ALPHA_VALUE | (province.is_water() ? 0x4287F5 : 0x0D7017); - } }, - { "mapmode_province", - [](Map const&, Province const& province) -> colour_t { - return HIGH_ALPHA_VALUE | province.get_colour(); - } }, - { "mapmode_region", - [](Map const&, Province const& province) -> colour_t { - Region const* region = province.get_region(); - if (region != nullptr) return HIGH_ALPHA_VALUE | region->get_colour(); - return NULL_COLOUR; - } }, - { "mapmode_index", - [](Map const& map, Province const& province) -> colour_t { - const colour_t f = fraction_to_colour_byte(province.get_index(), map.get_province_count() + 1); - return HIGH_ALPHA_VALUE | (f << 16) | (f << 8) | f; - } }, - { "mapmode_rgo", - [](Map const& map, Province const& province) -> colour_t { - Good const* rgo = province.get_rgo(); - if (rgo != nullptr) return HIGH_ALPHA_VALUE | rgo->get_colour(); - return NULL_COLOUR; - } }, - { "mapmode_infrastructure", - [](Map const& map, Province const& province) -> colour_t { - Building const* railroad = province.get_building_by_identifier("building_railroad"); - if (railroad != nullptr) { - colour_t val = fraction_to_colour_byte(railroad->get_level(), railroad->get_type().get_max_level() + 1, 0.5f, 1.0f); - switch (railroad->get_expansion_state()) { - case Building::ExpansionState::CannotExpand: val <<= 16; break; - case Building::ExpansionState::CanExpand: break; - default: val <<= 8; break; - } - return HIGH_ALPHA_VALUE | val; - } - return NULL_COLOUR; - } }, - { "mapmode_population", - [](Map const& map, Province const& province) -> colour_t { - return HIGH_ALPHA_VALUE | (fraction_to_colour_byte(province.get_total_population(), map.get_highest_province_population() + 1, 0.1f, 1.0f) << 8); - } }, - { "mapmode_culture", - [](Map const& map, Province const& province) -> colour_t { - distribution_t const& cultures = province.get_culture_distribution(); - if (!cultures.empty()) { - // This breaks if replaced with distribution_t::value_type, something - // about operator=(volatile const&) being deleted. - std::pair culture = *cultures.begin(); - for (distribution_t::value_type const p : cultures) { - if (p.second > culture.second) culture = p; - } - return HIGH_ALPHA_VALUE | culture.first->get_colour(); - } - return NULL_COLOUR; - } } - }; - for (mapmode_t const& mapmode : mapmodes) - if (game_manager.map.add_mapmode(mapmode.first, mapmode.second) != SUCCESS) - err = FAILED; - game_manager.map.lock_mapmodes(); - - using building_type_t = std::tuple; - const std::vector building_types { - { "building_fort", 4, 8 }, { "building_naval_base", 6, 15 }, { "building_railroad", 5, 10 } - }; - for (building_type_t const& type : building_types) - if (game_manager.building_manager.add_building_type(std::get<0>(type), std::get<1>(type), std::get<2>(type)) != SUCCESS) - err = FAILED; - game_manager.building_manager.lock_building_types(); - - return err; -} - GameSingleton::~GameSingleton() { ERR_FAIL_COND(singleton != this); singleton = nullptr; } Error GameSingleton::setup_game() { - return ERR(game_manager.setup()); + return_t ret = game_manager.setup(); + if (dataloader.load_pop_history(game_manager, "history/pops/" + game_manager.get_today().to_string()) != SUCCESS) { + ret = FAILURE; + } + return ERR(ret); } int32_t GameSingleton::get_province_index_from_uv_coords(Vector2 const& coords) const { @@ -340,8 +251,8 @@ Dictionary GameSingleton::get_province_info_from_index(int32_t index) const { building_dict[get_building_info_building_key()] = std_to_godot_string(building.get_identifier()); building_dict[get_building_info_level_key()] = static_cast(building.get_level()); building_dict[get_building_info_expansion_state_key()] = static_cast(building.get_expansion_state()); - building_dict[get_building_info_start_date_key()] = std_to_godot_string(static_cast(building.get_start_date())); - building_dict[get_building_info_end_date_key()] = std_to_godot_string(static_cast(building.get_end_date())); + building_dict[get_building_info_start_date_key()] = std_to_godot_string(building.get_start_date().to_string()); + building_dict[get_building_info_end_date_key()] = std_to_godot_string(building.get_end_date().to_string()); building_dict[get_building_info_expansion_progress_key()] = building.get_expansion_progress(); buildings_array[idx] = building_dict; @@ -476,7 +387,7 @@ bool GameSingleton::can_decrease_speed() const { } String GameSingleton::get_longform_date() const { - return std_to_godot_string(static_cast(game_manager.get_today())); + return std_to_godot_string(game_manager.get_today().to_string()); } void GameSingleton::try_tick() { diff --git a/extension/src/GameSingleton.hpp b/extension/src/GameSingleton.hpp index a1d77c1..a484520 100644 --- a/extension/src/GameSingleton.hpp +++ b/extension/src/GameSingleton.hpp @@ -4,6 +4,7 @@ #include #include "openvic/GameManager.hpp" +#include "openvic/dataloader/Dataloader.hpp" namespace OpenVic { struct TerrainVariant : HasIdentifierAndColour { @@ -14,6 +15,7 @@ namespace OpenVic { TerrainVariant(const std::string_view new_identfier, colour_t new_colour, godot::Ref const& new_image); + public: static constexpr size_t MAX_TERRIN_VARIANT_COUNT = 1 << (8 * sizeof(Map::terrain_t)); @@ -27,6 +29,7 @@ namespace OpenVic { static GameSingleton* singleton; GameManager game_manager; + Dataloader dataloader; godot::Vector2i image_subdivisions; godot::Ref province_shape_texture; @@ -38,27 +41,12 @@ namespace OpenVic { godot::Ref terrain_texture; godot::Dictionary good_icons; - godot::Error _parse_province_identifier_entry(godot::String const& identifier, godot::Variant const& entry); - godot::Error _parse_region_entry(godot::String const& identifier, godot::Variant const& entry); - godot::Error _parse_terrain_entry(godot::String const& identifier, godot::Variant const& entry, godot::String const& terrain_texture_dir_path); - godot::Error _parse_good_entry(godot::String const& identifier, godot::Variant const& entry); - - godot::Error _load_province_identifier_file(godot::String const& file_path); - godot::Error _load_water_province_file(godot::String const& file_path); - godot::Error _load_region_file(godot::String const& file_path); - godot::Error _load_terrain_variants(godot::String const& terrain_identifiers_path, godot::String const& terrain_texture_dir_path); godot::Error _generate_terrain_texture_array(); godot::Error _load_map_images(godot::String const& province_image_path, godot::String const& terrain_image_path, bool flip_vertical = false); - godot::Error _load_goods(godot::String const& defines_path, godot::String const& icons_dir_path); godot::Error _load_province_identifier_file_compatibility_mode(godot::String const& file_path); godot::Error _load_terrain_variants_compatibility_mode(godot::String const& terrain_image_path, godot::String const& terrain_texturesheet_path); - /* Hardcoded data for defining things for which parsing from files has - * not been implemented, currently mapmodes and building types. - */ - godot::Error _load_hardcoded_defines(); - /* Generate the province_colour_texture from the current mapmode. */ godot::Error _update_colour_image(); @@ -83,25 +71,10 @@ namespace OpenVic { static void setup_logger(); - static godot::StringName const& get_province_identifier_file_key(); - static godot::StringName const& get_water_province_file_key(); - static godot::StringName const& get_region_file_key(); - static godot::StringName const& get_terrain_variant_file_key(); - static godot::StringName const& get_terrain_texture_dir_key(); - static godot::StringName const& get_province_image_file_key(); - static godot::StringName const& get_terrain_image_file_key(); - static godot::StringName const& get_goods_file_key(); - static godot::StringName const& get_good_icons_dir_key(); - - /* Load the game's defines from the filepaths listed as Strings - * in a Dictionary, using the StringNames above as keys. - */ - godot::Error load_defines(godot::Dictionary const& file_dict); - /* Load the game's defines in compatiblity mode from the filepath * pointing to the defines folder. */ - godot::Error load_defines_compatibility_mode(godot::String const& file_path); + godot::Error load_defines_compatibility_mode(godot::PackedStringArray const& file_paths); /* Post-load/restart game setup - reset the game to post-load state * and (re)generate starting data, e.g. buildings. diff --git a/extension/src/LoadGameCompatibility.cpp b/extension/src/LoadGameCompatibility.cpp index 27d8250..1567977 100644 --- a/extension/src/LoadGameCompatibility.cpp +++ b/extension/src/LoadGameCompatibility.cpp @@ -65,8 +65,7 @@ Error GameSingleton::_load_province_identifier_file_compatibility_mode(String co err = FAILED; continue; } - static const std::string province_prefix = "PROV"; - if (game_manager.map.add_province(province_prefix + std::to_string(id), colour) != SUCCESS) err = FAILED; + if (game_manager.map.add_province(std::to_string(id), colour) != SUCCESS) err = FAILED; } } game_manager.map.lock_provinces(); @@ -104,7 +103,7 @@ Error GameSingleton::_load_terrain_variants_compatibility_mode(String const& ter { Ref water_image = Image::create(slice_size, slice_size, false, terrain_sheet->get_format()); ERR_FAIL_NULL_V_EDMSG(water_image, FAILED, "Failed to create water terrain image"); - water_image->fill({ 0.0f, 0.0f, 1.0f }); + water_image->fill({ 0.1f, 0.1f, 0.5f }); terrain_variants.add_item({ "terrain_water", 0xFFFFFF, water_image }); } Error err = OK; @@ -123,29 +122,53 @@ Error GameSingleton::_load_terrain_variants_compatibility_mode(String const& ter return err; } -Error GameSingleton::load_defines_compatibility_mode(String const& file_path) { - static const String province_identifier_file = "/map/definition.csv"; - static const String province_image_file = "/map/provinces.bmp"; - static const String terrain_image_file = "/map/terrain.bmp"; - static const String terrain_texture_dir = "/map/terrain/texturesheet.tga"; +Error GameSingleton::load_defines_compatibility_mode(PackedStringArray const& file_paths) { + static const std::filesystem::path province_identifier_file = "map/definition.csv"; + static const std::filesystem::path province_image_file = "map/provinces.bmp"; + static const std::filesystem::path terrain_image_file = "map/terrain.bmp"; + static const std::filesystem::path terrain_texture_file = "map/terrain/texturesheet.tga"; + + std::vector roots; + for (String const& path : file_paths) { + roots.push_back(godot_to_std_string(path)); + } Error err = OK; - if (_load_province_identifier_file_compatibility_mode(file_path + province_identifier_file) != OK) { + + if (dataloader.set_roots(roots) != SUCCESS) { + Logger::error("Failed to set dataloader roots!"); + err = FAILED; + } + + if (dataloader.load_defines(game_manager) != SUCCESS) { + UtilityFunctions::push_error("Failed to load defines!"); + err = FAILED; + } + + if (_load_province_identifier_file_compatibility_mode( + std_to_godot_string(dataloader.lookup_file(province_identifier_file).string()) + ) != OK) { UtilityFunctions::push_error("Failed to load province identifiers!"); err = FAILED; } game_manager.map.lock_water_provinces(); game_manager.map.lock_regions(); - if (_load_terrain_variants_compatibility_mode(file_path + terrain_image_file, file_path + terrain_texture_dir) != OK) { + if (_load_terrain_variants_compatibility_mode( + std_to_godot_string(dataloader.lookup_file(terrain_image_file).string()), + std_to_godot_string(dataloader.lookup_file(terrain_texture_file).string()) + ) != OK) { UtilityFunctions::push_error("Failed to load terrain variants!"); err = FAILED; } - if (_load_map_images(file_path + province_image_file, file_path + terrain_image_file, true) != OK) { + if (_load_map_images( + std_to_godot_string(dataloader.lookup_file(province_image_file).string()), + std_to_godot_string(dataloader.lookup_file(terrain_image_file).string()), + true) != OK) { UtilityFunctions::push_error("Failed to load map images!"); err = FAILED; } game_manager.good_manager.lock_goods(); - if (_load_hardcoded_defines() != OK) { + if (game_manager.load_hardcoded_defines() != SUCCESS) { UtilityFunctions::push_error("Failed to hardcoded defines!"); err = FAILED; } diff --git a/extension/src/LoadGameOpenVic.cpp b/extension/src/LoadGameOpenVic.cpp index 8e29f60..b262a28 100644 --- a/extension/src/LoadGameOpenVic.cpp +++ b/extension/src/LoadGameOpenVic.cpp @@ -9,195 +9,6 @@ using namespace godot; using namespace OpenVic; -static Error _load_json_file(String const& file_description, String const& file_path, Variant& result) { - result.clear(); - UtilityFunctions::print("Loading ", file_description, " file: ", file_path); - const Ref file = FileAccess::open(file_path, FileAccess::ModeFlags::READ); - Error err = FileAccess::get_open_error(); - if (err != OK || file.is_null()) { - UtilityFunctions::push_error("Failed to load ", file_description, " file: ", file_path); - return err == OK ? FAILED : err; - } - const String json_string = file->get_as_text(); - Ref json; - json.instantiate(); - err = json->parse(json_string); - if (err != OK) { - UtilityFunctions::push_error("Failed to parse ", file_description, " file as JSON: ", file_path, - "\nError at line ", json->get_error_line(), ": ", json->get_error_message()); - return err; - } - result = json->get_data(); - return err; -} - -using parse_json_entry_func_t = std::function; - -static Error _parse_json_dictionary_file(String const& file_description, String const& file_path, - String const& identifier_prefix, parse_json_entry_func_t parse_entry) { - Variant json_var; - Error err = _load_json_file(file_description, file_path, json_var); - if (err != OK) return err; - const Variant::Type type = json_var.get_type(); - if (type != Variant::DICTIONARY) { - UtilityFunctions::push_error("Invalid ", file_description, " JSON: root has type ", - Variant::get_type_name(type), " (expected Dictionary)"); - return FAILED; - } - Dictionary const& dict = json_var; - const Array identifiers = dict.keys(); - for (int64_t idx = 0; idx < identifiers.size(); ++idx) { - String const& identifier = identifiers[idx]; - Variant const& entry = dict[identifier]; - if (identifier.is_empty()) { - UtilityFunctions::push_error("Empty identifier in ", file_description, " file with entry: ", entry); - err = FAILED; - continue; - } - if (!identifier.begins_with(identifier_prefix)) - UtilityFunctions::push_warning("Identifier in ", file_description, " file missing \"", identifier_prefix, "\" prefix: ", identifier); - if (parse_entry(identifier, entry) != OK) err = FAILED; - } - return err; -} - -static colour_t _parse_colour(Variant const& var) { - const Variant::Type type = var.get_type(); - if (type == Variant::ARRAY) { - Array const& colour_array = var; - if (colour_array.size() == 3) { - colour_t colour = NULL_COLOUR; - for (int jdx = 0; jdx < 3; ++jdx) { - Variant const& var = colour_array[jdx]; - if (var.get_type() != Variant::FLOAT) return NULL_COLOUR; - const double colour_double = var; - if (std::trunc(colour_double) != colour_double) return NULL_COLOUR; - const int64_t colour_int = static_cast(colour_double); - if (colour_int < 0 || colour_int > 255) return NULL_COLOUR; - colour = (colour << 8) | colour_int; - } - return colour; - } - } else if (type == Variant::STRING) { - String const& colour_string = var; - if (colour_string.is_valid_hex_number()) { - const int64_t colour_int = colour_string.hex_to_int(); - if (colour_int != NULL_COLOUR && colour_int <= MAX_COLOUR_RGB) - return colour_int; - } - } - return NULL_COLOUR; -} - -Error GameSingleton::_parse_province_identifier_entry(String const& identifier, Variant const& entry) { - const colour_t colour = _parse_colour(entry); - if (colour == NULL_COLOUR || colour > MAX_COLOUR_RGB) { - UtilityFunctions::push_error("Invalid colour for province identifier \"", identifier, "\": ", entry); - return FAILED; - } - return ERR(game_manager.map.add_province(godot_to_std_string(identifier), colour)); -} - -Error GameSingleton::_load_province_identifier_file(String const& file_path) { - const Error err = _parse_json_dictionary_file("province identifier", file_path, "prov_", - [this](String const& identifier, Variant const& entry) -> Error { - return _parse_province_identifier_entry(identifier, entry); - }); - game_manager.map.lock_provinces(); - return err; -} - -Error GameSingleton::_load_water_province_file(String const& file_path) { - Variant json_var; - Error err = _load_json_file("water province", file_path, json_var); - if (err != OK) return err; - Variant::Type type = json_var.get_type(); - if (type != Variant::ARRAY) { - UtilityFunctions::push_error("Invalid water province JSON: root has type ", - Variant::get_type_name(type), " (expected Array)"); - err = FAILED; - } else { - Array const& array = json_var; - for (int64_t idx = 0; idx < array.size(); ++idx) { - Variant const& entry = array[idx]; - type = entry.get_type(); - if (type != Variant::STRING) { - UtilityFunctions::push_error("Invalid water province identifier: ", entry); - err = FAILED; - continue; - } - String const& identifier = entry; - if (game_manager.map.set_water_province(godot_to_std_string(identifier)) != SUCCESS) - err = FAILED; - } - } - game_manager.map.lock_water_provinces(); - return err; -} - -Error GameSingleton::_parse_region_entry(String const& identifier, Variant const& entry) { - Error err = OK; - Variant::Type type = entry.get_type(); - std::vector province_identifiers; - if (type == Variant::ARRAY) { - Array const& province_array = entry; - for (int64_t idx = 0; idx < province_array.size(); ++idx) { - Variant const& province_var = province_array[idx]; - type = province_var.get_type(); - if (type == Variant::STRING) { - String const& province_string = province_var; - province_identifiers.push_back(godot_to_std_string(province_string)); - } else { - UtilityFunctions::push_error("Invalid province identifier for region \"", identifier, "\": ", entry); - err = FAILED; - } - } - } - if (province_identifiers.empty()) { - UtilityFunctions::push_error("Invalid province list for region \"", identifier, "\": ", entry); - return FAILED; - } - std::vector province_identifier_views; - for (std::string const& str : province_identifiers) { - province_identifier_views.push_back(str); - } - return ERR(game_manager.map.add_region(godot_to_std_string(identifier), province_identifier_views)); -} - -Error GameSingleton::_load_region_file(String const& file_path) { - const Error err = _parse_json_dictionary_file("region", file_path, "region_", - [this](String const& identifier, Variant const& entry) -> Error { - return _parse_region_entry(identifier, entry); - }); - game_manager.map.lock_regions(); - return err; -} - -Error GameSingleton::_parse_terrain_entry(String const& identifier, Variant const& entry, String const& terrain_texture_dir_path) { - const colour_t colour = _parse_colour(entry); - if (colour == NULL_COLOUR || colour > MAX_COLOUR_RGB) { - UtilityFunctions::push_error("Invalid colour for terrain texture \"", identifier, "\": ", entry); - return FAILED; - } - const String terrain_path = terrain_texture_dir_path + identifier; - const Ref terrain_image = load_godot_image(terrain_path); - if (terrain_image.is_null()) { - UtilityFunctions::push_error("Failed to load terrain image: ", terrain_path); - return FAILED; - } - return ERR(terrain_variants.add_item({ godot_to_std_string(identifier), colour, terrain_image })); -} - -Error GameSingleton::_load_terrain_variants(String const& terrain_identifiers_path, String const& terrain_texture_dir_path) { - Error err = _parse_json_dictionary_file("terrain variants", terrain_identifiers_path, "", - [this, terrain_texture_dir_path](String const& identifier, Variant const& entry) -> Error { - return _parse_terrain_entry(identifier, entry, terrain_texture_dir_path + String { "/" }); - }); - terrain_variants.lock(); - if (_generate_terrain_texture_array() != OK) return FAILED; - return err; -} - Error GameSingleton::_generate_terrain_texture_array() { Error err = OK; if (terrain_variants.get_item_count() == 0) { @@ -276,7 +87,7 @@ Error GameSingleton::_load_map_images(String const& province_image_path, String // Generate interleaved province and terrain ID image if (game_manager.map.generate_province_shape_image(province_dims.x, province_dims.y, province_image->get_data().ptr(), - terrain_image->get_data().ptr(), terrain_variant_map, true) != SUCCESS) err = FAILED; + terrain_image->get_data().ptr(), terrain_variant_map, false) != SUCCESS) err = FAILED; static constexpr int32_t GPU_DIM_LIMIT = 0x3FFF; // For each dimension of the image, this finds the small number of equal subdivisions required get the individual texture dims under GPU_DIM_LIMIT @@ -317,154 +128,3 @@ Error GameSingleton::_load_map_images(String const& province_image_path, String return err; } - -Error GameSingleton::_parse_good_entry(String const& identifier, Variant const& entry) { - if (entry.get_type() != Variant::DICTIONARY) { - UtilityFunctions::push_error("Invalid good entry for ", identifier, ": ", entry); - return FAILED; - } - Dictionary const& dict = entry; - - static const String key_category = "category"; - Variant const& var_category = dict.get(key_category, ""); - String category; - if (var_category.get_type() == Variant::STRING) category = var_category; - else UtilityFunctions::push_error("Invalid good category for ", identifier, ": ", var_category); - - static const String key_base_price = "base_price"; - Variant const& var_base_price = dict.get(key_base_price, NULL_PRICE); - price_t base_price = NULL_PRICE; - if (var_base_price.get_type() == Variant::FLOAT) base_price = var_base_price; - else UtilityFunctions::push_error("Invalid good base price for ", identifier, ": ", var_base_price); - - static const String key_colour = "colour"; - Variant const& var_colour = dict.get(key_colour, ""); - const colour_t colour = _parse_colour(var_colour); - if (colour > MAX_COLOUR_RGB) { - UtilityFunctions::push_error("Invalid good colour for ", identifier, ": ", var_colour); - return FAILED; - } - - static const String key_default_available = "default_available"; - Variant const& var_default_available = dict.get(key_default_available, true); - bool default_available = false; - if (var_default_available.get_type() == Variant::BOOL) default_available = var_default_available; - else UtilityFunctions::push_error("Invalid good available default bool value for ", identifier, ": ", var_default_available); - - static const String key_tradeable = "tradeable"; - Variant const& var_tradeable = dict.get(key_tradeable, true); - bool tradeable = false; - if (var_tradeable.get_type() == Variant::BOOL) tradeable = var_tradeable; - else UtilityFunctions::push_error("Invalid good tradeable bool value for ", identifier, ": ", var_tradeable); - - static const String key_currency = "currency"; - Variant const& var_currency = dict.get(key_currency, true); - bool currency = false; - if (var_currency.get_type() == Variant::BOOL) currency = var_currency; - else UtilityFunctions::push_error("Invalid good currency bool value for ", identifier, ": ", var_currency); - - static const String key_overseas_maintenance = "overseas_maintenance"; - Variant const& var_overseas_maintenance = dict.get(key_overseas_maintenance, true); - bool overseas_maintenance = false; - if (var_overseas_maintenance.get_type() == Variant::BOOL) overseas_maintenance = var_overseas_maintenance; - else UtilityFunctions::push_error("Invalid good overseas maintenance bool value for ", identifier, ": ", var_overseas_maintenance); - - return ERR(game_manager.good_manager.add_good(godot_to_std_string(identifier), colour, godot_to_std_string(category), - base_price, default_available, tradeable, currency, overseas_maintenance)); -} - -Error GameSingleton::_load_goods(String const& defines_path, String const& icons_dir_path) { - Error err = _parse_json_dictionary_file("good", defines_path, "good_", - [this](String const& identifier, Variant const& entry) -> Error { - return _parse_good_entry(identifier, entry); - }); - game_manager.good_manager.lock_goods(); - for (Good const& good : game_manager.good_manager.get_goods()) { - const String path = icons_dir_path + String { "/" } + std_to_godot_string(good.get_identifier()) + ".png"; - const Ref image = load_godot_image(path); - if (image.is_null()) { - UtilityFunctions::push_error("Failed to load good icon image: ", path); - err = FAILED; - continue; - } - const Ref tex = ImageTexture::create_from_image(image); - if (tex.is_null()) { - UtilityFunctions::push_error("Failed to generate good icon texture: ", path); - err = FAILED; - continue; - } - good_icons[std_to_godot_string(good.get_identifier())] = tex; - } - return err; -} - -StringName const& GameSingleton::get_province_identifier_file_key() { - static const StringName key = "province_identifiers"; - return key; -} -StringName const& GameSingleton::get_water_province_file_key() { - static const StringName key = "water_provinces"; - return key; -} -StringName const& GameSingleton::get_region_file_key() { - static const StringName key = "regions"; - return key; -} -StringName const& GameSingleton::get_terrain_variant_file_key() { - static const StringName key = "terrain_variants"; - return key; -} -StringName const& GameSingleton::get_terrain_texture_dir_key() { - static const StringName key = "terrain_textures"; - return key; -} -StringName const& GameSingleton::get_province_image_file_key() { - static const StringName key = "province_image"; - return key; -} -StringName const& GameSingleton::get_terrain_image_file_key() { - static const StringName key = "terrain_image"; - return key; -} -StringName const& GameSingleton::get_goods_file_key() { - static const StringName key = "goods"; - return key; -} -StringName const& GameSingleton::get_good_icons_dir_key() { - static const StringName key = "good_icons"; - return key; -} - -Error GameSingleton::load_defines(Dictionary const& file_dict) { - Error err = OK; - if (_load_province_identifier_file(file_dict.get(get_province_identifier_file_key(), "")) != OK) { - UtilityFunctions::push_error("Failed to load province identifiers!"); - err = FAILED; - } - if (_load_water_province_file(file_dict.get(get_water_province_file_key(), "")) != OK) { - UtilityFunctions::push_error("Failed to load water provinces!"); - err = FAILED; - } - if (_load_region_file(file_dict.get(get_region_file_key(), "")) != OK) { - UtilityFunctions::push_error("Failed to load regions!"); - err = FAILED; - } - if (_load_terrain_variants(file_dict.get(get_terrain_variant_file_key(), ""), - file_dict.get(get_terrain_texture_dir_key(), "")) != OK) { - UtilityFunctions::push_error("Failed to load terrain variants!"); - err = FAILED; - } - if (_load_map_images(file_dict.get(get_province_image_file_key(), ""), file_dict.get(get_terrain_image_file_key(), "")) != OK) { - UtilityFunctions::push_error("Failed to load map images!"); - err = FAILED; - } - if (_load_goods(file_dict.get(get_goods_file_key(), ""), file_dict.get(get_good_icons_dir_key(), "")) != OK) { - UtilityFunctions::push_error("Failed to load goods!"); - err = FAILED; - } - if (_load_hardcoded_defines() != OK) { - UtilityFunctions::push_error("Failed to hardcoded defines!"); - err = FAILED; - } - return err; -} diff --git a/extension/src/Utilities.cpp b/extension/src/Utilities.cpp index f09eae0..4ca6855 100644 --- a/extension/src/Utilities.cpp +++ b/extension/src/Utilities.cpp @@ -19,7 +19,7 @@ Ref OpenVic::load_godot_image(String const& path) { // Get the polar coordinates of a pixel relative to the center static Vector2 getPolar(Vector2 UVin, Vector2 center) { - Vector2 relcoord = (UVin-center); + Vector2 relcoord = (UVin - center); float dist = relcoord.length(); float theta = std::numbers::pi / 2 + atan2(relcoord.y, relcoord.x); if (theta < 0.0f) theta += std::numbers::pi * 2; @@ -27,11 +27,11 @@ static Vector2 getPolar(Vector2 UVin, Vector2 center) { } // From thebookofshaders, returns a gradient falloff -static inline float parabola(float base, float x, float k){ +static inline float parabola(float base, float x, float k) { return powf(base * x * (1.0 - x), k); } -static inline float parabola_shadow(float base, float x){ +static inline float parabola_shadow(float base, float x) { return base * x * x; } @@ -57,9 +57,9 @@ static Color pie_chart_fragment(Vector2 UV, float radius, Array const& stopAngle return { trim_colour, 1.0 }; } // Interior - else if (dist <= radius-trim_size) { + else if (dist <= radius - trim_size) { Color col { 1.0f, 0.0f, 0.0f }; - for (int i = 0; i < stopAngles.size(); i++){ + for (int i = 0; i < stopAngles.size(); i++) { if (theta <= float(stopAngles[i])) { col = colours[i]; break; @@ -73,7 +73,7 @@ static Color pie_chart_fragment(Vector2 UV, float radius, Array const& stopAngle return { trim_colour, 1.0 }; } // Outside the circle - else{ + else { return { 0.1, 0.1, 0.1, shadow_gradient }; } } diff --git a/extension/src/Utilities.hpp b/extension/src/Utilities.hpp index e8796e9..fedaa6b 100644 --- a/extension/src/Utilities.hpp +++ b/extension/src/Utilities.hpp @@ -2,7 +2,7 @@ #include -#include "openvic/Types.hpp" +#include "openvic/types/Colour.hpp" #define ERR(x) ((x) == SUCCESS ? OK : FAILED) diff --git a/game/src/Game/Autoload/GameLoader.gd b/game/src/Game/Autoload/GameLoader.gd index 1720e3c..8c14c7e 100644 --- a/game/src/Game/Autoload/GameLoader.gd +++ b/game/src/Game/Autoload/GameLoader.gd @@ -1,17 +1,5 @@ extends Node -var define_filepaths_dict : Dictionary = { - GameSingleton.get_province_identifier_file_key(): "res://common/map/provinces.json", - GameSingleton.get_water_province_file_key(): "res://common/map/water.json", - GameSingleton.get_region_file_key(): "res://common/map/regions.json", - GameSingleton.get_terrain_variant_file_key(): "res://common/map/terrain.json", - GameSingleton.get_terrain_texture_dir_key(): "res://art/terrain/", - GameSingleton.get_province_image_file_key(): "res://common/map/provinces.png", - GameSingleton.get_terrain_image_file_key(): "res://common/map/terrain.png", - GameSingleton.get_goods_file_key(): "res://common/goods.json", - GameSingleton.get_good_icons_dir_key(): "res://art/economy/goods" -} - var ShaderManager : ShaderManagerClass func _init(): diff --git a/game/src/Game/GameStart.gd b/game/src/Game/GameStart.gd index 723086e..a5524d6 100644 --- a/game/src/Game/GameStart.gd +++ b/game/src/Game/GameStart.gd @@ -36,7 +36,17 @@ func _initialize_game() -> void: # into the mod's dir for a temporary fix) # Usage: OpenVic --compatibility-mode - var compatibility_mode_path : String = ArgumentParser.get_argument(&"compatibility-mode") + 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] + + # Example for adding mod paths + #compatibility_mode_paths.push_back("C:/Program Files (x86)/Steam/steamapps/common/Victoria 2/mod/TGC") var start := Time.get_ticks_usec() @@ -49,13 +59,8 @@ func _initialize_game() -> void: # TODO: Loading takes way too long to keep the LoadingScreen at 50% # Should either split this up or seperately multithread the compatibility mode loader # Or both and emit a signal that allows us to add percentages to the LoadingScreen - if compatibility_mode_path: - if GameSingleton.load_defines_compatibility_mode(compatibility_mode_path) != OK: - push_error("Errors loading game defines!") - else: - GameLoader.define_filepaths_dict.make_read_only() - if GameSingleton.load_defines(GameLoader.define_filepaths_dict) != OK: - push_error("Errors loading game defines!") + if GameSingleton.load_defines_compatibility_mode(compatibility_mode_paths) != OK: + push_error("Errors loading game defines!") loading_screen.try_update_loading_screen(100) var end := Time.get_ticks_usec() -- cgit v1.2.3-56-ga3b1