Skip to content

Commit 72faabf

Browse files
authored
Merge pull request #1973 from ineveraskedforthis/main
Adjust urban sprawl to work better with different map sizes
2 parents 63868e7 + 45c7b55 commit 72faabf

File tree

6 files changed

+53
-17
lines changed

6 files changed

+53
-17
lines changed

src/economy/economy.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ void initialize(sys::state& state) {
745745
province::for_each_land_province(state, [&](dcon::province_id p) {
746746
auto fp = fatten(state.world, p);
747747
//max size of exploitable land:
748-
auto max_rgo_size = std::ceil(4000.f * state.map_state.map_data.province_area[province::to_map_id(p)]);
748+
auto max_rgo_size = std::ceil(state.map_state.map_data.province_area_km2[province::to_map_id(p)]);
749749
// currently exploited land
750750
float pop_amount = 0.0f;
751751
for(auto pt : state.world.in_pop_type) {

src/gamestate/serialization.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ uint8_t const* read_scenario_section(uint8_t const* ptr_in, uint8_t const* secti
150150
ptr_in = deserialize(ptr_in, state.map_state.map_data.terrain_id_map);
151151
ptr_in = deserialize(ptr_in, state.map_state.map_data.province_id_map);
152152
ptr_in = deserialize(ptr_in, state.map_state.map_data.province_area);
153+
ptr_in = deserialize(ptr_in, state.map_state.map_data.province_area_km2);
153154
ptr_in = deserialize(ptr_in, state.map_state.map_data.diagonal_borders);
154155
}
155156
{
@@ -331,6 +332,7 @@ uint8_t* write_scenario_section(uint8_t* ptr_in, sys::state& state) {
331332
ptr_in = serialize(ptr_in, state.map_state.map_data.terrain_id_map);
332333
ptr_in = serialize(ptr_in, state.map_state.map_data.province_id_map);
333334
ptr_in = serialize(ptr_in, state.map_state.map_data.province_area);
335+
ptr_in = serialize(ptr_in, state.map_state.map_data.province_area_km2);
334336
ptr_in = serialize(ptr_in, state.map_state.map_data.diagonal_borders);
335337
}
336338
{
@@ -512,6 +514,7 @@ scenario_size sizeof_scenario_section(sys::state& state) {
512514
sz += serialize_size(state.map_state.map_data.terrain_id_map);
513515
sz += serialize_size(state.map_state.map_data.province_id_map);
514516
sz += serialize_size(state.map_state.map_data.province_area);
517+
sz += serialize_size(state.map_state.map_data.province_area_km2);
515518
sz += serialize_size(state.map_state.map_data.diagonal_borders);
516519
}
517520
{ sz += sizeof(parsing::defines); }

src/map/map.cpp

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,13 +2342,16 @@ bool get_provinces_part_of_rr_path(sys::state& state, std::vector<bool>& visited
23422342
return true;
23432343
}
23442344

2345-
glm::vec2 get_node(sys::state& state, glm::vec2 center, int i, int j) {
2345+
glm::vec2 get_node(sys::state& state, glm::vec2 center, int i, int j, int size_x, int size_y) {
23462346
const auto rpx = rng::get_random(state, j ^ i ^ (uint32_t)center.x, i);
23472347
const float rx = (float(rng::reduce(uint32_t(rpx), 8192)) / (8192.f)) - 0.5f;
23482348
const auto rpy = rng::get_random(state, j ^ i ^ (uint32_t)center.y ^ 5653, j);
23492349
const float ry = (float(rng::reduce(uint32_t(rpy), 8192)) / (8192.f)) - 0.5f;
23502350

2351-
auto base_shift = glm::vec2{ (float)i + rx, (float)j + ry } * 0.4f / sqrt(sqrt((float) (i * i) + (float) (j * j) + 1));
2351+
auto scale_x = (float)size_x / 5600.f;
2352+
auto scale_y = (float)size_y / 2160.f;
2353+
2354+
auto base_shift = glm::vec2{ ((float)i + rx) * scale_x, ((float)j + ry) * scale_y} * 0.4f / sqrt(sqrt((float) (i * i) + (float) (j * j) + 1));
23522355
return center + base_shift;
23532356
}
23542357

@@ -2362,25 +2365,29 @@ void display_data::update_sprawl(sys::state& state) {
23622365
std::vector<std::vector<glm::vec2>> connectors{};
23632366
connectors.resize(state.world.province_size());
23642367

2368+
auto minimal_population_per_visible_settlement = 2500.f;
2369+
23652370
// Populate paths with railroads - only account provinces that have been visited
23662371
// but not the adjacencies
23672372
for(const auto p : state.world.in_province) {
23682373

23692374
auto rural_population = 0.f;
2370-
for(auto wt : state.culture_definitions.rgo_workers) {
2371-
rural_population += state.world.province_get_demographics(p, demographics::to_key(state, wt));
2375+
for(auto pt : state.world.in_pop_type) {
2376+
if(pt.get_is_paid_rgo_worker())
2377+
rural_population += state.world.province_get_demographics(p, demographics::to_key(state, pt));
23722378
}
2373-
rural_population += state.world.province_get_demographics(p, demographics::to_employment_key(state, state.culture_definitions.slaves));
2374-
2379+
rural_population += state.world.province_get_demographics(p, demographics::to_key(state, state.culture_definitions.slaves));
2380+
rural_population += state.world.province_get_demographics(p, demographics::to_key(state, state.culture_definitions.clergy));
23752381

23762382
auto urban_pop = p.get_demographics(demographics::total) - rural_population;
23772383

2378-
if(urban_pop < 1000.f) {
2384+
if(urban_pop < minimal_population_per_visible_settlement) {
23792385
continue;
23802386
}
23812387

2382-
auto province_size = state.map_state.map_data.province_area[province::to_map_id(p)];
2383-
if(province_size < 1) {
2388+
auto province_size = state.map_state.map_data.province_area_km2[province::to_map_id(p)];
2389+
auto province_size_pixels = state.map_state.map_data.province_area[province::to_map_id(p)];
2390+
if(province_size_pixels < 1) {
23842391
continue;
23852392
}
23862393

@@ -2404,7 +2411,17 @@ void display_data::update_sprawl(sys::state& state) {
24042411

24052412
std::vector<std::pair<glm::vec2, float>> weighted_settlements;
24062413

2407-
int potential_settlement_slots = std::min((unsigned)7, province_size / 200);
2414+
auto km2_per_potential_settlement = 2000.f;
2415+
2416+
2417+
int potential_settlement_slots = std::min(
2418+
(int)7, std::min(
2419+
(int)(province_size / km2_per_potential_settlement),
2420+
(int)(urban_pop / minimal_population_per_visible_settlement)
2421+
)
2422+
);
2423+
potential_settlement_slots = std::max(1, potential_settlement_slots);
2424+
24082425
int settlement_slots = potential_settlement_slots;
24092426

24102427
if(p.get_port_to()) {
@@ -2421,7 +2438,7 @@ void display_data::update_sprawl(sys::state& state) {
24212438
}
24222439
}
24232440

2424-
auto side = sqrt(province_size);
2441+
auto side = sqrt(province_size_pixels);
24252442

24262443
// try to spawn random settlements in this area
24272444

@@ -2446,7 +2463,7 @@ void display_data::update_sprawl(sys::state& state) {
24462463
settlement_slots -= 1;
24472464
weighted_settlements.push_back({ pos, 0.5f / (potential_settlement_slots + 1) });
24482465
roads.push_back({ pos, central_settlement });
2449-
if(settlement_slots < 0) {
2466+
if(settlement_slots <= 0) {
24502467
break;
24512468
}
24522469
}
@@ -2527,10 +2544,10 @@ void display_data::update_sprawl(sys::state& state) {
25272544
continue;
25282545
}
25292546

2530-
auto node_1 = get_node(state, settlement.first, i, k);
2531-
auto node_2 = get_node(state, settlement.first, i + 1, k);
2532-
auto node_3 = get_node(state, settlement.first, i, k + 1);
2533-
auto node_4 = get_node(state, settlement.first, i + 1, k + 1);
2547+
auto node_1 = get_node(state, settlement.first, i, k, size_x, size_y);
2548+
auto node_2 = get_node(state, settlement.first, i + 1, k, size_x, size_y);
2549+
auto node_3 = get_node(state, settlement.first, i, k + 1, size_x, size_y);
2550+
auto node_4 = get_node(state, settlement.first, i + 1, k + 1, size_x, size_y);
25342551

25352552
auto node_center = (node_1 + node_2 + node_3 + node_4) / 4.f;
25362553

src/map/map.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ class display_data {
195195
std::vector<uint8_t> terrain_id_map;
196196
std::vector<uint8_t> median_terrain_type;
197197
std::vector<uint32_t> province_area;
198+
std::vector<float> province_area_km2;
198199
std::vector<uint8_t> diagonal_borders;
199200

200201
// map pixel -> province id

src/map/map_data_loading.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "system_state.hpp"
55
#include "parsers_declarations.hpp"
66
#include "opengl_wrapper.hpp"
7+
#include "math_fns.hpp"
78

89
#ifdef _WIN64
910

@@ -474,12 +475,24 @@ void display_data::load_terrain_data(parsers::scenario_building_context& context
474475
void display_data::load_median_terrain_type(parsers::scenario_building_context& context) {
475476
median_terrain_type.resize(context.state.world.province_size() + 1);
476477
province_area.resize(context.state.world.province_size() + 1);
478+
province_area_km2.resize(context.state.world.province_size() + 1);
479+
480+
float R = context.state.defines.alice_globe_mean_radius_km;
481+
477482
std::vector<std::array<int, 64>> terrain_histogram(context.state.world.province_size() + 1, std::array<int, 64>{});
478483
for(int i = size_x * size_y - 1; i-- > 0;) {
479484
auto prov_id = province_id_map[i];
480485
auto terrain_id = terrain_id_map[i];
481486
if(terrain_id < 64)
482487
terrain_histogram[prov_id][terrain_id] += 1;
488+
auto x = i % size_x;
489+
auto y = i / size_x;
490+
// 0.5f is added to shift us to the center of the pixel;
491+
// float s = (((float)x + 0.5f) / (float) size_x) * 2 * math::pi;
492+
float t = (((float)y + 0.5f) / (float) size_y - 0.5f) * math::pi;
493+
auto area_form = R * R * math::cos(t);
494+
auto pixel_size = area_form * (1.f / (float)size_y * math::pi) * (1.f / (float)size_x * 2 * math::pi);
495+
province_area_km2[prov_id] += pixel_size;
483496
}
484497

485498
for(int i = context.state.world.province_size(); i-- > 1;) { // map-id province 0 == the invalid province; we don't need to collect data for it

src/parsing/defines.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@
742742
LUA_DEFINES_LIST_ELEMENT(alice_naval_base_to_colonial_distance_factor, 0.04) \
743743
LUA_DEFINES_LIST_ELEMENT(alice_allow_factories_in_colonies, 0.0) \
744744
LUA_DEFINES_LIST_ELEMENT(alice_always_available_cbs_zero_infamy, 1.0) \
745+
LUA_DEFINES_LIST_ELEMENT(alice_globe_mean_radius_km, 6371.0) \
746+
745747

746748
// scales the needs values so that they are needs per this many pops
747749
// this value was arrived at by looking at farmers: 40'000 farmers produces enough grain to satisfy about 2/3

0 commit comments

Comments
 (0)