From eac94bdf4a011f573a75511c960fdf98554a91ab Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 6 Jun 2016 22:14:28 +0200 Subject: [PATCH 1/4] add a test that demonstrates bug 2211 --- src/laws.test.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/laws.test.c b/src/laws.test.c index 1b2136db7..8363921a9 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1251,6 +1251,38 @@ static void test_show_without_item(CuTest *tc) test_cleanup(); } +static void test_show_elf(CuTest *tc) { + order *ord; + unit *u; + struct locale *loc; + message * msg; + + test_cleanup(); + + test_create_race("elf"); + test_create_itemtype("elvenhorse"); + + loc = get_or_create_locale("de"); + locale_setstring(loc, "elvenhorse", "Elfenpferd"); + locale_setstring(loc, "elvenhorse_p", "Elfenpferde"); + locale_setstring(loc, "race::elf_p", "Elfen"); + locale_setstring(loc, "race::elf", "Elf"); + init_locale(loc); + + CuAssertPtrNotNull(tc, finditemtype("elf", loc)); + CuAssertPtrNotNull(tc, findrace("elf", loc)); + + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u->faction->locale = loc; + ord = create_order(K_RESHOW, loc, "Elf"); + reshow_cmd(u, ord); + CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); + msg = test_find_messagetype(u->faction->msgs, "msg_event"); + CuAssertPtrNotNull(tc, msg); + free_order(ord); + test_cleanup(); +} + static int low_wage(const region * r, const faction * f, const race * rc, int in_turn) { return 1; } @@ -1386,6 +1418,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_name_building); SUITE_ADD_TEST(suite, test_name_ship); SUITE_ADD_TEST(suite, test_show_without_item); + SUITE_ADD_TEST(suite, test_show_elf); SUITE_ADD_TEST(suite, test_immigration); SUITE_ADD_TEST(suite, test_demon_hunger); From c79ecc1a7840786a2ca5f60c78c960bada69c337 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 6 Jun 2016 23:24:33 +0200 Subject: [PATCH 2/4] fix bug 2211, ignore a match for items we don't have. --- src/laws.c | 142 +++++++++++++++++++++++------------------------- src/laws.test.c | 6 +- 2 files changed, 73 insertions(+), 75 deletions(-) diff --git a/src/laws.c b/src/laws.c index 79889e7da..203970dc4 100755 --- a/src/laws.c +++ b/src/laws.c @@ -2213,26 +2213,13 @@ int send_cmd(unit * u, struct order *ord) return 0; } -static bool display_item(faction * f, unit * u, const item_type * itype) +static void display_item(unit * u, const item_type * itype) { + faction * f = u->faction; const char *name; const char *key; const char *info; - if (u != NULL) { - int i = i_get(u->items, itype); - if (i == 0) { - if (u->region->land != NULL) { - i = i_get(u->region->land->items, itype); - } - if (i == 0) { - i = i_get(u->faction->items, itype); - if (i == 0) - return false; - } - } - } - name = resourcename(itype->rtype, 0); key = mkname("iteminfo", name); info = locale_getstring(f->locale, key); @@ -2242,23 +2229,13 @@ static bool display_item(faction * f, unit * u, const item_type * itype) } ADDMSG(&f->msgs, msg_message("displayitem", "weight item description", itype->weight, itype->rtype, info)); - - return true; } -static bool display_potion(faction * f, unit * u, const potion_type * ptype) +static void display_potion(unit * u, const potion_type * ptype) { + faction * f = u->faction; attrib *a; - if (ptype == NULL) - return false; - else { - int i = i_get(u->items, ptype->itype); - if (i == 0 && 2 * ptype->level > effskill(u, SK_ALCHEMY, 0)) { - return false; - } - } - a = a_find(f->attribs, &at_showitem); while (a && a->data.v != ptype) a = a->next; @@ -2266,12 +2243,11 @@ static bool display_potion(faction * f, unit * u, const potion_type * ptype) a = a_add(&f->attribs, a_new(&at_showitem)); a->data.v = (void *)ptype->itype; } - - return true; } -static bool display_race(faction * f, unit * u, const race * rc) +static void display_race(unit * u, const race * rc) { + faction * f = u->faction; const char *name, *key; const char *info; int a, at_count; @@ -2279,8 +2255,6 @@ static bool display_race(faction * f, unit * u, const race * rc) size_t size = sizeof(buf) - 1; size_t bytes; - if (u && u_race(u) != rc) - return false; name = rc_name_s(rc, NAME_SINGULAR); bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name)); @@ -2294,7 +2268,7 @@ static bool display_race(faction * f, unit * u, const race * rc) info = LOC(f->locale, mkname("raceinfo", "no_info")); } - bufp = STRLCPY(bufp, info, size); + if (info) bufp = STRLCPY(bufp, info, size); /* hp_p : Trefferpunkte */ bytes = @@ -2412,17 +2386,72 @@ static bool display_race(faction * f, unit * u, const race * rc) *bufp = 0; addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT); +} - return true; +static void reshow_other(unit * u, struct order *ord, const char *s) { + int err = 21; + + if (s) { + const spell *sp = 0; + const item_type *itype; + const race *rc; + /* check if it's an item */ + itype = finditemtype(s, u->faction->locale); + sp = unit_getspell(u, s, u->faction->locale); + rc = findrace(s, u->faction->locale); + + if (itype) { + // if this is a potion, we need the right alchemy skill + int i = i_get(u->items, itype); + + err = 36; // we do not have this item? + if (i <= 0) { + // we don't have the item, but it may be a potion that we know + const potion_type *ptype = resource2potion(item2resource(itype)); + if (ptype) { + if (2 * ptype->level > effskill(u, SK_ALCHEMY, 0)) { + itype = NULL; + } + } else { + itype = NULL; + } + } + } + + if (itype) { + const potion_type *ptype = itype->rtype->ptype; + if (ptype) { + display_potion(u, ptype); + } + else { + display_item(u, itype); + } + return; + } + + if (sp) { + attrib *a = a_find(u->faction->attribs, &at_seenspell); + while (a != NULL && a->type == &at_seenspell && a->data.v != sp) { + a = a->next; + } + if (a != NULL) { + a_remove(&u->faction->attribs, a); + } + return; + } + + if (rc && u_race(u) == rc) { + display_race(u, rc); + return; + } + } + cmistake(u, ord, err, MSG_EVENT); } static void reshow(unit * u, struct order *ord, const char *s, param_t p) { int skill, c; const potion_type *ptype; - const item_type *itype; - const spell *sp = 0; - const race *rc; switch (p) { case P_ZAUBER: @@ -2433,48 +2462,15 @@ static void reshow(unit * u, struct order *ord, const char *s, param_t p) c = 0; for (ptype = potiontypes; ptype != NULL; ptype = ptype->next) { if (ptype->level * 2 <= skill) { - c += display_potion(u->faction, u, ptype); + display_potion(u, ptype); + ++c; } } if (c == 0) cmistake(u, ord, 285, MSG_EVENT); break; case NOPARAM: - if (s) { - /* check if it's an item */ - itype = finditemtype(s, u->faction->locale); - if (itype != NULL) { - ptype = resource2potion(item2resource(itype)); - if (ptype != NULL) { - if (display_potion(u->faction, u, ptype)) - break; - } - else { - if (!display_item(u->faction, u, itype)) - cmistake(u, ord, 36, MSG_EVENT); - - break; - } - } - /* try for a spell */ - sp = unit_getspell(u, s, u->faction->locale); - if (sp) { - attrib *a = a_find(u->faction->attribs, &at_seenspell); - while (a != NULL && a->type == &at_seenspell && a->data.v != sp) { - a = a->next; - } - if (a != NULL) { - a_remove(&u->faction->attribs, a); - } - break; - } - /* last, check if it's a race. */ - rc = findrace(s, u->faction->locale); - if (rc != NULL && display_race(u->faction, u, rc)) { - break; - } - } - cmistake(u, ord, 21, MSG_EVENT); + reshow_other(u, ord, s); break; default: cmistake(u, ord, 222, MSG_EVENT); diff --git a/src/laws.test.c b/src/laws.test.c index 8363921a9..290933369 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1253,13 +1253,14 @@ static void test_show_without_item(CuTest *tc) static void test_show_elf(CuTest *tc) { order *ord; + race * rc; unit *u; struct locale *loc; message * msg; test_cleanup(); - test_create_race("elf"); + rc = test_create_race("elf"); test_create_itemtype("elvenhorse"); loc = get_or_create_locale("de"); @@ -1272,13 +1273,14 @@ static void test_show_elf(CuTest *tc) { CuAssertPtrNotNull(tc, finditemtype("elf", loc)); CuAssertPtrNotNull(tc, findrace("elf", loc)); - u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); u->faction->locale = loc; ord = create_order(K_RESHOW, loc, "Elf"); reshow_cmd(u, ord); CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); msg = test_find_messagetype(u->faction->msgs, "msg_event"); CuAssertPtrNotNull(tc, msg); + test_clear_messages(u->faction); free_order(ord); test_cleanup(); } From 44d8f49bc31f8acf9dceb241aa5bd9e43c7ec0fa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 6 Jun 2016 23:39:40 +0200 Subject: [PATCH 3/4] test SHOW only works for your own race. testing message contents is hard! --- src/laws.test.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/laws.test.c b/src/laws.test.c index 290933369..7f947be45 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1260,6 +1260,7 @@ static void test_show_elf(CuTest *tc) { test_cleanup(); + mt_register(mt_new_va("msg_event", "string:string", 0)); rc = test_create_race("elf"); test_create_itemtype("elvenhorse"); @@ -1280,11 +1281,53 @@ static void test_show_elf(CuTest *tc) { CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error36") == NULL); msg = test_find_messagetype(u->faction->msgs, "msg_event"); CuAssertPtrNotNull(tc, msg); + CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); test_clear_messages(u->faction); free_order(ord); test_cleanup(); } +static void test_show_race(CuTest *tc) { + order *ord; + race * rc; + unit *u; + struct locale *loc; + message * msg; + + test_cleanup(); + + mt_register(mt_new_va("msg_event", "string:string", 0)); + test_create_race("human"); + rc = test_create_race("elf"); + + loc = get_or_create_locale("de"); + locale_setstring(loc, "race::elf_p", "Elfen"); + locale_setstring(loc, "race::elf", "Elf"); + locale_setstring(loc, "race::human_p", "Menschen"); + locale_setstring(loc, "race::human", "Mensch"); + init_locale(loc); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + u->faction->locale = loc; + + ord = create_order(K_RESHOW, loc, "Mensch"); + reshow_cmd(u, ord); + CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error21") != NULL); + CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "msg_event") == NULL); + test_clear_messages(u->faction); + free_order(ord); + + ord = create_order(K_RESHOW, loc, "Elf"); + reshow_cmd(u, ord); + CuAssertTrue(tc, test_find_messagetype(u->faction->msgs, "error21") == NULL); + msg = test_find_messagetype(u->faction->msgs, "msg_event"); + CuAssertPtrNotNull(tc, msg); + CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); + test_clear_messages(u->faction); + free_order(ord); + + test_cleanup(); +} + static int low_wage(const region * r, const faction * f, const race * rc, int in_turn) { return 1; } @@ -1421,6 +1464,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_name_ship); SUITE_ADD_TEST(suite, test_show_without_item); SUITE_ADD_TEST(suite, test_show_elf); + SUITE_ADD_TEST(suite, test_show_race); SUITE_ADD_TEST(suite, test_immigration); SUITE_ADD_TEST(suite, test_demon_hunger); From 1443c24b36c6258f63b47c12f4b38d8f0c233b7e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 6 Jun 2016 23:45:11 +0200 Subject: [PATCH 4/4] fix gcc build --- src/laws.test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/laws.test.c b/src/laws.test.c index 7f947be45..623717619 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -27,6 +27,7 @@ #include #include +#include static void test_new_building_can_be_renamed(CuTest * tc) {