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, 0, env.f2->newbies);
CuAssertIntEquals(tc, 1, env.f1->num_units); CuAssertIntEquals(tc, 1, env.f1->num_units);
CuAssertIntEquals(tc, 1, env.f2->num_units); CuAssertIntEquals(tc, 1, env.f2->num_units);
CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "too_many_units_in_faction"));
test_cleanup(); 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) static void perform_join(void)
{ {
int alimit = rule_alliance_limit();
alliance_transaction **tap = transactions + ALLIANCE_JOIN; alliance_transaction **tap = transactions + ALLIANCE_JOIN;
while (*tap) { while (*tap) {
alliance_transaction *ta = *tap; alliance_transaction *ta = *tap;
@ -270,7 +287,16 @@ static void perform_join(void)
ti = *tip; ti = *tip;
} }
if (ti) { if (ti) {
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); setalliance(fj, al);
}
*tip = ti->next; *tip = ti->next;
free(ti); free(ti);
} }

View File

@ -67,7 +67,7 @@ extern "C" {
struct faction *alliance_get_leader(struct alliance *al); struct faction *alliance_get_leader(struct alliance *al);
void alliance_cmd(void); void alliance_cmd(void);
bool is_allied(const struct faction *f1, const struct faction *f2); 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); void alliance_setname(alliance * self, const char *name);
/* execute commands */ /* execute commands */

View File

@ -112,6 +112,29 @@ static void test_alliance_cmd(CuTest *tc) {
test_cleanup(); 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) { static void test_alliance_cmd_kick(CuTest *tc) {
unit *u1, *u2; unit *u1, *u2;
struct region *r; 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_dead_faction);
SUITE_ADD_TEST(suite, test_alliance_make); SUITE_ADD_TEST(suite, test_alliance_make);
SUITE_ADD_TEST(suite, test_alliance_join); 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);
SUITE_ADD_TEST(suite, test_alliance_cmd_no_invite); SUITE_ADD_TEST(suite, test_alliance_cmd_no_invite);
SUITE_ADD_TEST(suite, test_alliance_cmd_kick); 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(); alimit = rule_alliance_limit();
if (alimit) { if (alimit) {
faction *f2; int unitsinalliance = alliance_size(f->alliance);
int unitsinalliance = fno; if (unitsinalliance + add > alimit) {
if (unitsinalliance > alimit) {
return 1; 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; return 0;