Neues Datenformat macht Schluss mit der Speicherung von spell-ids im Datenfile.

This commit is contained in:
Enno Rehling 2005-10-08 15:25:21 +00:00
parent 128b5d0b9a
commit 1771a81c52
12 changed files with 221 additions and 206 deletions

View File

@ -803,25 +803,22 @@ cr_output_unit(FILE * F, const region * r,
/* spells */ /* spells */
if (is_mage(u)) { if (is_mage(u)) {
sc_mage * mage = get_mage(u); sc_mage * mage = get_mage(u);
spell_ptr *spt = mage->spellptr; spell_list * slist = mage->spells;
if (spt) { if (slist) {
spell *sp;
int i; int i;
int t = effskill(u, SK_MAGIC); int t = effskill(u, SK_MAGIC);
fprintf(F, "SPRUECHE\n"); fprintf(F, "SPRUECHE\n");
for (;spt; spt = spt->next) { for (;slist; slist = slist->next) {
sp = find_spellbyid(spt->spellid); spell * sp = slist->data;
if (sp) { const char * name = sp->sname;
const char * name = sp->sname; if (sp->level > t) continue;
if (sp->level > t) continue; if (sp->info==NULL) {
if (sp->info==NULL) { name = add_translation(mkname("spell", name), spell_name(sp, f->locale));
name = add_translation(mkname("spell", name), spell_name(sp, f->locale));
}
fprintf(F, "\"%s\"\n", name);
} }
fprintf(F, "\"%s\"\n", name);
} }
for (i=0;i!=MAXCOMBATSPELLS;++i) { for (i=0;i!=MAXCOMBATSPELLS;++i) {
sp = find_spellbyid(mage->combatspell[i]); const spell * sp = mage->combatspells[i].sp;
if (sp) { if (sp) {
const char * name = sp->sname; const char * name = sp->sname;
if (sp->info==NULL) { if (sp->info==NULL) {
@ -829,7 +826,7 @@ cr_output_unit(FILE * F, const region * r,
} }
fprintf(F, "KAMPFZAUBER %d\n", i); fprintf(F, "KAMPFZAUBER %d\n", i);
fprintf(F, "\"%s\";name\n", name); fprintf(F, "\"%s\";name\n", name);
fprintf(F, "%d;level\n", mage->combatspelllevel[i]); fprintf(F, "%d;level\n", mage->combatspells[i].level);
} }
} }
} }

View File

@ -2498,10 +2498,10 @@ reshow(unit * u, struct order * ord, const char * s, param_t p)
} }
} }
/* try for a spell */ /* 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)) { if (sp!=NULL && has_spell(u, sp)) {
attrib *a = a_find(u->faction->attribs, &at_seenspell); 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); if (a!=NULL) a_remove(&u->faction->attribs, a);
break; break;
} }
@ -2682,7 +2682,7 @@ combatspell_cmd(unit * u, struct order * ord)
s = getstrtoken(); s = getstrtoken();
} }
spell = find_spellbyname(u, s, u->faction->locale); spell = get_spellfromtoken(u, s, u->faction->locale);
if(!spell){ if(!spell){
cmistake(u, ord, 173, MSG_MAGIC); cmistake(u, ord, 173, MSG_MAGIC);

View File

@ -160,6 +160,7 @@ struct building_type;
#define CLAIM_VERSION 318 #define CLAIM_VERSION 318
#define BACTION_VERSION 319 /* building action gets a param string */ #define BACTION_VERSION 319 /* building action gets a param string */
#define NOLASTORDER_VERSION 320 /* do not use lastorder */ #define NOLASTORDER_VERSION 320 /* do not use lastorder */
#define SPELLNAME_VERSION 321 /* reference spells by name */
#define MIN_VERSION CURSETYPE_VERSION #define MIN_VERSION CURSETYPE_VERSION
#define REGIONOWNERS_VERSION 400 #define REGIONOWNERS_VERSION 400
@ -170,7 +171,7 @@ struct building_type;
#elif defined(LASTORDER) #elif defined(LASTORDER)
# define RELEASE_VERSION BACTION_VERSION # define RELEASE_VERSION BACTION_VERSION
#else #else
# define RELEASE_VERSION NOLASTORDER_VERSION # define RELEASE_VERSION SPELLNAME_VERSION
#endif #endif
#if RESOURCE_CONVERSION #if RESOURCE_CONVERSION

View File

@ -192,7 +192,7 @@ static void
free_mage(attrib * a) free_mage(attrib * a)
{ {
sc_mage * mage = (sc_mage*)a->data.v; sc_mage * mage = (sc_mage*)a->data.v;
freelist(mage->spellptr); freelist(mage->spells);
free(mage); free(mage);
} }
@ -201,27 +201,38 @@ read_mage(attrib * a, FILE * F)
{ {
int i, mtype; int i, mtype;
sc_mage * mage = (sc_mage*)a->data.v; sc_mage * mage = (sc_mage*)a->data.v;
char spname[64];
fscanf(F, "%d %d %d", &mtype, &mage->spellpoints, &mage->spchange); fscanf(F, "%d %d %d", &mtype, &mage->spellpoints, &mage->spchange);
mage->magietyp = (magic_t)mtype; mage->magietyp = (magic_t)mtype;
for (i=0;i!=MAXCOMBATSPELLS;++i) { for (i=0;i!=MAXCOMBATSPELLS;++i) {
int spid; if (global.data_version<SPELLNAME_VERSION) {
fscanf (F, "%d %d", &spid, &mage->combatspelllevel[i]); int spid;
if (spid<0) spid = SPL_NOSPELL; fscanf (F, "%d %d", &spid, &mage->combatspells[i].level);
mage->combatspell[i] = (spellid_t)spid; if (spid>=0) mage->combatspells[i].sp = find_spellbyid((spellid_t)spid);
} } else {
for (;;) { fscanf (F, "%s %d", spname, &mage->combatspells[i].level);
int i; if (strcmp("none", spname)!=0) {
mage->combatspells[i].sp = find_spell(mage->magietyp, spname);
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);
} }
} }
for (;;) {
spell * sp;
if (global.data_version<SPELLNAME_VERSION) {
fscanf (F, "%d", &i);
if (i < 0) break;
sp = find_spellbyid((spellid_t)i);
} else {
fscanf(F, "%s", spname);
if (strcmp(spname, "end")==0) break;
sp = find_spell(mage->magietyp, spname);
}
if (sp==NULL) continue;
add_spell(mage, sp);
}
return AT_READ_OK; return AT_READ_OK;
} }
@ -229,16 +240,22 @@ static void
write_mage(const attrib * a, FILE * F) { write_mage(const attrib * a, FILE * F) {
int i; int i;
sc_mage *mage = (sc_mage*)a->data.v; 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); fprintf(F, "%d %d %d ", mage->magietyp, mage->spellpoints, mage->spchange);
for (i=0;i!=MAXCOMBATSPELLS;++i) { 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) { while (slist!=NULL) {
fprintf (F, "%d ", sp->spellid); spell * sp = slist->data;
sp = sp->next; fprintf (F, "%s ", sp->sname);
slist = slist->next;
} }
#if RELEASE_VERSION < SPELLNAME_VERSION
fprintf (F, "-1 "); fprintf (F, "-1 ");
#else
fputs("end ", F);
#endif
} }
attrib_type at_mage = { attrib_type at_mage = {
@ -301,7 +318,7 @@ createspelllist(unit *u, magic_t mtyp)
spell * sp = slist->data; spell * sp = slist->data;
if (sp->magietyp == mtyp && sp->level <= sk) { if (sp->magietyp == mtyp && sp->level <= sk) {
if (!has_spell(u, sp)) { 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; sc_mage *mage;
attrib *a; attrib *a;
int i;
a = a_find(u->attribs, &at_mage); a = a_find(u->attribs, &at_mage);
if (a==NULL) { if (a==NULL) {
@ -323,16 +339,10 @@ create_mage(unit * u, magic_t mtyp)
a->data.v = mage; a->data.v = mage;
} else { } else {
mage = a->data.v; mage = a->data.v;
memset(&mage, 0, sizeof(sc_mage));
} }
mage->magietyp = mtyp; mage->magietyp = mtyp;
mage->spellpoints = 0;
mage->spchange = 0;
mage->spellcount = 0;
for (i=0;i<MAXCOMBATSPELLS;i++) {
mage->combatspell[i] = SPL_NOSPELL;
}
mage->spellptr = NULL;
createspelllist(u, mtyp); createspelllist(u, mtyp);
return mage; return mage;
} }
@ -372,13 +382,13 @@ updatespelllist(unit * u)
/* Nur Orkmagier bekommen den Keuschheitsamulettzauber */ /* Nur Orkmagier bekommen den Keuschheitsamulettzauber */
sp = find_spellbyid(SPL_ARTEFAKT_CHASTITYBELT); sp = find_spellbyid(SPL_ARTEFAKT_CHASTITYBELT);
if (u->race == new_race[RC_ORC] && !has_spell(u, sp) && sp->level<=sk) { 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 */ /* Nur Wyrm-Magier bekommen den Wyrmtransformationszauber */
sp = find_spellbyid(SPL_BECOMEWYRM); sp = find_spellbyid(SPL_BECOMEWYRM);
if (fspecial(u->faction, FS_WYRM) && !has_spell(u, sp) && sp->level<=sk) { 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 */ /* Transformierte Wyrm-Magier bekommen Drachenodem */
@ -389,17 +399,17 @@ updatespelllist(unit * u)
case RC_WYRM: case RC_WYRM:
sp = find_spellbyid(SPL_WYRMODEM); sp = find_spellbyid(SPL_WYRMODEM);
if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) { if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) {
add_spell(mage, sp->id); add_spell(mage, sp);
} }
case RC_DRAGON: case RC_DRAGON:
sp = find_spellbyid(SPL_DRAGONODEM); sp = find_spellbyid(SPL_DRAGONODEM);
if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) { if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) {
add_spell(mage, sp->id); add_spell(mage, sp);
} }
case RC_FIREDRAGON: case RC_FIREDRAGON:
sp = find_spellbyid(SPL_FIREDRAGONODEM); sp = find_spellbyid(SPL_FIREDRAGONODEM);
if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) { if (sp!=NULL && !has_spell(u, sp) && sp->level<=sk) {
add_spell(mage, sp->id); add_spell(mage, sp);
} }
break; break;
} }
@ -417,7 +427,7 @@ updatespelllist(unit * u)
if (know || (gebiet!=M_GRAU && sp->magietyp == gebiet)) { if (know || (gebiet!=M_GRAU && sp->magietyp == gebiet)) {
faction * f = u->faction; 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)) { 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_reportspell))->data.i = sp->id;
a_add(&f->attribs, a_new(&at_seenspell))->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 */ /* Funktionen für die Bearbeitung der List-of-known-spells */
void void
add_spell(sc_mage* m, spellid_t spellid) add_spell(sc_mage* m, spell * sp)
{ {
if (m==NULL) { if (m==NULL) {
log_error(("add_spell: unit is not a mage.\n")); log_error(("add_spell: unit is not a mage.\n"));
} else { } else {
spell_ptr *newsp; spell_list ** slist = spelllist_find(&m->spells, sp);
spell_ptr **spinsert = &m->spellptr; if (*slist) {
while (*spinsert && (*spinsert)->spellid<spellid) spinsert=&(*spinsert)->next; spell * psp = (*slist)->data;
newsp = *spinsert; if (psp==sp) {
if (newsp && newsp->spellid==spellid) { log_error(("add_spell: unit already has spell '%s'.\n", sp->sname));
log_error(("add_spell: unit already has spell %d.\n", spellid)); return;
return; }
} }
newsp = calloc(1, sizeof(spell_ptr)); spelllist_add(slist, sp);
newsp->spellid = spellid;
newsp->next = *spinsert;
*spinsert = newsp;
} }
return;
} }
boolean boolean
has_spell(const unit *u, const spell * sp) has_spell(const unit *u, const spell * sp)
{ {
spell_ptr *spt;
sc_mage * m = get_mage(u); sc_mage * m = get_mage(u);
if (m!=NULL) {
if (m==NULL) return false; spell_list * sfind = *spelllist_find(&m->spells, sp);
return sfind!=NULL && sfind->data==sp;
spt = m->spellptr; }
while (spt && spt->spellid<sp->id) spt = spt->next;
if (spt && spt->spellid==sp->id) return true;
return false; return false;
} }
@ -472,21 +475,20 @@ has_spell(const unit *u, const spell * sp)
int int
get_combatspelllevel(const unit *u, int nr) get_combatspelllevel(const unit *u, int nr)
{ {
sc_mage *m; sc_mage *m = get_mage(u);
assert(nr < MAXCOMBATSPELLS); assert(nr < MAXCOMBATSPELLS);
m = get_mage(u); if (m) {
if (!m) { int level = eff_skill(u, SK_MAGIC, u->region);
return -1; return min(m->combatspells[nr].level, level);
} }
return -1;
return min(m->combatspelllevel[nr], eff_skill(u, SK_MAGIC, u->region));
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* Kampfzauber ermitteln, setzen oder löschen */ /* Kampfzauber ermitteln, setzen oder löschen */
spell* const spell*
get_combatspell(const unit *u, int nr) get_combatspell(const unit *u, int nr)
{ {
sc_mage *m; sc_mage *m;
@ -494,8 +496,8 @@ get_combatspell(const unit *u, int nr)
assert(nr < MAXCOMBATSPELLS); assert(nr < MAXCOMBATSPELLS);
m = get_mage(u); m = get_mage(u);
if (m) { if (m) {
return find_spellbyid(m->combatspell[nr]); return m->combatspells[nr].sp;
} else if(u->race->precombatspell != SPL_NOSPELL) { } else if (u->race->precombatspell != SPL_NOSPELL) {
return find_spellbyid(u->race->precombatspell); return find_spellbyid(u->race->precombatspell);
} }
@ -505,9 +507,8 @@ get_combatspell(const unit *u, int nr)
void void
set_combatspell(unit *u, spell *sp, struct order * ord, int level) set_combatspell(unit *u, spell *sp, struct order * ord, int level)
{ {
sc_mage *m; sc_mage *m = get_mage(u);
int i = -1;
m = get_mage(u);
if (!m) return; if (!m) return;
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */ /* 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; return;
} }
if (sp->sptyp & PRECOMBATSPELL) { if (sp->sptyp & PRECOMBATSPELL) i = 0;
m->combatspell[0] = sp->id; else if (sp->sptyp & COMBATSPELL) i = 1;
m->combatspelllevel[0] = level; else if (sp->sptyp & POSTCOMBATSPELL) i = 2;
} else if (sp->sptyp & COMBATSPELL) { assert(i>=0);
m->combatspell[1] = sp->id; m->combatspells[i].sp = sp;
m->combatspelllevel[1] = level; m->combatspells[i].level = level;
} else if (sp->sptyp & POSTCOMBATSPELL) {
m->combatspell[2] = sp->id;
m->combatspelllevel[2] = level;
}
return; return;
} }
@ -553,7 +550,7 @@ unset_combatspell(unit *u, spell *sp)
/* Kampfzauber löschen */ /* Kampfzauber löschen */
if (!sp) { if (!sp) {
for (i=0;i<MAXCOMBATSPELLS;i++) { for (i=0;i<MAXCOMBATSPELLS;i++) {
m->combatspell[i] = SPL_NOSPELL; m->combatspells[i].sp = NULL;
} }
} }
else if (sp->sptyp & PRECOMBATSPELL) { else if (sp->sptyp & PRECOMBATSPELL) {
@ -562,18 +559,16 @@ unset_combatspell(unit *u, spell *sp)
} else if (sp->sptyp & COMBATSPELL) { } else if (sp->sptyp & COMBATSPELL) {
if (sp != get_combatspell(u,1)) { if (sp != get_combatspell(u,1)) {
return; return;
} else {
nr = 1;
} }
nr = 1;
} else if (sp->sptyp & POSTCOMBATSPELL) { } else if (sp->sptyp & POSTCOMBATSPELL) {
if (sp != get_combatspell(u,2)) { if (sp != get_combatspell(u,2)) {
return; return;
} else {
nr = 2;
} }
nr = 2;
} }
m->combatspell[nr] = SPL_NOSPELL; m->combatspells[nr].sp = NULL;
m->combatspelllevel[nr] = 0; m->combatspells[nr].level = 0;
return; return;
} }
@ -2490,15 +2485,15 @@ magic(void)
cmistake(u, ord, 172, MSG_MAGIC); cmistake(u, ord, 172, MSG_MAGIC);
continue; 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 /* 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. */ * die Einheit beherrscht. */
if (sp == NULL && is_familiar(u)) { if (sp == NULL && is_familiar(u)) {
familiar = u; familiar = u;
mage = get_familiar_mage(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) { if (sp == NULL) {
@ -2769,10 +2764,21 @@ spell_name(const struct spell * sp, const struct locale * lang)
} }
void void
add_spelllist(spell_list ** lspells, spell * sp) spelllist_add(spell_list ** lspells, spell * sp)
{ {
spell_list * entry = malloc(sizeof(spell_list)); spell_list * entry = malloc(sizeof(spell_list));
entry->data = sp; entry->data = sp;
entry->next = *lspells; entry->next = *lspells;
*lspells = entry; *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;
}

View File

@ -105,19 +105,18 @@ extern const char *magietypen[MAXMAGIETYP];
* - Spruchliste * - Spruchliste
*/ */
typedef struct spell_ptr { typedef struct combatspell {
struct spell_ptr *next; int level;
spellid_t spellid; const struct spell * sp;
} spell_ptr; } combatspell;
typedef struct sc_mage { typedef struct sc_mage {
magic_t magietyp; magic_t magietyp;
int spellpoints; int spellpoints;
int spchange; int spchange;
int spellcount; int spellcount;
spellid_t combatspell[MAXCOMBATSPELLS]; combatspell combatspells[MAXCOMBATSPELLS];
int combatspelllevel[MAXCOMBATSPELLS]; struct spell_list * spells;
struct spell_ptr *spellptr;
} sc_mage; } sc_mage;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -166,7 +165,8 @@ typedef struct spell_list {
spell * data; spell * data;
} spell_list; } 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 */ /* besondere Spruchtypen */
@ -262,22 +262,22 @@ boolean is_familiar(const struct unit *u);
/* gibt true, wenn eine Familiar-Relation besteht. */ /* gibt true, wenn eine Familiar-Relation besteht. */
/* Sprüche */ /* 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 /* versucht einen Spruch über den Namen zu identifizieren, gibt
* ansonsten NULL zurück */ * ansonsten NULL zurück */
spell *find_spellbyid(spellid_t i); spell *find_spellbyid(spellid_t i);
/* versucht einen Spruch über seine Id zu identifizieren, gibt /* versucht einen Spruch über seine Id zu identifizieren, gibt
* ansonsten NULL zurück */ * ansonsten NULL zurück */
int get_combatspelllevel(const struct unit *u, int nr); int get_combatspelllevel(const struct unit *u, int nr);
/* versucht, eine eingestellte maximale Kampfzauberstufe /* versucht, eine eingestellte maximale Kampfzauberstufe
* zurückzugeben. 0 = Maximum, -1 u ist kein Magier. */ * 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 */ /* gibt den Kampfzauber nr [pre/kampf/post] oder NULL zurück */
void set_combatspell(struct unit *u, spell *sp, struct order * ord, int level); void set_combatspell(struct unit *u, spell *sp, struct order * ord, int level);
/* setzt Kampfzauber */ /* setzt Kampfzauber */
void unset_combatspell(struct unit *u, spell *sp); void unset_combatspell(struct unit *u, spell *sp);
/* löscht Kampfzauber */ /* 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. */ /* fügt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */
boolean has_spell(const struct unit *u, const struct spell * sp); boolean has_spell(const struct unit *u, const struct spell * sp);
/* prüft, ob der Spruch in der Spruchliste der Einheit steht. */ /* prüft, ob der Spruch in der Spruchliste der Einheit steht. */

View File

@ -340,8 +340,6 @@ oldfamiliars(unit * familiar)
/* Magie+1, Spionage, Tarnung, Wahrnehmung, Ausdauer */ /* Magie+1, Spionage, Tarnung, Wahrnehmung, Ausdauer */
m = create_mage(familiar, M_GRAU); m = create_mage(familiar, M_GRAU);
set_level(familiar, SK_MAGIC, 1); set_level(familiar, SK_MAGIC, 1);
m->combatspell[0] = SPL_FLEE;
m->combatspell[1] = SPL_SLEEP;
break; break;
case RC_NYMPH: case RC_NYMPH:
/* Alc, Arm, Bog+2, Han-2, Kräu+4, Mag+1, Pfer+5, Rei+5, /* 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_ENTERTAINMENT, 1);
set_level(familiar, SK_OBSERVATION, 1); set_level(familiar, SK_OBSERVATION, 1);
m = create_mage(familiar, M_GRAU); m = create_mage(familiar, M_GRAU);
m->combatspell[0] = SPL_SONG_OF_CONFUSION;
break; break;
case RC_UNICORN: case RC_UNICORN:
/* Mag+2, Spi, Tak, Tar+4, Wahr+4, Aus */ /* Mag+2, Spi, Tak, Tar+4, Wahr+4, Aus */
@ -424,7 +421,7 @@ oldfamiliars(unit * familiar)
if (m!=NULL) { if (m!=NULL) {
spell_list * fspells = familiarspells(familiar->race); spell_list * fspells = familiarspells(familiar->race);
while (fspells!=NULL) { while (fspells!=NULL) {
add_spell(m, fspells->data->id); add_spell(m, fspells->data);
fspells=fspells->next; fspells=fspells->next;
} }
} }
@ -631,46 +628,46 @@ init_familiarspells(void)
familiar_spells * fspells; familiar_spells * fspells;
fspells = mkspells(new_race[RC_PSEUDODRAGON]); fspells = mkspells(new_race[RC_PSEUDODRAGON]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_FLEE)); spelllist_add(&fspells->spells, find_spellbyid(SPL_FLEE));
add_spelllist(&fspells->spells, find_spellbyid(SPL_SLEEP)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SLEEP));
add_spelllist(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); spelllist_add(&fspells->spells, find_spellbyid(SPL_FRIGHTEN));
fspells = mkspells(new_race[RC_NYMPH]); fspells = mkspells(new_race[RC_NYMPH]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SEDUCE));
add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER));
add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION));
add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK));
fspells = mkspells(new_race[RC_NYMPH]); fspells = mkspells(new_race[RC_NYMPH]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SEDUCE));
add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER));
add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION));
add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK));
fspells = mkspells(new_race[RC_UNICORN]); fspells = mkspells(new_race[RC_UNICORN]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_RESISTMAGICBONUS)); spelllist_add(&fspells->spells, find_spellbyid(SPL_RESISTMAGICBONUS));
add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_PEACE)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SONG_OF_PEACE));
add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER));
add_spelllist(&fspells->spells, find_spellbyid(SPL_HERO)); spelllist_add(&fspells->spells, find_spellbyid(SPL_HERO));
add_spelllist(&fspells->spells, find_spellbyid(SPL_HEALINGSONG)); spelllist_add(&fspells->spells, find_spellbyid(SPL_HEALINGSONG));
add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK));
fspells = mkspells(new_race[RC_WRAITH]); fspells = mkspells(new_race[RC_WRAITH]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_STEALAURA)); spelllist_add(&fspells->spells, find_spellbyid(SPL_STEALAURA));
add_spelllist(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); spelllist_add(&fspells->spells, find_spellbyid(SPL_FRIGHTEN));
add_spelllist(&fspells->spells, find_spellbyid(SPL_SUMMONUNDEAD)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SUMMONUNDEAD));
fspells = mkspells(new_race[RC_IMP]); 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]); fspells = mkspells(new_race[RC_DREAMCAT]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_ILL_SHAPESHIFT)); spelllist_add(&fspells->spells, find_spellbyid(SPL_ILL_SHAPESHIFT));
add_spelllist(&fspells->spells, find_spellbyid(SPL_TRANSFERAURA_TRAUM)); spelllist_add(&fspells->spells, find_spellbyid(SPL_TRANSFERAURA_TRAUM));
fspells = mkspells(new_race[RC_FEY]); fspells = mkspells(new_race[RC_FEY]);
add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); spelllist_add(&fspells->spells, find_spellbyid(SPL_DENYATTACK));
add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); spelllist_add(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER));
add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); spelllist_add(&fspells->spells, find_spellbyid(SPL_SEDUCE));
} }
void void

View File

@ -201,7 +201,6 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
skill_t sk; skill_t sk;
int getarnt = fval(u, UFL_PARTEITARNUNG); int getarnt = fval(u, UFL_PARTEITARNUNG);
const char *pzTmp; const char *pzTmp;
spell *sp;
building * b; building * b;
boolean isbattle = (boolean)(mode == see_battle); boolean isbattle = (boolean)(mode == see_battle);
int telepath_see = fspecial(f, FS_TELEPATHY); 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 (show!=u->items) while (show) i_free(i_remove(&show, show));
if (u->faction == f || telepath_see) { if (u->faction == f || telepath_see) {
dh = 0; sc_mage * m = get_mage(u);
if (is_mage(u) == true) { if (m!=NULL) {
spell_ptr *spt; spell_list *slist = m->spells;
int t = effskill(u, SK_MAGIC); int t = effskill(u, SK_MAGIC);
bufp += snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region,u)); bufp += snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region,u));
size = sizeof(buf)-(bufp-buf); size = sizeof(buf)-(bufp-buf);
for (spt = get_mage(u)->spellptr;spt; spt = spt->next) { for (dh=0; slist; slist=slist->next) {
sp = find_spellbyid(spt->spellid); spell * sp = slist->data;
if (sp->level > t) continue; if (sp->level > t) continue;
if (!dh) { if (!dh) {
rsize = snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_spells")); 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; bufp += rsize;
} }
dh = 0; for (i=0; i!=MAXCOMBATSPELLS; ++i) {
for (i = 0; i < MAXCOMBATSPELLS; i++){ if (get_combatspell(u, i)) break;
sp = get_combatspell(u,i);
if (sp) {
dh = 1;
}
} }
if (dh) { if (i!=MAXCOMBATSPELLS) {
dh = 0;
bufp += snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_combatspells")); bufp += snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_combatspells"));
size = sizeof(buf)-(bufp-buf); size = sizeof(buf)-(bufp-buf);
dh = 0;
for (i = 0; i < MAXCOMBATSPELLS; i++){ for (i = 0; i < MAXCOMBATSPELLS; i++){
const spell *sp;
if (!dh){ if (!dh){
dh = 1; dh = 1;
} else { } else {
@ -982,32 +978,26 @@ spy_message(int spy, unit *u, unit *target)
/* Zauberwirkungen */ /* Zauberwirkungen */
} }
if (spy > 20){ if (spy > 20){
sc_mage * m = get_mage(target);
/* bei Magiern Zaubersprüche und Magiegebiet */ /* bei Magiern Zaubersprüche und Magiegebiet */
if (is_mage(target)){ if (m) {
spell_ptr *spt; spell_list *slist = m->spells;
spell *sp; boolean first = true;
int first = 1;
int found = 0;
scat("Magiegebiet: "); scat("Magiegebiet: ");
scat(LOC(u->faction->locale, magietypen[find_magetype(target)])); 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){ for (;slist; slist=slist->next) {
sp = find_spellbyid(spt->spellid); spell * sp = slist->data;
found++; if (first) {
if (first == 1){ first = false;
first = 0; } else {
} else { scat(", ");
scat(", ");
}
scat(spell_name(sp, u->faction->locale));
}
if (found == 0) {
scat("Keine");
} }
scat(spell_name(sp, u->faction->locale));
} }
if (first) scat("Keine");
scat(". "); scat(". ");
} }
} }

View File

@ -1220,12 +1220,12 @@ readunit(FILE * F)
mage->spellpoints = ri(F); mage->spellpoints = ri(F);
mage->spchange = ri(F); mage->spchange = ri(F);
while ((i = ri(F)) != -1) { while ((i = ri(F)) != -1) {
mage->combatspell[csp] = (spellid_t) i; mage->combatspells[csp].sp = find_spellbyid((spellid_t)i);
mage->combatspelllevel[csp] = ri(F); mage->combatspells[csp].level = ri(F);
csp++; csp++;
} }
while ((i = ri(F)) != -1) { while ((i = ri(F)) != -1) {
add_spell(mage, (spellid_t) i); add_spell(mage, find_spellbyid((spellid_t)i));
} }
mage->spellcount = 0; mage->spellcount = 0;
a = a_add(&u->attribs, a_new(&at_mage)); a = a_add(&u->attribs, a_new(&at_mage));

View File

@ -7152,7 +7152,7 @@ sp_becomewyrm(castorder *co)
} }
u->race = new_race[RC_WYRM]; 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)); ADDMSG(&u->faction->msgs, msg_message("becomewyrm", "u", u));
@ -7501,6 +7501,25 @@ register_spell(spell * sp)
spells = slist; 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 */ /* Spruch identifizieren */
@ -7546,7 +7565,7 @@ get_spellnames(const struct locale * lang, magic_t mtype)
} }
static spell * 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 }; variant token = { 0 };
spell_names * sn; spell_names * sn;
@ -7556,29 +7575,32 @@ find_spellbyname_i(const char *name, const struct locale * lang, magic_t mtype)
magic_t mt; magic_t mt;
/* if we could not find it in the main magic type, we look through all the others */ /* if we could not find it in the main magic type, we look through all the others */
for (mt=0;mt!=MAXMAGIETYP;++mt) { for (mt=0;mt!=MAXMAGIETYP;++mt) {
sn = get_spellnames(lang, mt); if (mt!=mtype) {
if (findtoken(&sn->names, name, &token)!=E_TOK_NOMATCH) break; sn = get_spellnames(lang, mt);
if (findtoken(&sn->names, name, &token)!=E_TOK_NOMATCH) break;
}
} }
} }
if (token.v!=NULL) return (spell*)token.v; if (token.v!=NULL) return (spell*)token.v;
if (lang==default_locale) return NULL; if (lang==default_locale) return NULL;
return find_spellbyname_i(name, default_locale, mtype); return get_spellfromtoken_i(name, default_locale, mtype);
} }
spell * 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); sc_mage * m = get_mage(u);
spell * sp; spell * sp;
if (m==NULL) return NULL; if (m==NULL) return NULL;
sp = find_spellbyname_i(name, lang, m->magietyp); sp = get_spellfromtoken_i(name, lang, m->magietyp);
if (sp!=NULL) { if (sp!=NULL) {
spell_ptr *spt; spell_list * slist = m->spells;
for (spt = m->spellptr; spt; spt = spt->next) { while (slist && slist->data->id<=sp->id) {
if (sp->id==spt->spellid) return sp; if (sp==slist->data) return sp;
slist = slist->next;
} }
} }
return NULL; return NULL;

View File

@ -287,6 +287,7 @@ extern "C" {
extern struct spell_list * spells; extern struct spell_list * spells;
extern void init_spells(void); extern void init_spells(void);
extern void register_spell(struct spell * sp); extern void register_spell(struct spell * sp);
struct spell * find_spell(magic_t mtype, const char * name);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -19,6 +19,7 @@ LUASERVER_SOURCES =
<lua>eressea.cpp <lua>eressea.cpp
<lua>event.cpp <lua>event.cpp
<lua>faction.cpp <lua>faction.cpp
<lua>message.cpp
<lua>region.cpp <lua>region.cpp
<lua>script.cpp <lua>script.cpp
<lua>ship.cpp <lua>ship.cpp

View File

@ -40,16 +40,16 @@ using namespace luabind;
class bind_spell_ptr { class bind_spell_ptr {
public: public:
static spell_ptr * next(spell_ptr * node) { return node->next; } static spell_list * next(spell_list * node) { return node->next; }
static spell * value(spell_ptr * node) { return find_spellbyid(node->spellid); } static spell * value(spell_list * node) { return node->data; }
}; };
static eressea::list<spell *, spell_ptr *, bind_spell_ptr> static eressea::list<spell *, spell_list *, bind_spell_ptr>
unit_spells(const unit& u) { unit_spells(const unit& u) {
sc_mage * mage = get_mage(&u); sc_mage * mage = get_mage(&u);
if (mage==NULL) return eressea::list<spell *, spell_ptr *, bind_spell_ptr>(NULL); if (mage==NULL) return eressea::list<spell *, spell_list *, bind_spell_ptr>(NULL);
spell_ptr * splist = mage->spellptr; spell_list * splist = mage->spells;
return eressea::list<spell *, spell_ptr *, bind_spell_ptr>(splist); return eressea::list<spell *, spell_list *, bind_spell_ptr>(splist);
} }
class bind_spell_list { class bind_spell_list {
@ -218,7 +218,7 @@ unit_addspell(unit& u, const char * name)
if (strcmp(name, sp->sname)==0) { if (strcmp(name, sp->sname)==0) {
struct sc_mage * mage = get_mage(&u); struct sc_mage * mage = get_mage(&u);
if (add) log_error(("two spells are called %s.\n", name)); if (add) log_error(("two spells are called %s.\n", name));
add_spell(mage, sp->id); add_spell(mage, sp);
add = true; add = true;
} }
slist=slist->next; slist=slist->next;
@ -237,12 +237,12 @@ unit_removespell(unit& u, const spell * sp)
{ {
sc_mage * mage = get_mage(&u); sc_mage * mage = get_mage(&u);
if (mage!=NULL) { if (mage!=NULL) {
spell_ptr ** isptr = &mage->spellptr; spell_list ** isptr = &mage->spells;
while (*isptr && (*isptr)->spellid != sp->id) { while (*isptr && (*isptr)->data != sp) {
isptr = &(*isptr)->next; isptr = &(*isptr)->next;
} }
if (*isptr) { if (*isptr) {
spell_ptr * sptr = *isptr; spell_list * sptr = *isptr;
*isptr = sptr->next; *isptr = sptr->next;
free(sptr); free(sptr);
} }