From ffbe2579f376b80fa38fd8286dae949c8a60fbd1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 2 Nov 2024 18:12:40 +0100 Subject: [PATCH] in spellbooks, use stb arrays, not selist --- scripts/tests/study.lua | 4 +--- src/bind_unit.c | 36 +++++++++++++++++++------------- src/creport.c | 8 +++---- src/kernel/spellbook.c | 46 ++++++++++++++++------------------------- src/kernel/spellbook.h | 2 +- src/laws.c | 15 +++++++------- src/magic.c | 16 +++++++------- src/magic.test.c | 3 ++- src/reports.c | 8 +++---- 9 files changed, 66 insertions(+), 72 deletions(-) diff --git a/scripts/tests/study.lua b/scripts/tests/study.lua index 8f4e17e17..073b41860 100644 --- a/scripts/tests/study.lua +++ b/scripts/tests/study.lua @@ -67,9 +67,7 @@ function test_unit_spells() u:add_spell("toast") assert_equal(nil, u.spells) u:add_spell("fireball", 2) - local sp = u.spells() - assert_equal("fireball", sp.name) - assert_equal(2, sp.level) + assert_equal(2, u:get_spell("fireball")) end local function make_teacher(student, f, skill) diff --git a/src/bind_unit.c b/src/bind_unit.c index c91710033..6cf0bb78d 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -507,6 +507,27 @@ static int tolua_unit_castspell(lua_State * L) return 0; } +static int tolua_unit_getspell(lua_State *L) +{ + unit *u = (unit *)tolua_tousertype(L, 1, NULL); + const char *str = tolua_tostring(L, 2, NULL); + spellbook *sb; + spellbook_entry *sbe = NULL; + + sb = unit_get_spellbook(u); + if (sb) { + spell *sp = find_spell(str); + if (!sp) { + log_warning("spell %s could not be found\n", str); + } + else { + sbe = spellbook_get(sb, sp); + } + } + lua_pushinteger(L, sbe->level); + return 1; +} + static int tolua_unit_addspell(lua_State * L) { unit *u = (unit *)tolua_tousertype(L, 1, NULL); @@ -800,19 +821,6 @@ static int tolua_unit_get_items(lua_State * L) return 1; } -static int tolua_unit_get_spells(lua_State * L) -{ - unit *u = (unit *) tolua_tousertype(L, 1, NULL); - struct sc_mage *mage = u ? get_mage(u) : NULL; - spellbook *sb = mage_get_spellbook(mage); - selist *slist = NULL; - if (sb) { - selist **slist_ptr = &sb->spells; - slist = *slist_ptr; - } - return tolua_selist_push(L, "spellbook", "spell_entry", slist); -} - static int tolua_unit_get_curse(lua_State *L) { unit *u = (unit *)tolua_tousertype(L, 1, NULL); const char *name = tolua_tostring(L, 2, NULL); @@ -1118,7 +1126,7 @@ void tolua_unit_open(lua_State * L) tolua_variable(L, "race_name", tolua_unit_get_racename, tolua_unit_set_racename); tolua_function(L, "add_spell", tolua_unit_addspell); - tolua_variable(L, "spells", tolua_unit_get_spells, 0); + tolua_function(L, "get_spell", tolua_unit_getspell); tolua_function(L, "cast_spell", tolua_unit_castspell); tolua_function(L, "effect", bind_unit_effect); diff --git a/src/creport.c b/src/creport.c index 457547186..287daf82c 100644 --- a/src/creport.c +++ b/src/creport.c @@ -727,11 +727,11 @@ static void cr_output_spells(stream *out, const unit * u, int maxlevel) if (book) { const faction * f = u->faction; - selist *ql; - int qi, header = 0; + int header = 0; + ptrdiff_t qi, ql = arrlen(book->spells); - for (ql = book->spells, qi = 0; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi); + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)book->spells + qi; if (sbe->level <= maxlevel) { const spell *sp = spellref_get(&sbe->spref); const char * spname = mkname("spell", sp->sname); diff --git a/src/kernel/spellbook.c b/src/kernel/spellbook.c index 9127459a0..09d0100e6 100644 --- a/src/kernel/spellbook.c +++ b/src/kernel/spellbook.c @@ -5,7 +5,7 @@ #include "spellbook.h" -#include +#include #include #include @@ -18,7 +18,7 @@ spellbook * create_spellbook(const char * name) spellbook *result = (spellbook *)malloc(sizeof(spellbook)); if (!result) abort(); result->name = name ? str_strdup(name) : 0; - result->spells = 0; + result->spells = NULL; return result; } @@ -59,12 +59,11 @@ void read_spellbook(spellbook **bookp, gamedata *data, int(*get_level)(const spe void write_spellbook(const struct spellbook *book, struct storage *store) { - selist *ql; - int qi; - if (book) { - for (ql = book->spells, qi = 0; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi); + ptrdiff_t qi, ql = arrlen(book->spells); + + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)book->spells + qi; WRITE_TOK(store, spellref_name(&sbe->spref)); WRITE_INT(store, sbe->level); } @@ -76,11 +75,9 @@ void spellbook_addref(spellbook *sb, const char *name, int level) { spellbook_entry * sbe; assert(sb && name && level > 0); - sbe = (spellbook_entry *)malloc(sizeof(spellbook_entry)); - if (!sbe) abort(); + sbe = arraddnptr(sb->spells, 1); spellref_init(&sbe->spref, NULL, name); sbe->level = level; - selist_push(&sb->spells, sbe); } void spellbook_add(spellbook *sb, spell *sp, int level) @@ -93,35 +90,29 @@ void spellbook_add(spellbook *sb, spell *sp, int level) log_error("duplicate spell in spellbook '%s': '%s'\n", sb->name, sp->sname); } #endif - sbe = (spellbook_entry *)malloc(sizeof(spellbook_entry)); - if (!sbe) abort(); + sbe = arraddnptr(sb->spells, 1); spellref_init(&sbe->spref, sp, NULL); sbe->level = level; - selist_push(&sb->spells, sbe); } void spellbook_clear(spellbook *sb) { - selist *ql; - int qi; + ptrdiff_t qi, ql = arrlen(sb->spells); - assert(sb); - for (qi = 0, ql = sb->spells; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi); + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)sb->spells + qi; spellref_done(&sbe->spref); - free(sbe); } - selist_free(sb->spells); + arrfree(sb->spells); free(sb->name); } int spellbook_foreach(spellbook *sb, int(*callback)(spellbook_entry *, void *), void * data) { - selist *ql; - int qi; + ptrdiff_t qi, ql = arrlen(sb->spells); - for (qi = 0, ql = sb->spells; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi); + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)sb->spells + qi; int result = callback(sbe, data); if (result) { return result; @@ -133,11 +124,10 @@ int spellbook_foreach(spellbook *sb, int(*callback)(spellbook_entry *, void *), spellbook_entry * spellbook_get(spellbook *sb, const struct spell *sp) { if (sb) { - selist *ql; - int qi; + ptrdiff_t qi, ql = arrlen(sb->spells); - for (qi = 0, ql = sb->spells; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi); + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)sb->spells + qi; if (spellref_get(&sbe->spref) == sp) { return sbe; } diff --git a/src/kernel/spellbook.h b/src/kernel/spellbook.h index f1e8340f6..0be7b801b 100644 --- a/src/kernel/spellbook.h +++ b/src/kernel/spellbook.h @@ -19,7 +19,7 @@ extern "C" { typedef struct spellbook { char * name; - struct selist * spells; /* FIXME: selist only ever adds with push, could use stb array */ + struct spellbook_entry * spells; /* FIXME: selist only ever adds with push, could use stb array */ } spellbook; spellbook * create_spellbook(const char * name); diff --git a/src/laws.c b/src/laws.c index 18fcc8e52..12f06ec0b 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3137,10 +3137,10 @@ static void copy_spells(const spellbook * src, spellbook * dst, int maxlevel) { assert(dst); if (src && src->spells) { - selist *ql; - int qi; - for (qi = 0, ql = src->spells; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi); + ptrdiff_t qi, ql = arrlen(src->spells); + + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)src->spells + qi; if (sbe->level <= maxlevel) { spell *sp = spellref_get(&sbe->spref); if (!spellbook_get(dst, sp)) { @@ -3154,11 +3154,10 @@ static void copy_spells(const spellbook * src, spellbook * dst, int maxlevel) static void show_new_spells(faction * f, int level, const spellbook *book) { if (book) { - selist *ql = book->spells; - int qi; + ptrdiff_t qi, ql = arrlen(book->spells); - for (qi = 0; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi); + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)book->spells + qi; if (sbe->level <= level) { show_spell(f, sbe); } diff --git a/src/magic.c b/src/magic.c index 9f8295580..85a0dd484 100644 --- a/src/magic.c +++ b/src/magic.c @@ -425,15 +425,15 @@ struct spellbook * unit_get_spellbook(const struct unit * u) void pick_random_spells(faction * f, int level, spellbook * book, int num_spells) { spellbook_entry *commonspells[MAXSPELLS]; - int qi, numspells = 0; - selist *ql; + int numspells = 0; + ptrdiff_t qi, ql = arrlen(book->spells); if (level <= f->max_spelllevel) { return; } - for (qi = 0, ql = book->spells; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi); + for (qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)book->spells + qi; if (sbe && sbe->level <= level) { commonspells[numspells++] = sbe; } @@ -2878,14 +2878,12 @@ const char *curse_name(const curse_type * ctype, const struct locale *lang) } static void select_spellbook(void **tokens, spellbook *sb, const struct locale * lang) { - selist * ql; - int qi; + ptrdiff_t qi, ql; - assert(sb); assert(lang); - for (qi = 0, ql = sb->spells; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi); + for (ql = arrlen(sb->spells), qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)sb->spells + qi; const spell *sp = spellref_get(&sbe->spref); const char *spname = mkname("spell", sp->sname); const char *n = spell_name(spname, lang); diff --git a/src/magic.test.c b/src/magic.test.c index 23f926941..64fb2037a 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -32,6 +32,7 @@ #include #include +#include #include @@ -60,7 +61,7 @@ void test_updatespells(CuTest * tc) CuAssertPtrEquals(tc, NULL, f->spellbook); pick_random_spells(f, 1, book, 1); CuAssertPtrNotNull(tc, f->spellbook); - CuAssertIntEquals(tc, 1, selist_length(f->spellbook->spells)); + CuAssertIntEquals(tc, 1, (int) arrlen(f->spellbook->spells)); CuAssertPtrNotNull(tc, spellbook_get(f->spellbook, sp)); free_spellbook(book); test_teardown(); diff --git a/src/reports.c b/src/reports.c index 6b357e344..f5312f7ff 100644 --- a/src/reports.c +++ b/src/reports.c @@ -806,12 +806,12 @@ static void bufunit_spells(const unit* u, struct sbstring* sbp) spellbook* book = unit_get_spellbook(u); if (book) { - selist* ql = book->spells; - int i, qi, header, maxlevel = effskill(u, SK_MAGIC, NULL); + int i, header = 0, maxlevel = effskill(u, SK_MAGIC, NULL); + ptrdiff_t qi, ql; sbs_printf(sbp, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u, NULL)); - for (header = 0, qi = 0; ql; selist_advance(&ql, &qi, 1)) { - spellbook_entry* sbe = (spellbook_entry*)selist_get(ql, qi); + for (ql = arrlen(book->spells), qi = 0; qi != ql; ++qi) { + spellbook_entry *sbe = (spellbook_entry *)book->spells + qi; const spell* sp = spellref_get(&sbe->spref); if (sbe->level <= maxlevel) { if (!header) {