diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 8e6d66c9f..e6b3b8f4a 100755 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1299,3 +1299,38 @@ function test_bug_1870_leave_enter_e3() process_orders() assert_equal(u1.building.id, mine.id) end + +function test_bug_1795_limit() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u1 = one_unit(r,f) + u1:add_item("money", 100000000) + u1:add_order("REKRUTIEREN 9999") + r:set_resource("peasant", 2000) -- no fractional growth! + local peasants = r:get_resource("peasant") + local limit,frac = math.modf(peasants/40) -- one day this should be a parameter + local growth = peasants * 0.001 + + process_orders() + + assert_equal(limit+1, u1.number, u1.number .. "!=" .. (limit+1)) + assert_equal(peasants+growth-limit, r:get_resource("peasant")) +end + +function test_bug_1795_demons() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "demon", "de") + local u1 = one_unit(r,f) + r:set_resource("peasant", 2000) + local peasants = r:get_resource("peasant") + local limit,frac = math.modf(peasants/40) + local growth = peasants * 0.001 + + u1:add_item("money", 100000000) + u1:add_order("REKRUTIEREN 9999") + + process_orders() + + assert_equal(limit+1, u1.number, u1.number .. "!=" .. (limit+1)) + assert_equal(peasants+growth, r:get_resource("peasant")) +end diff --git a/src/gamecode/economy.c b/src/gamecode/economy.c index 859cdd079..10de6365d 100644 --- a/src/gamecode/economy.c +++ b/src/gamecode/economy.c @@ -215,6 +215,9 @@ typedef struct recruitment { int total, assigned; } recruitment; +/** Creates a list of recruitment structs, one for each faction. Adds every quantifyable request + * to the faction's struct and to total. + */ static recruitment *select_recruitment(request ** rop, int (*quantify) (const struct race *, int), int *total) { @@ -292,14 +295,14 @@ static int any_recruiters(const struct race *rc, int qty) return (int)(qty * 2 * rc->recruit_multi); } -static int peasant_recruiters(const struct race *rc, int qty) +/*static int peasant_recruiters(const struct race *rc, int qty) { if (rc->ec_flags & ECF_REC_ETHEREAL) return -1; if (rc->ec_flags & ECF_REC_HORSES) return -1; return (int)(qty * 2 * rc->recruit_multi); -} +}*/ static int horse_recruiters(const struct race *rc, int qty) { @@ -315,10 +318,12 @@ static int do_recruiting(recruitment * recruits, int available) recruitment *rec; int recruited = 0; + /* try to assign recruits to factions fairly */ while (available > 0) { int n = 0; int rest, mintotal = INT_MAX; + /* find smallest request */ for (rec = recruits; rec != NULL; rec = rec->next) { int want = rec->total - rec->assigned; if (want > 0) { @@ -334,6 +339,8 @@ static int do_recruiting(recruitment * recruits, int available) } rest = available - mintotal * n; + /* assign size of smallest request for everyone if possible; in the end roll dice to assign + * small rest */ for (rec = recruits; rec != NULL; rec = rec->next) { int want = rec->total - rec->assigned; @@ -350,6 +357,7 @@ static int do_recruiting(recruitment * recruits, int available) } } + /* do actual recruiting */ for (rec = recruits; rec != NULL; rec = rec->next) { request *req; int get = rec->assigned; @@ -365,8 +373,6 @@ static int do_recruiting(recruitment * recruits, int available) int afford = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, number * rc->recruitcost) / rc->recruitcost; number = MIN(number, afford); - use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, - rc->recruitcost * number); } if (u->number + number > UNIT_MAXSIZE) { ADDMSG(&u->faction->msgs, msg_feedback(u, req->ord, "error_unit_size", @@ -374,6 +380,10 @@ static int do_recruiting(recruitment * recruits, int available) number = UNIT_MAXSIZE - u->number; assert(number >= 0); } + if (rc->recruitcost) { + use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, + rc->recruitcost * number); + } add_recruits(u, number, req->qty); dec = (int)(number * multi); if ((rc->ec_flags & ECF_REC_ETHEREAL) == 0) { @@ -449,7 +459,7 @@ static void expandrecruit(region * r, request * recruitorders) } /* peasant limited: */ - recruits = select_recruitment(&recruitorders, peasant_recruiters, &orc_total); + recruits = select_recruitment(&recruitorders, any_recruiters, &orc_total); if (recruits) { int orc_recruited, orc_peasants = rpeasants(r) * 2; int orc_frac = orc_peasants / RECRUITFRACTION; /* anzahl orks. 2 ork = 1 bauer */ @@ -464,10 +474,10 @@ static void expandrecruit(region * r, request * recruitorders) /* no limit: */ recruits = select_recruitment(&recruitorders, any_recruiters, &orc_total); if (recruits) { - int recruited, peasants = rpeasants(r); + int recruited, peasants = rpeasants(r) * 2; recruited = do_recruiting(recruits, INT_MAX); if (recruited > 0) { - rsetpeasants(r, peasants - recruited / 2); + rsetpeasants(r, (peasants - recruited) / 2); } free_recruitments(recruits); }