From e50c67eb1aaa54f5fb31425f81616bea4e6b880a Mon Sep 17 00:00:00 2001 From: hop311 Date: Thu, 12 Oct 2023 20:19:00 +0100 Subject: Lots of accumulated changes --- src/openvic-simulation/map/Map.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/openvic-simulation/map/Map.cpp') diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 386e7be..8362ff4 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -78,11 +78,16 @@ bool Map::set_water_province(std::string_view identifier) { } bool Map::set_water_province_list(std::vector const& list) { + if (water_provinces.is_locked()) { + Logger::error("The map's water provinces have already been locked!"); + return false; + } bool ret = true; water_provinces.reserve(water_provinces.size() + list.size()); for (std::string_view const& identifier : list) { ret &= set_water_province(identifier); } + lock_water_provinces(); return ret; } -- cgit v1.2.3-56-ga3b1 From 6b3d2315225468e03bef30e942263fe9b8fc06fa Mon Sep 17 00:00:00 2001 From: hop311 Date: Thu, 12 Oct 2023 23:05:49 +0100 Subject: Further cleanup and rearrangement --- deps/lexy-vdf | 2 +- deps/openvic-dataloader | 2 +- scripts | 2 +- src/openvic-simulation/GameManager.cpp | 92 +----- src/openvic-simulation/GameManager.hpp | 51 +--- src/openvic-simulation/Modifier.cpp | 14 +- src/openvic-simulation/Modifier.hpp | 32 +- src/openvic-simulation/dataloader/Dataloader.cpp | 59 ++-- src/openvic-simulation/dataloader/Dataloader.hpp | 1 + src/openvic-simulation/economy/Building.cpp | 292 ++++++++++++++++++ src/openvic-simulation/economy/Building.hpp | 174 +++++++++++ src/openvic-simulation/economy/EconomyManager.hpp | 26 ++ src/openvic-simulation/economy/ProductionType.cpp | 4 +- src/openvic-simulation/economy/ProductionType.hpp | 4 +- src/openvic-simulation/map/Building.cpp | 292 ------------------ src/openvic-simulation/map/Building.hpp | 174 ----------- src/openvic-simulation/map/Map.cpp | 2 +- src/openvic-simulation/map/Map.hpp | 2 +- src/openvic-simulation/map/Province.hpp | 3 +- .../military/MilitaryManager.hpp | 12 + src/openvic-simulation/military/Unit.cpp | 338 +++++++++++++++++++++ src/openvic-simulation/military/Unit.hpp | 171 +++++++++++ src/openvic-simulation/politics/Government.hpp | 2 +- .../politics/PoliticsManager.hpp | 22 ++ .../testing/test_scripts/A_002_economy_tests.cpp | 2 +- .../types/IdentifierRegistry.hpp | 12 +- src/openvic-simulation/units/Unit.cpp | 338 --------------------- src/openvic-simulation/units/Unit.hpp | 171 ----------- 28 files changed, 1140 insertions(+), 1156 deletions(-) create mode 100644 src/openvic-simulation/economy/Building.cpp create mode 100644 src/openvic-simulation/economy/Building.hpp create mode 100644 src/openvic-simulation/economy/EconomyManager.hpp delete mode 100644 src/openvic-simulation/map/Building.cpp delete mode 100644 src/openvic-simulation/map/Building.hpp create mode 100644 src/openvic-simulation/military/MilitaryManager.hpp create mode 100644 src/openvic-simulation/military/Unit.cpp create mode 100644 src/openvic-simulation/military/Unit.hpp create mode 100644 src/openvic-simulation/politics/PoliticsManager.hpp delete mode 100644 src/openvic-simulation/units/Unit.cpp delete mode 100644 src/openvic-simulation/units/Unit.hpp (limited to 'src/openvic-simulation/map/Map.cpp') diff --git a/deps/lexy-vdf b/deps/lexy-vdf index eeb1028..96c316c 160000 --- a/deps/lexy-vdf +++ b/deps/lexy-vdf @@ -1 +1 @@ -Subproject commit eeb10288f707cdc87981b43edc441fc833b6cff1 +Subproject commit 96c316c52b45e2fa78a9562938f931f972474518 diff --git a/deps/openvic-dataloader b/deps/openvic-dataloader index 4009e1d..92c67f3 160000 --- a/deps/openvic-dataloader +++ b/deps/openvic-dataloader @@ -1 +1 @@ -Subproject commit 4009e1d576ad177aff59c8fce0339963303fc6e5 +Subproject commit 92c67f318114771999a73b05659023b59b103e06 diff --git a/scripts b/scripts index 3060e56..accb77a 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 3060e56388ac00d90deb6693ec19d47bad52deb2 +Subproject commit accb77a0af7d200818d4521b12492c078e4b7f42 diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp index 69adaac..1c4efb3 100644 --- a/src/openvic-simulation/GameManager.cpp +++ b/src/openvic-simulation/GameManager.cpp @@ -6,94 +6,6 @@ GameManager::GameManager(state_updated_func_t state_updated_callback) : clock { [this]() { tick(); }, [this]() { update_state(); } }, state_updated { state_updated_callback } {} -Map& GameManager::get_map() { - return map; -} - -Map const& GameManager::get_map() const { - return map; -} - -BuildingManager& GameManager::get_building_manager() { - return building_manager; -} - -BuildingManager const& GameManager::get_building_manager() const { - return building_manager; -} - -GoodManager& GameManager::get_good_manager() { - return good_manager; -} - -GoodManager const& GameManager::get_good_manager() const { - return good_manager; -} - -GovernmentTypeManager& GameManager::get_government_type_manager() { - return government_type_manager; -} - -GovernmentTypeManager const& GameManager::get_government_type_manager() const { - return government_type_manager; -} - -PopManager& GameManager::get_pop_manager() { - return pop_manager; -} - -PopManager const& GameManager::get_pop_manager() const { - return pop_manager; -} - -IdeologyManager& GameManager::get_ideology_manager() { - return ideology_manager; -} - -IdeologyManager const& GameManager::get_ideology_manager() const { - return ideology_manager; -} - -IssueManager& GameManager::get_issue_manager() { - return issue_manager; -} - -IssueManager const& GameManager::get_issue_manager() const { - return issue_manager; -} - -ProductionTypeManager& GameManager::get_production_type_manager() { - return production_type_manager; -} - -ProductionTypeManager const& GameManager::get_production_type_manager() const { - return production_type_manager; -} - -UnitManager& GameManager::get_unit_manager() { - return unit_manager; -} - -UnitManager const& GameManager::get_unit_manager() const { - return unit_manager; -} - -ModifierManager& GameManager::get_modifier_manager() { - return modifier_manager; -} - -ModifierManager const& GameManager::get_modifier_manager() const { - return modifier_manager; -} - -GameAdvancementHook& GameManager::get_clock() { - return clock; -} - -GameAdvancementHook const& GameManager::get_clock() const { - return clock; -} - void GameManager::set_needs_update() { needs_update = true; } @@ -120,8 +32,8 @@ bool GameManager::setup() { session_start = time(nullptr); clock.reset(); today = { 1836 }; - good_manager.reset_to_defaults(); - bool ret = map.setup(good_manager, building_manager, pop_manager); + economy_manager.get_good_manager().reset_to_defaults(); + bool ret = map.setup(economy_manager.get_building_manager(), pop_manager); set_needs_update(); return ret; } diff --git a/src/openvic-simulation/GameManager.hpp b/src/openvic-simulation/GameManager.hpp index 8982e21..6e6c0b8 100644 --- a/src/openvic-simulation/GameManager.hpp +++ b/src/openvic-simulation/GameManager.hpp @@ -1,13 +1,11 @@ #pragma once #include "openvic-simulation/GameAdvancementHook.hpp" -#include "openvic-simulation/economy/Good.hpp" -#include "openvic-simulation/politics/Government.hpp" -#include "openvic-simulation/economy/ProductionType.hpp" +#include "openvic-simulation/Modifier.hpp" +#include "openvic-simulation/economy/EconomyManager.hpp" #include "openvic-simulation/map/Map.hpp" -#include "openvic-simulation/politics/Ideology.hpp" -#include "openvic-simulation/politics/Issue.hpp" -#include "openvic-simulation/units/Unit.hpp" +#include "openvic-simulation/military/MilitaryManager.hpp" +#include "openvic-simulation/politics/PoliticsManager.hpp" namespace OpenVic { struct GameManager { @@ -15,15 +13,11 @@ namespace OpenVic { private: Map map; - BuildingManager building_manager; - GoodManager good_manager; - GovernmentTypeManager government_type_manager; - PopManager pop_manager; - IdeologyManager ideology_manager; - IssueManager issue_manager; - ProductionTypeManager production_type_manager; - UnitManager unit_manager; + EconomyManager economy_manager; + MilitaryManager military_manager; ModifierManager modifier_manager; + PoliticsManager politics_manager; + PopManager pop_manager; GameAdvancementHook clock; time_t session_start; /* SS-54, as well as allowing time-tracking */ @@ -38,28 +32,13 @@ namespace OpenVic { public: GameManager(state_updated_func_t state_updated_callback); - Map& get_map(); - Map const& get_map() const; - BuildingManager& get_building_manager(); - BuildingManager const& get_building_manager() const; - GoodManager& get_good_manager(); - GoodManager const& get_good_manager() const; - GovernmentTypeManager& get_government_type_manager(); - GovernmentTypeManager const& get_government_type_manager() const; - PopManager& get_pop_manager(); - PopManager const& get_pop_manager() const; - IdeologyManager& get_ideology_manager(); - IdeologyManager const& get_ideology_manager() const; - IssueManager& get_issue_manager(); - IssueManager const& get_issue_manager() const; - ProductionTypeManager& get_production_type_manager(); - ProductionTypeManager const& get_production_type_manager() const; - UnitManager& get_unit_manager(); - UnitManager const& get_unit_manager() const; - ModifierManager& get_modifier_manager(); - ModifierManager const& get_modifier_manager() const; - GameAdvancementHook& get_clock(); - GameAdvancementHook const& get_clock() const; + REF_GETTERS(map) + REF_GETTERS(economy_manager) + REF_GETTERS(military_manager) + REF_GETTERS(modifier_manager) + REF_GETTERS(politics_manager) + REF_GETTERS(pop_manager) + REF_GETTERS(clock) bool setup(); diff --git a/src/openvic-simulation/Modifier.cpp b/src/openvic-simulation/Modifier.cpp index 5aadd79..4e5b860 100644 --- a/src/openvic-simulation/Modifier.cpp +++ b/src/openvic-simulation/Modifier.cpp @@ -131,7 +131,7 @@ bool ModifierManager::setup_modifier_effects() { return ret; } -node_callback_t ModifierManager::expect_modifier_value(callback_t modifier_callback, key_value_callback_t default_callback) const { +node_callback_t ModifierManager::expect_modifier_value_and_default(callback_t modifier_callback, key_value_callback_t default_callback) const { return [this, modifier_callback, default_callback](ast::NodeCPtr root) -> bool { ModifierValue modifier; bool ret = expect_dictionary( @@ -154,9 +154,13 @@ node_callback_t ModifierManager::expect_modifier_value(callback_t modifier_callback, key_map_t&& key_map) const { +node_callback_t ModifierManager::expect_modifier_value(callback_t modifier_callback) const { + return expect_modifier_value_and_default(modifier_callback, key_value_invalid_callback); +} + +node_callback_t ModifierManager::expect_modifier_value_and_key_map_and_default(callback_t modifier_callback, key_value_callback_t default_callback, key_map_t&& key_map) const { return [this, modifier_callback, key_map = std::move(key_map)](ast::NodeCPtr node) mutable -> bool { - bool ret = expect_modifier_value( + bool ret = expect_modifier_value_and_default( modifier_callback, dictionary_keys_callback(key_map, key_value_invalid_callback) )(node); ret &= check_key_map_counts(key_map); @@ -164,6 +168,10 @@ node_callback_t ModifierManager::_expect_modifier_value_and_keys(callback_t modifier_callback, key_map_t&& key_map) const { + return expect_modifier_value_and_key_map_and_default(modifier_callback, key_value_invalid_callback, std::move(key_map)); +} + namespace OpenVic { //so the compiler shuts up std::ostream& operator<<(std::ostream& stream, ModifierValue const& value) { for (ModifierValue::effect_map_t::value_type const& effect : value.values) { diff --git a/src/openvic-simulation/Modifier.hpp b/src/openvic-simulation/Modifier.hpp index 0c4e636..2e1b03a 100644 --- a/src/openvic-simulation/Modifier.hpp +++ b/src/openvic-simulation/Modifier.hpp @@ -92,17 +92,6 @@ namespace OpenVic { IdentifierRegistry modifier_effects; IdentifierRegistry modifiers; - NodeTools::node_callback_t _expect_modifier_value_and_keys(NodeTools::callback_t modifier_callback, NodeTools::key_map_t&& key_map) const; - - template - NodeTools::node_callback_t _expect_modifier_value_and_keys( - NodeTools::callback_t modifier_callback, NodeTools::key_map_t&& key_map, - std::string_view key, NodeTools::dictionary_entry_t::expected_count_t expected_count, NodeTools::node_callback_t callback, - Args... args) const { - NodeTools::add_key_map_entry(key_map, key, expected_count, callback); - return _expect_modifier_value_and_keys(modifier_callback, std::move(key_map), args...); - } - public: ModifierManager(); @@ -114,11 +103,28 @@ namespace OpenVic { bool setup_modifier_effects(); - NodeTools::node_callback_t expect_modifier_value(NodeTools::callback_t modifier_callback, NodeTools::key_value_callback_t default_callback) const; + NodeTools::node_callback_t expect_modifier_value_and_default(NodeTools::callback_t modifier_callback, NodeTools::key_value_callback_t default_callback) const; + NodeTools::node_callback_t expect_modifier_value(NodeTools::callback_t modifier_callback) const; + + NodeTools::node_callback_t expect_modifier_value_and_key_map_and_default(NodeTools::callback_t modifier_callback, NodeTools::key_value_callback_t default_callback, NodeTools::key_map_t&& key_map) const; + NodeTools::node_callback_t expect_modifier_value_and_key_map(NodeTools::callback_t modifier_callback, NodeTools::key_map_t&& key_map) const; + template + NodeTools::node_callback_t expect_modifier_value_and_key_map_and_default( + NodeTools::callback_t modifier_callback, NodeTools::key_value_callback_t default_callback, NodeTools::key_map_t&& key_map, + std::string_view key, NodeTools::dictionary_entry_t::expected_count_t expected_count, NodeTools::node_callback_t callback, + Args... args) const { + NodeTools::add_key_map_entry(key_map, key, expected_count, callback); + return expect_modifier_value_and_key_map_and_default(modifier_callback, default_callback, std::move(key_map), args...); + } + + template + NodeTools::node_callback_t expect_modifier_value_and_keys_and_default(NodeTools::callback_t modifier_callback, NodeTools::key_value_callback_t default_callback, Args... args) const { + return expect_modifier_value_and_key_map_and_default(modifier_callback, default_callback, {}, args...); + } template NodeTools::node_callback_t expect_modifier_value_and_keys(NodeTools::callback_t modifier_callback, Args... args) const { - return _expect_modifier_value_and_keys(modifier_callback, {}, args...); + return expect_modifier_value_and_key_map_and_default(modifier_callback, NodeTools::key_value_invalid_callback, {}, args...); } }; } diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index bd634ce..718218f 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -436,6 +436,14 @@ v2script::Parser Dataloader::parse_defines(fs::path const& path) { return _run_ovdl_parser(path); } +static bool _lua_parse(v2script::Parser& parser) { + return parser.lua_defines_parse(); +} + +static ovdl::v2script::Parser parse_lua_defines(fs::path const& path) { + return _run_ovdl_parser(path); +} + static bool _csv_parse(csv::Windows1252Parser& parser) { return parser.parse_csv(); } @@ -527,17 +535,20 @@ bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_di Logger::error("Failed to load map default file!"); } - if (!map.load_province_definitions(parse_csv(lookup_file(map_directory / definitions)).get_lines())) { + if (!map.load_province_definitions( + parse_csv(lookup_file(map_directory / definitions)).get_lines())) { Logger::error("Failed to load province definitions file!"); ret = false; } - if (!map.load_province_positions(game_manager.get_building_manager(), parse_defines(lookup_file(map_directory / positions)).get_file_node())) { + if (!map.load_province_positions( + game_manager.get_economy_manager().get_building_manager(), parse_defines(lookup_file(map_directory / positions)).get_file_node())) { Logger::error("Failed to load province positions file!"); ret = false; } - if (!map.load_region_file(parse_defines(lookup_file(map_directory / region)).get_file_node())) { + if (!map.load_region_file( + parse_defines(lookup_file(map_directory / region)).get_file_node())) { Logger::error("Failed to load region file!"); ret = false; } @@ -547,17 +558,22 @@ bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_di ret = false; } - if (!map.get_terrain_type_manager().load_terrain_types(game_manager.get_modifier_manager(), parse_defines(lookup_file(map_directory / terrain_definition)).get_file_node())) { + if (!map.get_terrain_type_manager().load_terrain_types( + game_manager.get_modifier_manager(), + parse_defines(lookup_file(map_directory / terrain_definition)).get_file_node())) { Logger::error("Failed to load terrain types!"); ret = false; } - if (!map.load_map_images(lookup_file(map_directory / provinces), lookup_file(map_directory / terrain), false)) { + if (!map.load_map_images( + lookup_file(map_directory / provinces), + lookup_file(map_directory / terrain), false)) { Logger::error("Failed to load map images!"); ret = false; } - if (!map.generate_and_load_province_adjacencies(parse_csv(lookup_file(map_directory / adjacencies)).get_lines())) { + if (!map.generate_and_load_province_adjacencies( + parse_csv(lookup_file(map_directory / adjacencies)).get_lines())) { Logger::error("Failed to generate and load province adjacencies!"); ret = false; } @@ -586,7 +602,8 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to set up modifier effects!"); ret = false; } - if (!game_manager.get_good_manager().load_goods_file(parse_defines(lookup_file(goods_file)).get_file_node())) { + if (!game_manager.get_economy_manager().get_good_manager().load_goods_file( + parse_defines(lookup_file(goods_file)).get_file_node())) { Logger::error("Failed to load goods!"); ret = false; } @@ -594,40 +611,43 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load pop types!"); ret = false; } - if (!game_manager.get_pop_manager().get_culture_manager().load_graphical_culture_type_file(parse_defines(lookup_file(graphical_culture_type_file)).get_file_node())) { + if (!game_manager.get_pop_manager().get_culture_manager().load_graphical_culture_type_file( + parse_defines(lookup_file(graphical_culture_type_file)).get_file_node())) { Logger::error("Failed to load graphical culture types!"); ret = false; } - if (!game_manager.get_pop_manager().get_culture_manager().load_culture_file(parse_defines(lookup_file(culture_file)).get_file_node())) { + if (!game_manager.get_pop_manager().get_culture_manager().load_culture_file( + parse_defines(lookup_file(culture_file)).get_file_node())) { Logger::error("Failed to load cultures!"); ret = false; } - if (!game_manager.get_pop_manager().get_religion_manager().load_religion_file(parse_defines(lookup_file(religion_file)).get_file_node())) { + if (!game_manager.get_pop_manager().get_religion_manager().load_religion_file( + parse_defines(lookup_file(religion_file)).get_file_node())) { Logger::error("Failed to load religions!"); ret = false; } - if (!game_manager.get_ideology_manager().load_ideology_file(parse_defines(lookup_file(ideology_file)).get_file_node())) { + if (!game_manager.get_politics_manager().get_ideology_manager().load_ideology_file( + parse_defines(lookup_file(ideology_file)).get_file_node())) { Logger::error("Failed to load ideologies!"); ret = false; } - if (!game_manager.get_government_type_manager().load_government_types_file(game_manager.get_ideology_manager(), parse_defines(lookup_file(governments_file)).get_file_node())) { + if (!game_manager.get_politics_manager().load_government_types_file( + parse_defines(lookup_file(governments_file)).get_file_node())) { Logger::error("Failed to load government types!"); ret = false; } - if (!game_manager.get_issue_manager().load_issues_file(parse_defines(lookup_file(issues_file)).get_file_node())) { + if (!game_manager.get_politics_manager().get_issue_manager().load_issues_file( + parse_defines(lookup_file(issues_file)).get_file_node())) { Logger::error("Failed to load issues!"); ret = false; } - if (!game_manager.get_production_type_manager().load_production_types_file( - game_manager.get_good_manager(), + if (!game_manager.get_economy_manager().load_production_types_file( game_manager.get_pop_manager(), parse_defines(lookup_file(production_types_file)).get_file_node())) { Logger::error("Failed to load production types!"); ret = false; } - if (!game_manager.get_building_manager().load_buildings_file( - game_manager.get_good_manager(), - game_manager.get_production_type_manager(), + if (!game_manager.get_economy_manager().load_buildings_file( game_manager.get_modifier_manager(), parse_defines(lookup_file(buildings_file)).get_file_node())) { Logger::error("Failed to load buildings!"); @@ -637,7 +657,8 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load map!"); ret = false; } - if (!_load_units(game_manager.get_unit_manager(), game_manager.get_good_manager(), units_directory)) { + if (!_load_units(game_manager.get_military_manager().get_unit_manager(), + game_manager.get_economy_manager().get_good_manager(), units_directory)) { Logger::error("Failed to load units!"); ret = false; } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index 30eed6e..c4cd7c7 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -29,6 +29,7 @@ namespace OpenVic { public: static ovdl::v2script::Parser parse_defines(fs::path const& path); + static ovdl::v2script::Parser parse_lua_defines(fs::path const& path); static ovdl::csv::Windows1252Parser parse_csv(fs::path const& path); Dataloader() = default; diff --git a/src/openvic-simulation/economy/Building.cpp b/src/openvic-simulation/economy/Building.cpp new file mode 100644 index 0000000..d27c91a --- /dev/null +++ b/src/openvic-simulation/economy/Building.cpp @@ -0,0 +1,292 @@ +#include "Building.hpp" + +#include "openvic-simulation/map/Province.hpp" //imported here so the hpp doesn't get circular imports + +using namespace OpenVic; +using namespace OpenVic::NodeTools; + +Building::Building(std::string_view identifier, BuildingType const& type, ARGS) : HasIdentifier { identifier }, ModifierValue { std::move(modifiers) }, type { type }, + on_completion { on_completion }, completion_size { completion_size }, max_level { max_level }, goods_cost { goods_cost }, cost { cost }, build_time { build_time }, + visibility { visibility }, on_map { on_map }, default_enabled { default_enabled }, production_type { production_type }, pop_build_factory { pop_build_factory }, + strategic_factory { strategic_factory }, advanced_factory { advanced_factory }, fort_level { fort_level }, naval_capacity { naval_capacity }, + colonial_points { colonial_points }, in_province { in_province }, one_per_state { one_per_state }, colonial_range { colonial_range }, + infrastructure { infrastructure }, movement_cost { movement_cost }, local_ship_build { local_ship_build }, spawn_railway_track { spawn_railway_track }, + sail { sail }, steam { steam }, capital { capital }, port { port } {} + +BuildingType const& Building::get_type() const { + return type; +} + +std::string const& Building::get_on_completion() const { + return on_completion; +} + +fixed_point_t Building::get_completion_size() const { + return completion_size; +} + +Building::level_t Building::get_max_level() const { + return max_level; +} + +std::map const& Building::get_goods_cost() const { + return goods_cost; +} + +fixed_point_t Building::get_cost() const { + return cost; +} + +Timespan Building::get_build_time() const { + return build_time; +} + +bool Building::has_visibility() const { + return visibility; +} + +bool Building::is_on_map() const { + return on_map; +} + +bool Building::is_default_enabled() const { + return default_enabled; +} + +ProductionType const* Building::get_production_type() const { + return production_type; +} + +bool Building::is_pop_built_factory() const { + return pop_build_factory; +} + +bool Building::is_strategic_factory() const { + return strategic_factory; +} + +bool Building::is_advanced_factory() const { + return advanced_factory; +} + +Building::level_t Building::get_fort_level() const { + return fort_level; +} + +uint64_t Building::get_naval_capacity() const { + return naval_capacity; +} + +std::vector const& Building::get_colonial_points() const { + return colonial_points; +} + +bool Building::is_in_province() const { + return in_province; +} + +bool Building::is_one_per_state() const { + return one_per_state; +} + +fixed_point_t Building::get_colonial_range() const { + return colonial_range; +} + +fixed_point_t Building::get_infrastructure() const { + return infrastructure; +} + +fixed_point_t Building::get_movement_cost() const { + return movement_cost; +} + +bool Building::spawned_railway_track() const { + return spawn_railway_track; +} + +BuildingType::BuildingType(std::string_view new_identifier) : HasIdentifier { new_identifier } {} + +BuildingInstance::BuildingInstance(Building const& building) : HasIdentifier { building.get_identifier() }, building { building } {} + +Building const& BuildingInstance::get_building() const { + return building; +} + +bool BuildingInstance::_can_expand() const { + return level < building.get_max_level(); +} + +BuildingInstance::level_t BuildingInstance::get_current_level() const { + return level; +} + +ExpansionState BuildingInstance::get_expansion_state() const { + return expansion_state; +} + +Date const& BuildingInstance::get_start_date() const { + return start; +} + +Date const& BuildingInstance::get_end_date() const { + return end; +} + +float BuildingInstance::get_expansion_progress() const { + return expansion_progress; +} + +bool BuildingInstance::expand() { + if (expansion_state == ExpansionState::CanExpand) { + expansion_state = ExpansionState::Preparing; + expansion_progress = 0.0f; + return true; + } + return false; +} + +/* REQUIREMENTS: + * MAP-71, MAP-74, MAP-77 + */ +void BuildingInstance::update_state(Date const& today) { + switch (expansion_state) { + case ExpansionState::Preparing: + start = today; + end = start + building.get_build_time(); + break; + case ExpansionState::Expanding: + expansion_progress = static_cast(today - start) / static_cast(end - start); + break; + default: expansion_state = _can_expand() ? ExpansionState::CanExpand : ExpansionState::CannotExpand; + } +} + +void BuildingInstance::tick(Date const& today) { + if (expansion_state == ExpansionState::Preparing) { + expansion_state = ExpansionState::Expanding; + } + if (expansion_state == ExpansionState::Expanding) { + if (end <= today) { + level++; + expansion_state = ExpansionState::CannotExpand; + } + } +} + +BuildingManager::BuildingManager() : building_types { "building types" }, buildings { "buildings" } {} + +bool BuildingManager::add_building_type(std::string_view identifier) { + if (identifier.empty()) { + Logger::error("Invalid building type identifier - empty!"); + return false; + } + return building_types.add_item({ identifier }); +} + +bool BuildingManager::add_building(std::string_view identifier, BuildingType const* type, ARGS) { + if (identifier.empty()) { + Logger::error("Invalid building identifier - empty!"); + return false; + } + if (type == nullptr) { + Logger::error("Invalid building type for ", identifier, ": null"); + return false; + } + + return buildings.add_item({ + identifier, *type, on_completion, completion_size, max_level, goods_cost, cost, build_time, visibility, on_map, default_enabled, + production_type, pop_build_factory, strategic_factory, advanced_factory, fort_level, naval_capacity, colonial_points, in_province, one_per_state, + colonial_range, infrastructure, movement_cost, local_ship_build, spawn_railway_track, sail, steam, capital, port, std::move(modifiers) + }); +} + +bool BuildingManager::load_buildings_file(GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root) { + bool ret = expect_dictionary_reserve_length(buildings, [this](std::string_view, ast::NodeCPtr value) -> bool { + return expect_key("type", expect_identifier( + [this](std::string_view identifier) -> bool { + if (!building_types.has_identifier(identifier)) { + return building_types.add_item({ identifier }); + } + return true; + } + ))(value); + })(root); + lock_building_types(); + + ret &= expect_dictionary([this, &good_manager, &production_type_manager, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool { + BuildingType const* type = nullptr; + ProductionType const* production_type = nullptr; + std::string_view on_completion; + fixed_point_t completion_size = 0, cost = 0, infrastructure = 0, movement_cost = 0, colonial_range = 0, local_ship_build = 0; + Building::level_t max_level = 0, fort_level = 0; + std::map goods_cost; + Timespan build_time; + bool visibility = false, on_map = false, default_enabled = false, pop_build_factory = false, strategic_factory = false, advanced_factory = false; + bool in_province = false, one_per_state = false, spawn_railway_track = false, sail = false, steam = false, capital = false, port = false; + uint64_t naval_capacity = 0; + std::vector colonial_points; + ModifierValue modifiers; + + bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(modifiers), + "type", ONE_EXACTLY, expect_identifier(expect_building_type_identifier(assign_variable_callback_pointer(type))), + "on_completion", ZERO_OR_ONE, expect_identifier(assign_variable_callback(on_completion)), + "completion_size", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(completion_size)), + "max_level", ONE_EXACTLY, expect_uint(assign_variable_callback(max_level)), + "goods_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(goods_cost)), + "cost", ZERO_OR_MORE, expect_fixed_point(assign_variable_callback(cost)), + "time", ONE_EXACTLY, expect_days(assign_variable_callback(build_time)), + "visibility", ONE_EXACTLY, expect_bool(assign_variable_callback(visibility)), + "onmap", ONE_EXACTLY, expect_bool(assign_variable_callback(on_map)), + "default_enabled", ZERO_OR_ONE, expect_bool(assign_variable_callback(default_enabled)), + "production_type", ZERO_OR_ONE, expect_identifier(production_type_manager.expect_production_type_identifier(assign_variable_callback_pointer(production_type))), + "pop_build_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(pop_build_factory)), + "strategic_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(strategic_factory)), + "advanced_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(advanced_factory)), + "fort_level", ZERO_OR_ONE, expect_uint(assign_variable_callback(fort_level)), + "naval_capacity", ZERO_OR_ONE, expect_uint(assign_variable_callback(naval_capacity)), + "colonial_points", ZERO_OR_ONE, expect_list(expect_fixed_point([&colonial_points](fixed_point_t points) -> bool { + colonial_points.push_back(points); + return true; + })), + "province", ZERO_OR_ONE, expect_bool(assign_variable_callback(in_province)), + "one_per_state", ZERO_OR_ONE, expect_bool(assign_variable_callback(one_per_state)), + "colonial_range", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(colonial_range)), + "infrastructure", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(infrastructure)), + "movement_cost", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(movement_cost)), + "local_ship_build", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(local_ship_build)), + "spawn_railway_track", ZERO_OR_ONE, expect_bool(assign_variable_callback(spawn_railway_track)), + "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(sail)), + "steam", ZERO_OR_ONE, expect_bool(assign_variable_callback(steam)), + "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(capital)), + "port", ZERO_OR_ONE, expect_bool(assign_variable_callback(port)) + )(value); + + ret &= add_building( + key, type, on_completion, completion_size, max_level, goods_cost, cost, build_time, visibility, on_map, default_enabled, + production_type, pop_build_factory, strategic_factory, advanced_factory, fort_level, naval_capacity, colonial_points, in_province, + one_per_state, colonial_range, infrastructure, movement_cost, local_ship_build, spawn_railway_track, sail, steam, capital, port, std::move(modifiers) + ); + + return ret; + })(root); + lock_buildings(); + + return ret; +} + +bool BuildingManager::generate_province_buildings(Province& province) const { + province.reset_buildings(); + if (!building_types.is_locked()) { + Logger::error("Cannot generate buildings until building types are locked!"); + return false; + } + bool ret = true; + if (!province.get_water()) { + for (Building const& building : buildings.get_items()) { + ret &= province.add_building({ building }); + } + } + province.lock_buildings(); + return ret; +} diff --git a/src/openvic-simulation/economy/Building.hpp b/src/openvic-simulation/economy/Building.hpp new file mode 100644 index 0000000..3f74c3d --- /dev/null +++ b/src/openvic-simulation/economy/Building.hpp @@ -0,0 +1,174 @@ +#pragma once + +#include "openvic-simulation/types/Date.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/types/IdentifierRegistry.hpp" +#include "openvic-simulation/economy/Good.hpp" +#include "openvic-simulation/economy/ProductionType.hpp" +#include "openvic-simulation/Modifier.hpp" + +#define ARGS std::string_view on_completion, fixed_point_t completion_size, level_t max_level, \ + std::map goods_cost, fixed_point_t cost, Timespan build_time, bool visibility, bool on_map, bool default_enabled, \ + ProductionType const* production_type, bool pop_build_factory, bool strategic_factory, bool advanced_factory, level_t fort_level, \ + uint64_t naval_capacity, std::vector colonial_points, bool in_province, bool one_per_state, fixed_point_t colonial_range, \ + fixed_point_t infrastructure, fixed_point_t movement_cost, fixed_point_t local_ship_build, bool spawn_railway_track, bool sail, bool steam, \ + bool capital, bool port, ModifierValue&& modifiers + +namespace OpenVic { + + struct BuildingManager; + struct BuildingType; + + /* REQUIREMENTS: + * MAP-11, MAP-72, MAP-73 + * MAP-12, MAP-75, MAP-76 + * MAP-13, MAP-78, MAP-79 + */ + struct Building : HasIdentifier, ModifierValue { + friend struct BuildingManager; + + using level_t = int16_t; + + private: + BuildingType const& type; + const std::string on_completion; //probably sound played on completion + const fixed_point_t completion_size; + const level_t max_level; + const std::map goods_cost; + const fixed_point_t cost; + const Timespan build_time; //time + const bool visibility; + const bool on_map; //onmap + + const bool default_enabled; + ProductionType const* production_type; + const bool pop_build_factory; + const bool strategic_factory; + const bool advanced_factory; + + const level_t fort_level; //probably the step-per-level + + const uint64_t naval_capacity; + const std::vector colonial_points; + const bool in_province; //province + const bool one_per_state; + const fixed_point_t colonial_range; + + const fixed_point_t infrastructure; + const fixed_point_t movement_cost; + const fixed_point_t local_ship_build; + const bool spawn_railway_track; + + const bool sail; //only in clipper shipyard + const bool steam; //only in steamer shipyard + const bool capital; //only in naval base + const bool port; //only in naval base + + Building(std::string_view identifier, BuildingType const& type, ARGS); + + public: + Building(Building&&) = default; + + BuildingType const& get_type() const; + std::string const& get_on_completion() const; + fixed_point_t get_completion_size() const; + level_t get_max_level() const; + std::map const& get_goods_cost() const; + fixed_point_t get_cost() const; + Timespan get_build_time() const; + bool has_visibility() const; + bool is_on_map() const; + + bool is_default_enabled() const; + ProductionType const* get_production_type() const; + bool is_pop_built_factory() const; + bool is_strategic_factory() const; + bool is_advanced_factory() const; + + level_t get_fort_level() const; + + uint64_t get_naval_capacity() const; + std::vector const& get_colonial_points() const; + bool is_in_province() const; + bool is_one_per_state() const; + fixed_point_t get_colonial_range() const; + + fixed_point_t get_infrastructure() const; + fixed_point_t get_movement_cost() const; + fixed_point_t get_local_ship_build() const; + bool spawned_railway_track() const; + }; + + struct BuildingType : HasIdentifier { + friend struct BuildingManager; + + private: + BuildingType(std::string_view new_identifier); + + public: + BuildingType(BuildingType&&) = default; + }; + + enum class ExpansionState { + CannotExpand, + CanExpand, + Preparing, + Expanding + }; + + struct BuildingInstance : HasIdentifier { //used in the actual game + friend struct BuildingManager; + using level_t = Building::level_t; + + private: + Building const& building; + + level_t level = 0; + ExpansionState expansion_state = ExpansionState::CannotExpand; + Date start, end; + float expansion_progress; + + bool _can_expand() const; + + BuildingInstance(Building const& building); + + public: + BuildingInstance(BuildingInstance&&) = default; + + Building const& get_building() const; + + level_t get_current_level() const; + ExpansionState get_expansion_state() const; + Date const& get_start_date() const; + Date const& get_end_date() const; + float get_expansion_progress() const; + + bool expand(); + void update_state(Date const& today); + void tick(Date const& today); + + }; + + struct Province; + + struct BuildingManager { + using level_t = Building::level_t; //this is getting ridiculous + + private: + IdentifierRegistry building_types; + IdentifierRegistry buildings; + + public: + BuildingManager(); + + bool add_building_type(std::string_view identifier); + IDENTIFIER_REGISTRY_ACCESSORS(building_type) + + bool add_building(std::string_view identifier, BuildingType const* type, ARGS); + IDENTIFIER_REGISTRY_ACCESSORS(building) + + bool load_buildings_file(GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root); + + bool generate_province_buildings(Province& province) const; + }; +} diff --git a/src/openvic-simulation/economy/EconomyManager.hpp b/src/openvic-simulation/economy/EconomyManager.hpp new file mode 100644 index 0000000..05dfc91 --- /dev/null +++ b/src/openvic-simulation/economy/EconomyManager.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "openvic-simulation/economy/Building.hpp" +#include "openvic-simulation/economy/Good.hpp" +#include "openvic-simulation/economy/ProductionType.hpp" + +namespace OpenVic { + struct EconomyManager { + private: + BuildingManager building_manager; + GoodManager good_manager; + ProductionTypeManager production_type_manager; + public: + REF_GETTERS(building_manager) + REF_GETTERS(good_manager) + REF_GETTERS(production_type_manager) + + inline bool load_production_types_file(PopManager const& pop_manager, ast::NodeCPtr root) { + return production_type_manager.load_production_types_file(good_manager, pop_manager, root); + } + + inline bool load_buildings_file(ModifierManager const& modifier_manager, ast::NodeCPtr root) { + return building_manager.load_buildings_file(good_manager, production_type_manager, modifier_manager, root); + } + }; +} diff --git a/src/openvic-simulation/economy/ProductionType.cpp b/src/openvic-simulation/economy/ProductionType.cpp index b2d94c3..01d45be 100644 --- a/src/openvic-simulation/economy/ProductionType.cpp +++ b/src/openvic-simulation/economy/ProductionType.cpp @@ -138,7 +138,7 @@ node_callback_t ProductionTypeManager::_expect_employed_pop_list(GoodManager con return false; \ } -bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS, GoodManager& good_manager) { +bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS, GoodManager const& good_manager) { if (identifier.empty()) { Logger::error("Invalid production type identifier - empty!"); return false; @@ -186,7 +186,7 @@ bool ProductionTypeManager::add_production_type(PRODUCTION_TYPE_ARGS, GoodManage "mine", ZERO_OR_ONE, expect_bool(assign_variable_callback(mine)) \ ) -bool ProductionTypeManager::load_production_types_file(GoodManager& good_manager, PopManager& pop_manager, ast::NodeCPtr root) { +bool ProductionTypeManager::load_production_types_file(GoodManager const& good_manager, PopManager const& pop_manager, ast::NodeCPtr root) { size_t expected_types = 0; // pass 1: find and store template identifiers diff --git a/src/openvic-simulation/economy/ProductionType.hpp b/src/openvic-simulation/economy/ProductionType.hpp index fdb0010..420e70e 100644 --- a/src/openvic-simulation/economy/ProductionType.hpp +++ b/src/openvic-simulation/economy/ProductionType.hpp @@ -103,9 +103,9 @@ namespace OpenVic { public: ProductionTypeManager(); - bool add_production_type(PRODUCTION_TYPE_ARGS, GoodManager& good_manager); + bool add_production_type(PRODUCTION_TYPE_ARGS, GoodManager const& good_manager); IDENTIFIER_REGISTRY_ACCESSORS(production_type) - bool load_production_types_file(GoodManager& good_manager, PopManager& pop_manager, ast::NodeCPtr root); + bool load_production_types_file(GoodManager const& good_manager, PopManager const& pop_manager, ast::NodeCPtr root); }; } \ No newline at end of file diff --git a/src/openvic-simulation/map/Building.cpp b/src/openvic-simulation/map/Building.cpp deleted file mode 100644 index d27c91a..0000000 --- a/src/openvic-simulation/map/Building.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#include "Building.hpp" - -#include "openvic-simulation/map/Province.hpp" //imported here so the hpp doesn't get circular imports - -using namespace OpenVic; -using namespace OpenVic::NodeTools; - -Building::Building(std::string_view identifier, BuildingType const& type, ARGS) : HasIdentifier { identifier }, ModifierValue { std::move(modifiers) }, type { type }, - on_completion { on_completion }, completion_size { completion_size }, max_level { max_level }, goods_cost { goods_cost }, cost { cost }, build_time { build_time }, - visibility { visibility }, on_map { on_map }, default_enabled { default_enabled }, production_type { production_type }, pop_build_factory { pop_build_factory }, - strategic_factory { strategic_factory }, advanced_factory { advanced_factory }, fort_level { fort_level }, naval_capacity { naval_capacity }, - colonial_points { colonial_points }, in_province { in_province }, one_per_state { one_per_state }, colonial_range { colonial_range }, - infrastructure { infrastructure }, movement_cost { movement_cost }, local_ship_build { local_ship_build }, spawn_railway_track { spawn_railway_track }, - sail { sail }, steam { steam }, capital { capital }, port { port } {} - -BuildingType const& Building::get_type() const { - return type; -} - -std::string const& Building::get_on_completion() const { - return on_completion; -} - -fixed_point_t Building::get_completion_size() const { - return completion_size; -} - -Building::level_t Building::get_max_level() const { - return max_level; -} - -std::map const& Building::get_goods_cost() const { - return goods_cost; -} - -fixed_point_t Building::get_cost() const { - return cost; -} - -Timespan Building::get_build_time() const { - return build_time; -} - -bool Building::has_visibility() const { - return visibility; -} - -bool Building::is_on_map() const { - return on_map; -} - -bool Building::is_default_enabled() const { - return default_enabled; -} - -ProductionType const* Building::get_production_type() const { - return production_type; -} - -bool Building::is_pop_built_factory() const { - return pop_build_factory; -} - -bool Building::is_strategic_factory() const { - return strategic_factory; -} - -bool Building::is_advanced_factory() const { - return advanced_factory; -} - -Building::level_t Building::get_fort_level() const { - return fort_level; -} - -uint64_t Building::get_naval_capacity() const { - return naval_capacity; -} - -std::vector const& Building::get_colonial_points() const { - return colonial_points; -} - -bool Building::is_in_province() const { - return in_province; -} - -bool Building::is_one_per_state() const { - return one_per_state; -} - -fixed_point_t Building::get_colonial_range() const { - return colonial_range; -} - -fixed_point_t Building::get_infrastructure() const { - return infrastructure; -} - -fixed_point_t Building::get_movement_cost() const { - return movement_cost; -} - -bool Building::spawned_railway_track() const { - return spawn_railway_track; -} - -BuildingType::BuildingType(std::string_view new_identifier) : HasIdentifier { new_identifier } {} - -BuildingInstance::BuildingInstance(Building const& building) : HasIdentifier { building.get_identifier() }, building { building } {} - -Building const& BuildingInstance::get_building() const { - return building; -} - -bool BuildingInstance::_can_expand() const { - return level < building.get_max_level(); -} - -BuildingInstance::level_t BuildingInstance::get_current_level() const { - return level; -} - -ExpansionState BuildingInstance::get_expansion_state() const { - return expansion_state; -} - -Date const& BuildingInstance::get_start_date() const { - return start; -} - -Date const& BuildingInstance::get_end_date() const { - return end; -} - -float BuildingInstance::get_expansion_progress() const { - return expansion_progress; -} - -bool BuildingInstance::expand() { - if (expansion_state == ExpansionState::CanExpand) { - expansion_state = ExpansionState::Preparing; - expansion_progress = 0.0f; - return true; - } - return false; -} - -/* REQUIREMENTS: - * MAP-71, MAP-74, MAP-77 - */ -void BuildingInstance::update_state(Date const& today) { - switch (expansion_state) { - case ExpansionState::Preparing: - start = today; - end = start + building.get_build_time(); - break; - case ExpansionState::Expanding: - expansion_progress = static_cast(today - start) / static_cast(end - start); - break; - default: expansion_state = _can_expand() ? ExpansionState::CanExpand : ExpansionState::CannotExpand; - } -} - -void BuildingInstance::tick(Date const& today) { - if (expansion_state == ExpansionState::Preparing) { - expansion_state = ExpansionState::Expanding; - } - if (expansion_state == ExpansionState::Expanding) { - if (end <= today) { - level++; - expansion_state = ExpansionState::CannotExpand; - } - } -} - -BuildingManager::BuildingManager() : building_types { "building types" }, buildings { "buildings" } {} - -bool BuildingManager::add_building_type(std::string_view identifier) { - if (identifier.empty()) { - Logger::error("Invalid building type identifier - empty!"); - return false; - } - return building_types.add_item({ identifier }); -} - -bool BuildingManager::add_building(std::string_view identifier, BuildingType const* type, ARGS) { - if (identifier.empty()) { - Logger::error("Invalid building identifier - empty!"); - return false; - } - if (type == nullptr) { - Logger::error("Invalid building type for ", identifier, ": null"); - return false; - } - - return buildings.add_item({ - identifier, *type, on_completion, completion_size, max_level, goods_cost, cost, build_time, visibility, on_map, default_enabled, - production_type, pop_build_factory, strategic_factory, advanced_factory, fort_level, naval_capacity, colonial_points, in_province, one_per_state, - colonial_range, infrastructure, movement_cost, local_ship_build, spawn_railway_track, sail, steam, capital, port, std::move(modifiers) - }); -} - -bool BuildingManager::load_buildings_file(GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root) { - bool ret = expect_dictionary_reserve_length(buildings, [this](std::string_view, ast::NodeCPtr value) -> bool { - return expect_key("type", expect_identifier( - [this](std::string_view identifier) -> bool { - if (!building_types.has_identifier(identifier)) { - return building_types.add_item({ identifier }); - } - return true; - } - ))(value); - })(root); - lock_building_types(); - - ret &= expect_dictionary([this, &good_manager, &production_type_manager, &modifier_manager](std::string_view key, ast::NodeCPtr value) -> bool { - BuildingType const* type = nullptr; - ProductionType const* production_type = nullptr; - std::string_view on_completion; - fixed_point_t completion_size = 0, cost = 0, infrastructure = 0, movement_cost = 0, colonial_range = 0, local_ship_build = 0; - Building::level_t max_level = 0, fort_level = 0; - std::map goods_cost; - Timespan build_time; - bool visibility = false, on_map = false, default_enabled = false, pop_build_factory = false, strategic_factory = false, advanced_factory = false; - bool in_province = false, one_per_state = false, spawn_railway_track = false, sail = false, steam = false, capital = false, port = false; - uint64_t naval_capacity = 0; - std::vector colonial_points; - ModifierValue modifiers; - - bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(modifiers), - "type", ONE_EXACTLY, expect_identifier(expect_building_type_identifier(assign_variable_callback_pointer(type))), - "on_completion", ZERO_OR_ONE, expect_identifier(assign_variable_callback(on_completion)), - "completion_size", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(completion_size)), - "max_level", ONE_EXACTLY, expect_uint(assign_variable_callback(max_level)), - "goods_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(goods_cost)), - "cost", ZERO_OR_MORE, expect_fixed_point(assign_variable_callback(cost)), - "time", ONE_EXACTLY, expect_days(assign_variable_callback(build_time)), - "visibility", ONE_EXACTLY, expect_bool(assign_variable_callback(visibility)), - "onmap", ONE_EXACTLY, expect_bool(assign_variable_callback(on_map)), - "default_enabled", ZERO_OR_ONE, expect_bool(assign_variable_callback(default_enabled)), - "production_type", ZERO_OR_ONE, expect_identifier(production_type_manager.expect_production_type_identifier(assign_variable_callback_pointer(production_type))), - "pop_build_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(pop_build_factory)), - "strategic_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(strategic_factory)), - "advanced_factory", ZERO_OR_ONE, expect_bool(assign_variable_callback(advanced_factory)), - "fort_level", ZERO_OR_ONE, expect_uint(assign_variable_callback(fort_level)), - "naval_capacity", ZERO_OR_ONE, expect_uint(assign_variable_callback(naval_capacity)), - "colonial_points", ZERO_OR_ONE, expect_list(expect_fixed_point([&colonial_points](fixed_point_t points) -> bool { - colonial_points.push_back(points); - return true; - })), - "province", ZERO_OR_ONE, expect_bool(assign_variable_callback(in_province)), - "one_per_state", ZERO_OR_ONE, expect_bool(assign_variable_callback(one_per_state)), - "colonial_range", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(colonial_range)), - "infrastructure", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(infrastructure)), - "movement_cost", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(movement_cost)), - "local_ship_build", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(local_ship_build)), - "spawn_railway_track", ZERO_OR_ONE, expect_bool(assign_variable_callback(spawn_railway_track)), - "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(sail)), - "steam", ZERO_OR_ONE, expect_bool(assign_variable_callback(steam)), - "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(capital)), - "port", ZERO_OR_ONE, expect_bool(assign_variable_callback(port)) - )(value); - - ret &= add_building( - key, type, on_completion, completion_size, max_level, goods_cost, cost, build_time, visibility, on_map, default_enabled, - production_type, pop_build_factory, strategic_factory, advanced_factory, fort_level, naval_capacity, colonial_points, in_province, - one_per_state, colonial_range, infrastructure, movement_cost, local_ship_build, spawn_railway_track, sail, steam, capital, port, std::move(modifiers) - ); - - return ret; - })(root); - lock_buildings(); - - return ret; -} - -bool BuildingManager::generate_province_buildings(Province& province) const { - province.reset_buildings(); - if (!building_types.is_locked()) { - Logger::error("Cannot generate buildings until building types are locked!"); - return false; - } - bool ret = true; - if (!province.get_water()) { - for (Building const& building : buildings.get_items()) { - ret &= province.add_building({ building }); - } - } - province.lock_buildings(); - return ret; -} diff --git a/src/openvic-simulation/map/Building.hpp b/src/openvic-simulation/map/Building.hpp deleted file mode 100644 index 3f74c3d..0000000 --- a/src/openvic-simulation/map/Building.hpp +++ /dev/null @@ -1,174 +0,0 @@ -#pragma once - -#include "openvic-simulation/types/Date.hpp" -#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" -#include "openvic-simulation/types/IdentifierRegistry.hpp" -#include "openvic-simulation/economy/Good.hpp" -#include "openvic-simulation/economy/ProductionType.hpp" -#include "openvic-simulation/Modifier.hpp" - -#define ARGS std::string_view on_completion, fixed_point_t completion_size, level_t max_level, \ - std::map goods_cost, fixed_point_t cost, Timespan build_time, bool visibility, bool on_map, bool default_enabled, \ - ProductionType const* production_type, bool pop_build_factory, bool strategic_factory, bool advanced_factory, level_t fort_level, \ - uint64_t naval_capacity, std::vector colonial_points, bool in_province, bool one_per_state, fixed_point_t colonial_range, \ - fixed_point_t infrastructure, fixed_point_t movement_cost, fixed_point_t local_ship_build, bool spawn_railway_track, bool sail, bool steam, \ - bool capital, bool port, ModifierValue&& modifiers - -namespace OpenVic { - - struct BuildingManager; - struct BuildingType; - - /* REQUIREMENTS: - * MAP-11, MAP-72, MAP-73 - * MAP-12, MAP-75, MAP-76 - * MAP-13, MAP-78, MAP-79 - */ - struct Building : HasIdentifier, ModifierValue { - friend struct BuildingManager; - - using level_t = int16_t; - - private: - BuildingType const& type; - const std::string on_completion; //probably sound played on completion - const fixed_point_t completion_size; - const level_t max_level; - const std::map goods_cost; - const fixed_point_t cost; - const Timespan build_time; //time - const bool visibility; - const bool on_map; //onmap - - const bool default_enabled; - ProductionType const* production_type; - const bool pop_build_factory; - const bool strategic_factory; - const bool advanced_factory; - - const level_t fort_level; //probably the step-per-level - - const uint64_t naval_capacity; - const std::vector colonial_points; - const bool in_province; //province - const bool one_per_state; - const fixed_point_t colonial_range; - - const fixed_point_t infrastructure; - const fixed_point_t movement_cost; - const fixed_point_t local_ship_build; - const bool spawn_railway_track; - - const bool sail; //only in clipper shipyard - const bool steam; //only in steamer shipyard - const bool capital; //only in naval base - const bool port; //only in naval base - - Building(std::string_view identifier, BuildingType const& type, ARGS); - - public: - Building(Building&&) = default; - - BuildingType const& get_type() const; - std::string const& get_on_completion() const; - fixed_point_t get_completion_size() const; - level_t get_max_level() const; - std::map const& get_goods_cost() const; - fixed_point_t get_cost() const; - Timespan get_build_time() const; - bool has_visibility() const; - bool is_on_map() const; - - bool is_default_enabled() const; - ProductionType const* get_production_type() const; - bool is_pop_built_factory() const; - bool is_strategic_factory() const; - bool is_advanced_factory() const; - - level_t get_fort_level() const; - - uint64_t get_naval_capacity() const; - std::vector const& get_colonial_points() const; - bool is_in_province() const; - bool is_one_per_state() const; - fixed_point_t get_colonial_range() const; - - fixed_point_t get_infrastructure() const; - fixed_point_t get_movement_cost() const; - fixed_point_t get_local_ship_build() const; - bool spawned_railway_track() const; - }; - - struct BuildingType : HasIdentifier { - friend struct BuildingManager; - - private: - BuildingType(std::string_view new_identifier); - - public: - BuildingType(BuildingType&&) = default; - }; - - enum class ExpansionState { - CannotExpand, - CanExpand, - Preparing, - Expanding - }; - - struct BuildingInstance : HasIdentifier { //used in the actual game - friend struct BuildingManager; - using level_t = Building::level_t; - - private: - Building const& building; - - level_t level = 0; - ExpansionState expansion_state = ExpansionState::CannotExpand; - Date start, end; - float expansion_progress; - - bool _can_expand() const; - - BuildingInstance(Building const& building); - - public: - BuildingInstance(BuildingInstance&&) = default; - - Building const& get_building() const; - - level_t get_current_level() const; - ExpansionState get_expansion_state() const; - Date const& get_start_date() const; - Date const& get_end_date() const; - float get_expansion_progress() const; - - bool expand(); - void update_state(Date const& today); - void tick(Date const& today); - - }; - - struct Province; - - struct BuildingManager { - using level_t = Building::level_t; //this is getting ridiculous - - private: - IdentifierRegistry building_types; - IdentifierRegistry buildings; - - public: - BuildingManager(); - - bool add_building_type(std::string_view identifier); - IDENTIFIER_REGISTRY_ACCESSORS(building_type) - - bool add_building(std::string_view identifier, BuildingType const* type, ARGS); - IDENTIFIER_REGISTRY_ACCESSORS(building) - - bool load_buildings_file(GoodManager const& good_manager, ProductionTypeManager const& production_type_manager, ModifierManager const& modifier_manager, ast::NodeCPtr root); - - bool generate_province_buildings(Province& province) const; - }; -} diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 8362ff4..acd882e 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -276,7 +276,7 @@ Pop::pop_size_t Map::get_total_map_population() const { return total_map_population; } -bool Map::setup(GoodManager const& good_manager, BuildingManager const& building_manager, PopManager const& pop_manager) { +bool Map::setup(BuildingManager const& building_manager, PopManager const& pop_manager) { bool ret = true; for (Province& province : provinces.get_items()) { province.clear_pops(); diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index a959158..578b471 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -102,7 +102,7 @@ namespace OpenVic { static constexpr size_t MAPMODE_COLOUR_SIZE = 4; bool generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) const; - bool setup(GoodManager const& good_manager, BuildingManager const& building_manager, PopManager const& pop_manager); + bool setup(BuildingManager const& building_manager, PopManager const& pop_manager); void update_highest_province_population(); Pop::pop_size_t get_highest_province_population() const; diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index c9b29ea..d925898 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -2,7 +2,7 @@ #include -#include "openvic-simulation/map/Building.hpp" +#include "openvic-simulation/economy/Building.hpp" #include "openvic-simulation/pop/Pop.hpp" namespace OpenVic { @@ -55,7 +55,6 @@ namespace OpenVic { fvec2_t navalbase; fixed_point_t navalbase_rotation; }; - static constexpr index_t NULL_INDEX = 0, MAX_INDEX = std::numeric_limits::max(); diff --git a/src/openvic-simulation/military/MilitaryManager.hpp b/src/openvic-simulation/military/MilitaryManager.hpp new file mode 100644 index 0000000..36b5010 --- /dev/null +++ b/src/openvic-simulation/military/MilitaryManager.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "openvic-simulation/military/Unit.hpp" + +namespace OpenVic { + struct MilitaryManager { + private: + UnitManager unit_manager; + public: + REF_GETTERS(unit_manager) + }; +} diff --git a/src/openvic-simulation/military/Unit.cpp b/src/openvic-simulation/military/Unit.cpp new file mode 100644 index 0000000..3da24da --- /dev/null +++ b/src/openvic-simulation/military/Unit.cpp @@ -0,0 +1,338 @@ +#include "Unit.hpp" + +#include + +#define UNIT_ARGS icon, sprite, active, unit_type, floating_flag, priority, max_strength, \ + default_organisation, maximum_speed, weighted_value, build_time, build_cost, supply_consumption, \ + supply_cost +#define LAND_ARGS primary_culture, sprite_override, sprite_mount, sprite_mount_attach_node, \ + reconnaissance, attack, defence, discipline, support, maneuver, siege +#define NAVY_ARGS naval_icon, sail, transport, capital, move_sound, select_sound, colonial_points, build_overseas, min_port_level, \ + limit_per_port, supply_consumption_score, hull, gun_power, fire_range, evasion, torpedo_attack + +using namespace OpenVic; +using namespace OpenVic::NodeTools; + +Unit::Unit(std::string_view identifier, type_t type, UNIT_PARAMS) : HasIdentifier { identifier }, + icon { icon }, type { type }, sprite { sprite }, active { active }, unit_type { unit_type }, + floating_flag { floating_flag }, priority { priority }, max_strength { max_strength }, + default_organisation { default_organisation }, maximum_speed { maximum_speed }, weighted_value { weighted_value }, + build_time { build_time }, build_cost { build_cost }, supply_consumption { supply_consumption }, supply_cost { supply_cost } {} + +Unit::icon_t Unit::get_icon() const { + return icon; +} + +Unit::type_t Unit::get_type() const { + return type; +} + +std::string const& Unit::get_sprite() const { + return sprite; +} + +bool Unit::is_active() const { + return active; +} + +std::string const& Unit::get_unit_type() const { + return unit_type; +} + +bool Unit::has_floating_flag() const { + return floating_flag; +} + +uint32_t Unit::get_priority() const { + return priority; +} + +fixed_point_t Unit::get_max_strength() const { + return max_strength; +} + +fixed_point_t Unit::get_default_organisation() const { + return default_organisation; +} + +fixed_point_t Unit::get_maximum_speed() const { + return maximum_speed; +} + +Timespan Unit::get_build_time() const { + return build_time; +} + +fixed_point_t Unit::get_weighted_value() const { + return weighted_value; +} + +std::map const& Unit::get_build_cost() const { + return build_cost; +} + +fixed_point_t Unit::get_supply_consumption() const { + return supply_consumption; +} + +std::map const& Unit::get_supply_cost() const { + return supply_cost; +} + +LandUnit::LandUnit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS) + : Unit { identifier, type_t::LAND, UNIT_ARGS }, primary_culture { primary_culture }, sprite_override { sprite_override }, + sprite_mount { sprite_mount }, sprite_mount_attach_node { sprite_mount_attach_node }, reconnaissance { reconnaissance }, + attack { attack }, defence { defence }, discipline { discipline }, support { support }, maneuver { maneuver }, siege { siege } {} + +bool LandUnit::get_primary_culture() const { + return primary_culture; +} + +std::string const& LandUnit::get_sprite_override() const { + return sprite_override; +} + +std::string const& LandUnit::get_sprite_mount() const { + return sprite_mount; +} + +std::string const& LandUnit::get_sprite_mount_attach_node() const { + return sprite_mount_attach_node; +} + +fixed_point_t LandUnit::get_reconnaissance() const { + return reconnaissance; +} + +fixed_point_t LandUnit::get_attack() const { + return attack; +} + +fixed_point_t LandUnit::get_defence() const { + return defence; +} + +fixed_point_t LandUnit::get_discipline() const { + return discipline; +} + +fixed_point_t LandUnit::get_support() const { + return support; +} + +fixed_point_t LandUnit::get_maneuver() const { + return maneuver; +} + +fixed_point_t LandUnit::get_siege() const { + return siege; +} + +NavalUnit::NavalUnit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS) : Unit { identifier, type_t::NAVAL, UNIT_ARGS }, + naval_icon { naval_icon }, sail { sail }, transport { transport }, capital { capital }, move_sound { move_sound }, + select_sound { select_sound }, colonial_points { colonial_points }, build_overseas { build_overseas }, + min_port_level { min_port_level }, limit_per_port { limit_per_port }, supply_consumption_score { supply_consumption_score }, + hull { hull }, gun_power { gun_power }, fire_range { fire_range }, evasion { evasion }, torpedo_attack { torpedo_attack } {}; + +NavalUnit::icon_t NavalUnit::get_naval_icon() const { + return naval_icon; +} + +bool NavalUnit::can_sail() const { + return sail; +} + +bool NavalUnit::is_transport() const { + return transport; +} + +std::string const& NavalUnit::get_move_sound() const { + return move_sound; +} + +std::string const& NavalUnit::get_select_sound() const { + return select_sound; +} + +fixed_point_t NavalUnit::get_colonial_points() const { + return colonial_points; +} + +bool NavalUnit::can_build_overseas() const { + return build_overseas; +} + +uint32_t NavalUnit::get_min_port_level() const { + return min_port_level; +} + +int32_t NavalUnit::get_limit_per_port() const { + return limit_per_port; +} + +fixed_point_t NavalUnit::get_supply_consumption_score() const { + return supply_consumption_score; +} + +fixed_point_t NavalUnit::get_hull() const { + return hull; +} + +fixed_point_t NavalUnit::get_gun_power() const { + return gun_power; +} + +fixed_point_t NavalUnit::get_fire_range() const { + return fire_range; +} + +fixed_point_t NavalUnit::get_evasion() const { + return evasion; +} + +fixed_point_t NavalUnit::get_torpedo_attack() const { + return torpedo_attack; +} + +UnitManager::UnitManager() : units { "units" } {} + +bool UnitManager::_check_shared_parameters(std::string_view identifier, UNIT_PARAMS) { + if (identifier.empty()) { + Logger::error("Invalid religion identifier - empty!"); + return false; + } + + if (sprite.empty()) { + Logger::error("Invalid sprite identifier - empty!"); + return false; + } + + if (unit_type.empty()) { + Logger::error("Invalid unit type - empty!"); + return false; + } + + //TODO check that icon and sprite exist + + return true; +} + +bool UnitManager::add_land_unit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS) { + if (!_check_shared_parameters(identifier, UNIT_ARGS)) { + return false; + } + + return units.add_item(LandUnit { identifier, UNIT_ARGS, LAND_ARGS }); +} + +bool UnitManager::add_naval_unit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS) { + if (!_check_shared_parameters(identifier, UNIT_ARGS)) { + return false; + } + + //TODO: check that icon and sounds exist + + return units.add_item(NavalUnit { identifier, UNIT_ARGS, NAVY_ARGS }); +} + +static bool shared_keys_callback(std::string_view key, ast::NodeCPtr) { + static const std::set> reserved_keys = { + "icon", "type", "sprite", "active", "unit_type", "floating_flag", "priority", + "max_strength", "default_organisation", "maximum_speed", "weighted_value", + "build_time", "build_cost", "supply_consumption", "supply_cost" + }; + if (reserved_keys.contains(key)) return true; + Logger::error("Invalid key: ", key); + return false; +}; + +bool UnitManager::load_unit_file(GoodManager const& good_manager, ast::NodeCPtr root) { + return expect_dictionary([this, &good_manager](std::string_view key, ast::NodeCPtr value) -> bool { + Unit::icon_t icon = 0; + std::string_view type, unit_type, sprite; + bool active = true, floating_flag = false; + uint32_t priority = 0; + Timespan build_time; + fixed_point_t maximum_speed = 0, max_strength = 0, default_organisation = 0, weighted_value = 0, supply_consumption = 0; + std::map build_cost, supply_cost; + + //shared + bool ret = expect_dictionary_keys_and_default( + key_value_success_callback, + "icon", ONE_EXACTLY, expect_uint(assign_variable_callback(icon)), + "type", ONE_EXACTLY, expect_identifier(assign_variable_callback(type)), + "sprite", ONE_EXACTLY, expect_identifier(assign_variable_callback(sprite)), + "active", ZERO_OR_ONE, expect_bool(assign_variable_callback(active)), + "unit_type", ONE_EXACTLY, expect_identifier(assign_variable_callback(unit_type)), + "floating_flag", ONE_EXACTLY, expect_bool(assign_variable_callback(floating_flag)), + "priority", ONE_EXACTLY, expect_uint(assign_variable_callback(priority)), + "max_strength", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(max_strength)), + "default_organisation", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(default_organisation)), + "maximum_speed", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(maximum_speed)), + "weighted_value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(weighted_value)), + "build_time", ONE_EXACTLY, expect_days(assign_variable_callback(build_time)), + "build_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(build_cost)), + "supply_consumption", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(supply_consumption)), + "supply_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(supply_cost)) + )(value); + + if (type == "land") { + bool primary_culture = false; + std::string_view sprite_override, sprite_mount, sprite_mount_attach_node; + fixed_point_t reconnaissance = 0, attack = 0, defence = 0, discipline = 0, support = 0, maneuver = 0, siege = 0; + + ret &= expect_dictionary_keys_and_default( + shared_keys_callback, + "primary_culture", ZERO_OR_ONE, expect_bool(assign_variable_callback(primary_culture)), + "sprite_override", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_override)), + "sprite_mount", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_mount)), + "sprite_mount_attach_node", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_mount_attach_node)), + "reconnaissance", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(reconnaissance)), + "attack", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(attack)), + "defence", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(defence)), + "discipline", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(discipline)), + "support", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(support)), + "maneuver", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(maneuver)), + "siege", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(siege)) + )(value); + + ret &= add_land_unit(key, UNIT_ARGS, LAND_ARGS); + + return ret; + } else if (type == "naval") { + Unit::icon_t naval_icon = 0; + bool sail = false, transport = false, capital = false, build_overseas = false; + std::string_view move_sound, select_sound; //TODO defaults for both + uint32_t min_port_level = 0; + int32_t limit_per_port = 0; + fixed_point_t fire_range = 0, evasion = 0, supply_consumption_score = 0, hull = 0, gun_power = 0, colonial_points = 0, torpedo_attack = 0; + + ret &= expect_dictionary_keys_and_default( + shared_keys_callback, + "naval_icon", ONE_EXACTLY, expect_uint(assign_variable_callback(naval_icon)), + "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(sail)), + "transport", ZERO_OR_ONE, expect_bool(assign_variable_callback(transport)), + "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(capital)), + "move_sound", ZERO_OR_ONE, expect_identifier(assign_variable_callback(move_sound)), + "select_sound", ZERO_OR_ONE, expect_identifier(assign_variable_callback(select_sound)), + "colonial_points", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(colonial_points)), + "can_build_overseas", ZERO_OR_ONE, expect_bool(assign_variable_callback(build_overseas)), + "min_port_level", ONE_EXACTLY, expect_uint(assign_variable_callback(min_port_level)), + "limit_per_port", ONE_EXACTLY, expect_int(assign_variable_callback(limit_per_port)), + "supply_consumption_score", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(supply_consumption_score)), + "hull", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(hull)), + "gun_power", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(gun_power)), + "fire_range", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(fire_range)), + "evasion", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(evasion)), + "torpedo_attack", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(torpedo_attack)) + )(value); + + ret &= add_naval_unit(key, UNIT_ARGS, NAVY_ARGS); + + return ret; + } else { + Logger::error("Invalid type for unit ", key, ": ", type); + return false; + } + })(root); +} \ No newline at end of file diff --git a/src/openvic-simulation/military/Unit.hpp b/src/openvic-simulation/military/Unit.hpp new file mode 100644 index 0000000..65e6259 --- /dev/null +++ b/src/openvic-simulation/military/Unit.hpp @@ -0,0 +1,171 @@ +#pragma once + +#include +#include +#include "openvic-simulation/economy/Good.hpp" +#include "openvic-simulation/types/IdentifierRegistry.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/economy/Good.hpp" +#include "openvic-simulation/types/Date.hpp" + +#define UNIT_PARAMS Unit::icon_t icon, std::string_view sprite, bool active, std::string_view unit_type, \ + bool floating_flag, uint32_t priority, fixed_point_t max_strength, fixed_point_t default_organisation, \ + fixed_point_t maximum_speed, fixed_point_t weighted_value, Timespan build_time, \ + std::map build_cost, fixed_point_t supply_consumption, \ + std::map supply_cost +#define LAND_PARAMS bool primary_culture, std::string_view sprite_override, std::string_view sprite_mount, \ + std::string_view sprite_mount_attach_node, fixed_point_t reconnaissance, fixed_point_t attack, \ + fixed_point_t defence, fixed_point_t discipline, fixed_point_t support, fixed_point_t maneuver, fixed_point_t siege +#define NAVY_PARAMS Unit::icon_t naval_icon, bool sail, bool transport, bool capital, std::string_view move_sound, \ + std::string_view select_sound, fixed_point_t colonial_points, bool build_overseas, uint32_t min_port_level, \ + int32_t limit_per_port, fixed_point_t supply_consumption_score, fixed_point_t hull, fixed_point_t gun_power, \ + fixed_point_t fire_range, fixed_point_t evasion, fixed_point_t torpedo_attack + +namespace OpenVic { + struct Unit : HasIdentifier { + using icon_t = uint32_t; + + enum struct type_t { + LAND, NAVAL + }; + + private: + const type_t type; + const icon_t icon; + const std::string sprite; + const bool active; + const std::string unit_type; + const bool floating_flag; + + const uint32_t priority; + const fixed_point_t max_strength; + const fixed_point_t default_organisation; + const fixed_point_t maximum_speed; + const fixed_point_t weighted_value; + + const Timespan build_time; + const std::map build_cost; + const fixed_point_t supply_consumption; + const std::map supply_cost; + + protected: + Unit(std::string_view identifier, type_t type, UNIT_PARAMS); + + public: + Unit(Unit&&) = default; + + icon_t get_icon() const; + type_t get_type() const; + std::string const& get_sprite() const; + bool is_active() const; + std::string const& get_unit_type() const; + bool has_floating_flag() const; + + uint32_t get_priority() const; + fixed_point_t get_max_strength() const; + fixed_point_t get_default_organisation() const; + fixed_point_t get_maximum_speed() const; + fixed_point_t get_weighted_value() const; + + Timespan get_build_time() const; + std::map const& get_build_cost() const; + fixed_point_t get_supply_consumption() const; + std::map const& get_supply_cost() const; + }; + + struct LandUnit : Unit { + friend struct UnitManager; + + private: + const bool primary_culture; + const std::string sprite_override, sprite_mount, sprite_mount_attach_node; + const fixed_point_t reconnaissance; + const fixed_point_t attack; + const fixed_point_t defence; + const fixed_point_t discipline; + const fixed_point_t support; + const fixed_point_t maneuver; + const fixed_point_t siege; + + LandUnit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS); + + public: + LandUnit(LandUnit&&) = default; + + bool get_primary_culture() const; + std::string const& get_sprite_override() const; + std::string const& get_sprite_mount() const; + std::string const& get_sprite_mount_attach_node() const; + + fixed_point_t get_reconnaissance() const; + fixed_point_t get_attack() const; + fixed_point_t get_defence() const; + fixed_point_t get_discipline() const; + fixed_point_t get_support() const; + fixed_point_t get_maneuver() const; + fixed_point_t get_siege() const; + }; + + struct NavalUnit : Unit { + friend struct UnitManager; + + private: + const icon_t naval_icon; + const bool sail; + const bool transport; + const bool capital; + const std::string move_sound; + const std::string select_sound; + const fixed_point_t colonial_points; + const bool build_overseas; + const uint32_t min_port_level; + const int32_t limit_per_port; + const fixed_point_t supply_consumption_score; + + const fixed_point_t hull; + const fixed_point_t gun_power; + const fixed_point_t fire_range; + const fixed_point_t evasion; + const fixed_point_t torpedo_attack; + + NavalUnit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS); + + public: + NavalUnit(NavalUnit&&) = default; + + icon_t get_naval_icon() const; + bool can_sail() const; + bool is_transport() const; + bool is_capital() const; + std::string const& get_move_sound() const; + std::string const& get_select_sound() const; + fixed_point_t get_colonial_points() const; + bool can_build_overseas() const; + uint32_t get_min_port_level() const; + int32_t get_limit_per_port() const; + fixed_point_t get_supply_consumption_score() const; + + fixed_point_t get_hull() const; + fixed_point_t get_gun_power() const; + fixed_point_t get_fire_range() const; + fixed_point_t get_evasion() const; + fixed_point_t get_torpedo_attack() const; + }; + + struct UnitManager { + private: + IdentifierRegistry units; + + bool _check_shared_parameters(std::string_view identifier, UNIT_PARAMS); + + public: + UnitManager(); + + bool add_land_unit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS); + bool add_naval_unit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS); + IDENTIFIER_REGISTRY_ACCESSORS(unit) + + bool load_unit_file(GoodManager const& good_manager, ast::NodeCPtr root); + }; +} \ No newline at end of file diff --git a/src/openvic-simulation/politics/Government.hpp b/src/openvic-simulation/politics/Government.hpp index 3bc754c..c72dae6 100644 --- a/src/openvic-simulation/politics/Government.hpp +++ b/src/openvic-simulation/politics/Government.hpp @@ -39,4 +39,4 @@ namespace OpenVic { bool load_government_types_file(IdeologyManager const& ideology_manager, ast::NodeCPtr root); }; -} // namespace OpenVic +} // namespace OpenVic diff --git a/src/openvic-simulation/politics/PoliticsManager.hpp b/src/openvic-simulation/politics/PoliticsManager.hpp new file mode 100644 index 0000000..9072d72 --- /dev/null +++ b/src/openvic-simulation/politics/PoliticsManager.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "openvic-simulation/politics/Government.hpp" +#include "openvic-simulation/politics/Ideology.hpp" +#include "openvic-simulation/politics/Issue.hpp" + +namespace OpenVic { + struct PoliticsManager { + private: + GovernmentTypeManager government_type_manager; + IdeologyManager ideology_manager; + IssueManager issue_manager; + public: + REF_GETTERS(government_type_manager) + REF_GETTERS(ideology_manager) + REF_GETTERS(issue_manager) + + inline bool load_government_types_file(ast::NodeCPtr root) { + return government_type_manager.load_government_types_file(ideology_manager, root); + } + }; +} diff --git a/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp index c74c5e9..d1a857f 100644 --- a/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp +++ b/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp @@ -505,7 +505,7 @@ namespace OpenVic { void check_base_price(std::string identifier, std::string target_value, std::string req_name) { // Get string of base_price from goods manager - fixed_point_t base_price_fp = get_game_manager()->get_good_manager().get_good_by_identifier(identifier)->get_base_price(); + fixed_point_t base_price_fp = get_game_manager()->get_economy_manager().get_good_manager().get_good_by_identifier(identifier)->get_base_price(); std::stringstream ss; ss << std::fixed << std::setprecision(1) << base_price_fp.to_double(); // Use a single digit floating point of the value std::string base_price = ss.str(); diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp index 4e13813..aea5728 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -6,6 +6,10 @@ #include "openvic-simulation/dataloader/NodeTools.hpp" #include "openvic-simulation/utility/Logger.hpp" +#define REF_GETTERS(var) \ + constexpr decltype(var)& get_##var() { return var; } \ + constexpr decltype(var) const& get_##var() const { return var; } + namespace OpenVic { /* * Base class for objects with a non-empty string identifier, @@ -179,13 +183,7 @@ namespace OpenVic { return get_item_by_index(index) != nullptr; } - std::vector& get_items() { - return items; - } - - std::vector const& get_items() const { - return items; - } + REF_GETTERS(items) std::vector get_item_identifiers() const { std::vector identifiers; diff --git a/src/openvic-simulation/units/Unit.cpp b/src/openvic-simulation/units/Unit.cpp deleted file mode 100644 index 3da24da..0000000 --- a/src/openvic-simulation/units/Unit.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#include "Unit.hpp" - -#include - -#define UNIT_ARGS icon, sprite, active, unit_type, floating_flag, priority, max_strength, \ - default_organisation, maximum_speed, weighted_value, build_time, build_cost, supply_consumption, \ - supply_cost -#define LAND_ARGS primary_culture, sprite_override, sprite_mount, sprite_mount_attach_node, \ - reconnaissance, attack, defence, discipline, support, maneuver, siege -#define NAVY_ARGS naval_icon, sail, transport, capital, move_sound, select_sound, colonial_points, build_overseas, min_port_level, \ - limit_per_port, supply_consumption_score, hull, gun_power, fire_range, evasion, torpedo_attack - -using namespace OpenVic; -using namespace OpenVic::NodeTools; - -Unit::Unit(std::string_view identifier, type_t type, UNIT_PARAMS) : HasIdentifier { identifier }, - icon { icon }, type { type }, sprite { sprite }, active { active }, unit_type { unit_type }, - floating_flag { floating_flag }, priority { priority }, max_strength { max_strength }, - default_organisation { default_organisation }, maximum_speed { maximum_speed }, weighted_value { weighted_value }, - build_time { build_time }, build_cost { build_cost }, supply_consumption { supply_consumption }, supply_cost { supply_cost } {} - -Unit::icon_t Unit::get_icon() const { - return icon; -} - -Unit::type_t Unit::get_type() const { - return type; -} - -std::string const& Unit::get_sprite() const { - return sprite; -} - -bool Unit::is_active() const { - return active; -} - -std::string const& Unit::get_unit_type() const { - return unit_type; -} - -bool Unit::has_floating_flag() const { - return floating_flag; -} - -uint32_t Unit::get_priority() const { - return priority; -} - -fixed_point_t Unit::get_max_strength() const { - return max_strength; -} - -fixed_point_t Unit::get_default_organisation() const { - return default_organisation; -} - -fixed_point_t Unit::get_maximum_speed() const { - return maximum_speed; -} - -Timespan Unit::get_build_time() const { - return build_time; -} - -fixed_point_t Unit::get_weighted_value() const { - return weighted_value; -} - -std::map const& Unit::get_build_cost() const { - return build_cost; -} - -fixed_point_t Unit::get_supply_consumption() const { - return supply_consumption; -} - -std::map const& Unit::get_supply_cost() const { - return supply_cost; -} - -LandUnit::LandUnit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS) - : Unit { identifier, type_t::LAND, UNIT_ARGS }, primary_culture { primary_culture }, sprite_override { sprite_override }, - sprite_mount { sprite_mount }, sprite_mount_attach_node { sprite_mount_attach_node }, reconnaissance { reconnaissance }, - attack { attack }, defence { defence }, discipline { discipline }, support { support }, maneuver { maneuver }, siege { siege } {} - -bool LandUnit::get_primary_culture() const { - return primary_culture; -} - -std::string const& LandUnit::get_sprite_override() const { - return sprite_override; -} - -std::string const& LandUnit::get_sprite_mount() const { - return sprite_mount; -} - -std::string const& LandUnit::get_sprite_mount_attach_node() const { - return sprite_mount_attach_node; -} - -fixed_point_t LandUnit::get_reconnaissance() const { - return reconnaissance; -} - -fixed_point_t LandUnit::get_attack() const { - return attack; -} - -fixed_point_t LandUnit::get_defence() const { - return defence; -} - -fixed_point_t LandUnit::get_discipline() const { - return discipline; -} - -fixed_point_t LandUnit::get_support() const { - return support; -} - -fixed_point_t LandUnit::get_maneuver() const { - return maneuver; -} - -fixed_point_t LandUnit::get_siege() const { - return siege; -} - -NavalUnit::NavalUnit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS) : Unit { identifier, type_t::NAVAL, UNIT_ARGS }, - naval_icon { naval_icon }, sail { sail }, transport { transport }, capital { capital }, move_sound { move_sound }, - select_sound { select_sound }, colonial_points { colonial_points }, build_overseas { build_overseas }, - min_port_level { min_port_level }, limit_per_port { limit_per_port }, supply_consumption_score { supply_consumption_score }, - hull { hull }, gun_power { gun_power }, fire_range { fire_range }, evasion { evasion }, torpedo_attack { torpedo_attack } {}; - -NavalUnit::icon_t NavalUnit::get_naval_icon() const { - return naval_icon; -} - -bool NavalUnit::can_sail() const { - return sail; -} - -bool NavalUnit::is_transport() const { - return transport; -} - -std::string const& NavalUnit::get_move_sound() const { - return move_sound; -} - -std::string const& NavalUnit::get_select_sound() const { - return select_sound; -} - -fixed_point_t NavalUnit::get_colonial_points() const { - return colonial_points; -} - -bool NavalUnit::can_build_overseas() const { - return build_overseas; -} - -uint32_t NavalUnit::get_min_port_level() const { - return min_port_level; -} - -int32_t NavalUnit::get_limit_per_port() const { - return limit_per_port; -} - -fixed_point_t NavalUnit::get_supply_consumption_score() const { - return supply_consumption_score; -} - -fixed_point_t NavalUnit::get_hull() const { - return hull; -} - -fixed_point_t NavalUnit::get_gun_power() const { - return gun_power; -} - -fixed_point_t NavalUnit::get_fire_range() const { - return fire_range; -} - -fixed_point_t NavalUnit::get_evasion() const { - return evasion; -} - -fixed_point_t NavalUnit::get_torpedo_attack() const { - return torpedo_attack; -} - -UnitManager::UnitManager() : units { "units" } {} - -bool UnitManager::_check_shared_parameters(std::string_view identifier, UNIT_PARAMS) { - if (identifier.empty()) { - Logger::error("Invalid religion identifier - empty!"); - return false; - } - - if (sprite.empty()) { - Logger::error("Invalid sprite identifier - empty!"); - return false; - } - - if (unit_type.empty()) { - Logger::error("Invalid unit type - empty!"); - return false; - } - - //TODO check that icon and sprite exist - - return true; -} - -bool UnitManager::add_land_unit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS) { - if (!_check_shared_parameters(identifier, UNIT_ARGS)) { - return false; - } - - return units.add_item(LandUnit { identifier, UNIT_ARGS, LAND_ARGS }); -} - -bool UnitManager::add_naval_unit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS) { - if (!_check_shared_parameters(identifier, UNIT_ARGS)) { - return false; - } - - //TODO: check that icon and sounds exist - - return units.add_item(NavalUnit { identifier, UNIT_ARGS, NAVY_ARGS }); -} - -static bool shared_keys_callback(std::string_view key, ast::NodeCPtr) { - static const std::set> reserved_keys = { - "icon", "type", "sprite", "active", "unit_type", "floating_flag", "priority", - "max_strength", "default_organisation", "maximum_speed", "weighted_value", - "build_time", "build_cost", "supply_consumption", "supply_cost" - }; - if (reserved_keys.contains(key)) return true; - Logger::error("Invalid key: ", key); - return false; -}; - -bool UnitManager::load_unit_file(GoodManager const& good_manager, ast::NodeCPtr root) { - return expect_dictionary([this, &good_manager](std::string_view key, ast::NodeCPtr value) -> bool { - Unit::icon_t icon = 0; - std::string_view type, unit_type, sprite; - bool active = true, floating_flag = false; - uint32_t priority = 0; - Timespan build_time; - fixed_point_t maximum_speed = 0, max_strength = 0, default_organisation = 0, weighted_value = 0, supply_consumption = 0; - std::map build_cost, supply_cost; - - //shared - bool ret = expect_dictionary_keys_and_default( - key_value_success_callback, - "icon", ONE_EXACTLY, expect_uint(assign_variable_callback(icon)), - "type", ONE_EXACTLY, expect_identifier(assign_variable_callback(type)), - "sprite", ONE_EXACTLY, expect_identifier(assign_variable_callback(sprite)), - "active", ZERO_OR_ONE, expect_bool(assign_variable_callback(active)), - "unit_type", ONE_EXACTLY, expect_identifier(assign_variable_callback(unit_type)), - "floating_flag", ONE_EXACTLY, expect_bool(assign_variable_callback(floating_flag)), - "priority", ONE_EXACTLY, expect_uint(assign_variable_callback(priority)), - "max_strength", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(max_strength)), - "default_organisation", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(default_organisation)), - "maximum_speed", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(maximum_speed)), - "weighted_value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(weighted_value)), - "build_time", ONE_EXACTLY, expect_days(assign_variable_callback(build_time)), - "build_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(build_cost)), - "supply_consumption", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(supply_consumption)), - "supply_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(supply_cost)) - )(value); - - if (type == "land") { - bool primary_culture = false; - std::string_view sprite_override, sprite_mount, sprite_mount_attach_node; - fixed_point_t reconnaissance = 0, attack = 0, defence = 0, discipline = 0, support = 0, maneuver = 0, siege = 0; - - ret &= expect_dictionary_keys_and_default( - shared_keys_callback, - "primary_culture", ZERO_OR_ONE, expect_bool(assign_variable_callback(primary_culture)), - "sprite_override", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_override)), - "sprite_mount", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_mount)), - "sprite_mount_attach_node", ZERO_OR_ONE, expect_identifier(assign_variable_callback(sprite_mount_attach_node)), - "reconnaissance", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(reconnaissance)), - "attack", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(attack)), - "defence", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(defence)), - "discipline", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(discipline)), - "support", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(support)), - "maneuver", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(maneuver)), - "siege", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(siege)) - )(value); - - ret &= add_land_unit(key, UNIT_ARGS, LAND_ARGS); - - return ret; - } else if (type == "naval") { - Unit::icon_t naval_icon = 0; - bool sail = false, transport = false, capital = false, build_overseas = false; - std::string_view move_sound, select_sound; //TODO defaults for both - uint32_t min_port_level = 0; - int32_t limit_per_port = 0; - fixed_point_t fire_range = 0, evasion = 0, supply_consumption_score = 0, hull = 0, gun_power = 0, colonial_points = 0, torpedo_attack = 0; - - ret &= expect_dictionary_keys_and_default( - shared_keys_callback, - "naval_icon", ONE_EXACTLY, expect_uint(assign_variable_callback(naval_icon)), - "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(sail)), - "transport", ZERO_OR_ONE, expect_bool(assign_variable_callback(transport)), - "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(capital)), - "move_sound", ZERO_OR_ONE, expect_identifier(assign_variable_callback(move_sound)), - "select_sound", ZERO_OR_ONE, expect_identifier(assign_variable_callback(select_sound)), - "colonial_points", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(colonial_points)), - "can_build_overseas", ZERO_OR_ONE, expect_bool(assign_variable_callback(build_overseas)), - "min_port_level", ONE_EXACTLY, expect_uint(assign_variable_callback(min_port_level)), - "limit_per_port", ONE_EXACTLY, expect_int(assign_variable_callback(limit_per_port)), - "supply_consumption_score", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(supply_consumption_score)), - "hull", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(hull)), - "gun_power", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(gun_power)), - "fire_range", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(fire_range)), - "evasion", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(evasion)), - "torpedo_attack", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(torpedo_attack)) - )(value); - - ret &= add_naval_unit(key, UNIT_ARGS, NAVY_ARGS); - - return ret; - } else { - Logger::error("Invalid type for unit ", key, ": ", type); - return false; - } - })(root); -} \ No newline at end of file diff --git a/src/openvic-simulation/units/Unit.hpp b/src/openvic-simulation/units/Unit.hpp deleted file mode 100644 index 65e6259..0000000 --- a/src/openvic-simulation/units/Unit.hpp +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -#include -#include -#include "openvic-simulation/economy/Good.hpp" -#include "openvic-simulation/types/IdentifierRegistry.hpp" -#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" -#include "openvic-simulation/dataloader/NodeTools.hpp" -#include "openvic-simulation/economy/Good.hpp" -#include "openvic-simulation/types/Date.hpp" - -#define UNIT_PARAMS Unit::icon_t icon, std::string_view sprite, bool active, std::string_view unit_type, \ - bool floating_flag, uint32_t priority, fixed_point_t max_strength, fixed_point_t default_organisation, \ - fixed_point_t maximum_speed, fixed_point_t weighted_value, Timespan build_time, \ - std::map build_cost, fixed_point_t supply_consumption, \ - std::map supply_cost -#define LAND_PARAMS bool primary_culture, std::string_view sprite_override, std::string_view sprite_mount, \ - std::string_view sprite_mount_attach_node, fixed_point_t reconnaissance, fixed_point_t attack, \ - fixed_point_t defence, fixed_point_t discipline, fixed_point_t support, fixed_point_t maneuver, fixed_point_t siege -#define NAVY_PARAMS Unit::icon_t naval_icon, bool sail, bool transport, bool capital, std::string_view move_sound, \ - std::string_view select_sound, fixed_point_t colonial_points, bool build_overseas, uint32_t min_port_level, \ - int32_t limit_per_port, fixed_point_t supply_consumption_score, fixed_point_t hull, fixed_point_t gun_power, \ - fixed_point_t fire_range, fixed_point_t evasion, fixed_point_t torpedo_attack - -namespace OpenVic { - struct Unit : HasIdentifier { - using icon_t = uint32_t; - - enum struct type_t { - LAND, NAVAL - }; - - private: - const type_t type; - const icon_t icon; - const std::string sprite; - const bool active; - const std::string unit_type; - const bool floating_flag; - - const uint32_t priority; - const fixed_point_t max_strength; - const fixed_point_t default_organisation; - const fixed_point_t maximum_speed; - const fixed_point_t weighted_value; - - const Timespan build_time; - const std::map build_cost; - const fixed_point_t supply_consumption; - const std::map supply_cost; - - protected: - Unit(std::string_view identifier, type_t type, UNIT_PARAMS); - - public: - Unit(Unit&&) = default; - - icon_t get_icon() const; - type_t get_type() const; - std::string const& get_sprite() const; - bool is_active() const; - std::string const& get_unit_type() const; - bool has_floating_flag() const; - - uint32_t get_priority() const; - fixed_point_t get_max_strength() const; - fixed_point_t get_default_organisation() const; - fixed_point_t get_maximum_speed() const; - fixed_point_t get_weighted_value() const; - - Timespan get_build_time() const; - std::map const& get_build_cost() const; - fixed_point_t get_supply_consumption() const; - std::map const& get_supply_cost() const; - }; - - struct LandUnit : Unit { - friend struct UnitManager; - - private: - const bool primary_culture; - const std::string sprite_override, sprite_mount, sprite_mount_attach_node; - const fixed_point_t reconnaissance; - const fixed_point_t attack; - const fixed_point_t defence; - const fixed_point_t discipline; - const fixed_point_t support; - const fixed_point_t maneuver; - const fixed_point_t siege; - - LandUnit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS); - - public: - LandUnit(LandUnit&&) = default; - - bool get_primary_culture() const; - std::string const& get_sprite_override() const; - std::string const& get_sprite_mount() const; - std::string const& get_sprite_mount_attach_node() const; - - fixed_point_t get_reconnaissance() const; - fixed_point_t get_attack() const; - fixed_point_t get_defence() const; - fixed_point_t get_discipline() const; - fixed_point_t get_support() const; - fixed_point_t get_maneuver() const; - fixed_point_t get_siege() const; - }; - - struct NavalUnit : Unit { - friend struct UnitManager; - - private: - const icon_t naval_icon; - const bool sail; - const bool transport; - const bool capital; - const std::string move_sound; - const std::string select_sound; - const fixed_point_t colonial_points; - const bool build_overseas; - const uint32_t min_port_level; - const int32_t limit_per_port; - const fixed_point_t supply_consumption_score; - - const fixed_point_t hull; - const fixed_point_t gun_power; - const fixed_point_t fire_range; - const fixed_point_t evasion; - const fixed_point_t torpedo_attack; - - NavalUnit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS); - - public: - NavalUnit(NavalUnit&&) = default; - - icon_t get_naval_icon() const; - bool can_sail() const; - bool is_transport() const; - bool is_capital() const; - std::string const& get_move_sound() const; - std::string const& get_select_sound() const; - fixed_point_t get_colonial_points() const; - bool can_build_overseas() const; - uint32_t get_min_port_level() const; - int32_t get_limit_per_port() const; - fixed_point_t get_supply_consumption_score() const; - - fixed_point_t get_hull() const; - fixed_point_t get_gun_power() const; - fixed_point_t get_fire_range() const; - fixed_point_t get_evasion() const; - fixed_point_t get_torpedo_attack() const; - }; - - struct UnitManager { - private: - IdentifierRegistry units; - - bool _check_shared_parameters(std::string_view identifier, UNIT_PARAMS); - - public: - UnitManager(); - - bool add_land_unit(std::string_view identifier, UNIT_PARAMS, LAND_PARAMS); - bool add_naval_unit(std::string_view identifier, UNIT_PARAMS, NAVY_PARAMS); - IDENTIFIER_REGISTRY_ACCESSORS(unit) - - bool load_unit_file(GoodManager const& good_manager, ast::NodeCPtr root); - }; -} \ No newline at end of file -- cgit v1.2.3-56-ga3b1