diff --git a/src/gamecode/laws.c b/src/gamecode/laws.c index 8b0875afc..d4e591fd2 100644 --- a/src/gamecode/laws.c +++ b/src/gamecode/laws.c @@ -2457,7 +2457,7 @@ static void reshow(unit * u, struct order *ord, const char *s, param_t p) } } /* try for a spell */ - sp = get_spellfromtoken(u, s, u->faction->locale); + 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) { @@ -2641,7 +2641,7 @@ static int combatspell_cmd(unit * u, struct order *ord) s = getstrtoken(); } - sp = get_spellfromtoken(u, s, u->faction->locale); + sp = unit_getspell(u, s, u->faction->locale); if (!sp) { cmistake(u, ord, 173, MSG_MAGIC); return 0; diff --git a/src/kernel/battle.c b/src/kernel/battle.c index d0d0f9a31..6c51ce01b 100644 --- a/src/kernel/battle.c +++ b/src/kernel/battle.c @@ -42,6 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "reports.h" #include "ship.h" #include "skill.h" +#include "spell.h" #include "terrain.h" #include "unit.h" diff --git a/src/kernel/magic.c b/src/kernel/magic.c index 17dbd1218..092c0abe8 100644 --- a/src/kernel/magic.c +++ b/src/kernel/magic.c @@ -74,8 +74,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -/* ------------------------------------------------------------- */ - const char *magic_school[MAXMAGIETYP] = { "gray", "illaun", @@ -547,13 +545,6 @@ void add_spellname(sc_mage * mage, const spell * sp) } } -void add_spell(struct quicklist **slistp, spell * sp) -{ - if (ql_set_insert(slistp, sp) != 0) { - log_error("add_spell: the list already contains the spell '%s'.\n", sp->sname); - } -} - int u_hasspell(const sc_mage *mage, const struct spell *sp) { return mage ? has_spell(mage->spells, sp) : 0; @@ -2586,16 +2577,16 @@ static castorder *cast_cmd(unit * u, order * ord) return 0; } - sp = get_spellfromtoken(u, s, u->faction->locale); + sp = unit_getspell(u, s, u->faction->locale); /* Vertraute können auch Zauber sprechen, die sie selbst nicht - * können. get_spellfromtoken findet aber nur jene Sprüche, die + * können. unit_getspell findet aber nur jene Sprüche, die * die Einheit beherrscht. */ if (!sp && is_familiar(u)) { caster = get_familiar_mage(u); if (caster) { familiar = u; - sp = get_spellfromtoken(caster, s, caster->faction->locale); + sp = unit_getspell(caster, s, caster->faction->locale); } else { /* somehow, this familiar has no mage! */ log_error("cast_cmd: familiar %s is without a mage?\n", unitname(u)); @@ -2913,6 +2904,43 @@ const char *curse_name(const curse_type * ctype, const struct locale *lang) return LOC(lang, mkname("spell", ctype->cname)); } +spell *unit_getspell(struct unit *u, const char *name, + const struct locale * lang) +{ + sc_mage * mage = get_mage(u); + if (mage) { + variant token; + struct spell_names * names = mage->spellnames; + for (;names;names=names->next) { + if (names->lang==lang) break; + } + if (!names) { + quicklist *ql = mage->spells; + int qi; + names = (spell_names *)calloc(1, sizeof(spell_names)); + names->next = mage->spellnames; + names->lang = lang; + names->tokens = 0; + for (qi = 0, ql = mage->spells; ql; ql_advance(&ql, &qi, 1)) { + spell *sp = (spell *) ql_get(ql, qi); + const char *n = spell_name(sp, lang); + if (!n) { + log_error("no translation in locae %s for spell $s\n", locale_name(lang), sp->sname); + } else { + token.v = sp; + addtoken(&names->tokens, n, token); + } + } + mage->spellnames = names; + } + + if (findtoken(names->tokens, name, &token) != E_TOK_NOMATCH) { + return (spell *) token.v; + } + } + return 0; +} + struct quicklist **get_spelllist(struct sc_mage *mage, struct faction *f) { if (mage) { diff --git a/src/kernel/magic.h b/src/kernel/magic.h index 5edefbd7d..73ef8018b 100644 --- a/src/kernel/magic.h +++ b/src/kernel/magic.h @@ -150,24 +150,6 @@ typedef struct sc_mage { int cost; } spell_component; - typedef int (*spell_f)(castorder * co); - typedef void(*fumble_f)(castorder * co); - - typedef struct spell { - unsigned int id; - char *sname; - char *syntax; - char *parameter; - int sptyp; - int rank; /* Reihenfolge der Zauber */ - struct spell_component *components; - spell_f cast; - fumble_f patzer; - - /* this is not so much the spell's data, but the school's studying data */ - int level; /* Stufe des Zaubers */ - } spell; - /* ------------------------------------------------------------- */ /* besondere Spruchtypen */ @@ -261,15 +243,14 @@ typedef struct sc_mage { int get_combatspelllevel(const struct unit *u, int nr); /* versucht, eine eingestellte maximale Kampfzauberstufe * zurückzugeben. 0 = Maximum, -1 u ist kein Magier. */ - const spell *get_combatspell(const struct unit *u, int nr); + const struct spell *get_combatspell(const struct unit *u, int nr); /* gibt den Kampfzauber nr [pre/kampf/post] oder NULL zurück */ - void set_combatspell(struct unit *u, spell * sp, struct order *ord, + void set_combatspell(struct unit *u, struct spell * sp, struct order *ord, int level); /* setzt Kampfzauber */ - void unset_combatspell(struct unit *u, spell * sp); + void unset_combatspell(struct unit *u, struct spell * sp); /* löscht Kampfzauber */ - void add_spell(struct quicklist **slistp, spell * sp); - void add_spellname(sc_mage * mage, const spell * sp); + void add_spellname(sc_mage * mage, const struct spell * sp); /* fügt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */ int u_hasspell(const sc_mage *mage, const struct spell *sp); /* prüft, ob der Spruch in der Spruchliste der Einheit steht. */ @@ -279,7 +260,7 @@ typedef struct sc_mage { * als das aktuelle Magietalent ist, in die Spruchliste der Einheit * ein */ boolean knowsspell(const struct region *r, const struct unit *u, - const spell * sp); + const struct spell * sp); /* prüft, ob die Einheit diesen Spruch gerade beherrscht, dh * mindestens die erforderliche Stufe hat. Hier können auch Abfragen * auf spezielle Antimagiezauber auf Regionen oder Einheiten eingefügt @@ -299,10 +280,10 @@ typedef struct sc_mage { /* verändert die maximalen Magiepunkte einer Einheit */ /* Zaubern */ - extern double spellpower(struct region *r, struct unit *u, const spell * sp, + extern double spellpower(struct region *r, struct unit *u, const struct spell * sp, int cast_level, struct order *ord); /* ermittelt die Stärke eines Spruchs */ - boolean fumble(struct region *r, struct unit *u, const spell * sp, + boolean fumble(struct region *r, struct unit *u, const struct spell * sp, int cast_level); /* true, wenn der Zauber misslingt, bei false gelingt der Zauber */ @@ -325,19 +306,19 @@ typedef struct sc_mage { int countspells(struct unit *u, int step); /* erhöht den Counter für Zaubersprüche um 'step' und gibt die neue * Anzahl der gezauberten Sprüche zurück. */ - int spellcost(struct unit *u, const spell * sp); + int spellcost(struct unit *u, const struct spell * sp); /* gibt die für diesen Spruch derzeit notwendigen Magiepunkte auf der * geringstmöglichen Stufe zurück, schon um den Faktor der bereits * zuvor gezauberten Sprüche erhöht */ - boolean cancast(struct unit *u, const spell * spruch, int eff_stufe, + boolean cancast(struct unit *u, const struct spell * spruch, int eff_stufe, int distance, struct order *ord); /* true, wenn Einheit alle Komponenten des Zaubers (incl. MP) für die * geringstmögliche Stufe hat und den Spruch beherrscht */ - void pay_spell(struct unit *u, const spell * sp, int eff_stufe, int distance); + void pay_spell(struct unit *u, const struct spell * sp, int eff_stufe, int distance); /* zieht die Komponenten des Zaubers aus dem Inventory der Einheit * ab. Die effektive Stufe des gezauberten Spruchs ist wichtig für * die korrekte Bestimmung der Magiepunktkosten */ - int eff_spelllevel(struct unit *u, const spell * sp, int cast_level, + int eff_spelllevel(struct unit *u, const struct spell * sp, int cast_level, int distance); /* ermittelt die effektive Stufe des Zaubers. Dabei ist cast_level * die gewünschte maximale Stufe (im Normalfall Stufe des Magiers, @@ -352,8 +333,10 @@ typedef struct sc_mage { int resist_bonus); /* gibt false zurück, wenn der Zauber gelingt, true, wenn das Ziel * widersteht */ + extern struct spell * unit_getspell(struct unit *u, const char *s, + const struct locale *lang); -/* Sprüche in der struct region */ + /* Sprüche in der struct region */ /* (sind in curse) */ extern struct unit *get_familiar(const struct unit *u); extern struct unit *get_familiar_mage(const struct unit *u); diff --git a/src/kernel/magic_test.c b/src/kernel/magic_test.c index 6e7be814a..716ce3a85 100644 --- a/src/kernel/magic_test.c +++ b/src/kernel/magic_test.c @@ -167,7 +167,7 @@ void test_pay_spell_failure(CuTest * tc) CuAssertIntEquals(tc, 2, get_resource(u, rt_find("horse"))); } -void test_get_spellfromtoken_unit(CuTest * tc) +void test_getspell_unit(CuTest * tc) { spell *sp; struct unit * u; @@ -188,13 +188,13 @@ void test_get_spellfromtoken_unit(CuTest * tc) sp = create_spell("testspell", 0); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); - CuAssertPtrEquals(tc, 0, get_spellfromtoken(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); unit_add_spell(u, 0, sp, 1); - CuAssertPtrNotNull(tc, get_spellfromtoken(u, "Herp-a-derp", lang)); + CuAssertPtrNotNull(tc, unit_getspell(u, "Herp-a-derp", lang)); } -void test_get_spellfromtoken_faction(CuTest * tc) +void test_getspell_faction(CuTest * tc) { spell *sp; struct unit * u; @@ -215,14 +215,14 @@ void test_get_spellfromtoken_faction(CuTest * tc) sp = create_spell("testspell", 0); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); - CuAssertPtrEquals(tc, 0, get_spellfromtoken(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); f->spellbook = create_spellbook(0); spellbook_add(f->spellbook, sp, 1); - CuAssertPtrEquals(tc, sp, get_spellfromtoken(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, sp, unit_getspell(u, "Herp-a-derp", lang)); } -void test_get_spellfromtoken_school(CuTest * tc) +void test_getspell_school(CuTest * tc) { spell *sp; struct unit * u; @@ -245,11 +245,11 @@ void test_get_spellfromtoken_school(CuTest * tc) sp = create_spell("testspell", 0); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); - CuAssertPtrEquals(tc, 0, get_spellfromtoken(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); book = get_spellbook(magic_school[f->magiegebiet]); spellbook_add(book, sp, 1); - CuAssertPtrEquals(tc, sp, get_spellfromtoken(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, sp, unit_getspell(u, "Herp-a-derp", lang)); } CuSuite *get_magic_suite(void) @@ -259,8 +259,8 @@ CuSuite *get_magic_suite(void) SUITE_ADD_TEST(suite, test_spellbooks); SUITE_ADD_TEST(suite, test_pay_spell); SUITE_ADD_TEST(suite, test_pay_spell_failure); - SUITE_ADD_TEST(suite, test_get_spellfromtoken_unit); - SUITE_ADD_TEST(suite, test_get_spellfromtoken_faction); - SUITE_ADD_TEST(suite, test_get_spellfromtoken_school); + SUITE_ADD_TEST(suite, test_getspell_unit); + SUITE_ADD_TEST(suite, test_getspell_faction); + SUITE_ADD_TEST(suite, test_getspell_school); return suite; } diff --git a/src/kernel/race.h b/src/kernel/race.h index c2cafa01f..c7c7c43fc 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -39,6 +39,9 @@ extern "C" { #define RACESPOILCHANCE 5 /* Chance auf rassentypische Beute */ + struct param; + struct spell; + typedef struct att { int type; union { @@ -49,8 +52,6 @@ extern "C" { int level; } att; - struct param; - extern int num_races; typedef struct race { @@ -75,7 +76,7 @@ extern "C" { int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */ int at_bonus; /* Verändert den Angriffsskill (default: 0) */ int df_bonus; /* Verändert den Verteidigungskill (default: 0) */ - const spell *precombatspell; + const struct spell *precombatspell; struct att attack[10]; char bonus[MAXSKILLS]; signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */ diff --git a/src/kernel/spell.c b/src/kernel/spell.c index 5af6793f4..eb59a4f68 100644 --- a/src/kernel/spell.c +++ b/src/kernel/spell.c @@ -20,10 +20,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "spell.h" -/* kernel includes */ -#include "magic.h" -#include "unit.h" - /* util includes */ #include #include @@ -45,6 +41,13 @@ void free_spells(void) { spells = 0; } +void add_spell(struct quicklist **slistp, spell * sp) +{ + if (ql_set_insert(slistp, sp) != 0) { + log_error("add_spell: the list already contains the spell '%s'.\n", sp->sname); + } +} + spell * create_spell(const char * name, unsigned int id) { spell * sp; @@ -101,46 +104,6 @@ spell *find_spell(const char *name) return sp; } -/* ------------------------------------------------------------- */ -/* Spruch identifizieren */ - -spell *get_spellfromtoken(struct unit *u, const char *name, - const struct locale * lang) -{ - sc_mage * mage = get_mage(u); - if (mage) { - variant token; - struct spell_names * names = mage->spellnames; - for (;names;names=names->next) { - if (names->lang==lang) break; - } - if (!names) { - quicklist *ql = mage->spells; - int qi; - names = (spell_names *)calloc(1, sizeof(spell_names)); - names->next = mage->spellnames; - names->lang = lang; - names->tokens = 0; - for (qi = 0, ql = mage->spells; ql; ql_advance(&ql, &qi, 1)) { - spell *sp = (spell *) ql_get(ql, qi); - const char *n = spell_name(sp, lang); - if (!n) { - log_error("no translation in locae %s for spell $s\n", locale_name(lang), sp->sname); - } else { - token.v = sp; - addtoken(&names->tokens, n, token); - } - } - mage->spellnames = names; - } - - if (findtoken(names->tokens, name, &token) != E_TOK_NOMATCH) { - return (spell *) token.v; - } - } - return 0; -} - spell *find_spellbyid(unsigned int id) { quicklist *ql; diff --git a/src/kernel/spell.h b/src/kernel/spell.h index 627a855d6..5a4df26e9 100644 --- a/src/kernel/spell.h +++ b/src/kernel/spell.h @@ -22,25 +22,39 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - /* Prototypen */ + struct castorder; + typedef int (*spell_f)(struct castorder * co); + typedef void(*fumble_f)(struct castorder * co); + + typedef struct spell { + unsigned int id; + char *sname; + char *syntax; + char *parameter; + int sptyp; + int rank; /* Reihenfolge der Zauber */ + struct spell_component *components; + spell_f cast; + fumble_f patzer; + + /* this is not so much the spell's data, but the school's studying data */ + int level; /* Stufe des Zaubers */ + } spell; int use_item_power(struct region *r, struct unit *u); int use_item_regeneration(struct region *r, struct unit *u); void showspells(struct region *r, struct unit *u); int sp_antimagiczone(struct castorder *co); - /* ------------------------------------------------------------- */ - - extern struct attrib_type at_unitdissolve; - extern struct attrib_type at_wdwpyramid; - extern struct spell * create_spell(const char * name, unsigned int id); extern struct spell * find_spell(const char *name); extern struct spell * find_spellbyid(unsigned int i); - extern struct spell * get_spellfromtoken(struct unit *u, const char *s, - const struct locale *lang); + extern void add_spell(struct quicklist **slistp, spell * sp); extern void free_spells(void); + /** globals **/ + extern struct attrib_type at_unitdissolve; + extern struct attrib_type at_wdwpyramid; extern struct quicklist * spells; #ifdef __cplusplus }