aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/map/TerrainType.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/map/TerrainType.cpp')
-rw-r--r--src/openvic-simulation/map/TerrainType.cpp63
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;
}