Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/openvic-simulation/core/template/Concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,9 @@ namespace OpenVic {
concept mul_add_assignable = requires(Lhs& lhs, const A a, const B b) {
{ lhs += a * b } -> std::same_as<Lhs&>;
};

template<typename Lhs, typename Rhs = Lhs>
concept equalable = requires(Lhs const& lhs, Rhs const& rhs) {
{ lhs == rhs } -> std::convertible_to<bool>;
};
}
69 changes: 35 additions & 34 deletions src/openvic-simulation/country/CountryInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/types/IndexedFlatMap.hpp"
#include "openvic-simulation/types/PopSize.hpp"
#include "openvic-simulation/population/PopSize.hpp"
#include "openvic-simulation/population/PopSum.hpp"
#include "openvic-simulation/types/UnitBranchType.hpp"
#include "openvic-simulation/utility/Containers.hpp"
#include "openvic-simulation/utility/Logger.hpp"
Expand Down Expand Up @@ -782,8 +783,8 @@ bool CountryInstance::modify_unit_type_unlock(UnitTypeBranched<Branch> const& un
if (unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for unit type {} in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
unit_type, *this, static_cast<int64_t>(unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(unlock_level + unlock_level_change)
unit_type, *this, unlock_level,
unlock_level_change, unlock_level + unlock_level_change
);
return false;
}
Expand Down Expand Up @@ -842,7 +843,7 @@ bool CountryInstance::modify_unit_type_unlock(UnitType const& unit_type, technol
}

bool CountryInstance::unlock_unit_type(UnitType const& unit_type) {
return modify_unit_type_unlock(unit_type, 1);
return modify_unit_type_unlock(unit_type, technology_unlock_level_t { 1 });
}

bool CountryInstance::is_unit_type_unlocked(UnitType const& unit_type) const {
Expand Down Expand Up @@ -871,8 +872,8 @@ bool CountryInstance::modify_building_type_unlock(
if (unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for building type {} in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
building_type, *this, static_cast<int64_t>(unlock_level), static_cast<int64_t>(unlock_level_change),
static_cast<int64_t>(unlock_level + unlock_level_change)
building_type, *this, unlock_level, unlock_level_change,
unlock_level + unlock_level_change
);
return false;
}
Expand All @@ -887,7 +888,7 @@ bool CountryInstance::modify_building_type_unlock(
}

bool CountryInstance::unlock_building_type(BuildingType const& building_type) {
return modify_building_type_unlock(building_type, 1);
return modify_building_type_unlock(building_type, technology_unlock_level_t { 1 });
}

bool CountryInstance::is_building_type_unlocked(BuildingType const& building_type) const {
Expand All @@ -901,8 +902,8 @@ bool CountryInstance::modify_crime_unlock(Crime const& crime, technology_unlock_
if (unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for crime {} in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
crime, *this, static_cast<int64_t>(unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(unlock_level + unlock_level_change)
crime, *this, unlock_level,
unlock_level_change, unlock_level + unlock_level_change
);
return false;
}
Expand All @@ -913,7 +914,7 @@ bool CountryInstance::modify_crime_unlock(Crime const& crime, technology_unlock_
}

bool CountryInstance::unlock_crime(Crime const& crime) {
return modify_crime_unlock(crime, 1);
return modify_crime_unlock(crime, technology_unlock_level_t { 1 });
}

bool CountryInstance::is_crime_unlocked(Crime const& crime) const {
Expand All @@ -925,8 +926,8 @@ bool CountryInstance::modify_gas_attack_unlock(technology_unlock_level_t unlock_
if (gas_attack_unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for gas attack in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
*this, static_cast<int64_t>(gas_attack_unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(gas_attack_unlock_level + unlock_level_change)
*this, gas_attack_unlock_level,
unlock_level_change, gas_attack_unlock_level + unlock_level_change
);
return false;
}
Expand All @@ -937,7 +938,7 @@ bool CountryInstance::modify_gas_attack_unlock(technology_unlock_level_t unlock_
}

bool CountryInstance::unlock_gas_attack() {
return modify_gas_attack_unlock(1);
return modify_gas_attack_unlock(technology_unlock_level_t { 1 });
}

bool CountryInstance::is_gas_attack_unlocked() const {
Expand All @@ -949,8 +950,8 @@ bool CountryInstance::modify_gas_defence_unlock(technology_unlock_level_t unlock
if (gas_defence_unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for gas defence in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
*this, static_cast<int64_t>(gas_defence_unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(gas_defence_unlock_level + unlock_level_change)
*this, gas_defence_unlock_level,
unlock_level_change, gas_defence_unlock_level + unlock_level_change
);
return false;
}
Expand All @@ -961,7 +962,7 @@ bool CountryInstance::modify_gas_defence_unlock(technology_unlock_level_t unlock
}

bool CountryInstance::unlock_gas_defence() {
return modify_gas_defence_unlock(1);
return modify_gas_defence_unlock(technology_unlock_level_t { 1 });
}

bool CountryInstance::is_gas_defence_unlocked() const {
Expand All @@ -986,8 +987,8 @@ bool CountryInstance::modify_unit_variant_unlock(unit_variant_t unit_variant, te
if (unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for unit variant {} in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
static_cast<uint64_t>(unit_variant), *this, static_cast<int64_t>(unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(unlock_level + unlock_level_change)
static_cast<uint64_t>(unit_variant), *this, unlock_level,
unlock_level_change, unlock_level + unlock_level_change
);
ret = false;
} else {
Expand All @@ -1002,7 +1003,7 @@ bool CountryInstance::modify_unit_variant_unlock(unit_variant_t unit_variant, te
}

bool CountryInstance::unlock_unit_variant(unit_variant_t unit_variant) {
return modify_unit_variant_unlock(unit_variant, 1);
return modify_unit_variant_unlock(unit_variant, technology_unlock_level_t { 1 });
}

unit_variant_t CountryInstance::get_max_unlocked_unit_variant() const {
Expand All @@ -1018,8 +1019,8 @@ bool CountryInstance::modify_technology_unlock(
if (unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for technology {} in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
technology, *this, static_cast<int64_t>(unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(unlock_level + unlock_level_change)
technology, *this, unlock_level,
unlock_level_change, unlock_level + unlock_level_change
);
return false;
}
Expand Down Expand Up @@ -1051,7 +1052,7 @@ bool CountryInstance::set_technology_unlock_level(
}

bool CountryInstance::unlock_technology(Technology const& technology) {
return modify_technology_unlock(technology, 1);
return modify_technology_unlock(technology, technology_unlock_level_t { 1 });
}

bool CountryInstance::is_technology_unlocked(Technology const& technology) const {
Expand All @@ -1067,8 +1068,8 @@ bool CountryInstance::modify_invention_unlock(
if (unlock_level + unlock_level_change < 0) {
spdlog::error_s(
"Attempted to change unlock level for invention {} in country {} to invalid value: current level = {}, change = {}, invalid new value = {}",
invention, *this, static_cast<int64_t>(unlock_level),
static_cast<int64_t>(unlock_level_change), static_cast<int64_t>(unlock_level + unlock_level_change)
invention, *this, unlock_level,
unlock_level_change, unlock_level + unlock_level_change
);
return false;
}
Expand Down Expand Up @@ -1114,7 +1115,7 @@ bool CountryInstance::set_invention_unlock_level(
}

bool CountryInstance::unlock_invention(Invention const& invention) {
return modify_invention_unlock(invention, 1);
return modify_invention_unlock(invention, technology_unlock_level_t { 1 });
}

bool CountryInstance::is_invention_unlocked(Invention const& invention) const {
Expand Down Expand Up @@ -1237,7 +1238,7 @@ bool CountryInstance::apply_history_to_country(
ret &= set_technology_unlock_level(*technology, level);
}
for (auto const& [invention, activated] : entry.get_inventions()) {
ret &= set_invention_unlock_level(*invention, activated ? 1 : 0);
ret &= set_invention_unlock_level(*invention, technology_unlock_level_t { static_cast<int8_t>(activated ? 1 : 0) });
}

apply_foreign_investments(entry.get_foreign_investment(), country_instance_manager);
Expand Down Expand Up @@ -1340,8 +1341,8 @@ void CountryInstance::_update_budget() {
OpenVic immediately updates both.
*/

pop_size_t total_non_colonial_population = 0;
pop_size_t administrators = 0;
pop_sum_t total_non_colonial_population = 0;
pop_sum_t administrators = 0;
for (State const* const state_ptr : states) {
if (state_ptr == nullptr) {
continue;
Expand All @@ -1352,7 +1353,7 @@ void CountryInstance::_update_budget() {
continue;
}

IndexedFlatMap<PopType, pop_size_t> const& state_population_by_type = state.get_population_by_type();
IndexedFlatMap<PopType, pop_sum_t> const& state_population_by_type = state.get_population_by_type();

for (auto const& [pop_type, size] : state_population_by_type) {
if (pop_type.is_administrator) {
Expand All @@ -1365,13 +1366,13 @@ void CountryInstance::_update_budget() {
if (total_non_colonial_population == 0) {
administrative_efficiency_from_administrators.set(fixed_point_t::_1);
administrator_percentage.set(fixed_point_t::_0);
} else {
administrator_percentage.set(fixed_point_t::parse(administrators) / total_non_colonial_population);
} else {
administrator_percentage.set(fixed_point_t::parse(type_safe::get(administrators)) / type_safe::get(total_non_colonial_population));

const fixed_point_t desired_administrators = desired_administrator_percentage.get_untracked() * total_non_colonial_population;
const fixed_point_t desired_administrators = desired_administrator_percentage.get_untracked() * type_safe::get(total_non_colonial_population);
const fixed_point_t administrative_efficiency_from_administrators_unclamped = std::min(
fixed_point_t::mul_div(
administrators,
type_safe::get(administrators),
fixed_point_t::_1 + get_modifier_effect_value(*modifier_effect_cache.get_administrative_efficiency()),
desired_administrators
)
Expand All @@ -1397,7 +1398,7 @@ void CountryInstance::_update_budget() {
projected_education_spending_unscaled_by_slider_running_total += size * education_salary_base_by_pop_type.at(pop_type).get_untracked();
projected_military_spending_unscaled_by_slider_running_total += size * military_salary_base_by_pop_type.at(pop_type).get_untracked();
projected_pensions_spending_unscaled_by_slider_running_total += size * calculate_pensions_base(pop_type);
projected_unemployment_subsidies_spending_unscaled_by_slider_running_total += get_unemployed_pops_by_type(pop_type)
projected_unemployment_subsidies_spending_unscaled_by_slider_running_total += type_safe::get(get_unemployed_pops_by_type(pop_type))
* calculate_unemployment_subsidies_base(pop_type);
}

Expand Down
6 changes: 3 additions & 3 deletions src/openvic-simulation/country/CountryInstance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "openvic-simulation/types/HasIndex.hpp"
#include "openvic-simulation/types/IndexedFlatMap.hpp"
#include "openvic-simulation/types/OrderedContainers.hpp"
#include "openvic-simulation/types/TechnologyUnlockLevel.hpp"
#include "openvic-simulation/research/TechnologyUnlockLevel.hpp"
#include "openvic-simulation/types/TypedIndices.hpp"
#include "openvic-simulation/types/UnitBranchType.hpp"
#include "openvic-simulation/types/UnitVariant.hpp"
Expand Down Expand Up @@ -388,8 +388,8 @@ namespace OpenVic {
OV_IFLATMAP_PROPERTY(RegimentType, technology_unlock_level_t, regiment_type_unlock_levels);
regiment_allowed_cultures_t PROPERTY(allowed_regiment_cultures, regiment_allowed_cultures_t::NO_CULTURES);
OV_IFLATMAP_PROPERTY(ShipType, technology_unlock_level_t, ship_type_unlock_levels);
technology_unlock_level_t PROPERTY(gas_attack_unlock_level, 0);
technology_unlock_level_t PROPERTY(gas_defence_unlock_level, 0);
technology_unlock_level_t PROPERTY(gas_attack_unlock_level, technology_unlock_level_t { 0 });
technology_unlock_level_t PROPERTY(gas_defence_unlock_level, technology_unlock_level_t { 0 });
memory::vector<technology_unlock_level_t> SPAN_PROPERTY(unit_variant_unlock_levels);

public:
Expand Down
4 changes: 2 additions & 2 deletions src/openvic-simulation/dataloader/Dataloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ string_set_t Dataloader::lookup_dirs_in_dir(std::string_view path) const {
return ret;
}

template<std::derived_from<detail::BasicParser> Parser, bool (*parse_func)(Parser&)>
template<std::derived_from<ovdl::detail::BasicParser> Parser, bool (*parse_func)(Parser&)>
static Parser _run_ovdl_parser(fs::path const& path) {
Parser parser;
memory::string buffer;
auto error_log_stream = detail::make_callback_stream<char>(
auto error_log_stream = ovdl::detail::make_callback_stream<char>(
[](void const* s, std::streamsize n, void* user_data) -> std::streamsize {
if (s != nullptr && n > 0 && user_data != nullptr) {
static_cast<memory::string*>(user_data)->append(static_cast<char const*>(s), n);
Expand Down
52 changes: 40 additions & 12 deletions src/openvic-simulation/dataloader/NodeTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,49 @@ using namespace std::string_view_literals;
return expect_uint(callback, base);
}

template<derived_from_specialization_of<type_safe::strong_typedef> T, typename AsT = type_safe::underlying_type<T>>
NodeCallback auto expect_strong_typedef(callback_t<T>& callback, int base = 10) {
if constexpr (std::unsigned_integral<AsT>) {
return expect_uint64(
[callback](uint64_t val) mutable -> bool {
if (val <= static_cast<uint64_t>(std::numeric_limits<AsT>::max())) {
return callback(T(val));
}
spdlog::error_s(
"Invalid uint: {} (valid range: [0, {}])", val,
static_cast<uint64_t>(std::numeric_limits<AsT>::max())
);
return false;
},
base
);
} else {
return expect_int64(
[callback](int64_t val) mutable -> bool {
if (val >= static_cast<int64_t>(std::numeric_limits<AsT>::min()) &&
val <= static_cast<int64_t>(std::numeric_limits<AsT>::max())) {
return callback(T(val));
}
spdlog::error_s(
"Invalid int: {} (valid range: [{}, {}])", val,
static_cast<int64_t>(std::numeric_limits<AsT>::min()),
static_cast<int64_t>(std::numeric_limits<AsT>::max())
);
return false;
},
base
);
}
}
template<derived_from_specialization_of<type_safe::strong_typedef> T, typename AsT = type_safe::underlying_type<T>>
NodeCallback auto expect_strong_typedef(callback_t<T>&& callback, int base = 10) {
return expect_strong_typedef<T, AsT>(callback, base);
}

template<derived_from_specialization_of<type_safe::strong_typedef> T>
requires std::unsigned_integral<type_safe::underlying_type<T>>
NodeCallback auto expect_index(callback_t<T>& callback, int base = 10) {
using underlying_type = type_safe::underlying_type<T>;

return expect_uint64([callback](uint64_t val) mutable -> bool {
if (val <= static_cast<uint64_t>(std::numeric_limits<underlying_type>::max())) {
return callback(T(val));
}
spdlog::error_s(
"Invalid uint: {} (valid range: [0, {}])",
val, static_cast<uint64_t>(std::numeric_limits<underlying_type>::max())
);
return false;
}, base);
return expect_strong_typedef<T>(callback, base);
}
template<derived_from_specialization_of<type_safe::strong_typedef> T>
requires std::unsigned_integral<type_safe::underlying_type<T>>
Expand Down
4 changes: 2 additions & 2 deletions src/openvic-simulation/defines/MilitaryDefines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ node_callback_t MilitaryDefines::expect_defines() {
"REINFORCE_SPEED", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(reinforce_speed)),
"COMBAT_DIFFICULTY_IMPACT", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(combat_difficulty_impact)),
"BASE_COMBAT_WIDTH", ONE_EXACTLY, expect_uint(assign_variable_callback(base_combat_width)),
"POP_MIN_SIZE_FOR_REGIMENT", ONE_EXACTLY, expect_uint(assign_variable_callback(min_pop_size_for_regiment)),
"POP_SIZE_PER_REGIMENT", ONE_EXACTLY, expect_uint(assign_variable_callback(pop_size_per_regiment)),
"POP_MIN_SIZE_FOR_REGIMENT", ONE_EXACTLY, expect_strong_typedef<pop_size_t>(assign_variable_callback(min_pop_size_for_regiment)),
"POP_SIZE_PER_REGIMENT", ONE_EXACTLY, expect_strong_typedef<pop_size_t>(assign_variable_callback(pop_size_per_regiment)),
"SOLDIER_TO_POP_DAMAGE", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(soldier_to_pop_damage)),
"LAND_SPEED_MODIFIER", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(land_speed_modifier)),
"NAVAL_SPEED_MODIFIER", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(naval_speed_modifier)),
Expand Down
2 changes: 1 addition & 1 deletion src/openvic-simulation/defines/MilitaryDefines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "openvic-simulation/dataloader/NodeTools.hpp"
#include "openvic-simulation/types/Date.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/types/PopSize.hpp"
#include "openvic-simulation/population/PopSize.hpp"
#include "openvic-simulation/utility/Getters.hpp"

namespace OpenVic {
Expand Down
4 changes: 2 additions & 2 deletions src/openvic-simulation/defines/PopsDefines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ node_callback_t PopsDefines::expect_defines() {
"MOVEMENT_SUPPORT_UH_FACTOR", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(movement_support_uh_factor)),
"REBEL_OCCUPATION_STRENGTH_BONUS", ONE_EXACTLY,
expect_fixed_point(assign_variable_callback(rebel_occupation_strength_bonus)),
"LARGE_POPULATION_LIMIT", ONE_EXACTLY, expect_uint(assign_variable_callback(large_population_limit)),
"LARGE_POPULATION_LIMIT", ONE_EXACTLY, expect_strong_typedef<pop_sum_t>(assign_variable_callback(large_population_limit)),
"LARGE_POPULATION_INFLUENCE_PENALTY_CHUNK", ONE_EXACTLY,
expect_uint(assign_variable_callback(large_population_influence_penalty_chunk))
expect_strong_typedef<pop_sum_t>(assign_variable_callback(large_population_influence_penalty_chunk))
);
}
6 changes: 3 additions & 3 deletions src/openvic-simulation/defines/PopsDefines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "openvic-simulation/dataloader/NodeTools.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/types/PopSize.hpp"
#include "openvic-simulation/population/PopSum.hpp"
#include "openvic-simulation/types/ProvinceLifeRating.hpp"
#include "openvic-simulation/utility/Getters.hpp"

Expand Down Expand Up @@ -71,8 +71,8 @@ namespace OpenVic {
fixed_point_t PROPERTY(nationalist_movement_mil_cap);
fixed_point_t PROPERTY(movement_support_uh_factor);
fixed_point_t PROPERTY(rebel_occupation_strength_bonus);
pop_size_t PROPERTY(large_population_limit, 0);
pop_size_t PROPERTY(large_population_influence_penalty_chunk, 0);
pop_sum_t PROPERTY(large_population_limit, 0);
pop_sum_t PROPERTY(large_population_influence_penalty_chunk, 0);

PopsDefines();

Expand Down
Loading