diff --git a/src/creport.c b/src/creport.c index 4fb9a50b2..551ee7fa9 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1363,9 +1363,11 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) fprintf(F, "%d;Rekruten\n", rpeasants(r) / RECRUITFRACTION); } if (max_production(r)) { - int p_wage = wage(r, NULL, NULL, turn + 1); + /* Im CR steht der Bauernlohn, der bei Trauer nur 10 ist */ + bool mourn = is_mourning(r, turn); + int p_wage = peasant_wage(r, mourn); fprintf(F, "%d;Lohn\n", p_wage); - if (is_mourning(r, turn + 1)) { + if (mourn) { fputs("1;mourning\n", F); } } diff --git a/src/economy.c b/src/economy.c index d7a1b9373..fd87ee20c 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1993,7 +1993,8 @@ expandwork(region * r, econ_request * work_begin, econ_request * work_end, int m /* n: verbleibende Einnahmen */ /* fishes: maximale Arbeiter */ int jobs = maxwork; - int p_wage = wage(r, NULL, NULL, turn); + bool mourn = is_mourning(r, turn); + int p_wage = peasant_wage(r, mourn); int money = rmoney(r); if (total > 0 && !rule_autowork()) { econ_request *o; @@ -2017,7 +2018,7 @@ expandwork(region * r, econ_request * work_begin, econ_request * work_end, int m assert(workers >= 0); - u->n = workers * wage(u->region, u->faction, u_race(u), turn); + u->n = workers * wage(u->region, u_race(u)); jobs -= workers; assert(jobs >= 0); @@ -2061,7 +2062,7 @@ static int work_cmd(unit * u, order * ord, econ_request ** io_req) } return 0; } - w = wage(r, u->faction, u_race(u), turn); + w = wage(r, u_race(u)); add_request(req++, ECON_WORK, u, ord, w * u->number); *io_req = req; return u->number; diff --git a/src/kernel/building.c b/src/kernel/building.c index a2283c1cc..94eb6f2e0 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -495,20 +495,22 @@ extern struct attrib_type at_icastle; /** returns the building's build stage (NOT size in people). * only makes sense for castles or similar buildings with multiple * stages */ -int buildingeffsize(const building * b, int img) +int buildingeffsize(const building * b, bool imaginary) { const struct building_type *btype = NULL; if (b == NULL) return 0; - btype = b->type; - if (img) { + if (imaginary) { const attrib *a = a_find(b->attribs, &at_icastle); if (a) { btype = (const struct building_type *)a->data.v; } } + else { + btype = b->type; + } return bt_effsize(btype, b, b->size); } @@ -518,7 +520,7 @@ int bt_effsize(const building_type * btype, const building * b, int bsize) bsize = adjust_size(b, bsize); } - if (btype->stages) { + if (btype && btype->stages) { int n = 0; const building_stage *stage = btype->stages; do { @@ -728,7 +730,7 @@ static const int wagetable[7][3] = { }; static int -default_wage(const region * r, const faction * f, const race * rc, int in_turn) +default_wage(const region * r, const race * rc) { building *b = largestbuilding(r, cmp_wage, false); int esize = 0; @@ -739,34 +741,32 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn) esize = buildingeffsize(b, false); } - if (f != NULL) { + if (rc != NULL) { + static const struct race *rc_orc, *rc_snotling; + static int rc_cache; int index = 0; - if (rc == get_race(RC_ORC) || rc == get_race(RC_SNOTLING)) { + if (rc_changed(&rc_cache)) { + rc_orc = get_race(RC_ORC); + rc_snotling = get_race(RC_SNOTLING); + } + if (rc == rc_orc || rc == rc_snotling) { index = 1; } wage = wagetable[esize][index]; } else { - if (is_mourning(r, in_turn)) { - wage = 10; - } - else if (fval(r->terrain, SEA_REGION)) { - wage = 11; - } - else { - wage = wagetable[esize][2]; - } - if (r->attribs && rule_blessed_harvest() == HARVEST_WORK) { - /* E1 rules */ - wage += harvest_effect(r); - } + wage = wagetable[esize][2]; } if (r->attribs) { attrib *a; curse *c; variant vm; - + + if (rule_blessed_harvest() & HARVEST_WORK) { + /* In E3 */ + wage += harvest_effect(r); + } /* Godcurse: Income -10 */ vm = frac_make(wage, 1); @@ -786,31 +786,37 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn) } static int -minimum_wage(const region * r, const faction * f, const race * rc, int in_turn) +minimum_wage(const region * r, const race * rc) { - if (f && rc) { + if (rc) { return rc->maintenance; } - return default_wage(r, f, rc, in_turn); + return default_wage(r, rc); } /** * Gibt Arbeitslohn fuer entsprechende Rasse zurueck, oder fuer - * die Bauern wenn f == NULL. */ -int wage(const region * r, const faction * f, const race * rc, int in_turn) + * die Bauern wenn rc == NULL. */ +int wage(const region * r, const race * rc) { static int config; static int rule_wage; if (config_changed(&config)) { rule_wage = config_get_int("rules.wage.function", 1); } - if (rule_wage==0) { + if (rule_wage == 0) { return 0; } - if (rule_wage==1) { - return default_wage(r, f, rc, in_turn); + + if (rule_wage == 1) { + return default_wage(r, rc); } - return minimum_wage(r, f, rc, in_turn); + return minimum_wage(r, rc); +} + +int peasant_wage(const struct region *r, bool mourn) +{ + return mourn ? 10 : wage(r, NULL); } int cmp_wage(const struct building *b, const building * a) diff --git a/src/kernel/building.h b/src/kernel/building.h index 74128a036..dfe1b544a 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -116,8 +116,8 @@ extern "C" { int id, int size, struct order *ord); bool building_finished(const struct building *b); - int wage(const struct region *r, const struct faction *f, - const struct race *rc, int in_turn); + int wage(const struct region *r, const struct race *rc); + int peasant_wage(const struct region *r, bool mourn); typedef int(*cmp_building_cb) (const struct building * b, const struct building * a); @@ -130,7 +130,7 @@ extern "C" { int building_taxes(const building *b); /* old functions, still in build.c: */ - int buildingeffsize(const building * b, int imaginary); + int buildingeffsize(const building * b, bool imaginary); void bhash(struct building *b); void bunhash(struct building *b); int buildingcapacity(const struct building *b); diff --git a/src/kernel/building.test.c b/src/kernel/building.test.c index daa75b496..91806ba3d 100644 --- a/src/kernel/building.test.c +++ b/src/kernel/building.test.c @@ -434,6 +434,80 @@ static void test_cmp_castle_size(CuTest *tc) { test_teardown(); } +static void test_wage(CuTest *tc) { + region *r; + building *b; + building_type *btype; + struct building_stage *stage; + race *rc_orc, *rc_elf; + test_setup(); + rc_orc = test_create_race("orc"); + rc_elf = test_create_race("elf"); + rc_elf->maintenance = 13; + btype = test_create_buildingtype("castle"); + stage = btype->stages; + stage->construction->maxsize = 2; /* site */ + stage = stage->next = calloc(1, sizeof(struct building_stage)); + stage->construction = calloc(1, sizeof(struct construction)); + stage->construction->maxsize = 8; /* tradepost */ + stage = stage->next = calloc(1, sizeof(struct building_stage)); + stage->construction = calloc(1, sizeof(struct construction)); + stage->construction->maxsize = 40; /* fortification */ + stage = stage->next = calloc(1, sizeof(struct building_stage)); + stage->construction = calloc(1, sizeof(struct construction)); + stage->construction->maxsize = 200; /* fortification */ + r = test_create_plain(0, 0); + CuAssertIntEquals(tc, 10, wage(r, rc_elf)); + CuAssertIntEquals(tc, 10, wage(r, rc_orc)); + CuAssertIntEquals(tc, 11, peasant_wage(r, false)); + CuAssertIntEquals(tc, 10, peasant_wage(r, true)); + + b = test_create_building(r, btype); + b->size = 1; + CuAssertIntEquals(tc, 0, buildingeffsize(b, false)); + CuAssertIntEquals(tc, 10, wage(r, rc_elf)); + CuAssertIntEquals(tc, 10, wage(r, rc_orc)); + CuAssertIntEquals(tc, 11, peasant_wage(r, false)); + CuAssertIntEquals(tc, 10, peasant_wage(r, true)); + b->size = 2; + CuAssertIntEquals(tc, 1, buildingeffsize(b, false)); + b->size = 9; + CuAssertIntEquals(tc, 1, buildingeffsize(b, false)); + CuAssertIntEquals(tc, 10, wage(r, rc_elf)); + CuAssertIntEquals(tc, 10, wage(r, rc_orc)); + CuAssertIntEquals(tc, 11, peasant_wage(r, false)); + CuAssertIntEquals(tc, 10, peasant_wage(r, true)); + b->size = 10; + CuAssertIntEquals(tc, 2, buildingeffsize(b, false)); + b->size = 49; + CuAssertIntEquals(tc, 2, buildingeffsize(b, false)); + CuAssertIntEquals(tc, 11, wage(r, rc_elf)); + CuAssertIntEquals(tc, 11, wage(r, rc_orc)); + CuAssertIntEquals(tc, 12, peasant_wage(r, false)); + CuAssertIntEquals(tc, 10, peasant_wage(r, true)); + b->size = 50; + CuAssertIntEquals(tc, 3, buildingeffsize(b, false)); + b->size = 249; + CuAssertIntEquals(tc, 3, buildingeffsize(b, false)); + CuAssertIntEquals(tc, 12, wage(r, rc_elf)); + CuAssertIntEquals(tc, 11, wage(r, rc_orc)); + CuAssertIntEquals(tc, 13, peasant_wage(r, false)); + CuAssertIntEquals(tc, 10, peasant_wage(r, true)); + b->size = 250; + CuAssertIntEquals(tc, 4, buildingeffsize(b, false)); + CuAssertIntEquals(tc, 13, wage(r, rc_elf)); + CuAssertIntEquals(tc, 12, wage(r, rc_orc)); + CuAssertIntEquals(tc, 14, peasant_wage(r, false)); + CuAssertIntEquals(tc, 10, peasant_wage(r, true)); + config_set_int("rules.wage.function", 1); + CuAssertIntEquals(tc, 13, wage(r, rc_elf)); + config_set_int("rules.wage.function", 0); + CuAssertIntEquals(tc, 0, wage(r, rc_elf)); + config_set_int("rules.wage.function", 2); + CuAssertIntEquals(tc, rc_elf->maintenance, wage(r, rc_elf)); + test_teardown(); +} + static void test_cmp_wage(CuTest *tc) { region *r; building *b1, *b2; @@ -619,6 +693,7 @@ CuSuite *get_building_suite(void) SUITE_ADD_TEST(suite, test_cmp_castle_size); SUITE_ADD_TEST(suite, test_cmp_taxes); SUITE_ADD_TEST(suite, test_cmp_wage); + SUITE_ADD_TEST(suite, test_wage); SUITE_ADD_TEST(suite, test_cmp_current_owner); SUITE_ADD_TEST(suite, test_register_building); SUITE_ADD_TEST(suite, test_btype_defaults); diff --git a/src/kernel/config.h b/src/kernel/config.h index 9b10f1520..4ee59406b 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -42,7 +42,7 @@ extern "C" { bool rule_stealth_anon(void); /* units can anonymize their faction, TARNE PARTEI [NICHT] */ int rule_alliance_limit(void); int rule_faction_limit(void); -#define HARVEST_WORK 0x00 +#define HARVEST_WORK 0x02 #define HARVEST_TAXES 0x01 int rule_blessed_harvest(void); #define GIVE_SELF 1 diff --git a/src/kernel/region.c b/src/kernel/region.c index 927a9918f..a3681158e 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -602,7 +602,7 @@ int rpeasants(const region * r) return value; } -void rsetpeasants(region * r, int value) +int rsetpeasants(region * r, int value) { assert(r->land || value==0); assert(value >= 0); @@ -612,7 +612,9 @@ void rsetpeasants(region * r, int value) value = USHRT_MAX; } r->land->peasants = (unsigned short)value; + return r->land->peasants; } + return 0; } int rmoney(const region * r) @@ -746,17 +748,16 @@ int rsettrees(const region * r, int ageclass, int value) { if (!r->land) { assert(value == 0); + return 0; + } + assert(value >= 0); + if (value < MAXTREES) { + r->land->trees[ageclass] = value; } else { - assert(value >= 0); - if (value <= MAXTREES) { - return r->land->trees[ageclass] = value; - } - else { - r->land->trees[ageclass] = MAXTREES; - } + r->land->trees[ageclass] = MAXTREES; } - return 0; + return r->land->trees[ageclass]; } region *region_create(int uid) @@ -1095,11 +1096,10 @@ void init_region(region *r) if (!fval(r, RF_CHAOTIC)) { int peasants; + int p_wage = 1 + peasant_wage(r, false) + rng_int() % 5; peasants = (region_maxworkers(r) * (20 + dice(6, 10))) / 100; if (peasants < 100) peasants = 100; - rsetpeasants(r, peasants); - rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL, - INT_MAX) + 1) + rng_int() % 5)); + rsetmoney(r, rsetpeasants(r, peasants) * p_wage); } } diff --git a/src/kernel/region.h b/src/kernel/region.h index 89b240f1b..9a7563712 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -176,7 +176,7 @@ extern "C" { int rsettrees(const struct region *r, int ageclass, int value); int rpeasants(const struct region *r); - void rsetpeasants(struct region *r, int value); + int rsetpeasants(struct region *r, int value); int rmoney(const struct region *r); void rsetmoney(struct region *r, int value); int rhorses(const struct region *r); diff --git a/src/laws.c b/src/laws.c index b67e641b8..25ce5aeea 100644 --- a/src/laws.c +++ b/src/laws.c @@ -743,7 +743,8 @@ void immigration(void) /* if less than 50 are in the region and there is space and no monster or demon units in the region */ if (repopulate) { int peasants = rpeasants(r); - int income = wage(r, NULL, NULL, turn) - maintenance_cost(NULL) + 1; + bool mourn = is_mourning(r, turn); + int income = peasant_wage(r, mourn) - maintenance_cost(NULL) + 1; if (income >= 0 && r->land && (peasants < repopulate) && region_maxworkers(r) >(peasants + 30) * 2) { int badunit = 0; unit *u; @@ -754,7 +755,7 @@ void immigration(void) } } if (badunit == 0) { - peasants += (int)(rng_double()*income); + peasants += (int)(rng_double() * income); rsetpeasants(r, peasants); } } @@ -836,8 +837,10 @@ void demographics(void) if (r->age > 20) { double mwp = fmax(region_maxworkers(r), 1); + bool mourn = is_mourning(r, turn); + int p_wage = peasant_wage(r, mourn); double prob = - pow(rpeasants(r) / (mwp * wage(r, NULL, NULL, turn) * 0.13), 4.0) + pow(rpeasants(r) / (mwp * p_wage * 0.13), 4.0) * PLAGUE_CHANCE; if (rng_double() < prob) { diff --git a/src/report.c b/src/report.c index f283b552f..09b9ab82e 100644 --- a/src/report.c +++ b/src/report.c @@ -1182,11 +1182,13 @@ static void report_statistics(struct stream *out, const region * r, const factio if (max_production(r) && (!fval(r->terrain, SEA_REGION) || f->race == get_race(RC_AQUARIAN))) { if (markets_module()) { /* hack */ + bool mourn = is_mourning(r, turn); + int p_wage = peasant_wage(r, mourn); m = - msg_message("nr_stat_salary_new", "max", wage(r, NULL, NULL, turn + 1)); + msg_message("nr_stat_salary_new", "max", p_wage); } else { - m = msg_message("nr_stat_salary", "max", wage(r, f, f->race, turn + 1)); + m = msg_message("nr_stat_salary", "max", wage(r, f->race)); } nr_render(m, f->locale, buf, sizeof(buf), f); paragraph(out, buf, 2, 2, 0); @@ -1337,7 +1339,7 @@ report_template(const char *filename, report_context * ctx, const char *bom) } rps_nowrap(out, buf); newline(out); - sprintf(buf, "; ECheck Lohn %d", wage(r, f, f->race, turn + 1)); + sprintf(buf, "; ECheck Lohn %d", wage(r, f->race)); rps_nowrap(out, buf); newline(out); newline(out);