From 7557b97deee6b52f45a6b181759810d95e1079de Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 13 Nov 2016 16:09:58 +0100 Subject: [PATCH] BUG 2253: Magicians cannot give men to empty units or peasants. https://bugs.eressea.de/view.php?id=2253 --- src/give.c | 22 +++++++------- src/give.test.c | 70 +++++++++++++++++++++++++++++++------------ src/kernel/messages.c | 7 +++-- 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/give.c b/src/give.c index b6d1bd118..912aba2dc 100644 --- a/src/give.c +++ b/src/give.c @@ -224,15 +224,11 @@ static bool unit_has_cursed_item(const unit * u) return false; } -static bool can_give_men(const unit *u, order *ord, message **msg) { - if (u_race(u) == get_race(RC_SNOTLING)) { - /* snotlings may not be given to the peasants. */ - if (msg) *msg = msg_error(u, ord, 307); - } - else if (unit_has_cursed_item(u)) { +static bool can_give_men(const unit *u, const unit *dst, order *ord, message **msg) { + if (unit_has_cursed_item(u)) { if (msg) *msg = msg_error(u, ord, 78); } - else if (has_skill(u, SK_MAGIC)) { + else if (dst && (has_skill(u, SK_MAGIC) && dst->number > 0)) { /* cannot give units to and from magicians */ if (msg) *msg = msg_error(u, ord, 158); } @@ -263,9 +259,9 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) message * msg; int maxt = max_transfers(); - assert(u2); + assert(u2); // use disband_men for GIVE 0 - if (!can_give_men(u, ord, &msg)) { + if (!can_give_men(u, u2, ord, &msg)) { return msg; } @@ -401,10 +397,16 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) message * disband_men(int n, unit * u, struct order *ord) { message * msg; - if (!can_give_men(u, ord, &msg)) { + // TODO: cache RC_SNOTLING + if (u_race(u) == get_race(RC_SNOTLING)) { + /* snotlings may not be given to the peasants. */ + return msg_error(u, ord, 307); + } + if (!can_give_men(u, NULL, ord, &msg)) { return msg; } transfermen(u, NULL, n); + //TODO: is ORCIFICATION still working? snotlings cannot be given to peasants #ifdef ORCIFICATION if (u_race(u) == get_race(RC_SNOTLING) && !fval(u->region, RF_ORCIFIED)) { attrib *a = a_find(u->region->attribs, &at_orcification); diff --git a/src/give.test.c b/src/give.test.c index e65c2861c..c719ddd5c 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -50,7 +50,7 @@ static void setup_give(struct give *env) { static void test_give_unit_to_peasants(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; setup_give(&env); @@ -63,7 +63,7 @@ static void test_give_unit_to_peasants(CuTest * tc) { static void test_give_unit(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); @@ -82,7 +82,7 @@ static void test_give_unit(CuTest * tc) { static void test_give_unit_in_ocean(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; setup_give(&env); @@ -94,7 +94,7 @@ static void test_give_unit_in_ocean(CuTest * tc) { static void test_give_men(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); CuAssertPtrEquals(tc, 0, give_men(1, env.src, env.dst, NULL)); @@ -103,10 +103,41 @@ static void test_give_men(CuTest * tc) { test_cleanup(); } +static void test_give_men_magicians(CuTest * tc) { + struct give env; + int p; + message * msg; + + test_setup(); + env.f2 = env.f1 = test_create_faction(0); + setup_give(&env); + set_level(env.src, SK_MAGIC, 1); + CuAssertPtrNotNull(tc, msg = give_men(1, env.src, env.dst, NULL)); + CuAssertStrEquals(tc, "error158", (const char *)msg->parameters[3].v); + CuAssertIntEquals(tc, 1, env.dst->number); + CuAssertIntEquals(tc, 1, env.src->number); + msg_release(msg); + + + set_number(env.dst, 0); + CuAssertPtrEquals(tc, NULL, give_men(1, env.src, env.dst, NULL)); + CuAssertIntEquals(tc, 1, env.dst->number); + CuAssertIntEquals(tc, 0, env.src->number); + + p = rpeasants(env.r); + CuAssertPtrNotNull(tc, msg = disband_men(1, env.dst, NULL)); + CuAssertStrEquals(tc, "give_person_peasants", (const char *)msg->parameters[0].v); + CuAssertIntEquals(tc, 0, env.dst->number); + CuAssertIntEquals(tc, p+1, rpeasants(env.r)); + msg_release(msg); + + test_cleanup(); +} + static void test_give_men_limit(CuTest * tc) { struct give env; message *msg; - test_cleanup(); + test_setup(); env.f2 = test_create_faction(0); env.f1 = test_create_faction(0); setup_give(&env); @@ -137,7 +168,7 @@ static void test_give_men_in_ocean(CuTest * tc) { struct give env; message * msg; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; setup_give(&env); @@ -151,7 +182,7 @@ static void test_give_men_in_ocean(CuTest * tc) { static void test_give_men_too_many(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); CuAssertPtrEquals(tc, 0, give_men(2, env.src, env.dst, NULL)); @@ -164,7 +195,7 @@ static void test_give_men_none(CuTest * tc) { struct give env; message * msg; - test_cleanup(); + test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); msg = give_men(0, env.src, env.dst, NULL); @@ -179,7 +210,7 @@ static void test_give_men_other_faction(CuTest * tc) { struct give env; message * msg; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); @@ -198,7 +229,7 @@ static void test_give_men_requires_contact(CuTest * tc) { order *ord; char cmd[32]; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); @@ -222,7 +253,7 @@ static void test_give_men_requires_contact(CuTest * tc) { static void test_give_men_not_to_self(CuTest * tc) { struct give env; message * msg; - test_cleanup(); + test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); msg = give_men(1, env.src, env.src, NULL); @@ -236,7 +267,7 @@ static void test_give_peasants(CuTest * tc) { struct give env; message * msg; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; setup_give(&env); @@ -252,7 +283,7 @@ static void test_give_peasants(CuTest * tc) { static void test_give(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); @@ -272,7 +303,7 @@ static void test_give_herbs(CuTest * tc) { struct order *ord; char cmd[32]; - test_cleanup(); + test_setup(); test_create_world(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); @@ -292,7 +323,7 @@ static void test_give_herbs(CuTest * tc) { static void test_give_okay(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f2 = env.f1 = test_create_faction(0); setup_give(&env); @@ -305,7 +336,7 @@ static void test_give_denied_by_rules(CuTest * tc) { struct give env; struct message *msg; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); @@ -320,7 +351,7 @@ static void test_give_dead_unit(CuTest * tc) { struct give env; struct message *msg; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); @@ -334,7 +365,7 @@ static void test_give_dead_unit(CuTest * tc) { static void test_give_new_unit(CuTest * tc) { struct give env; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = test_create_faction(0); setup_give(&env); @@ -349,7 +380,7 @@ static void test_give_invalid_target(CuTest *tc) { struct give env; order *ord; - test_cleanup(); + test_setup(); env.f1 = test_create_faction(0); env.f2 = 0; setup_give(&env); @@ -370,6 +401,7 @@ CuSuite *get_give_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_give); SUITE_ADD_TEST(suite, test_give_men); + SUITE_ADD_TEST(suite, test_give_men_magicians); SUITE_ADD_TEST(suite, test_give_men_limit); SUITE_ADD_TEST(suite, test_give_men_in_ocean); SUITE_ADD_TEST(suite, test_give_men_none); diff --git a/src/kernel/messages.c b/src/kernel/messages.c index 330c2feeb..566e9bdef 100644 --- a/src/kernel/messages.c +++ b/src/kernel/messages.c @@ -92,10 +92,11 @@ struct message *msg_feedback(const struct unit *u, struct order *ord, if (!mtype) { log_warning("trying to create message of unknown type \"%s\"\n", name); if (!mt_find("missing_feedback")) { - mt_register(mt_new_va("missing_feedback", "unit:unit", "region:region", "command:order", "name:string", 0)); + mt_register(mt_new_va("missing_feedback", "unit:unit", + "region:region", "command:order", "name:string", 0)); } - return msg_message("missing_feedback", "unit region command name", u, - u->region, ord, name); + return msg_message("missing_feedback", "name unit region command", + name, u, u->region, ord); } var.v = (void *)u;