diff options
Diffstat (limited to 'src/openvic-simulation/map/TerrainType.cpp')
-rw-r--r-- | src/openvic-simulation/map/TerrainType.cpp | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/src/openvic-simulation/map/TerrainType.cpp b/src/openvic-simulation/map/TerrainType.cpp index 704e79e..011a3c3 100644 --- a/src/openvic-simulation/map/TerrainType.cpp +++ b/src/openvic-simulation/map/TerrainType.cpp @@ -1,5 +1,8 @@ #include "TerrainType.hpp" +#include <string_view> + +#include "openvic-simulation/modifier/ModifierManager.hpp" #include "openvic-simulation/types/Colour.hpp" using namespace OpenVic; @@ -7,7 +10,8 @@ using namespace OpenVic::NodeTools; TerrainType::TerrainType( std::string_view new_identifier, colour_t new_colour, ModifierValue&& new_modifier, bool new_is_water -) : Modifier { new_identifier, std::move(new_modifier) }, HasColour { new_colour, false }, is_water { new_is_water } {} +) : Modifier { new_identifier, std::move(new_modifier), modifier_type_t::TERRAIN }, HasColour { new_colour, false }, + is_water { new_is_water } {} TerrainTypeMapping::TerrainTypeMapping( std::string_view new_identifier, TerrainType const& new_type, std::vector<index_t>&& new_terrain_indicies, @@ -15,6 +19,38 @@ TerrainTypeMapping::TerrainTypeMapping( ) : HasIdentifier { new_identifier }, type { new_type }, terrain_indices { std::move(new_terrain_indicies) }, priority { new_priority }, has_texture { new_has_texture } {} +bool TerrainTypeManager::generate_modifiers(ModifierManager& modifier_manager) const { + using enum ModifierEffect::format_t; + IndexedMap<TerrainType, ModifierEffectCache::unit_terrain_effects_t>& unit_terrain_effects = + modifier_manager.modifier_effect_cache.unit_terrain_effects; + + unit_terrain_effects.set_keys(&get_terrain_types()); + + constexpr bool has_no_effect = true; + bool ret = true; + for (TerrainType const& terrain_type : get_terrain_types()) { + const std::string_view identifier = terrain_type.get_identifier(); + ModifierEffectCache::unit_terrain_effects_t& this_unit_terrain_effects = unit_terrain_effects[terrain_type]; + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.attack, ModifierManager::get_flat_identifier("attack", identifier), true, + PROPORTION_DECIMAL, "UA_ATTACK", has_no_effect + ); + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.defence, ModifierManager::get_flat_identifier("defence", identifier), true, + PROPORTION_DECIMAL, "UA_DEFENCE", has_no_effect + ); + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.attrition, ModifierManager::get_flat_identifier("attrition", identifier), false, + RAW_DECIMAL, "UA_ATTRITION", has_no_effect + ); + ret &= modifier_manager.register_unit_terrain_modifier_effect( + this_unit_terrain_effects.movement, ModifierManager::get_flat_identifier("movement", identifier), true, + PROPORTION_DECIMAL, "UA_MOVEMENT" + ); + } + return ret; +} + bool TerrainTypeManager::add_terrain_type( std::string_view identifier, colour_t colour, ModifierValue&& values, bool is_water ) { @@ -22,6 +58,7 @@ bool TerrainTypeManager::add_terrain_type( Logger::error("Invalid terrain type identifier - empty!"); return false; } + return terrain_types.add_item({ identifier, colour, std::move(values), is_water }); } @@ -33,17 +70,22 @@ bool TerrainTypeManager::add_terrain_type_mapping( Logger::error("Cannot register terrain type mappings until terrain types are locked!"); return false; } + if (identifier.empty()) { Logger::error("Invalid terrain type mapping identifier - empty!"); return false; } + if (type == nullptr) { Logger::error("Null terrain type for mapping ", identifier); return false; } + bool ret = true; + for (TerrainTypeMapping::index_t idx : terrain_indicies) { const terrain_type_mappings_map_t::const_iterator it = terrain_type_mappings_map.find(idx); + if (it == terrain_type_mappings_map.end()) { terrain_type_mappings_map.emplace(idx, terrain_type_mappings.size()); } else { @@ -54,7 +96,9 @@ bool TerrainTypeManager::add_terrain_type_mapping( ret = false; } } + ret &= terrain_type_mappings.add_item({ identifier, *type, std::move(terrain_indicies), priority, has_texture }); + return ret; } @@ -65,15 +109,21 @@ node_callback_t TerrainTypeManager::_load_terrain_type_categories(ModifierManage ModifierValue values; colour_t colour = colour_t::null(); bool is_water = false; - bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(values), + + bool ret = NodeTools::expect_dictionary_keys_and_default( + modifier_manager.expect_terrain_modifier(values), "color", ONE_EXACTLY, expect_colour(assign_variable_callback(colour)), "is_water", ZERO_OR_ONE, expect_bool(assign_variable_callback(is_water)) )(type_node); + ret &= add_terrain_type(type_key, colour, std::move(values), is_water); + return ret; } )(root); + lock_terrain_types(); + return ret; }; } @@ -83,10 +133,12 @@ bool TerrainTypeManager::_load_terrain_type_mapping(std::string_view mapping_key Logger::error("Cannot define terrain type mapping before terrain texture limit: ", mapping_key); return false; } + if (!terrain_types_are_locked()) { Logger::error("Cannot define terrain type mapping before categories: ", mapping_key); return false; } + TerrainType const* type = nullptr; std::vector<TerrainTypeMapping::index_t> terrain_indicies; TerrainTypeMapping::index_t priority = 0; @@ -107,18 +159,23 @@ bool TerrainTypeManager::_load_terrain_type_mapping(std::string_view mapping_key "priority", ZERO_OR_ONE, expect_uint(assign_variable_callback(priority)), "has_texture", ZERO_OR_ONE, expect_bool(assign_variable_callback(has_texture)) )(mapping_value); + if (has_texture && ++terrain_texture_count == terrain_texture_limit + 1) { Logger::warning("More terrain textures than limit!"); } + ret &= add_terrain_type_mapping(mapping_key, type, std::move(terrain_indicies), priority, has_texture); + return true; } TerrainTypeMapping const* TerrainTypeManager::get_terrain_type_mapping_for(TerrainTypeMapping::index_t idx) const { const terrain_type_mappings_map_t::const_iterator it = terrain_type_mappings_map.find(idx); + if (it != terrain_type_mappings_map.end()) { return terrain_type_mappings.get_item_by_index(it->second); } + return nullptr; } @@ -135,6 +192,8 @@ bool TerrainTypeManager::load_terrain_types(ModifierManager const& modifier_mana "terrain", ONE_EXACTLY, expect_uint(assign_variable_callback(terrain_texture_limit)), "categories", ONE_EXACTLY, _load_terrain_type_categories(modifier_manager) )(root); + lock_terrain_type_mappings(); + return ret; } |