Skip to content

Commit

Permalink
fix religious conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
schombert committed Nov 11, 2024
1 parent b486abb commit dea7c50
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 186 deletions.
156 changes: 17 additions & 139 deletions src/economy/demographics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3233,88 +3233,6 @@ float get_estimated_assimilation(sys::state& state, dcon::pop_id ids) {
}
}

void update_conversion(sys::state& state, uint32_t offset, uint32_t divisions, conversion_buffer& pbuf) {
pbuf.update(state.world.pop_size());

/*
- religious conversion -- Conversion is per-month rather than per-day as in Victoria 2.
*/

pexecute_staggered_blocks(offset, divisions, state.world.pop_size(), [&](auto ids) {
pbuf.amounts.set(ids, 0.0f);
auto loc = state.world.pop_get_province_from_pop_location(ids);
auto owners = state.world.province_get_nation_from_province_ownership(loc);
auto conversion_chances = ve::max(trigger::evaluate_additive_modifier(state, state.culture_definitions.conversion_chance, trigger::to_generic(ids), trigger::to_generic(ids), 0), 0.0f);

ve::apply(
[&](dcon::pop_id p, dcon::province_id location, dcon::nation_id owner, float conversion_chance) {
// no conversion in unowned provinces
if(!owner)
return; // early exit

auto state_religion = state.world.nation_get_religion(owner);
// pops of the state religion do not convert
if(state_religion == state.world.pop_get_religion(p))
return; // early exit

// need at least 1 pop following the religion in the province
if(state.world.province_get_demographics(location, demographics::to_key(state, state_religion.id)) < 1.f)
return; // early exit

/*
Amount: define:CONVERSION_SCALE x (provincial-conversion-rate-modifier + 1) x
(national-conversion-rate-modifier + 1) x pop-size x conversion chance factor (computed additively, and always
at least 0.01).
*/

float current_size = state.world.pop_get_size(p);
float base_amount =
state.defines.conversion_scale *
std::max(0.0f, (state.world.province_get_modifier_values(location, sys::provincial_mod_offsets::conversion_rate) + 1.0f)) *
std::max(0.0f, (state.world.nation_get_modifier_values(owner, sys::national_mod_offsets::global_conversion_rate) + 1.0f)) *
conversion_chance * current_size;

if(base_amount >= 0.001f) {
auto transfer_amount = std::min(current_size, std::ceil(base_amount));
pbuf.amounts.set(p, transfer_amount);
}
},
ids, loc, owners, conversion_chances);
});
}

float get_estimated_conversion(sys::state& state, dcon::pop_id ids) {
auto location = state.world.pop_get_province_from_pop_location(ids);
auto owner = state.world.province_get_nation_from_province_ownership(location);
auto conversion_chances = std::max(trigger::evaluate_additive_modifier(state, state.culture_definitions.conversion_chance, trigger::to_generic(ids), trigger::to_generic(ids), 0), 0.0f);

// pops of the state religion do not convert
if(state.world.nation_get_religion(owner) == state.world.pop_get_religion(ids))
return 0.0f; // early exit

auto state_religion = state.world.nation_get_religion(owner);
// pops of the state religion do not convert
if(state_religion == state.world.pop_get_religion(ids))
return 0.0f; // early exit

// need at least 1 pop following the religion in the province
if(state.world.province_get_demographics(location, demographics::to_key(state, state_religion.id)) < 1.f)
return 0.0f; // early exit

float current_size = state.world.pop_get_size(ids);
float base_amount =
state.defines.conversion_scale *
std::max(0.0f, (state.world.province_get_modifier_values(location, sys::provincial_mod_offsets::conversion_rate) + 1.0f)) *
std::max(0.0f, (state.world.nation_get_modifier_values(owner, sys::national_mod_offsets::global_conversion_rate) + 1.0f)) *
conversion_chances * current_size;

if(base_amount >= 0.001f) {
return std::min(current_size, std::ceil(base_amount));
} else {
return 0.0f;
}
}

namespace impl {
dcon::province_id get_province_target_in_nation(sys::state& state, dcon::nation_id n, dcon::pop_id p) {
/*
Expand Down Expand Up @@ -3906,64 +3824,24 @@ void apply_type_changes(sys::state& state, uint32_t offset, uint32_t divisions,
}

void apply_assimilation(sys::state& state, uint32_t offset, uint32_t divisions, assimilation_buffer& pbuf) {
if(bool(state.defines.alice_nurture_religion_assimilation)) {
auto exec_fn = [&](auto ids) {
auto locs = state.world.pop_get_province_from_pop_location(ids);
ve::apply([&](dcon::pop_id p, dcon::province_id l, dcon::culture_id dac) {
if(pbuf.amounts.get(p) > 0.0f) {
//auto o = nations::owner_of_pop(state, p);
auto cul = dac ? dac : state.world.province_get_dominant_culture(l);
auto rel = state.world.pop_get_religion(p);
assert(state.world.pop_get_poptype(p));
auto target_pop = impl::find_or_make_pop(state, l, cul, rel, state.world.pop_get_poptype(p), pop_demographics::get_literacy(state, p));
state.world.pop_get_size(p) -= pbuf.amounts.get(p);
state.world.pop_get_size(target_pop) += pbuf.amounts.get(p);
}
},
ids, locs, state.world.province_get_dominant_accepted_culture(locs));
};
execute_staggered_blocks(offset, divisions, std::min(state.world.pop_size(), pbuf.size), exec_fn);
} else {
auto exec_fn = [&](auto ids) {
auto locs = state.world.pop_get_province_from_pop_location(ids);
ve::apply([&](dcon::pop_id p, dcon::province_id l, dcon::culture_id dac) {
if(pbuf.amounts.get(p) > 0.0f) {
//auto o = nations::owner_of_pop(state, p);
auto cul = dac ? dac : state.world.province_get_dominant_culture(l);
auto rel = dac
? state.world.nation_get_religion(nations::owner_of_pop(state, p))
: state.world.province_get_dominant_religion(l);
assert(state.world.pop_get_poptype(p));
auto target_pop = impl::find_or_make_pop(state, l, cul, rel, state.world.pop_get_poptype(p), pop_demographics::get_literacy(state, p));
state.world.pop_get_size(p) -= pbuf.amounts.get(p);
state.world.pop_get_size(target_pop) += pbuf.amounts.get(p);
}
},
ids, locs, state.world.province_get_dominant_accepted_culture(locs));
};
execute_staggered_blocks(offset, divisions, std::min(state.world.pop_size(), pbuf.size), exec_fn);
}
}

void apply_conversion(sys::state& state, uint32_t offset, uint32_t divisions, conversion_buffer& pbuf) {
execute_staggered_blocks(offset, divisions, std::min(state.world.pop_size(), pbuf.size), [&](auto ids) {
auto exec_fn = [&](auto ids) {
auto locs = state.world.pop_get_province_from_pop_location(ids);
ve::apply(
[&](dcon::pop_id p, dcon::province_id l) {
if(pbuf.amounts.get(p) > 0.0f) {
auto state_rel = state.world.nation_get_religion(nations::owner_of_pop(state, p));
auto rel = state_rel
? state_rel
: state.world.province_get_dominant_religion(l);
assert(state.world.pop_get_poptype(p));
assert(state.world.pop_get_culture(p));
auto target_pop = impl::find_or_make_pop(state, l, state.world.pop_get_culture(p), rel, state.world.pop_get_poptype(p), pop_demographics::get_literacy(state, p));
state.world.pop_get_size(p) -= pbuf.amounts.get(p);
state.world.pop_get_size(target_pop) += pbuf.amounts.get(p);
}
},
ids, locs);
});
ve::apply([&](dcon::pop_id p, dcon::province_id l, dcon::culture_id dac) {
if(pbuf.amounts.get(p) > 0.0f) {
//auto o = nations::owner_of_pop(state, p);
auto cul = dac ? dac : state.world.province_get_dominant_culture(l);
auto rel = dac
? state.world.nation_get_religion(nations::owner_of_pop(state, p))
: state.world.province_get_dominant_religion(l);
assert(state.world.pop_get_poptype(p));
auto target_pop = impl::find_or_make_pop(state, l, cul, rel, state.world.pop_get_poptype(p), pop_demographics::get_literacy(state, p));
state.world.pop_get_size(p) -= pbuf.amounts.get(p);
state.world.pop_get_size(target_pop) += pbuf.amounts.get(p);
}
},
ids, locs, state.world.province_get_dominant_accepted_culture(locs));
};
execute_staggered_blocks(offset, divisions, std::min(state.world.pop_size(), pbuf.size), exec_fn);
}

void apply_internal_migration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf) {
Expand Down
18 changes: 0 additions & 18 deletions src/economy/demographics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,21 +252,6 @@ struct assimilation_buffer {
}
};

struct conversion_buffer {
ve::vectorizable_buffer<float, dcon::pop_id> amounts;
uint32_t size = 0;
uint32_t reserved = 0;

conversion_buffer() : amounts(0), size(0) { }
void update(uint32_t s) {
size = s;
if(reserved < s) {
reserved = s;
amounts = ve::vectorizable_buffer<float, dcon::pop_id>(s);
}
}
};

struct migration_buffer {
ve::vectorizable_buffer<float, dcon::pop_id> amounts;
ve::vectorizable_buffer<dcon::province_id, dcon::pop_id> destinations;
Expand Down Expand Up @@ -295,7 +280,6 @@ void update_assimilation(sys::state& state, uint32_t offset, uint32_t divisions,
void update_internal_migration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf);
void update_colonial_migration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf);
void update_immigration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf);
void update_conversion(sys::state& state, uint32_t offset, uint32_t divisions, conversion_buffer& pbuf);

float get_estimated_literacy_change(sys::state& state, dcon::nation_id n);
float get_estimated_mil_change(sys::state& state, dcon::nation_id n);
Expand All @@ -309,7 +293,6 @@ void apply_assimilation(sys::state& state, uint32_t offset, uint32_t divisions,
void apply_internal_migration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf);
void apply_colonial_migration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf);
void apply_immigration(sys::state& state, uint32_t offset, uint32_t divisions, migration_buffer& pbuf);
void apply_conversion(sys::state& state, uint32_t offset, uint32_t divisions, conversion_buffer& pbuf);

void remove_size_zero_pops(sys::state& state);
void remove_small_pops(sys::state& state);
Expand All @@ -331,7 +314,6 @@ float get_estimated_internal_migration(sys::state& state, dcon::pop_id n);
float get_estimated_colonial_migration(sys::state& state, dcon::pop_id n);
float get_estimated_emigration(sys::state& state, dcon::pop_id n);
void estimate_directed_immigration(sys::state& state, dcon::nation_id n, std::vector<float>& national_amounts);
float get_estimated_conversion(sys::state& state, dcon::pop_id n);

float calculate_nation_sol(sys::state& state, dcon::nation_id nation_id);
void reduce_pop_size_safe(sys::state& state, dcon::pop_id pop_id, int32_t amount);
Expand Down
17 changes: 1 addition & 16 deletions src/gamestate/system_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3834,14 +3834,13 @@ void state::single_game_tick() {
static demographics::issues_buffer isbuf(*this);
static demographics::promotion_buffer pbuf;
static demographics::assimilation_buffer abuf;
static demographics::conversion_buffer rbuf;
static demographics::migration_buffer mbuf;
static demographics::migration_buffer cmbuf;
static demographics::migration_buffer imbuf;

// calculate complex changes in parallel where we can, but don't actually apply the results
// instead, the changes are saved to be applied only after all triggers have been evaluated
concurrency::parallel_for(0, 8, [&](int32_t index) {
concurrency::parallel_for(0, 7, [&](int32_t index) {
switch(index) {
case 0:
{
Expand Down Expand Up @@ -3899,14 +3898,6 @@ void state::single_game_tick() {
demographics::update_immigration(*this, o, days_in_month, imbuf);
break;
}
case 7:
{
auto o = uint32_t(ymd_date.day + 11);
if(o >= days_in_month)
o -= days_in_month;
demographics::update_conversion(*this, o, days_in_month, rbuf);
break;
}
default:
break;
}
Expand Down Expand Up @@ -4007,12 +3998,6 @@ void state::single_game_tick() {
o -= days_in_month;
demographics::apply_immigration(*this, o, days_in_month, imbuf);
}
{
auto o = uint32_t(ymd_date.day + 11);
if(o >= days_in_month)
o -= days_in_month;
demographics::apply_conversion(*this, o, days_in_month, rbuf);
}

demographics::remove_size_zero_pops(*this);

Expand Down
14 changes: 1 addition & 13 deletions src/gui/topbar_subwindows/gui_population_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,11 +393,10 @@ class pop_size_text : public simple_text_element_base {
auto growth = int64_t(demographics::get_monthly_pop_increase(state, pop));
auto promote = -int64_t(demographics::get_estimated_type_change(state, pop));
auto assimilation = -int64_t(demographics::get_estimated_assimilation(state, pop));
auto conversion = -int64_t(demographics::get_estimated_conversion(state, pop));
auto internal_migration = -int64_t(demographics::get_estimated_internal_migration(state, pop));
auto colonial_migration = -int64_t(demographics::get_estimated_colonial_migration(state, pop));
auto emigration = -int64_t(demographics::get_estimated_emigration(state, pop));
auto total = int64_t(growth) + promote + assimilation + conversion + internal_migration + colonial_migration + emigration;
auto total = int64_t(growth) + promote + assimilation + internal_migration + colonial_migration + emigration;

{
auto box = text::open_layout_box(contents);
Expand Down Expand Up @@ -477,17 +476,6 @@ class pop_size_text : public simple_text_element_base {
}
text::close_layout_box(contents, box);
}
{
auto box = text::open_layout_box(contents);
text::localised_format_box(state, contents, box, "pop_size_8");
if(conversion >= 0) {
text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
text::add_to_layout_box(state, contents, box, conversion, text::text_color::green);
} else {
text::add_to_layout_box(state, contents, box, conversion, text::text_color::red);
}
text::close_layout_box(contents, box);
}
}
};

Expand Down

0 comments on commit dea7c50

Please sign in to comment.