diff --git a/scripts/tests/spells.lua b/scripts/tests/spells.lua index f790e58fd..0101c2518 100644 --- a/scripts/tests/spells.lua +++ b/scripts/tests/spells.lua @@ -14,8 +14,8 @@ function test_roi() u.race = "elf" u:set_skill("magic", 10) u:add_item("money", 3010) - f.magic = "tybied" - u.magic = "tybied" + f.magic = "gwyrrd" + u.magic = "gwyrrd" u.aura = 200 u.ship = s1 diff --git a/src/gamecode/laws.c b/src/gamecode/laws.c index 660fc1580..f4bc53952 100644 --- a/src/gamecode/laws.c +++ b/src/gamecode/laws.c @@ -3730,6 +3730,7 @@ static void copy_spells(const spellbook * src, spellbook * dst, int maxlevel) } } } + static void update_spells(void) { faction *f; @@ -3747,15 +3748,7 @@ static void update_spells(void) } copy_spells(book, f->spellbook, maxlevel); if (maxlevel > f->max_spelllevel) { - static spellbook * common_spells; - if (!common_spells) { - const char *common_school = get_param(global.parameters, "rules.magic.common"); - if (!common_school) common_school = "common"; - common_spells = get_spellbook(common_school); - if (!common_spells) { - log_error("could not find a book of common spells: '%s'\n", common_school); - } - } + spellbook * common_spells = get_spellbook(magic_school[M_COMMON]); pick_random_spells(f, maxlevel, common_spells, COMMONSPELLS); } } diff --git a/src/kernel/magic.c b/src/kernel/magic.c index 9559e2316..783ef5cad 100644 --- a/src/kernel/magic.c +++ b/src/kernel/magic.c @@ -245,6 +245,14 @@ void read_spells(struct quicklist **slistp, magic_t mtype, } } +int get_spell_level_mage(const spell * sp, void * cbdata) +{ + sc_mage *mage = (sc_mage *)cbdata; + spellbook *book = get_spellbook(magic_school[mage->magietyp]); + spellbook_entry *sbe = spellbook_get(book, sp); + return sbe ? sbe->level : 0; +} + static int read_mage(attrib * a, void *owner, struct storage *store) { int i, mtype; @@ -291,9 +299,9 @@ static int read_mage(attrib * a, void *owner, struct storage *store) } } if (mage->magietyp==M_GRAY) { - read_spellbook(&mage->spellbook, store); + read_spellbook(&mage->spellbook, store, get_spell_level_mage, mage); } else { - read_spellbook(0, store); + read_spellbook(0, store, 0, mage); } return AT_READ_OK; } @@ -420,15 +428,14 @@ void show_new_spells(faction * f, int level, const spellbook *book) for (qi = 0; ql; ql_advance(&ql, &qi, 1)) { spellbook_entry *sbe = (spellbook_entry *) ql_get(ql, qi); if (sbe->level <= level) { - spell * sp = sbe->sp; - if (!already_seen(f, sp)) { + if (!already_seen(f, sbe->sp)) { attrib * a = a_new(&at_reportspell); spellbook_entry * entry = (spellbook_entry *)a->data.v; - entry->level = level; - entry->sp = sp; + entry->level = sbe->level; + entry->sp = sbe->sp; a_add(&f->attribs, a); - a_add(&f->attribs, a_new(&at_seenspell))->data.v = sp; + a_add(&f->attribs, a_new(&at_seenspell))->data.v = sbe->sp; } } } diff --git a/src/kernel/save.c b/src/kernel/save.c index 7fe3572e8..4a7454a48 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1204,12 +1204,36 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state) return &sf->next; } -void read_spellbook(spellbook **bookp, struct storage *store) +int get_spell_level_faction(const spell * sp, void * cbdata) { - int level; - for (level=0;;++level) { + static spellbook * common = 0; + spellbook * book; + faction * f = (faction *)cbdata; + spellbook_entry * sbe; + + book = get_spellbook(magic_school[f->magiegebiet]); + if (book) { + sbe = spellbook_get(book, sp); + if (sbe) return sbe->level; + } + if (!common) { + common = get_spellbook(magic_school[M_COMMON]); + } + sbe = spellbook_get(common, sp); + if (sbe) { + return sbe->level; + } else { + log_error("read_spellbook: faction '%s' has a spell with unknown level: '%s'", factionname(f), sp->sname); + } + return 0; +} + +void read_spellbook(spellbook **bookp, struct storage *store, int (*get_level)(const spell * sp, void *), void * cbdata) +{ + for (;;) { spell *sp = 0; char spname[64]; + int level = 0; if (store->version < SPELLNAME_VERSION) { int i = store->r_int(store); @@ -1233,6 +1257,9 @@ void read_spellbook(spellbook **bookp, struct storage *store) level = store->r_int(store); } if (sp) { + if (level<=0 && get_level) { + level = get_level(sp, cbdata); + } if (!*bookp) { *bookp = create_spellbook(0); } @@ -1395,7 +1422,7 @@ faction *readfaction(struct storage * store) read_groups(store, f); f->spellbook = 0; if (store->version >= REGIONOWNER_VERSION) { - read_spellbook(FactionSpells() ? &f->spellbook : 0, store); + read_spellbook(FactionSpells() ? &f->spellbook : 0, store, get_spell_level_faction, (void *)f); } return f; } diff --git a/src/kernel/save.h b/src/kernel/save.h index 58c7d5356..cd1fd6533 100644 --- a/src/kernel/save.h +++ b/src/kernel/save.h @@ -47,7 +47,7 @@ extern "C" { extern void read_items(struct storage *store, struct item **it); extern void write_items(struct storage *store, struct item *it); - extern void read_spellbook(struct spellbook **bookp, struct storage *store); + extern void read_spellbook(struct spellbook **bookp, struct storage *store, int (*get_level)(const struct spell * sp, void *), void * cbdata); extern void write_spellbook(const struct spellbook *book, struct storage *store); extern void write_unit(struct storage *store, const struct unit *u); diff --git a/src/kernel/spellbook.c b/src/kernel/spellbook.c index 16e88b101..45d2f6d50 100644 --- a/src/kernel/spellbook.c +++ b/src/kernel/spellbook.c @@ -20,7 +20,7 @@ void spellbook_add(spellbook *sb, struct spell * sp, int level) { spellbook_entry * sbe = (spellbook_entry *)malloc(sizeof(spellbook_entry)); - assert(sb); + assert(sb && level>0); sbe->sp = sp; sbe->level = level; ql_push(&sb->spells, sbe);