region.peasants can be short

This commit is contained in:
Enno Rehling 2019-08-03 15:12:07 +02:00
parent 867dcd27f7
commit a51d3edee7
6 changed files with 68 additions and 10 deletions

View file

@ -527,7 +527,7 @@ static int tolua_region_get_peasants(lua_State * L)
region *self = (region *)tolua_tousertype(L, 1, NULL);
if (self) {
lua_pushinteger(L, self->land ? self->land->peasants : 0);
lua_pushinteger(L, rpeasants(self));
return 1;
}
return 0;
@ -538,7 +538,7 @@ static int tolua_region_set_peasants(lua_State * L)
region *self = (region *)tolua_tousertype(L, 1, NULL);
if (self && self->land) {
self->land->peasants = lua_tointeger(L, 2);
rsetpeasants(self, lua_tointeger(L, 2));
}
return 0;
}

View file

@ -625,7 +625,10 @@ void rsetpeasants(region * r, int value)
assert(r->land || value==0);
assert(value >= 0);
if (r->land) {
r->land->peasants = value;
if (value > USHRT_MAX) {
value = USHRT_MAX;
}
r->land->peasants = (unsigned short)value;
}
}

View file

@ -97,12 +97,12 @@ extern "C" {
char *display;
demand *demands;
const struct item_type *herbtype;
unsigned short peasants;
short newpeasants;
int herbs;
int morale;
int trees[3]; /* 0 -> seeds, 1 -> shoots, 2 -> trees */
int horses;
int peasants;
int newpeasants;
int money;
struct region_owner *ownership;
} land_region;

View file

@ -281,14 +281,13 @@ static void live(region * r)
#define MAX_EMIGRATION(p) ((p)/MAXDIRECTIONS)
#define MAX_IMMIGRATION(p) ((p)*2/3)
static void calculate_emigration(region * r)
void peasant_migration(region * r)
{
int i;
int maxp = region_maxworkers(r);
int rp = rpeasants(r);
int max_immigrants = MAX_IMMIGRATION(maxp - rp);
if (volcano_module()) {
static int terrain_cache;
static const terrain_type *t_volcano;
@ -314,8 +313,14 @@ static void calculate_emigration(region * r)
if (max_emigration > 0) {
if (max_emigration > max_immigrants) max_emigration = max_immigrants;
r->land->newpeasants += max_emigration;
rc->land->newpeasants -= max_emigration;
if (max_emigration + r->land->newpeasants > USHRT_MAX) {
max_emigration = USHRT_MAX - r->land->newpeasants;
}
if (max_emigration + rc->land->newpeasants > USHRT_MAX) {
max_emigration = USHRT_MAX - rc->land->newpeasants;
}
r->land->newpeasants += (short)max_emigration;
rc->land->newpeasants -= (short)max_emigration;
max_immigrants -= max_emigration;
}
}
@ -779,6 +784,7 @@ void immigration(void)
/* FIXME: kann ernsthaft abs(newpeasants) > rpeasants(r) sein? */
if (rp < 0) rp = 0;
rsetpeasants(r, rp);
r->land->newpeasants = 0;
}
/* Genereate some (0-6 depending on the income) peasants out of nothing */
/* if less than 50 are in the region and there is space and no monster or demon units in the region */
@ -878,7 +884,7 @@ void demographics(void)
/* Seuchen erst nachdem die Bauern sich vermehrt haben
* und gewandert sind */
calculate_emigration(r);
peasant_migration(r);
peasants(r, peasant_rules);
if (r->age > 20) {

View file

@ -94,6 +94,7 @@ extern "C" {
int reserve_self(struct unit *u, struct order *ord);
int claim_cmd(struct unit *u, struct order *ord);
void transfer_faction(struct faction *fsrc, struct faction *fdst);
void peasant_migration(struct region * r);
void nmr_warnings(void);
bool nmr_death(const struct faction * f, int turn, int timeout);

View file

@ -1931,6 +1931,53 @@ static void test_long_order_on_ocean(CuTest *tc) {
test_teardown();
}
static void test_peasant_migration(CuTest *tc) {
region *r1, *r2;
int rmax;
test_setup();
config_set("rules.economy.repopulate_maximum", "0");
r1 = test_create_plain(0, 0);
rsettrees(r1, 0, 0);
rsettrees(r1, 1, 0);
rsettrees(r1, 2, 0);
rmax = region_maxworkers(r1);
r2 = test_create_plain(0, 1);
rsettrees(r2, 0, 0);
rsettrees(r2, 1, 0);
rsettrees(r2, 2, 0);
rsetpeasants(r1, rmax - 90);
rsetpeasants(r2, rmax);
peasant_migration(r1);
immigration();
CuAssertIntEquals(tc, rmax - 90, rpeasants(r1));
CuAssertIntEquals(tc, rmax, rpeasants(r2));
rsetpeasants(r1, rmax - 90);
rsetpeasants(r2, rmax + 60);
peasant_migration(r1);
immigration();
CuAssertIntEquals(tc, rmax - 80, rpeasants(r1));
CuAssertIntEquals(tc, rmax + 50, rpeasants(r2));
rsetpeasants(r1, rmax - 6); /* max 4 immigrants. */
rsetpeasants(r2, rmax + 60); /* max 10 emigrants. */
peasant_migration(r1);
immigration(); /* 4 peasants will move */
CuAssertIntEquals(tc, rmax - 2, rpeasants(r1));
CuAssertIntEquals(tc, rmax + 56, rpeasants(r2));
rsetpeasants(r1, rmax - 6); /* max 4 immigrants. */
rsetpeasants(r2, rmax + 6); /* max 1 emigrant. */
peasant_migration(r1);
immigration(); /* 4 peasants will move */
CuAssertIntEquals(tc, rmax - 5, rpeasants(r1));
CuAssertIntEquals(tc, rmax + 5, rpeasants(r2));
test_teardown();
}
static void test_quit(CuTest *tc) {
faction *f;
unit *u;
@ -2177,6 +2224,7 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_long_orders);
SUITE_ADD_TEST(suite, test_long_order_on_ocean);
SUITE_ADD_TEST(suite, test_quit);
SUITE_ADD_TEST(suite, test_peasant_migration);
#ifdef QUIT_WITH_TRANSFER
SUITE_ADD_TEST(suite, test_quit_transfer);
SUITE_ADD_TEST(suite, test_quit_transfer_limited);