From f5b35a9a2bdc0a60f68a73ad4e825019397d1fa9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 24 May 2012 23:50:27 -0700 Subject: [PATCH] equipment sets that include spells now have levels on them and store in a spellbook. add some tests for equipment. --- res/equipment.xml | 48 +++++++++++++++---------------- src/kernel.vcxproj | 1 + src/kernel.vcxproj.filters | 3 ++ src/kernel/equipment.c | 33 ++++++++++++---------- src/kernel/equipment.h | 4 +-- src/kernel/equipment_test.c | 56 +++++++++++++++++++++++++++++++++++++ src/kernel/unit.c | 54 +++++++++++++++++------------------ src/kernel/xmlreader.c | 5 ++-- src/tests.c | 4 ++- 9 files changed, 136 insertions(+), 72 deletions(-) create mode 100644 src/kernel/equipment_test.c diff --git a/res/equipment.xml b/res/equipment.xml index 1a38ab808..a998ef712 100644 --- a/res/equipment.xml +++ b/res/equipment.xml @@ -32,9 +32,9 @@ - - - + + + @@ -48,10 +48,10 @@ - - - - + + + + @@ -59,12 +59,12 @@ - - - - - - + + + + + + @@ -75,9 +75,9 @@ - - - + + + @@ -87,9 +87,9 @@ - - - + + + @@ -99,16 +99,16 @@ - - + + - - - + + + diff --git a/src/kernel.vcxproj b/src/kernel.vcxproj index 6db6ea17b..78a213902 100644 --- a/src/kernel.vcxproj +++ b/src/kernel.vcxproj @@ -101,6 +101,7 @@ + diff --git a/src/kernel.vcxproj.filters b/src/kernel.vcxproj.filters index f09da757a..906d6566d 100644 --- a/src/kernel.vcxproj.filters +++ b/src/kernel.vcxproj.filters @@ -319,6 +319,9 @@ kernel + + kernel + diff --git a/src/kernel/equipment.c b/src/kernel/equipment.c index 740bf7703..44e275ce6 100644 --- a/src/kernel/equipment.c +++ b/src/kernel/equipment.c @@ -23,7 +23,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* kernel includes */ #include "item.h" #include "unit.h" +#include "faction.h" #include "race.h" +#include "spellbook.h" /* util includes */ #include @@ -43,13 +45,9 @@ equipment *create_equipment(const char *eqname) struct equipment *eq = *eqp; int i = eq ? strcmp(eq->name, eqname) : 1; if (i > 0) { - eq = malloc(sizeof(equipment)); + eq = (equipment *)calloc(1, sizeof(equipment)); eq->name = strdup(eqname); eq->next = *eqp; - eq->items = NULL; - eq->spells = NULL; - eq->subsets = NULL; - eq->callback = NULL; memset(eq->skills, 0, sizeof(eq->skills)); *eqp = eq; break; @@ -85,10 +83,13 @@ void equipment_setskill(equipment * eq, skill_t sk, const char *value) } } -void equipment_addspell(equipment * eq, spell * sp) +void equipment_addspell(equipment * eq, spell * sp, int level) { - if (eq != NULL) { - ql_set_insert(&eq->spells, sp); + if (eq) { + if (!eq->spellbook) { + eq->spellbook = create_spellbook(0); + } + spellbook_add(eq->spellbook, sp, level); } } @@ -140,16 +141,18 @@ void equip_unit_mask(struct unit *u, const struct equipment *eq, int mask) } if (mask & EQUIP_SPELLS) { - quicklist *ql = eq->spells; - if (ql) { - int qi; + if (eq->spellbook) { sc_mage *m = get_mage(u); + quicklist * ql = eq->spellbook->spells; + int qi; - assert(m || !"trying to equip spells on a non-mage!"); + if (!m) { + m = create_mage(u, u->faction?u->faction->magiegebiet:M_GRAY); + } for (qi = 0; ql; ql_advance(&ql, &qi, 1)) { - spell *sp = (spell *) ql_get(ql, qi); - add_spell(&m->spells, sp); - add_spellname(m, sp); + spellbook_entry *sbe = (spellbook_entry *) ql_get(ql, qi); + add_spell(&m->spells, sbe->sp); + add_spellname(m, sbe->sp); } } } diff --git a/src/kernel/equipment.h b/src/kernel/equipment.h index eae6a23c9..c6fd146c6 100644 --- a/src/kernel/equipment.h +++ b/src/kernel/equipment.h @@ -43,7 +43,7 @@ extern "C" { char *name; struct itemdata *items; char *skills[MAXSKILLS]; - struct quicklist *spells; + struct spellbook *spellbook; struct subset *subsets; struct equipment *next; void (*callback) (const struct equipment *, struct unit *); @@ -56,7 +56,7 @@ extern "C" { const struct item_type *itype, const char *value); extern void equipment_setskill(struct equipment *eq, skill_t sk, const char *value); - extern void equipment_addspell(struct equipment *eq, struct spell *sp); + extern void equipment_addspell(struct equipment *eq, struct spell *sp, int level); extern void equipment_setcallback(struct equipment *eq, void (*callback) (const struct equipment *, struct unit *)); diff --git a/src/kernel/equipment_test.c b/src/kernel/equipment_test.c new file mode 100644 index 000000000..d376ee644 --- /dev/null +++ b/src/kernel/equipment_test.c @@ -0,0 +1,56 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +void test_equipment(CuTest * tc) +{ + equipment * eq; + unit * u; + const item_type * it_horses; + const char * names[] = {"horse", "horse_p"}; + spell *sp; + sc_mage * mage; + + test_cleanup(); + skill_enabled[SK_MAGIC] = 1; + it_horses = test_create_itemtype(names); + CuAssertPtrNotNull(tc, it_horses); + sp = create_spell("testspell", 0); + CuAssertPtrNotNull(tc, sp); + + CuAssertPtrEquals(tc, 0, get_equipment("herpderp")); + eq = create_equipment("herpderp"); + CuAssertPtrEquals(tc, eq, get_equipment("herpderp")); + + equipment_setitem(eq, it_horses, "1"); + equipment_setskill(eq, SK_MAGIC, "5"); + equipment_addspell(eq, sp, 1); + + u = test_create_unit(0, 0); + equip_unit_mask(u, eq, EQUIP_ALL); + CuAssertIntEquals(tc, 1, i_get(u->items, it_horses)); + CuAssertIntEquals(tc, 5, get_level(u, SK_MAGIC)); + + mage = get_mage(u); + CuAssertPtrNotNull(tc, mage); + CuAssertPtrNotNull(tc, mage->spells); + CuAssertTrue(tc, u_hasspell(mage, sp)); +} + +CuSuite *get_equipment_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_equipment); + return suite; +} diff --git a/src/kernel/unit.c b/src/kernel/unit.c index e7844bd38..d868627ea 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1103,22 +1103,13 @@ void set_number(unit * u, int count) assert(count >= 0); assert(count <= UNIT_MAXSIZE); -#ifndef NDEBUG - assert(u->faction || count == 0); -#endif - if (count == 0) { u->flags &= ~(UFL_HERO); } - if (u->faction) { - if (playerrace(u->race)) { - u->faction->num_people += count - u->number; - } - u->number = (unsigned short)count; - } else if (u->number > 0) { - assert - (!"why doesn't this unit have a faction? this will fuck up num_people"); + if (u->faction && playerrace(u->race)) { + u->faction->num_people += count - u->number; } + u->number = (unsigned short)count; } boolean learn_skill(unit * u, skill_t sk, double chance) @@ -1415,15 +1406,22 @@ void name_unit(unit * u) } } else { char name[32]; - static const char * prefix[MAXLOCALES]; - int i = locale_index(u->faction->locale); - if (!prefix[i]) { - prefix[i] = LOC(u->faction->locale, "unitdefault"); + const char * result; + const struct locale * lang = u->faction ? u->faction->locale : default_locale; + if (lang) { + static const char * prefix[MAXLOCALES]; + int i = locale_index(lang); if (!prefix[i]) { - prefix[i] = parameters[P_UNIT]; + prefix[i] = LOC(lang, "unitdefault"); + if (!prefix[i]) { + prefix[i] = parameters[P_UNIT]; + } } + result = prefix[i]; + } else { + result = parameters[P_UNIT]; } - snprintf(name, sizeof(name), "%s %s", prefix[i], itoa36(u->no)); + snprintf(name, sizeof(name), "%s %s", result, itoa36(u->no)); unit_setname(u, name); } } @@ -1436,17 +1434,19 @@ void name_unit(unit * u) unit *create_unit(region * r, faction * f, int number, const struct race *urace, int id, const char *dname, unit * creator) { - unit *u = calloc(1, sizeof(unit)); + unit *u = (unit *)calloc(1, sizeof(unit)); assert(urace); - assert(f->alive); - u_setfaction(u, f); + if (f) { + assert(f->alive); + u_setfaction(u, f); - if (f->locale) { - order *deford = default_order(f->locale); - if (deford) { - set_order(&u->thisorder, NULL); - addlist(&u->orders, deford); + if (f->locale) { + order *deford = default_order(f->locale); + if (deford) { + set_order(&u->thisorder, NULL); + addlist(&u->orders, deford); + } } } u_seteffstealth(u, -1); @@ -1473,8 +1473,6 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, } else { u->name = strdup(dname); } - if (count_unit(u)) - f->no_units++; if (creator) { attrib *a; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 008c6a4d1..232ed917d 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1314,7 +1314,8 @@ static void add_spells(equipment * eq, xmlNodeSetPtr nsetItems) if (!sp) { log_error("no spell '%s' in school '%s' for equipment-set '%s'\n", (const char *)propValue, magic_school[mtype], eq->name); } else { - equipment_addspell(eq, sp); + int level = xml_ivalue(node, "level", sp->level); + equipment_addspell(eq, sp, level); } xmlFree(propValue); } @@ -1438,7 +1439,7 @@ static int parse_equipment(xmlDocPtr doc) xmlXPathFreeObject(xpathResult); xpathResult = xmlXPathEvalExpression(BAD_CAST "spell", xpath); - assert(!eq->spells); + assert(!eq->spellbook); add_spells(eq, xpathResult->nodesetval); xmlXPathFreeObject(xpathResult); diff --git a/src/tests.c b/src/tests.c index a78268590..e2ef1df7c 100644 --- a/src/tests.c +++ b/src/tests.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ int RunAllTests(void) CuSuiteAddSuite(suite, get_umlaut_suite()); /* kernel */ CuSuiteAddSuite(suite, get_curse_suite()); + CuSuiteAddSuite(suite, get_equipment_suite()); CuSuiteAddSuite(suite, get_item_suite()); CuSuiteAddSuite(suite, get_magic_suite()); CuSuiteAddSuite(suite, get_move_suite()); @@ -101,7 +103,7 @@ struct faction *test_create_faction(const struct race *rc) struct unit *test_create_unit(struct faction *f, struct region *r) { - unit *u = create_unit(r, f, 1, f->race, 0, 0, 0); + unit *u = create_unit(r, f, 1, f?f->race:rc_find("human"), 0, 0, 0); return u; }