aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author hop311 <hop3114@gmail.com>2023-11-14 22:27:39 +0100
committer hop311 <hop3114@gmail.com>2023-11-15 21:06:16 +0100
commite031758cf68535e97045c07f36e2524676447778 (patch)
treed6e49915c414c86ce808b2e1d7289c7e4e7d76df
parenta00b558a53edb40c9e6789790036f0b618e80ec1 (diff)
Striped mapmode and improved distributions
-rw-r--r--src/openvic-simulation/GameManager.cpp131
-rw-r--r--src/openvic-simulation/Modifier.hpp2
-rw-r--r--src/openvic-simulation/country/CountryInstance.hpp2
-rw-r--r--src/openvic-simulation/economy/Good.hpp2
-rw-r--r--src/openvic-simulation/history/CountryHistory.hpp2
-rw-r--r--src/openvic-simulation/history/ProvinceHistory.hpp2
-rw-r--r--src/openvic-simulation/map/Map.cpp29
-rw-r--r--src/openvic-simulation/map/Map.hpp14
-rw-r--r--src/openvic-simulation/map/Province.cpp2
-rw-r--r--src/openvic-simulation/map/Province.hpp12
-rw-r--r--src/openvic-simulation/map/Region.cpp13
-rw-r--r--src/openvic-simulation/map/Region.hpp3
-rw-r--r--src/openvic-simulation/military/Wargoal.hpp2
-rw-r--r--src/openvic-simulation/politics/NationalFocus.hpp6
-rw-r--r--src/openvic-simulation/pop/Pop.hpp2
-rw-r--r--src/openvic-simulation/types/Colour.hpp2
-rw-r--r--src/openvic-simulation/types/IdentifierRegistry.hpp23
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPointMap.hpp48
18 files changed, 187 insertions, 110 deletions
diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp
index 427fbb1..755ab37 100644
--- a/src/openvic-simulation/GameManager.cpp
+++ b/src/openvic-simulation/GameManager.cpp
@@ -61,14 +61,58 @@ bool GameManager::expand_building(Province::index_t province_index, std::string_
return province->expand_building(building_type_identifier);
}
-static constexpr colour_t LOW_ALPHA_VALUE = float_to_alpha_value(0.4f);
-static constexpr colour_t HIGH_ALPHA_VALUE = float_to_alpha_value(0.7f);
-
-static colour_t default_colour(Province const& province) {
- /* Nice looking colours to blend with the terrain textures */
- static constexpr colour_t LAND_COLOUR = 0x0D7017;
- static constexpr colour_t WATER_COLOUR = 0x4287F5;
- return LOW_ALPHA_VALUE | (province.get_water() ? WATER_COLOUR : LAND_COLOUR);
+static constexpr colour_t ALPHA_VALUE = float_to_alpha_value(0.5f);
+
+static constexpr Mapmode::base_stripe_t combine_base_stripe(colour_t base, colour_t stripe) {
+ return (static_cast<Mapmode::base_stripe_t>(stripe) << (sizeof(colour_t) * 8)) | base;
+}
+
+static constexpr Mapmode::base_stripe_t make_solid_base_stripe(colour_t colour) {
+ return combine_base_stripe(colour, colour);
+}
+
+static constexpr auto make_solid_base_stripe_func(auto func) {
+ return [func](Map const& map, Province const& province) -> Mapmode::base_stripe_t {
+ return make_solid_base_stripe(func(map, province));
+ };
+}
+
+template<std::derived_from<HasColour> T>
+static constexpr Mapmode::base_stripe_t get_colour_mapmode(T const* item) {
+ return item != nullptr ? make_solid_base_stripe(ALPHA_VALUE | item->get_colour()) : NULL_COLOUR;
+}
+
+template<std::derived_from<HasColour> T>
+static constexpr auto get_colour_mapmode(T const*(Province::*get_item)() const) {
+ return [get_item](Map const& map, Province const& province) -> Mapmode::base_stripe_t {
+ T const* item = (province.*get_item)();
+ return item != nullptr ? make_solid_base_stripe(ALPHA_VALUE | item->get_colour()) : NULL_COLOUR;
+ };
+}
+
+template<std::derived_from<HasColour> T>
+static constexpr Mapmode::base_stripe_t shaded_mapmode(fixed_point_map_t<T const*> const& map) {
+ const std::pair<fixed_point_map_const_iterator_t<T const*>, fixed_point_map_const_iterator_t<T const*>> largest =
+ get_largest_two_items(map);
+ if (largest.first != map.end()) {
+ const colour_t base_colour = ALPHA_VALUE | largest.first->first->get_colour();
+ if (largest.second != map.end()) {
+ /* If second largest is at least a third... */
+ if (largest.second->second * 3 >= get_total(map)) {
+ const colour_t stripe_colour = ALPHA_VALUE | largest.second->first->get_colour();
+ return combine_base_stripe(base_colour, stripe_colour);
+ }
+ }
+ return make_solid_base_stripe(base_colour);
+ }
+ return NULL_COLOUR;
+}
+
+template<std::derived_from<HasColour> T>
+static constexpr auto shaded_mapmode(fixed_point_map_t<T const*> const&(Province::*get_map)() const) {
+ return [get_map](Map const& map, Province const& province) -> Mapmode::base_stripe_t {
+ return shaded_mapmode((province.*get_map)());
+ };
}
bool GameManager::load_hardcoded_defines() {
@@ -78,48 +122,39 @@ bool GameManager::load_hardcoded_defines() {
const std::vector<mapmode_t> mapmodes {
{
"mapmode_terrain",
- [](Map const&, Province const& province) -> colour_t {
- return default_colour(province);
+ [](Map const&, Province const& province) -> Mapmode::base_stripe_t {
+ return NULL_COLOUR;
}
},
{
+ "mapmode_political", get_colour_mapmode(&Province::get_owner)
+ },
+ {
"mapmode_province",
- [](Map const&, Province const& province) -> colour_t {
- return HIGH_ALPHA_VALUE | province.get_colour();
- }
+ make_solid_base_stripe_func([](Map const&, Province const& province) -> colour_t {
+ return ALPHA_VALUE | province.get_colour();
+ })
},
{
- "mapmode_region",
- [](Map const&, Province const& province) -> colour_t {
- Region const* region = province.get_region();
- return region != nullptr ? HIGH_ALPHA_VALUE | region->get_colour() : default_colour(province);
- }
+ "mapmode_region", get_colour_mapmode(&Province::get_region)
},
{
"mapmode_index",
- [](Map const& map, Province const& province) -> colour_t {
+ make_solid_base_stripe_func([](Map const& map, Province const& province) -> colour_t {
const colour_t f = fraction_to_colour_byte(province.get_index(), map.get_province_count() + 1);
- return HIGH_ALPHA_VALUE | (f << 16) | (f << 8) | f;
- }
+ return ALPHA_VALUE | (f << 16) | (f << 8) | f;
+ })
},
{
- "mapmode_terrain_type",
- [](Map const& map, Province const& province) -> colour_t {
- TerrainType const* terrarin_type = province.get_terrain_type();
- return terrarin_type != nullptr ? HIGH_ALPHA_VALUE | terrarin_type->get_colour() : default_colour(province);
- }
+ "mapmode_terrain_type", get_colour_mapmode(&Province::get_terrain_type)
},
{
- "mapmode_rgo",
- [](Map const& map, Province const& province) -> colour_t {
- Good const* rgo = province.get_rgo();
- return rgo != nullptr ? HIGH_ALPHA_VALUE | rgo->get_colour() : default_colour(province);
- }
+ "mapmode_rgo", get_colour_mapmode(&Province::get_rgo)
},
{
"mapmode_infrastructure",
- [](Map const& map, Province const& province) -> colour_t {
- BuildingInstance const* railroad = province.get_building_by_identifier("building_railroad");
+ make_solid_base_stripe_func([](Map const& map, Province const& province) -> colour_t {
+ BuildingInstance const* railroad = province.get_building_by_identifier("railroad");
if (railroad != nullptr) {
colour_t val = fraction_to_colour_byte(railroad->get_current_level(),
railroad->get_building().get_max_level() + 1, 0.5f, 1.0f);
@@ -133,32 +168,30 @@ bool GameManager::load_hardcoded_defines() {
val <<= 8;
break;
}
- return HIGH_ALPHA_VALUE | val;
+ return ALPHA_VALUE | val;
}
- return default_colour(province);
- }
+ return NULL_COLOUR;
+ })
},
{
"mapmode_population",
- [](Map const& map, Province const& province) -> colour_t {
- return HIGH_ALPHA_VALUE | (fraction_to_colour_byte(province.get_total_population(), map.get_highest_province_population() + 1, 0.1f, 1.0f) << 8);
- }
+ make_solid_base_stripe_func([](Map const& map, Province const& province) -> colour_t {
+ // TODO - explore non-linear scaling to have more variation among non-massive provinces
+ // TODO - when selecting a province, only show the population of provinces controlled (or owned?)
+ // by the same country, relative to the most populous province in that set of provinces
+ return ALPHA_VALUE | (fraction_to_colour_byte(
+ province.get_total_population(), map.get_highest_province_population() + 1, 0.1f, 1.0f
+ ) << 8);
+ })
},
{
- "mapmode_culture",
- [](Map const& map, Province const& province) -> colour_t {
- HasIdentifierAndColour const* largest = get_largest_item(province.get_culture_distribution()).first;
- return largest != nullptr ? HIGH_ALPHA_VALUE | largest->get_colour() : default_colour(province);
- }
+ "mapmode_culture", shaded_mapmode(&Province::get_culture_distribution)
},
{
- "mapmode_religion",
- [](Map const& map, Province const& province) -> colour_t {
- HasIdentifierAndColour const* largest = get_largest_item(province.get_religion_distribution()).first;
- return largest != nullptr ? HIGH_ALPHA_VALUE | largest->get_colour() : default_colour(province);
- }
+ "mapmode_religion", shaded_mapmode(&Province::get_religion_distribution)
}
};
+
for (mapmode_t const& mapmode : mapmodes) {
ret &= map.add_mapmode(mapmode.first, mapmode.second);
}
diff --git a/src/openvic-simulation/Modifier.hpp b/src/openvic-simulation/Modifier.hpp
index fc37655..084a0c2 100644
--- a/src/openvic-simulation/Modifier.hpp
+++ b/src/openvic-simulation/Modifier.hpp
@@ -36,7 +36,7 @@ namespace OpenVic {
struct ModifierValue {
friend struct ModifierManager;
- using effect_map_t = decimal_map_t<ModifierEffect const*>;
+ using effect_map_t = fixed_point_map_t<ModifierEffect const*>;
private:
effect_map_t values;
diff --git a/src/openvic-simulation/country/CountryInstance.hpp b/src/openvic-simulation/country/CountryInstance.hpp
index 6510ecf..99461b5 100644
--- a/src/openvic-simulation/country/CountryInstance.hpp
+++ b/src/openvic-simulation/country/CountryInstance.hpp
@@ -15,7 +15,7 @@ namespace OpenVic {
Religion const* PROPERTY_RW(religion);
CountryParty const* PROPERTY_RW(ruling_party);
Date PROPERTY_RW(last_election);
- decimal_map_t<Ideology const*> PROPERTY(upper_house);
+ fixed_point_map_t<Ideology const*> PROPERTY(upper_house);
Province const* PROPERTY_RW(capital);
GovernmentType const* PROPERTY_RW(government_type);
fixed_point_t PROPERTY_RW(plurality);
diff --git a/src/openvic-simulation/economy/Good.hpp b/src/openvic-simulation/economy/Good.hpp
index ae2d6a9..bec5cca 100644
--- a/src/openvic-simulation/economy/Good.hpp
+++ b/src/openvic-simulation/economy/Good.hpp
@@ -33,7 +33,7 @@ namespace OpenVic {
using price_t = fixed_point_t;
static constexpr price_t NULL_PRICE = fixed_point_t::_0();
- using good_map_t = decimal_map_t<Good const*>;
+ using good_map_t = fixed_point_map_t<Good const*>;
private:
GoodCategory const& category;
diff --git a/src/openvic-simulation/history/CountryHistory.hpp b/src/openvic-simulation/history/CountryHistory.hpp
index ffb44c0..ed200bf 100644
--- a/src/openvic-simulation/history/CountryHistory.hpp
+++ b/src/openvic-simulation/history/CountryHistory.hpp
@@ -31,7 +31,7 @@ namespace OpenVic {
std::optional<Religion const*> PROPERTY(religion);
std::optional<CountryParty const*> PROPERTY(ruling_party);
std::optional<Date> PROPERTY(last_election);
- decimal_map_t<Ideology const*> PROPERTY(upper_house);
+ fixed_point_map_t<Ideology const*> PROPERTY(upper_house);
std::optional<Province const*> PROPERTY(capital);
std::optional<GovernmentType const*> PROPERTY(government_type);
std::optional<fixed_point_t> PROPERTY(plurality);
diff --git a/src/openvic-simulation/history/ProvinceHistory.hpp b/src/openvic-simulation/history/ProvinceHistory.hpp
index 5a18723..313f3a4 100644
--- a/src/openvic-simulation/history/ProvinceHistory.hpp
+++ b/src/openvic-simulation/history/ProvinceHistory.hpp
@@ -33,7 +33,7 @@ namespace OpenVic {
std::optional<Province::life_rating_t> PROPERTY(life_rating);
std::optional<TerrainType const*> PROPERTY(terrain_type);
building_level_map_t PROPERTY(buildings);
- decimal_map_t<Ideology const*> PROPERTY(party_loyalties);
+ fixed_point_map_t<Ideology const*> PROPERTY(party_loyalties);
ProvinceHistoryEntry(Province const& new_province, Date new_date);
};
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index 7e2213e..261a13e 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -24,7 +24,7 @@ Mapmode::index_t Mapmode::get_index() const {
return index;
}
-colour_t Mapmode::get_colour(Map const& map, Province const& province) const {
+Mapmode::base_stripe_t Mapmode::get_base_stripe_colours(Map const& map, Province const& province) const {
return colour_func ? colour_func(map, province) : NULL_COLOUR;
}
@@ -254,15 +254,23 @@ bool Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) cons
mapmode = &Mapmode::ERROR_MAPMODE;
}
// Skip past Province::NULL_INDEX
- for (size_t i = 0; i < MAPMODE_COLOUR_SIZE; ++i) {
+ for (size_t i = 0; i < sizeof(Mapmode::base_stripe_t); ++i) {
*target++ = 0;
}
for (Province const& province : provinces.get_items()) {
- const colour_t colour = mapmode->get_colour(*this, province);
- *target++ = (colour >> 16) & FULL_COLOUR;
- *target++ = (colour >> 8) & FULL_COLOUR;
- *target++ = colour & FULL_COLOUR;
- *target++ = (colour >> 24) & FULL_COLOUR;
+ const Mapmode::base_stripe_t base_stripe = mapmode->get_base_stripe_colours(*this, province);
+ const colour_t base_colour = static_cast<colour_t>(base_stripe);
+ const colour_t stripe_colour = static_cast<colour_t>(base_stripe >> (sizeof(colour_t) * 8));
+
+ *target++ = (base_colour >> 16) & COLOUR_COMPONENT; // red
+ *target++ = (base_colour >> 8) & COLOUR_COMPONENT; // green
+ *target++ = (base_colour >> 0) & COLOUR_COMPONENT; // blue
+ *target++ = (base_colour >> 24) & COLOUR_COMPONENT; // alpha
+
+ *target++ = (stripe_colour >> 16) & COLOUR_COMPONENT; // red
+ *target++ = (stripe_colour >> 8) & COLOUR_COMPONENT; // green
+ *target++ = (stripe_colour >> 0) & COLOUR_COMPONENT; // blue
+ *target++ = (stripe_colour >> 24) & COLOUR_COMPONENT; // alpha
}
return ret;
}
@@ -489,7 +497,7 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain
uint8_t const* terrain_data = terrain_bmp.get_pixel_data().data();
std::vector<bool> province_checklist(provinces.size());
- std::vector<decimal_map_t<TerrainType const*>> terrain_type_pixels_list(provinces.size());
+ std::vector<fixed_point_map_t<TerrainType const*>> terrain_type_pixels_list(provinces.size());
bool ret = true;
std::unordered_set<colour_t> unrecognised_province_colours;
@@ -553,9 +561,8 @@ bool Map::load_map_images(fs::path const& province_path, fs::path const& terrain
size_t missing = 0;
for (size_t idx = 0; idx < province_checklist.size(); ++idx) {
Province* province = provinces.get_item_by_index(idx);
- province->_set_terrain_type(
- reinterpret_cast<TerrainType const*>(get_largest_item(terrain_type_pixels_list[idx]).first)
- );
+ const fixed_point_map_const_iterator_t<TerrainType const*> largest = get_largest_item(terrain_type_pixels_list[idx]);
+ province->_set_terrain_type(largest != terrain_type_pixels_list[idx].end() ? largest->first : nullptr);
province->on_map = province_checklist[idx];
if (!province->on_map) {
if (detailed_errors) {
diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp
index d11ad8e..db67390 100644
--- a/src/openvic-simulation/map/Map.hpp
+++ b/src/openvic-simulation/map/Map.hpp
@@ -14,7 +14,10 @@ namespace OpenVic {
struct Mapmode : HasIdentifier {
friend struct Map;
- using colour_func_t = std::function<colour_t(Map const&, Province const&)>;
+ /* Bottom 32 bits are the base colour, top 32 are the stripe colour, both in ARGB format with the alpha channels
+ * controlling interpolation with the terrain colour (0 = all terrain, 255 = all corresponding RGB) */
+ using base_stripe_t = uint64_t;
+ using colour_func_t = std::function<base_stripe_t(Map const&, Province const&)>;
using index_t = size_t;
private:
@@ -29,7 +32,7 @@ namespace OpenVic {
Mapmode(Mapmode&&) = default;
index_t get_index() const;
- colour_t get_colour(Map const& map, Province const& province) const;
+ base_stripe_t get_base_stripe_colours(Map const& map, Province const& province) const;
};
struct GoodManager;
@@ -98,7 +101,12 @@ namespace OpenVic {
bool add_mapmode(std::string_view identifier, Mapmode::colour_func_t colour_func);
IDENTIFIER_REGISTRY_ACCESSORS(mapmode)
Mapmode const* get_mapmode_by_index(size_t index) const;
- static constexpr size_t MAPMODE_COLOUR_SIZE = 4;
+
+ /* The mapmode colour image contains of a list of base colours and stripe colours. Each colour is four bytes
+ * in RGBA format, with the alpha value being used to interpolate with the terrain colour, so A = 0 is fully terrain
+ * and A = 255 is fully the RGB colour packaged with A. The base and stripe colours for each province are packed
+ * together adjacently, so each province's entry is 8 bytes long. The list contains Province::MAX_INDEX + 1 entries,
+ * that is the maximum allowed number of provinces plus one for the index-zero "null province". */
bool generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) const;
bool setup(BuildingManager const& building_manager, PopManager const& pop_manager);
diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp
index 4b76210..1b47dea 100644
--- a/src/openvic-simulation/map/Province.cpp
+++ b/src/openvic-simulation/map/Province.cpp
@@ -16,7 +16,7 @@ Province::index_t Province::get_index() const {
return index;
}
-Region* Province::get_region() const {
+Region const* Province::get_region() const {
return region;
}
diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp
index eda05fb..21a974f 100644
--- a/src/openvic-simulation/map/Province.hpp
+++ b/src/openvic-simulation/map/Province.hpp
@@ -65,7 +65,7 @@ namespace OpenVic {
private:
const index_t index;
- Region* region = nullptr;
+ Region const* region = nullptr;
bool on_map = false, has_region = false, water = false;
life_rating_t life_rating = 0;
colony_status_t colony_status = colony_status_t::STATE;
@@ -75,10 +75,10 @@ namespace OpenVic {
std::vector<Pop> pops;
Pop::pop_size_t total_population;
- decimal_map_t<PopType const*> PROPERTY(pop_type_distribution);
- decimal_map_t<Ideology const*> PROPERTY(ideology_distribution);
- decimal_map_t<Culture const*> PROPERTY(culture_distribution);
- decimal_map_t<Religion const*> PROPERTY(religion_distribution);
+ fixed_point_map_t<PopType const*> PROPERTY(pop_type_distribution);
+ fixed_point_map_t<Ideology const*> PROPERTY(ideology_distribution);
+ fixed_point_map_t<Culture const*> PROPERTY(culture_distribution);
+ fixed_point_map_t<Religion const*> PROPERTY(religion_distribution);
std::vector<adjacency_t> adjacencies;
province_positions_t positions;
@@ -98,7 +98,7 @@ namespace OpenVic {
Province(Province&&) = default;
index_t get_index() const;
- Region* get_region() const;
+ Region const* get_region() const;
bool get_on_map() const;
bool get_has_region() const;
bool get_water() const;
diff --git a/src/openvic-simulation/map/Region.cpp b/src/openvic-simulation/map/Region.cpp
index ac232df..e33d9c9 100644
--- a/src/openvic-simulation/map/Region.cpp
+++ b/src/openvic-simulation/map/Region.cpp
@@ -65,18 +65,15 @@ ProvinceSet::provinces_t const& ProvinceSet::get_provinces() const {
return provinces;
}
+static constexpr colour_t ERROR_REGION_COLOUR = COLOUR_COMPONENT << 16;
+
Region::Region(std::string_view new_identifier, provinces_t&& new_provinces, bool new_meta)
- : HasIdentifier { new_identifier }, ProvinceSet { std::move(new_provinces) }, meta { new_meta } {
+ : HasIdentifierAndColour {
+ new_identifier, new_provinces.size() > 0 ? new_provinces.front()->get_colour() : ERROR_REGION_COLOUR, false, false
+ }, ProvinceSet { std::move(new_provinces) }, meta { new_meta } {
lock();
}
bool Region::get_meta() const {
return meta;
}
-
-colour_t Region::get_colour() const {
- if (empty()) {
- return FULL_COLOUR << 16;
- }
- return get_provinces().front()->get_colour();
-}
diff --git a/src/openvic-simulation/map/Region.hpp b/src/openvic-simulation/map/Region.hpp
index 157b643..9119b93 100644
--- a/src/openvic-simulation/map/Region.hpp
+++ b/src/openvic-simulation/map/Region.hpp
@@ -28,7 +28,7 @@ namespace OpenVic {
/* REQUIREMENTS:
* MAP-6, MAP-44, MAP-48
*/
- struct Region : HasIdentifier, ProvinceSet {
+ struct Region : HasIdentifierAndColour, ProvinceSet {
friend struct Map;
private:
@@ -44,6 +44,5 @@ namespace OpenVic {
Region(Region&&) = default;
bool get_meta() const;
- colour_t get_colour() const;
};
}
diff --git a/src/openvic-simulation/military/Wargoal.hpp b/src/openvic-simulation/military/Wargoal.hpp
index 3700347..b34d64f 100644
--- a/src/openvic-simulation/military/Wargoal.hpp
+++ b/src/openvic-simulation/military/Wargoal.hpp
@@ -47,7 +47,7 @@ namespace OpenVic {
WAR_SCORE_BATTLE_FACTOR,
CONSTRUCTION_SPEED
};
- using peace_modifiers_t = decimal_map_t<PEACE_MODIFIERS>;
+ using peace_modifiers_t = fixed_point_map_t<PEACE_MODIFIERS>;
private:
const std::string PROPERTY(sprite);
diff --git a/src/openvic-simulation/politics/NationalFocus.hpp b/src/openvic-simulation/politics/NationalFocus.hpp
index 7c5e40a..e7d1f90 100644
--- a/src/openvic-simulation/politics/NationalFocus.hpp
+++ b/src/openvic-simulation/politics/NationalFocus.hpp
@@ -23,9 +23,9 @@ namespace OpenVic {
friend struct NationalFocusManager;
public:
- using pop_promotion_map_t = std::map<PopType const*, fixed_point_t>;
- using party_loyalty_map_t = std::map<Ideology const*, fixed_point_t>;
- using production_map_t = std::map<Good const*, fixed_point_t>;
+ using pop_promotion_map_t = fixed_point_map_t<PopType const*>;
+ using party_loyalty_map_t = fixed_point_map_t<Ideology const*>;
+ using production_map_t = fixed_point_map_t<Good const*>;
private:
uint8_t PROPERTY(icon);
diff --git a/src/openvic-simulation/pop/Pop.hpp b/src/openvic-simulation/pop/Pop.hpp
index 4abb2a9..f7f20fe 100644
--- a/src/openvic-simulation/pop/Pop.hpp
+++ b/src/openvic-simulation/pop/Pop.hpp
@@ -49,7 +49,7 @@ namespace OpenVic {
friend struct PopManager;
using sprite_t = uint8_t;
- using rebel_units_t = decimal_map_t<Unit const*>;
+ using rebel_units_t = fixed_point_map_t<Unit const*>;
private:
const enum class strata_t { POOR, MIDDLE, RICH } strata;
diff --git a/src/openvic-simulation/types/Colour.hpp b/src/openvic-simulation/types/Colour.hpp
index e516d5b..7c97b12 100644
--- a/src/openvic-simulation/types/Colour.hpp
+++ b/src/openvic-simulation/types/Colour.hpp
@@ -15,7 +15,7 @@ namespace OpenVic {
* When colour_t is used in a purely graphical context, NULL_COLOUR
* should be allowed.
*/
- static constexpr colour_t NULL_COLOUR = 0, FULL_COLOUR = 0xFF;
+ static constexpr colour_t NULL_COLOUR = 0, COLOUR_COMPONENT = 0xFF;
static constexpr colour_t MAX_COLOUR_RGB = 0xFFFFFF, MAX_COLOUR_ARGB = 0xFFFFFFFF;
constexpr colour_t float_to_colour_byte(float f, float min = 0.0f, float max = 1.0f) {
diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp
index 662815e..3794dd6 100644
--- a/src/openvic-simulation/types/IdentifierRegistry.hpp
+++ b/src/openvic-simulation/types/IdentifierRegistry.hpp
@@ -6,6 +6,7 @@
#include <vector>
#include "openvic-simulation/dataloader/NodeTools.hpp"
+#include "openvic-simulation/types/fixed_point/FixedPointMap.hpp"
#include "openvic-simulation/utility/Getters.hpp"
#include "openvic-simulation/utility/Logger.hpp"
@@ -77,22 +78,6 @@ namespace OpenVic {
HasIdentifierAndColour& operator=(HasIdentifierAndColour&&) = delete;
};
- template<typename T>
- using decimal_map_t = std::map<T, fixed_point_t>;
-
- template<typename T>
- constexpr typename decimal_map_t<T>::value_type get_largest_item(decimal_map_t<T> const& map) {
- constexpr auto pred = [](typename decimal_map_t<T>::value_type a, typename decimal_map_t<T>::value_type b) -> bool {
- return a.second < b.second;
- };
- const typename decimal_map_t<T>::const_iterator result = std::max_element(map.begin(), map.end(), pred);
- if (result != map.end()) {
- return *result;
- } else {
- return { nullptr, -1 };
- }
- }
-
/* Callbacks for trying to add duplicate keys via UniqueKeyRegistry::add_item */
static bool duplicate_fail_callback(std::string_view registry_name, std::string_view duplicate_identifier) {
Logger::error(
@@ -274,10 +259,10 @@ namespace OpenVic {
}
NodeTools::node_callback_t expect_item_decimal_map(
- NodeTools::callback_t<decimal_map_t<value_type const*>&&> callback
+ NodeTools::callback_t<fixed_point_map_t<value_type const*>&&> callback
) const {
return [this, callback](ast::NodeCPtr node) -> bool {
- decimal_map_t<value_type const*> map;
+ fixed_point_map_t<value_type const*> map;
bool ret = expect_item_dictionary([&map](value_type const& key, ast::NodeCPtr value) -> bool {
fixed_point_t val;
const bool ret = NodeTools::expect_fixed_point(NodeTools::assign_variable_callback(val))(value);
@@ -370,7 +355,7 @@ namespace OpenVic {
return plural.expect_item_dictionary(callback); \
} \
NodeTools::node_callback_t expect_##singular##_decimal_map( \
- NodeTools::callback_t<decimal_map_t<decltype(plural)::value_type const*>&&> callback \
+ NodeTools::callback_t<fixed_point_map_t<decltype(plural)::value_type const*>&&> callback \
) const { \
return plural.expect_item_decimal_map(callback); \
}
diff --git a/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp b/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
new file mode 100644
index 0000000..a7d298b
--- /dev/null
+++ b/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
+
+namespace OpenVic {
+
+ template<typename T>
+ using fixed_point_map_t = std::map<T, fixed_point_t>;
+
+ template<typename T>
+ using fixed_point_map_value_t = typename fixed_point_map_t<T>::value_type;
+
+ template<typename T>
+ using fixed_point_map_const_iterator_t = typename fixed_point_map_t<T>::const_iterator;
+
+ template<typename T>
+ constexpr fixed_point_t get_total(fixed_point_map_t<T> const& map) {
+ fixed_point_t total = 0;
+ for (auto const& [key, value] : map) {
+ total += value;
+ }
+ return total;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_const_iterator_t<T> get_largest_item(fixed_point_map_t<T> const& map) {
+ constexpr auto pred = [](fixed_point_map_value_t<T> a, fixed_point_map_value_t<T> b) -> bool {
+ return a.second < b.second;
+ };
+ return std::max_element(map.begin(), map.end(), pred);
+ }
+
+ template<typename T>
+ constexpr std::pair<fixed_point_map_const_iterator_t<T>, fixed_point_map_const_iterator_t<T>> get_largest_two_items(
+ fixed_point_map_t<T> const& map
+ ) {
+ fixed_point_map_const_iterator_t<T> largest = map.end(), second_largest = map.end();
+ for (fixed_point_map_const_iterator_t<T> it = map.begin(); it != map.end(); ++it) {
+ if (largest == map.end() || it->second > largest->second) {
+ second_largest = largest;
+ largest = it;
+ } else if (second_largest == map.end() || it->second > second_largest->second) {
+ second_largest = it;
+ }
+ }
+ return std::make_pair(std::move(largest), std::move(second_largest));
+ }
+}