From 215136465bfaf193adc0db5dc61aea147f0afd47 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 10 Dec 2014 23:04:54 +0100 Subject: [PATCH] refactoring: getunitpeasants is an awful global hack, and I am pushing it out of give_men so I can eliminate it more easily. --- src/give.c | 129 ++++++++++++++++++++++++-------------------- src/give.test.c | 1 - src/kernel/config.c | 2 +- src/kernel/config.h | 2 +- 4 files changed, 73 insertions(+), 61 deletions(-) diff --git a/src/give.c b/src/give.c index 94ce97949..ecbbe949c 100644 --- a/src/give.c +++ b/src/give.c @@ -210,61 +210,81 @@ struct order *ord) return 0; } +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)) { + if (msg) *msg = msg_error(u, ord, 78); + } + else if (has_skill(u, SK_MAGIC)) { + /* cannot give units to and from magicians */ + if (msg) *msg = msg_error(u, ord, 158); + } + else if (fval(u, UFL_HUNGER)) { + /* hungry people cannot be given away */ + if (msg) *msg = msg_error(u, ord, 73); + } + else if (fval(u, UFL_LOCKED) || is_cursed(u->attribs, C_SLAVE, 0)) { + if (msg) *msg = msg_error(u, ord, 74); + } + else { + return true; + } + return false; +} + message * give_men(int n, unit * u, unit * u2, struct order *ord) { ship *sh; int k = 0; int error = 0; + message * msg; - if (u2 && u->faction != u2->faction && u->faction->age < GiveRestriction()) { + assert(u2); + + if (!can_give_men(u, ord, &msg)) { + return msg; + } + + if (u->faction != u2->faction && u->faction->age < GiveRestriction()) { return msg_feedback(u, ord, "giverestriction", "turns", GiveRestriction()); } else if (u == u2) { error = 10; } - else if (!u2 && u_race(u) == get_race(RC_SNOTLING)) { - /* snotlings may not be given to the peasants. */ - error = 307; - } - else if (u2 && u2->number && (fval(u, UFL_HERO) != fval(u2, UFL_HERO))) { + else if (u2->number && (fval(u, UFL_HERO) != fval(u2, UFL_HERO))) { /* heroes may not be given to non-heroes and vice versa */ error = 75; } - else if (unit_has_cursed_item(u) || (u2 && unit_has_cursed_item(u2))) { + else if (unit_has_cursed_item(u2)) { error = 78; } - else if (fval(u, UFL_LOCKED) || is_cursed(u->attribs, C_SLAVE, 0)) { - error = 74; - } - else if (u2 && fval(u, UFL_HUNGER)) { - /* hungry people cannot be given away */ - error = 73; - } - else if (u2 && (fval(u2, UFL_LOCKED) || is_cursed(u2->attribs, C_SLAVE, 0))) { + else if (fval(u2, UFL_LOCKED) || is_cursed(u2->attribs, C_SLAVE, 0)) { error = 75; } - else if (u2 && !ucontact(u2, u)) { + else if (!ucontact(u2, u)) { return msg_feedback(u, ord, "feedback_no_contact", "target", u2); } - else if (u2 && (has_skill(u, SK_MAGIC) || has_skill(u2, SK_MAGIC))) { + else if (has_skill(u2, SK_MAGIC)) { /* cannot give units to and from magicians */ error = 158; } - else if (u2 && (fval(u, UFL_WERE) != fval(u2, UFL_WERE))) { + else if (fval(u, UFL_WERE) != fval(u2, UFL_WERE)) { /* werewolves can't be given to non-werewolves and vice-versa */ error = 312; } - else if (u2 && u2->number != 0 && u_race(u2) != u_race(u)) { + else if (u2->number != 0 && u_race(u2) != u_race(u)) { log_debug("faction %s attempts to give %s to %s.\n", itoa36(u->faction->no), u_race(u)->_name, u_race(u2)->_name); error = 139; } - else if (u2 != NULL && (get_racename(u2->attribs) - || get_racename(u->attribs))) { + else if (get_racename(u2->attribs) || get_racename(u->attribs)) { error = 139; } - else if (u2 && u2->faction != u->faction && !rule_transfermen()) { + else if (u2->faction != u->faction && !rule_transfermen()) { error = 74; } else { @@ -279,7 +299,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) if (n == 0) { error = 96; } - else if (u2 && u->faction != u2->faction) { + else if (u->faction != u2->faction) { if (u2->faction->newbies + n > MAXNEWBIES) { error = 129; } @@ -301,7 +321,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) } } - if (u2 && (has_skill(u, SK_ALCHEMY) || has_skill(u2, SK_ALCHEMY))) { + if (has_skill(u, SK_ALCHEMY) || has_skill(u2, SK_ALCHEMY)) { k = count_skill(u2->faction, SK_ALCHEMY); /* Falls die Zieleinheit keine Alchemisten sind, werden sie nun @@ -325,7 +345,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) } if (error == 0) { - if (u2 && u2->number == 0) { + if (u2->number == 0) { set_racename(&u2->attribs, get_racename(u->attribs)); u_setrace(u2, u_race(u)); u2->irace = u->irace; @@ -335,41 +355,20 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) freset(u2, UFL_HERO); } - if (u2) { - /* Einheiten von Schiffen können nicht NACH in von - * Nicht-alliierten bewachten Regionen ausführen */ - sh = leftship(u); - if (sh) { - set_leftship(u2, sh); - } - transfermen(u, u2, n); - if (u->faction != u2->faction) { - u2->faction->newbies += n; - } + /* Einheiten von Schiffen können nicht NACH in von + * Nicht-alliierten bewachten Regionen ausführen */ + sh = leftship(u); + if (sh) { + set_leftship(u2, sh); } - else { - if (getunitpeasants) { -#ifdef ORCIFICATION - if (u_race(u) == get_race(RC_SNOTLING) && !fval(u->region, RF_ORCIFIED)) { - attrib *a = a_find(u->region->attribs, &at_orcification); - if (!a) - a = a_add(&u->region->attribs, a_new(&at_orcification)); - a->data.i += n; - } -#endif - transfermen(u, NULL, n); - } - else { - error = 159; - } + transfermen(u, u2, n); + if (u->faction != u2->faction) { + u2->faction->newbies += n; } } if (error > 0) { return msg_error(u, ord, error); } - else if (!u2) { - return msg_message("give_person_peasants", "unit amount", u, n); - } else if (u2->faction != u->faction) { message *msg = msg_message("give_person", "unit target amount", u, u2, n); add_message(&u2->faction->msgs, msg); @@ -379,8 +378,22 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) } message * disband_men(int n, unit * u, struct order *ord) { - getunitpeasants = true; - return give_men(n, u, NULL, ord); + message * msg; + + if (!can_give_men(u, ord, &msg)) { + return msg; + } + transfermen(u, NULL, n); +#ifdef ORCIFICATION + if (u_race(u) == get_race(RC_SNOTLING) && !fval(u->region, RF_ORCIFIED)) { + attrib *a = a_find(u->region->attribs, &at_orcification); + if (!a) { + a = a_add(&u->region->attribs, a_new(&at_orcification)); + } + a->data.i += n; + } +#endif + return msg_message("give_person_peasants", "unit amount", u, n); } void give_unit(unit * u, unit * u2, order * ord) @@ -678,7 +691,7 @@ void give_cmd(unit * u, order * ord) } else { message * msg; - msg = give_men(u->number, u, u2, ord); + msg = getunitpeasants ? disband_men(u->number, u, ord) : give_men(u->number, u, u2, ord); if (msg) { ADDMSG(&u->faction->msgs, msg); } @@ -734,7 +747,7 @@ void give_cmd(unit * u, order * ord) msg_feedback(u, ord, "race_noregroup", "race", u_race(u))); return; } - msg = give_men(u->number, u, u2, ord); + msg = getunitpeasants ? disband_men(u->number, u, ord) : give_men(u->number, u, u2, ord); if (msg) { ADDMSG(&u->faction->msgs, msg); } diff --git a/src/give.test.c b/src/give.test.c index 039663872..f376c4577 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -124,7 +124,6 @@ static void test_give_peasants(CuTest * tc) { env.f2 = 0; setup_give(&env); peasants = env.r->land->peasants; - getunitpeasants = 1; msg = disband_men(1, env.src, NULL); CuAssertStrEquals(tc, "give_person_peasants", (const char*)msg->parameters[0].v); CuAssertIntEquals(tc, 0, env.src->number); diff --git a/src/kernel/config.c b/src/kernel/config.c index 83cb2f7cc..3dd22b159 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -604,7 +604,7 @@ unsigned int atoip(const char *s) return n; } -bool unit_has_cursed_item(unit * u) +bool unit_has_cursed_item(const unit * u) { item *itm = u->items; while (itm) { diff --git a/src/kernel/config.h b/src/kernel/config.h index ab8916820..0a1f5b242 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -234,7 +234,7 @@ extern "C" { struct region *lastregion(struct faction *f); bool idle(struct faction *f); - bool unit_has_cursed_item(struct unit *u); + bool unit_has_cursed_item(const struct unit *u); /* simple garbage collection: */ void *gc_add(void *p);