From c48371387c5f3f121d537f7b1fbbc423d31c3254 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 4 Nov 2018 18:07:42 +0100 Subject: [PATCH] New Syntax: CONTACT [UNIT|FACTION] ... Move everything to contact module, add tests. --- src/contact.c | 94 ++++++++++++++++++++++++++++++++++--------- src/contact.h | 8 ++-- src/contact.test.c | 54 +++++++++++++++++++++++-- src/give.test.c | 6 +-- src/kernel/messages.h | 2 +- src/move.test.c | 2 +- 6 files changed, 136 insertions(+), 30 deletions(-) diff --git a/src/contact.c b/src/contact.c index 2ca5fc5be..635bdbd3d 100644 --- a/src/contact.c +++ b/src/contact.c @@ -6,9 +6,16 @@ #include "kernel/attrib.h" #include "kernel/faction.h" +#include "kernel/messages.h" #include "kernel/order.h" #include "kernel/unit.h" +#include "util/base36.h" +#include "util/param.h" +#include "util/parser.h" + +#include + static attrib_type at_contact_unit = { "contact_unit", DEFAULT_INIT, @@ -18,16 +25,7 @@ static attrib_type at_contact_unit = { NO_READ }; -static attrib_type at_contact_faction = { - "contact_faction", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - NO_WRITE, - NO_READ -}; - -void usetcontact(unit * u, const unit * u2) +void contact_unit(unit * u, const unit * u2) { attrib *a = a_find(u->attribs, &at_contact_unit); while (a && a->type == &at_contact_unit) { @@ -39,6 +37,27 @@ void usetcontact(unit * u, const unit * u2) a_add(&u->attribs, a_new(&at_contact_unit))->data.v = (void *)u2; } +static attrib_type at_contact_faction = { + "contact_faction", + DEFAULT_INIT, + DEFAULT_FINALIZE, + DEFAULT_AGE, + NO_WRITE, + NO_READ +}; + +void contact_faction(unit * u, const faction * f) +{ + attrib *a = a_find(u->attribs, &at_contact_faction); + while (a && a->type == &at_contact_faction) { + if (a->data.v == f) { + return; + } + a = a->next; + } + a_add(&u->attribs, a_new(&at_contact_faction))->data.v = (void *)f; +} + bool ucontact(const unit * u, const unit * u2) /* Prueft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */ { @@ -65,16 +84,53 @@ bool ucontact(const unit * u, const unit * u2) int contact_cmd(unit * u, order * ord) { - unit *u2; - int n; + char token[16]; + const char *str; + param_t p; init_order(ord, u->faction->locale); - n = read_unitid(u->faction, u->region); - u2 = findunit(n); - - if (u2 != NULL) { - usetcontact(u, u2); + str = gettoken(token, sizeof(token)); + p = findparam(str, u->faction->locale); + if (p == P_FACTION) { + /* new-style syntax, KONTAKTIERE PARTEI foo */ + faction * f = getfaction(); + if (!f) { + cmistake(u, ord, 66, MSG_EVENT); + } + else { + contact_faction(u, f); + return 0; + } } - return 0; + else if (p == P_UNIT) { + /* new-style syntax, KONTAKTIERE EINHEIT [TEMP] foo */ + unit *u2 = NULL; + if (GET_UNIT == getunit(u->region, u->faction, &u2)) { + assert(u2); + contact_unit(u, u2); + return 0; + } + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, + "feedback_unit_not_found", NULL)); + } + else { + /* old-style syntax, KONTAKTIERE foo */ + unit *u2; + int n = 0; + if (p == P_TEMP) { + n = getid(); + u2 = findnewunit(u->region, u->faction, n); + } + else { + n = atoi36((const char *)str); + u2 = findunit(n); + } + if (u2 != NULL) { + contact_unit(u, u2); + return 0; + } + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, + "feedback_unit_not_found", NULL)); + } + return -1; } - diff --git a/src/contact.h b/src/contact.h index d3f751887..0ab3d1e50 100644 --- a/src/contact.h +++ b/src/contact.h @@ -2,9 +2,11 @@ #include -struct unit; struct faction; +struct order; +struct unit; bool ucontact(const struct unit *u, const struct unit *u2); -void usetcontact(struct unit *u, const struct unit *c); - +void contact_unit(struct unit *u, const struct unit *c); +void contact_faction(struct unit * u, const struct faction * f); +int contact_cmd(struct unit * u, struct order * ord); diff --git a/src/contact.test.c b/src/contact.test.c index 4374eb259..3a9cc355e 100644 --- a/src/contact.test.c +++ b/src/contact.test.c @@ -1,11 +1,16 @@ #include "contact.h" +#include "kernel/faction.h" +#include "kernel/order.h" +#include "kernel/unit.h" + +#include "util/language.h" +#include "util/param.h" + #include "tests.h" #include struct region; -struct unit; -struct faction; static void test_contact(CuTest *tc) { struct unit *u1, *u2, *u3; @@ -21,16 +26,59 @@ static void test_contact(CuTest *tc) { CuAssertTrue(tc, ucontact(u1, u1)); CuAssertTrue(tc, ucontact(u1, u2)); CuAssertTrue(tc, !ucontact(u1, u3)); - usetcontact(u1, u3); + contact_unit(u1, u3); CuAssertTrue(tc, ucontact(u1, u3)); CuAssertTrue(tc, !ucontact(u2, u3)); test_teardown(); } +static void test_contact_cmd(CuTest *tc) { + struct unit *u, *u2; + struct region *r; + const struct locale *lang; + struct order *ord; + + test_setup(); + r = test_create_plain(0, 0); + u = test_create_unit(test_create_faction(NULL), r); + lang = u->faction->locale; + + u2 = test_create_unit(test_create_faction(NULL), r); + ord = create_order(K_CONTACT, u->faction->locale, "%s %i", + LOC(lang, parameters[P_UNIT]), u2->no); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + u2 = test_create_unit(test_create_faction(NULL), r); + ord = create_order(K_CONTACT, u->faction->locale, "%s %i", + LOC(lang, parameters[P_FACTION]), u2->faction->no); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + u2 = test_create_unit(test_create_faction(NULL), r); + ord = create_order(K_CONTACT, u->faction->locale, "%i", u2->no); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + u2 = test_create_unit(test_create_faction(NULL), r); + usetalias(u2, 42); + ord = create_order(K_CONTACT, u->faction->locale, "%s %i", + LOC(lang, parameters[P_TEMP]), ualias(u2)); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + test_teardown(); +} + CuSuite *get_contact_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_contact); + SUITE_ADD_TEST(suite, test_contact_cmd); return suite; } diff --git a/src/give.test.c b/src/give.test.c index f8009874c..c62973388 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -195,7 +195,7 @@ static void test_give_men_limit(CuTest * tc) { config_set("rules.give.max_men", "1"); /* below the limit, give men, increase newbies counter */ - usetcontact(env.dst, env.src); + contact_unit(env.dst, env.src); msg = give_men(1, env.src, env.dst, NULL); CuAssertStrEquals(tc, "give_person", test_get_messagetype(msg)); CuAssertIntEquals(tc, 2, env.dst->number); @@ -204,7 +204,7 @@ static void test_give_men_limit(CuTest * tc) { msg_release(msg); /* beyond the limit, do nothing */ - usetcontact(env.src, env.dst); + contact_unit(env.src, env.dst); msg = give_men(2, env.dst, env.src, NULL); CuAssertStrEquals(tc, "error129", test_get_messagetype(msg)); CuAssertIntEquals(tc, 2, env.dst->number); @@ -283,7 +283,7 @@ static void test_give_men_other_faction(CuTest * tc) { env.f1 = test_create_faction(NULL); env.f2 = test_create_faction(NULL); setup_give(&env); - usetcontact(env.dst, env.src); + contact_unit(env.dst, env.src); msg = give_men(1, env.src, env.dst, NULL); CuAssertStrEquals(tc, "give_person", test_get_messagetype(msg)); CuAssertIntEquals(tc, 2, env.dst->number); diff --git a/src/kernel/messages.h b/src/kernel/messages.h index 723ed2d01..ba441250d 100644 --- a/src/kernel/messages.h +++ b/src/kernel/messages.h @@ -63,7 +63,7 @@ extern "C" { struct mlist ** merge_messages(message_list *ml, message_list *append); void split_messages(message_list *ml, struct mlist **split); -#define ADDMSG(msgs, mcreate) { message * mx = mcreate; if (mx) { assert(mx->refcount>=1); add_message(msgs, mx); msg_release(mx); } } +#define ADDMSG(msgs, mcreate) { message * mx = mcreate; if (mx) { add_message(msgs, mx); msg_release(mx); } } void syntax_error(const struct unit *u, struct order *ord); void cmistake(const struct unit *u, struct order *ord, int mno, int mtype); diff --git a/src/move.test.c b/src/move.test.c index b240171d5..40a6d3504 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -130,7 +130,7 @@ static void test_ship_has_harbormaster_contact(CuTest * tc) { u = test_create_unit(test_create_faction(NULL), mf.r); u->building = mf.b; building_set_owner(u); - usetcontact(mf.b->_owner, mf.sh->_owner); + contact_unit(mf.b->_owner, mf.sh->_owner); CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r)); test_teardown();