From 023860d53a90774dcdba84ad7c0dca3c944c9a49 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Mon, 12 Feb 2024 12:15:04 +0100 Subject: feat: unit instance type definition, renamed existing structs for consistency --- src/openvic-simulation/military/Unit.cpp | 343 ------------------------------- 1 file changed, 343 deletions(-) delete mode 100644 src/openvic-simulation/military/Unit.cpp (limited to 'src/openvic-simulation/military/Unit.cpp') diff --git a/src/openvic-simulation/military/Unit.cpp b/src/openvic-simulation/military/Unit.cpp deleted file mode 100644 index 54fc763..0000000 --- a/src/openvic-simulation/military/Unit.cpp +++ /dev/null @@ -1,343 +0,0 @@ -#include "Unit.hpp" - -#include "openvic-simulation/map/TerrainType.hpp" - -using namespace OpenVic; -using namespace OpenVic::NodeTools; - -using enum Unit::branch_t; -using enum Unit::unit_type_t; - -Unit::Unit( - std::string_view new_identifier, branch_t new_branch, unit_args_t& unit_args -) : HasIdentifier { new_identifier }, - branch { new_branch }, - icon { unit_args.icon }, - sprite { unit_args.sprite }, - active { unit_args.active }, - unit_type { unit_args.unit_type }, - floating_flag { unit_args.floating_flag }, - priority { unit_args.priority }, - max_strength { unit_args.max_strength }, - default_organisation { unit_args.default_organisation }, - maximum_speed { unit_args.maximum_speed }, - weighted_value { unit_args.weighted_value }, - move_sound { unit_args.move_sound }, - select_sound { unit_args.select_sound }, - build_time { unit_args.build_time }, - build_cost { std::move(unit_args.build_cost) }, - supply_consumption { unit_args.supply_consumption }, - supply_cost { std::move(unit_args.supply_cost) }, - terrain_modifiers { std::move(unit_args.terrain_modifiers) } {} - -LandUnit::LandUnit( - std::string_view new_identifier, unit_args_t& unit_args, land_unit_args_t const& land_unit_args -) : Unit { new_identifier, LAND, unit_args }, - allowed_cultures { land_unit_args.allowed_cultures }, - sprite_override { land_unit_args.sprite_override }, - sprite_mount { land_unit_args.sprite_mount }, - sprite_mount_attach_node { land_unit_args.sprite_mount_attach_node }, - reconnaissance { land_unit_args.reconnaissance }, - attack { land_unit_args.attack }, - defence { land_unit_args.defence }, - discipline { land_unit_args.discipline }, - support { land_unit_args.support }, - maneuver { land_unit_args.maneuver }, - siege { land_unit_args.siege } {} - -NavalUnit::NavalUnit( - std::string_view new_identifier, unit_args_t& unit_args, naval_unit_args_t const& naval_unit_args -) : Unit { new_identifier, NAVAL, unit_args }, - naval_icon { naval_unit_args.naval_icon }, - sail { naval_unit_args.sail }, - transport { naval_unit_args.transport }, - capital { naval_unit_args.capital }, - colonial_points { naval_unit_args.colonial_points }, - build_overseas { naval_unit_args.build_overseas }, - min_port_level { naval_unit_args.min_port_level }, - limit_per_port { naval_unit_args.limit_per_port }, - supply_consumption_score { naval_unit_args.supply_consumption_score }, - hull { naval_unit_args.hull }, - gun_power { naval_unit_args.gun_power }, - fire_range { naval_unit_args.fire_range }, - evasion { naval_unit_args.evasion }, - torpedo_attack { naval_unit_args.torpedo_attack } {} - -void UnitManager::reserve_all_units(size_t size) { - reserve_more_units(size); - reserve_more_land_units(size); - reserve_more_naval_units(size); -} - -void UnitManager::lock_all_units() { - units.lock(); - land_units.lock(); - naval_units.lock(); -} - -static bool _check_shared_parameters(std::string_view identifier, Unit::unit_args_t const& unit_args) { - if (identifier.empty()) { - Logger::error("Invalid unit identifier - empty!"); - return false; - } - - if (unit_args.icon <= 0) { - Logger::error("Invalid icon for unit ", identifier, " - ", unit_args.icon, " (must be positive)"); - return false; - } - - if (unit_args.unit_type == INVALID_UNIT_TYPE) { - Logger::error("Invalid unit type for unit ", identifier, "!"); - return false; - } - - // TODO check that sprite, move_sound and select_sound exist - - return true; -} - -bool UnitManager::add_land_unit( - std::string_view identifier, Unit::unit_args_t& unit_args, LandUnit::land_unit_args_t const& land_unit_args -) { - if (!_check_shared_parameters(identifier, unit_args)) { - return false; - } - - // TODO check that sprite_override, sprite_mount, and sprite_mount_attach_node exist - - if (naval_units.has_identifier(identifier)) { - Logger::error("Land unit ", identifier, " already exists as a naval unit!"); - return false; - } - - bool ret = land_units.add_item({ identifier, unit_args, std::move(land_unit_args) }); - if (ret) { - ret &= units.add_item(&land_units.get_items().back()); - } - return ret; -} - -bool UnitManager::add_naval_unit( - std::string_view identifier, Unit::unit_args_t& unit_args, NavalUnit::naval_unit_args_t const& naval_unit_args -) { - if (!_check_shared_parameters(identifier, unit_args)) { - return false; - } - - if (naval_unit_args.naval_icon <= 0) { - Logger::error("Invalid naval icon identifier - ", naval_unit_args.naval_icon, " (must be positive)"); - return false; - } - - if (naval_unit_args.supply_consumption_score <= 0) { - Logger::warning("Supply consumption score for ", identifier, " is not positive!"); - } - - if (land_units.has_identifier(identifier)) { - Logger::error("Naval unit ", identifier, " already exists as a land unit!"); - return false; - } - - bool ret = naval_units.add_item({ identifier, unit_args, naval_unit_args }); - if (ret) { - ret &= units.add_item(&naval_units.get_items().back()); - } - return ret; -} - -bool UnitManager::load_unit_file( - GoodManager const& good_manager, TerrainTypeManager const& terrain_type_manager, ModifierManager const& modifier_manager, - ast::NodeCPtr root -) { - return expect_dictionary([this, &good_manager, &terrain_type_manager, &modifier_manager]( - std::string_view key, ast::NodeCPtr value - ) -> bool { - - Unit::branch_t branch = INVALID_BRANCH; - - bool ret = expect_key("type", expect_branch_identifier(assign_variable_callback(branch)))(value); - - /* We shouldn't just check ret as it can be false even if branch was successfully parsed, - * but more than one instance of the key was found. */ - if (branch != LAND && branch != NAVAL) { - Logger::error("Failed to read branch for unit: ", key); - return false; - } - - Unit::unit_args_t unit_args {}; - - static const string_map_t unit_type_map { - { "infantry", INFANTRY }, - { "cavalry", CAVALRY }, - { "support", SUPPORT }, - { "special", SPECIAL }, - { "big_ship", BIG_SHIP }, - { "light_ship", LIGHT_SHIP }, - { "transport", TRANSPORT } - }; - - key_map_t key_map {}; - /* Shared dictionary entries */ - ret &= add_key_map_entries(key_map, - "icon", ONE_EXACTLY, expect_uint(assign_variable_callback(unit_args.icon)), - "type", ONE_EXACTLY, success_callback, /* Already loaded above using expect_key */ - "sprite", ONE_EXACTLY, expect_identifier(assign_variable_callback(unit_args.sprite)), - "active", ZERO_OR_ONE, expect_bool(assign_variable_callback(unit_args.active)), - "unit_type", ONE_EXACTLY, - expect_identifier(expect_mapped_string(unit_type_map, assign_variable_callback(unit_args.unit_type))), - "floating_flag", ONE_EXACTLY, expect_bool(assign_variable_callback(unit_args.floating_flag)), - "priority", ONE_EXACTLY, expect_uint(assign_variable_callback(unit_args.priority)), - "max_strength", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(unit_args.max_strength)), - "default_organisation", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(unit_args.default_organisation)), - "maximum_speed", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(unit_args.maximum_speed)), - "weighted_value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(unit_args.weighted_value)), - "move_sound", ZERO_OR_ONE, expect_identifier(assign_variable_callback(unit_args.move_sound)), - "select_sound", ZERO_OR_ONE, expect_identifier(assign_variable_callback(unit_args.select_sound)), - "build_time", ONE_EXACTLY, expect_days(assign_variable_callback(unit_args.build_time)), - "build_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(unit_args.build_cost)), - "supply_consumption", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(unit_args.supply_consumption)), - "supply_cost", ONE_EXACTLY, good_manager.expect_good_decimal_map(move_variable_callback(unit_args.supply_cost)) - ); - - const auto add_terrain_modifier = [&unit_args, &terrain_type_manager, &modifier_manager]( - std::string_view default_key, ast::NodeCPtr default_value - ) -> bool { - TerrainType const* terrain_type = terrain_type_manager.get_terrain_type_by_identifier(default_key); - if (terrain_type != nullptr) { - // TODO - restrict what modifier effects can be used here - return modifier_manager.expect_modifier_value( - map_callback(unit_args.terrain_modifiers, terrain_type) - )(default_value); - } - return key_value_invalid_callback(default_key, default_value); - }; - - switch (branch) { - case LAND: { - LandUnit::land_unit_args_t land_unit_args {}; - bool is_restricted_to_primary_culture = false; - bool is_restricted_to_accepted_cultures = false; - - ret &= add_key_map_entries(key_map, - "primary_culture", ZERO_OR_ONE, expect_bool(assign_variable_callback(is_restricted_to_primary_culture)), - "accepted_culture", ZERO_OR_ONE, expect_bool(assign_variable_callback(is_restricted_to_accepted_cultures)), - "sprite_override", ZERO_OR_ONE, expect_identifier(assign_variable_callback(land_unit_args.sprite_override)), - "sprite_mount", ZERO_OR_ONE, expect_identifier(assign_variable_callback(land_unit_args.sprite_mount)), - "sprite_mount_attach_node", ZERO_OR_ONE, - expect_identifier(assign_variable_callback(land_unit_args.sprite_mount_attach_node)), - "reconnaissance", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_unit_args.reconnaissance)), - "attack", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_unit_args.attack)), - "defence", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_unit_args.defence)), - "discipline", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_unit_args.discipline)), - "support", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_unit_args.support)), - "maneuver", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_unit_args.maneuver)), - "siege", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(land_unit_args.siege)) - ); - - if (is_restricted_to_accepted_cultures) { - land_unit_args.allowed_cultures = LandUnit::allowed_cultures_t::ACCEPTED_CULTURES; - } else if (is_restricted_to_primary_culture) { - land_unit_args.allowed_cultures = LandUnit::allowed_cultures_t::PRIMARY_CULTURE; - } else { - land_unit_args.allowed_cultures = LandUnit::allowed_cultures_t::ALL_CULTURES; - } - - ret &= expect_dictionary_key_map_and_default(key_map, add_terrain_modifier)(value); - - ret &= add_land_unit(key, unit_args, land_unit_args); - - return ret; - } - case NAVAL: { - NavalUnit::naval_unit_args_t naval_unit_args {}; - - ret &= add_key_map_entries(key_map, - "naval_icon", ONE_EXACTLY, expect_uint(assign_variable_callback(naval_unit_args.naval_icon)), - "sail", ZERO_OR_ONE, expect_bool(assign_variable_callback(naval_unit_args.sail)), - "transport", ZERO_OR_ONE, expect_bool(assign_variable_callback(naval_unit_args.transport)), - "capital", ZERO_OR_ONE, expect_bool(assign_variable_callback(naval_unit_args.capital)), - "colonial_points", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(naval_unit_args.colonial_points)), - "can_build_overseas", ZERO_OR_ONE, expect_bool(assign_variable_callback(naval_unit_args.build_overseas)), - "min_port_level", ONE_EXACTLY, expect_uint(assign_variable_callback(naval_unit_args.min_port_level)), - "limit_per_port", ONE_EXACTLY, expect_int(assign_variable_callback(naval_unit_args.limit_per_port)), - "supply_consumption_score", ZERO_OR_ONE, - expect_fixed_point(assign_variable_callback(naval_unit_args.supply_consumption_score)), - "hull", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(naval_unit_args.hull)), - "gun_power", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(naval_unit_args.gun_power)), - "fire_range", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(naval_unit_args.fire_range)), - "evasion", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(naval_unit_args.evasion)), - "torpedo_attack", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(naval_unit_args.torpedo_attack)) - ); - - ret &= expect_dictionary_key_map_and_default(key_map, add_terrain_modifier)(value); - - ret &= add_naval_unit(key, unit_args, naval_unit_args); - - return ret; - } - default: - /* Unreachable - an earlier check terminates the function if branch isn't LAND or NAVAL. */ - Logger::error("Unknown branch for unit ", key, ": ", static_cast(branch)); - return false; - } - })(root); -} - -bool UnitManager::generate_modifiers(ModifierManager& modifier_manager) const { - bool ret = true; - - const auto generate_stat_modifiers = [&modifier_manager, &ret](std::string_view identifier, Unit::branch_t branch) -> void { - const auto stat_modifier = [&modifier_manager, &ret, &identifier]( - std::string_view suffix, bool is_positive_good, ModifierEffect::format_t format - ) -> void { - ret &= modifier_manager.add_modifier_effect( - ModifierManager::get_flat_identifier(identifier, suffix), is_positive_good, format - ); - }; - - using enum ModifierEffect::format_t; - - ret &= modifier_manager.register_complex_modifier(identifier); - - stat_modifier("attack", true, RAW_DECIMAL); - stat_modifier("defence", true, RAW_DECIMAL); - stat_modifier("default_organisation", true, RAW_DECIMAL); - stat_modifier("maximum_speed", true, RAW_DECIMAL); - stat_modifier("build_time", false, INT); - stat_modifier("supply_consumption", false, PROPORTION_DECIMAL); - - switch (branch) { - case LAND: - stat_modifier("reconnaissance", true, RAW_DECIMAL); - stat_modifier("discipline", true, PROPORTION_DECIMAL); - stat_modifier("support", true, PROPORTION_DECIMAL); - stat_modifier("maneuver", true, INT); - stat_modifier("siege", true, RAW_DECIMAL); - break; - case NAVAL: - stat_modifier("colonial_points", true, INT); - stat_modifier("supply_consumption_score", false, INT); - stat_modifier("hull", true, RAW_DECIMAL); - stat_modifier("gun_power", true, RAW_DECIMAL); - stat_modifier("fire_range", true, RAW_DECIMAL); - stat_modifier("evasion", true, PROPORTION_DECIMAL); - stat_modifier("torpedo_attack", true, RAW_DECIMAL); - break; - default: - /* Unreachable - units are only added via add_land_unit or add_naval_unit which set branch to LAND or NAVAL. */ - Logger::error("Invalid branch for unit ", identifier, ": ", static_cast(branch)); - } - }; - - generate_stat_modifiers("army_base", LAND); - for (LandUnit const& land_unit : get_land_units()) { - generate_stat_modifiers(land_unit.get_identifier(), LAND); - } - - generate_stat_modifiers("navy_base", NAVAL); - for (NavalUnit const& naval_unit : get_naval_units()) { - generate_stat_modifiers(naval_unit.get_identifier(), NAVAL); - } - - return ret; -} -- cgit v1.2.3-56-ga3b1