BUG 2311: enforce all unit limits.

This commit is contained in:
Enno Rehling 2017-03-11 20:30:17 +01:00
parent 21e260907c
commit 4c21ff5d63
5 changed files with 55 additions and 14 deletions

View File

@ -88,6 +88,7 @@ static void test_give_unit_limits(CuTest * tc) {
CuAssertIntEquals(tc, 0, env.f2->newbies);
CuAssertIntEquals(tc, 1, env.f1->num_units);
CuAssertIntEquals(tc, 1, env.f2->num_units);
CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "too_many_units_in_faction"));
test_cleanup();
}

View File

@ -239,8 +239,25 @@ static void perform_transfer(void)
}
}
bool num_units_cb(void *entry, void *more) {
faction *f = (faction *)entry;
int *num = (int *)more;
*num += f->num_units;
return true;
}
int alliance_size(const alliance *al)
{
int num = 0;
if (al) {
selist_foreach_ex(al->members, num_units_cb, &num);
}
return num;
}
static void perform_join(void)
{
int alimit = rule_alliance_limit();
alliance_transaction **tap = transactions + ALLIANCE_JOIN;
while (*tap) {
alliance_transaction *ta = *tap;
@ -270,7 +287,16 @@ static void perform_join(void)
ti = *tip;
}
if (ti) {
setalliance(fj, al);
int maxsize = (alimit > 0) ? (alimit - alliance_size(al)) : 0;
if (alimit > 0 && fj->num_units > maxsize) {
ADDMSG(&fj->msgs,
msg_feedback(ta->u, ta->ord,
"too_many_units_in_alliance",
"allowed", alimit));
}
else {
setalliance(fj, al);
}
*tip = ti->next;
free(ti);
}

View File

@ -67,7 +67,7 @@ extern "C" {
struct faction *alliance_get_leader(struct alliance *al);
void alliance_cmd(void);
bool is_allied(const struct faction *f1, const struct faction *f2);
int alliance_size(const struct alliance *al); /* #units in the alliance */
void alliance_setname(alliance * self, const char *name);
/* execute commands */

View File

@ -112,6 +112,29 @@ static void test_alliance_cmd(CuTest *tc) {
test_cleanup();
}
static void test_alliance_limits(CuTest *tc) {
unit *u1, *u2;
struct region *r;
test_setup();
r = test_create_region(0, 0, 0);
u1 = test_create_unit(test_create_faction(0), r);
u2 = test_create_unit(test_create_faction(0), r);
config_set("rules.limit.alliance", "1");
unit_addorder(u1, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_NEW], itoa36(42)));
unit_addorder(u1, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_INVITE], itoa36(u2->faction->no)));
unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42)));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction));
alliance_cmd();
CuAssertPtrNotNull(tc, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "too_many_units_in_alliance"));
test_cleanup();
}
static void test_alliance_cmd_kick(CuTest *tc) {
unit *u1, *u2;
struct region *r;
@ -200,6 +223,7 @@ CuSuite *get_alliance_suite(void)
SUITE_ADD_TEST(suite, test_alliance_dead_faction);
SUITE_ADD_TEST(suite, test_alliance_make);
SUITE_ADD_TEST(suite, test_alliance_join);
SUITE_ADD_TEST(suite, test_alliance_limits);
SUITE_ADD_TEST(suite, test_alliance_cmd);
SUITE_ADD_TEST(suite, test_alliance_cmd_no_invite);
SUITE_ADD_TEST(suite, test_alliance_cmd_kick);

View File

@ -3028,20 +3028,10 @@ int checkunitnumber(const faction * f, int add)
alimit = rule_alliance_limit();
if (alimit) {
faction *f2;
int unitsinalliance = fno;
if (unitsinalliance > alimit) {
int unitsinalliance = alliance_size(f->alliance);
if (unitsinalliance + add > alimit) {
return 1;
}
for (f2 = factions; f2; f2 = f2->next) {
if (f != f2 && f->alliance == f2->alliance) {
unitsinalliance += f2->num_units;
if (unitsinalliance > alimit) {
return 1;
}
}
}
}
return 0;