From 1771a81c529fdb43fbb190dbce707778e8e4355c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 8 Oct 2005 15:25:21 +0000 Subject: [PATCH] Neues Datenformat macht Schluss mit der Speicherung von spell-ids im Datenfile. --- src/common/gamecode/creport.c | 25 ++--- src/common/gamecode/laws.c | 6 +- src/common/kernel/eressea.h | 3 +- src/common/kernel/magic.c | 184 ++++++++++++++++++---------------- src/common/kernel/magic.h | 26 ++--- src/common/kernel/race.c | 57 +++++------ src/common/kernel/reports.c | 56 +++++------ src/common/kernel/save.c | 6 +- src/common/kernel/spell.c | 42 ++++++-- src/common/kernel/spell.h | 1 + src/eressea/Jamfile | 1 + src/eressea/lua/unit.cpp | 20 ++-- 12 files changed, 221 insertions(+), 206 deletions(-) diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 3af9624db..12176f33f 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -803,25 +803,22 @@ cr_output_unit(FILE * F, const region * r, /* spells */ if (is_mage(u)) { sc_mage * mage = get_mage(u); - spell_ptr *spt = mage->spellptr; - if (spt) { - spell *sp; + spell_list * slist = mage->spells; + if (slist) { int i; int t = effskill(u, SK_MAGIC); fprintf(F, "SPRUECHE\n"); - for (;spt; spt = spt->next) { - sp = find_spellbyid(spt->spellid); - if (sp) { - const char * name = sp->sname; - if (sp->level > t) continue; - if (sp->info==NULL) { - name = add_translation(mkname("spell", name), spell_name(sp, f->locale)); - } - fprintf(F, "\"%s\"\n", name); + for (;slist; slist = slist->next) { + spell * sp = slist->data; + const char * name = sp->sname; + if (sp->level > t) continue; + if (sp->info==NULL) { + name = add_translation(mkname("spell", name), spell_name(sp, f->locale)); } + fprintf(F, "\"%s\"\n", name); } for (i=0;i!=MAXCOMBATSPELLS;++i) { - sp = find_spellbyid(mage->combatspell[i]); + const spell * sp = mage->combatspells[i].sp; if (sp) { const char * name = sp->sname; if (sp->info==NULL) { @@ -829,7 +826,7 @@ cr_output_unit(FILE * F, const region * r, } fprintf(F, "KAMPFZAUBER %d\n", i); fprintf(F, "\"%s\";name\n", name); - fprintf(F, "%d;level\n", mage->combatspelllevel[i]); + fprintf(F, "%d;level\n", mage->combatspells[i].level); } } } diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index a1854927b..433e3c57f 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -2498,10 +2498,10 @@ reshow(unit * u, struct order * ord, const char * s, param_t p) } } /* try for a spell */ - sp = find_spellbyname(u, s, u->faction->locale); + sp = get_spellfromtoken(u, s, u->faction->locale); if (sp!=NULL && has_spell(u, sp)) { attrib *a = a_find(u->faction->attribs, &at_seenspell); - while (a!=NULL && a->data.i!=sp->id) a = a->nexttype; + while (a!=NULL && a->data.i!=(int)sp->id) a = a->nexttype; if (a!=NULL) a_remove(&u->faction->attribs, a); break; } @@ -2682,7 +2682,7 @@ combatspell_cmd(unit * u, struct order * ord) s = getstrtoken(); } - spell = find_spellbyname(u, s, u->faction->locale); + spell = get_spellfromtoken(u, s, u->faction->locale); if(!spell){ cmistake(u, ord, 173, MSG_MAGIC); diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 969460583..a5a01ef66 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -160,6 +160,7 @@ struct building_type; #define CLAIM_VERSION 318 #define BACTION_VERSION 319 /* building action gets a param string */ #define NOLASTORDER_VERSION 320 /* do not use lastorder */ +#define SPELLNAME_VERSION 321 /* reference spells by name */ #define MIN_VERSION CURSETYPE_VERSION #define REGIONOWNERS_VERSION 400 @@ -170,7 +171,7 @@ struct building_type; #elif defined(LASTORDER) # define RELEASE_VERSION BACTION_VERSION #else -# define RELEASE_VERSION NOLASTORDER_VERSION +# define RELEASE_VERSION SPELLNAME_VERSION #endif #if RESOURCE_CONVERSION diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 62f18a778..e1509f744 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -192,7 +192,7 @@ static void free_mage(attrib * a) { sc_mage * mage = (sc_mage*)a->data.v; - freelist(mage->spellptr); + freelist(mage->spells); free(mage); } @@ -201,27 +201,38 @@ read_mage(attrib * a, FILE * F) { int i, mtype; sc_mage * mage = (sc_mage*)a->data.v; + char spname[64]; fscanf(F, "%d %d %d", &mtype, &mage->spellpoints, &mage->spchange); mage->magietyp = (magic_t)mtype; for (i=0;i!=MAXCOMBATSPELLS;++i) { - int spid; - fscanf (F, "%d %d", &spid, &mage->combatspelllevel[i]); - if (spid<0) spid = SPL_NOSPELL; - mage->combatspell[i] = (spellid_t)spid; - } - for (;;) { - int i; - - fscanf (F, "%d", &i); - if (i < 0) break; - else { - spellid_t spid = (spellid_t)i; - - if (find_spellbyid(spid)==NULL) continue; - add_spell(mage, spid); + if (global.data_versioncombatspells[i].level); + if (spid>=0) mage->combatspells[i].sp = find_spellbyid((spellid_t)spid); + } else { + fscanf (F, "%s %d", spname, &mage->combatspells[i].level); + if (strcmp("none", spname)!=0) { + mage->combatspells[i].sp = find_spell(mage->magietyp, spname); + } } } + + for (;;) { + spell * sp; + + if (global.data_versionmagietyp, spname); + } + if (sp==NULL) continue; + add_spell(mage, sp); + } return AT_READ_OK; } @@ -229,16 +240,22 @@ static void write_mage(const attrib * a, FILE * F) { int i; sc_mage *mage = (sc_mage*)a->data.v; - spell_ptr *sp = mage->spellptr; + spell_list *slist = mage->spells; fprintf(F, "%d %d %d ", mage->magietyp, mage->spellpoints, mage->spchange); for (i=0;i!=MAXCOMBATSPELLS;++i) { - fprintf(F, "%d %d ", mage->combatspell[i], mage->combatspelllevel[i]); + fputs(mage->combatspells[i].sp?mage->combatspells[i].sp->sname:"none", F); + fprintf(F, " %d ", mage->combatspells[i].level); } - while (sp!=NULL) { - fprintf (F, "%d ", sp->spellid); - sp = sp->next; + while (slist!=NULL) { + spell * sp = slist->data; + fprintf (F, "%s ", sp->sname); + slist = slist->next; } +#if RELEASE_VERSION < SPELLNAME_VERSION fprintf (F, "-1 "); +#else + fputs("end ", F); +#endif } attrib_type at_mage = { @@ -301,7 +318,7 @@ createspelllist(unit *u, magic_t mtyp) spell * sp = slist->data; if (sp->magietyp == mtyp && sp->level <= sk) { if (!has_spell(u, sp)) { - add_spell(get_mage(u), sp->id); + add_spell(get_mage(u), sp); } } } @@ -314,7 +331,6 @@ create_mage(unit * u, magic_t mtyp) { sc_mage *mage; attrib *a; - int i; a = a_find(u->attribs, &at_mage); if (a==NULL) { @@ -323,16 +339,10 @@ create_mage(unit * u, magic_t mtyp) a->data.v = mage; } else { mage = a->data.v; + memset(&mage, 0, sizeof(sc_mage)); } mage->magietyp = mtyp; - mage->spellpoints = 0; - mage->spchange = 0; - mage->spellcount = 0; - for (i=0;icombatspell[i] = SPL_NOSPELL; - } - mage->spellptr = NULL; createspelllist(u, mtyp); return mage; } @@ -372,13 +382,13 @@ updatespelllist(unit * u) /* Nur Orkmagier bekommen den Keuschheitsamulettzauber */ sp = find_spellbyid(SPL_ARTEFAKT_CHASTITYBELT); if (u->race == new_race[RC_ORC] && !has_spell(u, sp) && sp->level<=sk) { - add_spell(mage, SPL_ARTEFAKT_CHASTITYBELT); + add_spell(mage, find_spellbyid(SPL_ARTEFAKT_CHASTITYBELT)); } /* Nur Wyrm-Magier bekommen den Wyrmtransformationszauber */ sp = find_spellbyid(SPL_BECOMEWYRM); if (fspecial(u->faction, FS_WYRM) && !has_spell(u, sp) && sp->level<=sk) { - add_spell(mage, SPL_BECOMEWYRM); + add_spell(mage, find_spellbyid(SPL_BECOMEWYRM)); } /* Transformierte Wyrm-Magier bekommen Drachenodem */ @@ -389,17 +399,17 @@ updatespelllist(unit * u) case RC_WYRM: sp = find_spellbyid(SPL_WYRMODEM); if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) { - add_spell(mage, sp->id); + add_spell(mage, sp); } case RC_DRAGON: sp = find_spellbyid(SPL_DRAGONODEM); if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) { - add_spell(mage, sp->id); + add_spell(mage, sp); } case RC_FIREDRAGON: sp = find_spellbyid(SPL_FIREDRAGONODEM); if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) { - add_spell(mage, sp->id); + add_spell(mage, sp); } break; } @@ -417,7 +427,7 @@ updatespelllist(unit * u) if (know || (gebiet!=M_GRAU && sp->magietyp == gebiet)) { faction * f = u->faction; - if (!know) add_spell(mage, sp->id); + if (!know) add_spell(mage, sp); if (!ismonster && !already_seen(u->faction, sp->id)) { a_add(&f->attribs, a_new(&at_reportspell))->data.i = sp->id; a_add(&f->attribs, a_new(&at_seenspell))->data.i = sp->id; @@ -431,38 +441,31 @@ updatespelllist(unit * u) /* Funktionen für die Bearbeitung der List-of-known-spells */ void -add_spell(sc_mage* m, spellid_t spellid) +add_spell(sc_mage* m, spell * sp) { if (m==NULL) { log_error(("add_spell: unit is not a mage.\n")); } else { - spell_ptr *newsp; - spell_ptr **spinsert = &m->spellptr; - while (*spinsert && (*spinsert)->spellidnext; - newsp = *spinsert; - if (newsp && newsp->spellid==spellid) { - log_error(("add_spell: unit already has spell %d.\n", spellid)); - return; + spell_list ** slist = spelllist_find(&m->spells, sp); + if (*slist) { + spell * psp = (*slist)->data; + if (psp==sp) { + log_error(("add_spell: unit already has spell '%s'.\n", sp->sname)); + return; + } } - newsp = calloc(1, sizeof(spell_ptr)); - newsp->spellid = spellid; - newsp->next = *spinsert; - *spinsert = newsp; + spelllist_add(slist, sp); } - return; } boolean has_spell(const unit *u, const spell * sp) { - spell_ptr *spt; sc_mage * m = get_mage(u); - - if (m==NULL) return false; - - spt = m->spellptr; - while (spt && spt->spellidid) spt = spt->next; - if (spt && spt->spellid==sp->id) return true; + if (m!=NULL) { + spell_list * sfind = *spelllist_find(&m->spells, sp); + return sfind!=NULL && sfind->data==sp; + } return false; } @@ -472,21 +475,20 @@ has_spell(const unit *u, const spell * sp) int get_combatspelllevel(const unit *u, int nr) { - sc_mage *m; + sc_mage *m = get_mage(u); assert(nr < MAXCOMBATSPELLS); - m = get_mage(u); - if (!m) { - return -1; + if (m) { + int level = eff_skill(u, SK_MAGIC, u->region); + return min(m->combatspells[nr].level, level); } - - return min(m->combatspelllevel[nr], eff_skill(u, SK_MAGIC, u->region)); + return -1; } /* ------------------------------------------------------------- */ /* Kampfzauber ermitteln, setzen oder löschen */ -spell* +const spell* get_combatspell(const unit *u, int nr) { sc_mage *m; @@ -494,8 +496,8 @@ get_combatspell(const unit *u, int nr) assert(nr < MAXCOMBATSPELLS); m = get_mage(u); if (m) { - return find_spellbyid(m->combatspell[nr]); - } else if(u->race->precombatspell != SPL_NOSPELL) { + return m->combatspells[nr].sp; + } else if (u->race->precombatspell != SPL_NOSPELL) { return find_spellbyid(u->race->precombatspell); } @@ -505,9 +507,8 @@ get_combatspell(const unit *u, int nr) void set_combatspell(unit *u, spell *sp, struct order * ord, int level) { - sc_mage *m; - - m = get_mage(u); + sc_mage *m = get_mage(u); + int i = -1; if (!m) return; /* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */ @@ -527,16 +528,12 @@ set_combatspell(unit *u, spell *sp, struct order * ord, int level) return; } - if (sp->sptyp & PRECOMBATSPELL) { - m->combatspell[0] = sp->id; - m->combatspelllevel[0] = level; - } else if (sp->sptyp & COMBATSPELL) { - m->combatspell[1] = sp->id; - m->combatspelllevel[1] = level; - } else if (sp->sptyp & POSTCOMBATSPELL) { - m->combatspell[2] = sp->id; - m->combatspelllevel[2] = level; - } + if (sp->sptyp & PRECOMBATSPELL) i = 0; + else if (sp->sptyp & COMBATSPELL) i = 1; + else if (sp->sptyp & POSTCOMBATSPELL) i = 2; + assert(i>=0); + m->combatspells[i].sp = sp; + m->combatspells[i].level = level; return; } @@ -553,7 +550,7 @@ unset_combatspell(unit *u, spell *sp) /* Kampfzauber löschen */ if (!sp) { for (i=0;icombatspell[i] = SPL_NOSPELL; + m->combatspells[i].sp = NULL; } } else if (sp->sptyp & PRECOMBATSPELL) { @@ -562,18 +559,16 @@ unset_combatspell(unit *u, spell *sp) } else if (sp->sptyp & COMBATSPELL) { if (sp != get_combatspell(u,1)) { return; - } else { - nr = 1; } + nr = 1; } else if (sp->sptyp & POSTCOMBATSPELL) { if (sp != get_combatspell(u,2)) { return; - } else { - nr = 2; } + nr = 2; } - m->combatspell[nr] = SPL_NOSPELL; - m->combatspelllevel[nr] = 0; + m->combatspells[nr].sp = NULL; + m->combatspells[nr].level = 0; return; } @@ -2490,15 +2485,15 @@ magic(void) cmistake(u, ord, 172, MSG_MAGIC); continue; } - sp = find_spellbyname(u, s, u->faction->locale); + sp = get_spellfromtoken(u, s, u->faction->locale); /* Vertraute können auch Zauber sprechen, die sie selbst nicht - * können. find_spellbyname findet aber nur jene Sprüche, die + * können. get_spellfromtoken findet aber nur jene Sprüche, die * die Einheit beherrscht. */ if (sp == NULL && is_familiar(u)) { familiar = u; mage = get_familiar_mage(u); - if (mage!=NULL) sp = find_spellbyname(mage, s, mage->faction->locale); + if (mage!=NULL) sp = get_spellfromtoken(mage, s, mage->faction->locale); } if (sp == NULL) { @@ -2769,10 +2764,21 @@ spell_name(const struct spell * sp, const struct locale * lang) } void -add_spelllist(spell_list ** lspells, spell * sp) +spelllist_add(spell_list ** lspells, spell * sp) { spell_list * entry = malloc(sizeof(spell_list)); entry->data = sp; entry->next = *lspells; *lspells = entry; } + +spell_list ** +spelllist_find(spell_list ** lspells, const spell * sp) +{ + while (*lspells) { + spell_list * slist = *lspells; + if (slist->data->id>=sp->id) break; + lspells = &slist->next; + } + return lspells; +} diff --git a/src/common/kernel/magic.h b/src/common/kernel/magic.h index def6c9a45..5cf3e6334 100644 --- a/src/common/kernel/magic.h +++ b/src/common/kernel/magic.h @@ -105,19 +105,18 @@ extern const char *magietypen[MAXMAGIETYP]; * - Spruchliste */ -typedef struct spell_ptr { - struct spell_ptr *next; - spellid_t spellid; -} spell_ptr; +typedef struct combatspell { + int level; + const struct spell * sp; +} combatspell; typedef struct sc_mage { magic_t magietyp; int spellpoints; int spchange; int spellcount; - spellid_t combatspell[MAXCOMBATSPELLS]; - int combatspelllevel[MAXCOMBATSPELLS]; - struct spell_ptr *spellptr; + combatspell combatspells[MAXCOMBATSPELLS]; + struct spell_list * spells; } sc_mage; /* ------------------------------------------------------------- */ @@ -166,7 +165,8 @@ typedef struct spell_list { spell * data; } spell_list; -extern void add_spelllist(spell_list ** lspells, spell * sp); +extern void spelllist_add(spell_list ** lspells, struct spell * sp); +extern spell_list ** spelllist_find(spell_list ** lspells, const struct spell * sp); /* ------------------------------------------------------------- */ /* besondere Spruchtypen */ @@ -262,22 +262,22 @@ boolean is_familiar(const struct unit *u); /* gibt true, wenn eine Familiar-Relation besteht. */ /* Sprüche */ -spell *find_spellbyname(struct unit *u, const char *s, const struct locale * lang); +spell *get_spellfromtoken(struct unit *u, const char *s, const struct locale * lang); /* versucht einen Spruch über den Namen zu identifizieren, gibt * ansonsten NULL zurück */ spell *find_spellbyid(spellid_t i); - /* versucht einen Spruch über seine Id zu identifizieren, gibt - * ansonsten NULL zurück */ +/* versucht einen Spruch über seine Id zu identifizieren, gibt +* ansonsten NULL zurück */ int get_combatspelllevel(const struct unit *u, int nr); /* versucht, eine eingestellte maximale Kampfzauberstufe * zurückzugeben. 0 = Maximum, -1 u ist kein Magier. */ -spell *get_combatspell(const struct unit *u, int nr); +const 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, int level); /* setzt Kampfzauber */ void unset_combatspell(struct unit *u, spell *sp); /* löscht Kampfzauber */ -void add_spell(struct sc_mage *mage, spellid_t spellid); +void add_spell(struct sc_mage *mage, spell *sp); /* fügt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */ boolean has_spell(const struct unit *u, const struct spell * sp); /* prüft, ob der Spruch in der Spruchliste der Einheit steht. */ diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 1564d9eb6..0758293d2 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -340,8 +340,6 @@ oldfamiliars(unit * familiar) /* Magie+1, Spionage, Tarnung, Wahrnehmung, Ausdauer */ m = create_mage(familiar, M_GRAU); set_level(familiar, SK_MAGIC, 1); - m->combatspell[0] = SPL_FLEE; - m->combatspell[1] = SPL_SLEEP; break; case RC_NYMPH: /* Alc, Arm, Bog+2, Han-2, Kräu+4, Mag+1, Pfer+5, Rei+5, @@ -357,7 +355,6 @@ oldfamiliars(unit * familiar) set_level(familiar, SK_ENTERTAINMENT, 1); set_level(familiar, SK_OBSERVATION, 1); m = create_mage(familiar, M_GRAU); - m->combatspell[0] = SPL_SONG_OF_CONFUSION; break; case RC_UNICORN: /* Mag+2, Spi, Tak, Tar+4, Wahr+4, Aus */ @@ -424,7 +421,7 @@ oldfamiliars(unit * familiar) if (m!=NULL) { spell_list * fspells = familiarspells(familiar->race); while (fspells!=NULL) { - add_spell(m, fspells->data->id); + add_spell(m, fspells->data); fspells=fspells->next; } } @@ -631,46 +628,46 @@ init_familiarspells(void) familiar_spells * fspells; fspells = mkspells(new_race[RC_PSEUDODRAGON]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_FLEE)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SLEEP)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_FLEE)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SLEEP)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); fspells = mkspells(new_race[RC_NYMPH]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SEDUCE)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); fspells = mkspells(new_race[RC_NYMPH]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SEDUCE)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); fspells = mkspells(new_race[RC_UNICORN]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_RESISTMAGICBONUS)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_PEACE)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_HERO)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_HEALINGSONG)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_RESISTMAGICBONUS)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SONG_OF_PEACE)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_HERO)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_HEALINGSONG)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); fspells = mkspells(new_race[RC_WRAITH]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_STEALAURA)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SUMMONUNDEAD)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_STEALAURA)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SUMMONUNDEAD)); fspells = mkspells(new_race[RC_IMP]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_STEALAURA)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_STEALAURA)); fspells = mkspells(new_race[RC_DREAMCAT]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_ILL_SHAPESHIFT)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_TRANSFERAURA_TRAUM)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_ILL_SHAPESHIFT)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_TRANSFERAURA_TRAUM)); fspells = mkspells(new_race[RC_FEY]); - add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); - add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + spelllist_add(&fspells->spells, find_spellbyid(SPL_SEDUCE)); } void diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 3a7fb0741..c18c74ce6 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -201,7 +201,6 @@ bufunit(const faction * f, const unit * u, int indent, int mode) skill_t sk; int getarnt = fval(u, UFL_PARTEITARNUNG); const char *pzTmp; - spell *sp; building * b; boolean isbattle = (boolean)(mode == see_battle); int telepath_see = fspecial(f, FS_TELEPATHY); @@ -507,16 +506,16 @@ bufunit(const faction * f, const unit * u, int indent, int mode) if (show!=u->items) while (show) i_free(i_remove(&show, show)); if (u->faction == f || telepath_see) { - dh = 0; + sc_mage * m = get_mage(u); - if (is_mage(u) == true) { - spell_ptr *spt; + if (m!=NULL) { + spell_list *slist = m->spells; int t = effskill(u, SK_MAGIC); bufp += snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region,u)); size = sizeof(buf)-(bufp-buf); - for (spt = get_mage(u)->spellptr;spt; spt = spt->next) { - sp = find_spellbyid(spt->spellid); + for (dh=0; slist; slist=slist->next) { + spell * sp = slist->data; if (sp->level > t) continue; if (!dh) { rsize = snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_spells")); @@ -533,18 +532,15 @@ bufunit(const faction * f, const unit * u, int indent, int mode) bufp += rsize; } - dh = 0; - for (i = 0; i < MAXCOMBATSPELLS; i++){ - sp = get_combatspell(u,i); - if (sp) { - dh = 1; - } + for (i=0; i!=MAXCOMBATSPELLS; ++i) { + if (get_combatspell(u, i)) break; } - if (dh) { - dh = 0; + if (i!=MAXCOMBATSPELLS) { bufp += snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_combatspells")); size = sizeof(buf)-(bufp-buf); + dh = 0; for (i = 0; i < MAXCOMBATSPELLS; i++){ + const spell *sp; if (!dh){ dh = 1; } else { @@ -982,32 +978,26 @@ spy_message(int spy, unit *u, unit *target) /* Zauberwirkungen */ } if (spy > 20){ + sc_mage * m = get_mage(target); /* bei Magiern Zaubersprüche und Magiegebiet */ - if (is_mage(target)){ - spell_ptr *spt; - spell *sp; - int first = 1; - int found = 0; + if (m) { + spell_list *slist = m->spells; + boolean first = true; scat("Magiegebiet: "); scat(LOC(u->faction->locale, magietypen[find_magetype(target)])); - if (get_mage(target)) { - scat(", Sprüche: "); + scat(", Sprüche: "); - for (spt = get_mage(target)->spellptr;spt; spt = spt->next){ - sp = find_spellbyid(spt->spellid); - found++; - if (first == 1){ - first = 0; - } else { - scat(", "); - } - scat(spell_name(sp, u->faction->locale)); - } - if (found == 0) { - scat("Keine"); + for (;slist; slist=slist->next) { + spell * sp = slist->data; + if (first) { + first = false; + } else { + scat(", "); } + scat(spell_name(sp, u->faction->locale)); } + if (first) scat("Keine"); scat(". "); } } diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index cf09be3a0..4764dd65c 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -1220,12 +1220,12 @@ readunit(FILE * F) mage->spellpoints = ri(F); mage->spchange = ri(F); while ((i = ri(F)) != -1) { - mage->combatspell[csp] = (spellid_t) i; - mage->combatspelllevel[csp] = ri(F); + mage->combatspells[csp].sp = find_spellbyid((spellid_t)i); + mage->combatspells[csp].level = ri(F); csp++; } while ((i = ri(F)) != -1) { - add_spell(mage, (spellid_t) i); + add_spell(mage, find_spellbyid((spellid_t)i)); } mage->spellcount = 0; a = a_add(&u->attribs, a_new(&at_mage)); diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index f05aac004..9600613b0 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -7152,7 +7152,7 @@ sp_becomewyrm(castorder *co) } u->race = new_race[RC_WYRM]; - add_spell(get_mage(u), SPL_WYRMODEM); + add_spell(get_mage(u), find_spellbyid(SPL_WYRMODEM)); ADDMSG(&u->faction->msgs, msg_message("becomewyrm", "u", u)); @@ -7501,6 +7501,25 @@ register_spell(spell * sp) spells = slist; } +/** versucht einen Spruch über gebiet + bame zu identifizieren. + * gibt ansonsten NULL zurück */ +spell * +find_spell(magic_t mtype, const char * name) +{ + spell_list * slist = spells; + spell * spx = NULL; + while (slist) { + spell * sp = slist->data; + if (strcmp(name, sp->sname)==0) { + if (sp->magietyp==mtype) return sp; + spx = sp; + } + slist = slist->next; + } + return spx; +} + + /* ------------------------------------------------------------- */ /* Spruch identifizieren */ @@ -7546,7 +7565,7 @@ get_spellnames(const struct locale * lang, magic_t mtype) } static spell * -find_spellbyname_i(const char *name, const struct locale * lang, magic_t mtype) +get_spellfromtoken_i(const char *name, const struct locale * lang, magic_t mtype) { variant token = { 0 }; spell_names * sn; @@ -7556,29 +7575,32 @@ find_spellbyname_i(const char *name, const struct locale * lang, magic_t mtype) magic_t mt; /* if we could not find it in the main magic type, we look through all the others */ for (mt=0;mt!=MAXMAGIETYP;++mt) { - sn = get_spellnames(lang, mt); - if (findtoken(&sn->names, name, &token)!=E_TOK_NOMATCH) break; + if (mt!=mtype) { + sn = get_spellnames(lang, mt); + if (findtoken(&sn->names, name, &token)!=E_TOK_NOMATCH) break; + } } } if (token.v!=NULL) return (spell*)token.v; if (lang==default_locale) return NULL; - return find_spellbyname_i(name, default_locale, mtype); + return get_spellfromtoken_i(name, default_locale, mtype); } spell * -find_spellbyname(unit *u, const char *name, const struct locale * lang) +get_spellfromtoken(unit *u, const char *name, const struct locale * lang) { sc_mage * m = get_mage(u); spell * sp; if (m==NULL) return NULL; - sp = find_spellbyname_i(name, lang, m->magietyp); + sp = get_spellfromtoken_i(name, lang, m->magietyp); if (sp!=NULL) { - spell_ptr *spt; + spell_list * slist = m->spells; - for (spt = m->spellptr; spt; spt = spt->next) { - if (sp->id==spt->spellid) return sp; + while (slist && slist->data->id<=sp->id) { + if (sp==slist->data) return sp; + slist = slist->next; } } return NULL; diff --git a/src/common/kernel/spell.h b/src/common/kernel/spell.h index 10acc731f..127dbe764 100644 --- a/src/common/kernel/spell.h +++ b/src/common/kernel/spell.h @@ -287,6 +287,7 @@ extern "C" { extern struct spell_list * spells; extern void init_spells(void); extern void register_spell(struct spell * sp); + struct spell * find_spell(magic_t mtype, const char * name); #ifdef __cplusplus } diff --git a/src/eressea/Jamfile b/src/eressea/Jamfile index f6ef0b74c..de162016e 100644 --- a/src/eressea/Jamfile +++ b/src/eressea/Jamfile @@ -19,6 +19,7 @@ LUASERVER_SOURCES = eressea.cpp event.cpp faction.cpp + message.cpp region.cpp script.cpp ship.cpp diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index c55e1c8e1..d08a5f5f0 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -40,16 +40,16 @@ using namespace luabind; class bind_spell_ptr { public: - static spell_ptr * next(spell_ptr * node) { return node->next; } - static spell * value(spell_ptr * node) { return find_spellbyid(node->spellid); } + static spell_list * next(spell_list * node) { return node->next; } + static spell * value(spell_list * node) { return node->data; } }; -static eressea::list +static eressea::list unit_spells(const unit& u) { sc_mage * mage = get_mage(&u); - if (mage==NULL) return eressea::list(NULL); - spell_ptr * splist = mage->spellptr; - return eressea::list(splist); + if (mage==NULL) return eressea::list(NULL); + spell_list * splist = mage->spells; + return eressea::list(splist); } class bind_spell_list { @@ -218,7 +218,7 @@ unit_addspell(unit& u, const char * name) if (strcmp(name, sp->sname)==0) { struct sc_mage * mage = get_mage(&u); if (add) log_error(("two spells are called %s.\n", name)); - add_spell(mage, sp->id); + add_spell(mage, sp); add = true; } slist=slist->next; @@ -237,12 +237,12 @@ unit_removespell(unit& u, const spell * sp) { sc_mage * mage = get_mage(&u); if (mage!=NULL) { - spell_ptr ** isptr = &mage->spellptr; - while (*isptr && (*isptr)->spellid != sp->id) { + spell_list ** isptr = &mage->spells; + while (*isptr && (*isptr)->data != sp) { isptr = &(*isptr)->next; } if (*isptr) { - spell_ptr * sptr = *isptr; + spell_list * sptr = *isptr; *isptr = sptr->next; free(sptr); }