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;
}