From c95342a88b6658792240d707c30885125fae4396 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Mar 2007 18:37:28 +0000 Subject: [PATCH] cleaning up in the magic code a little, and making the actual casting a separate function for easier debugging. --- src/common/gamecode/laws.c | 3 +- src/common/kernel/battle.c | 20 +- src/common/kernel/magic.c | 583 ++++++++++++++++++------------------- src/common/kernel/magic.h | 33 ++- 4 files changed, 318 insertions(+), 321 deletions(-) diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index a2b3a8254..0ff16d2c0 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -3847,7 +3847,8 @@ process(void) cmistake(u, ord, 52, MSG_PRODUCE); ord = NULL; } else if (fval(r->terrain, SEA_REGION) && u->race != new_race[RC_AQUARIAN] && !(u->race->flags & RCF_SWIM)) { - cmistake(u, ord, 242, MSG_INCOME); + /* error message disabled by popular demand */ + /* cmistake(u, ord, 242, MSG_INCOME); */ ord = NULL; } } diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index f899cee5c..c8cbfa2a8 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -1494,14 +1494,10 @@ do_combatmagic(battle *b, combatmagic_t was) side * s; region *r = b->region; castorder *co; - castorder *cll[MAX_SPELLRANK]; - int level; - int spellrank; - int sl; + int level, rank, sl; + spellrank spellranks[MAX_SPELLRANK]; - for (spellrank = 0; spellrank < MAX_SPELLRANK; spellrank++) { - cll[spellrank] = (castorder*)NULL; - } + memset(spellranks, 0, sizeof(spellranks)); for (s = b->sides; s; s = s->next) { fighter * fig; @@ -1561,13 +1557,13 @@ do_combatmagic(battle *b, combatmagic_t was) pay_spell(mage, sp, level, 1); } else { co = new_castorder(fig, 0, sp, r, level, power, 0, 0, 0); - add_castorder(&cll[(int)(sp->rank)], co); + add_castorder(&spellranks[sp->rank], co); } } } } - for (spellrank = 0; spellrank < MAX_SPELLRANK; spellrank++) { - for (co = cll[spellrank]; co; co = co->next) { + for (rank = 0; rank < MAX_SPELLRANK; rank++) { + for (co = spellranks[rank].begin; co; co = co->next) { fighter * fig = co->magician.fig; const spell * sp = co->sp; int level = co->level; @@ -1583,8 +1579,8 @@ do_combatmagic(battle *b, combatmagic_t was) } } } - for (spellrank = 0; spellrank < MAX_SPELLRANK; spellrank++) { - free_castorders(cll[spellrank]); + for (rank = 0; rank < MAX_SPELLRANK; rank++) { + free_castorders(spellranks[rank].begin); } } diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 860d93b79..39a85439f 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -728,22 +728,22 @@ change_maxspellpoints(unit * u, int csp) int countspells(unit *u, int step) { - sc_mage *m; - int count; + sc_mage *m; + int count; - m = get_mage(u); - if (!m) - return 0; + m = get_mage(u); + if (!m) + return 0; - if (step == 0) - return m->spellcount; + if (step == 0) + return m->spellcount; - count = m->spellcount + step; + count = m->spellcount + step; - /* negative Werte abfangen. */ - m->spellcount = max(0,count); + /* negative Werte abfangen. */ + m->spellcount = max(0,count); - return m->spellcount; + return m->spellcount; } /* ------------------------------------------------------------- */ @@ -2032,58 +2032,53 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, char ** param, castorder * new_castorder(void *u, unit *u2, const spell *sp, region *r, int lev, - double force, int range, struct order * ord, spellparameter *p) + double force, int range, struct order * ord, spellparameter *p) { - castorder *corder; + castorder *corder; - corder = calloc(1, sizeof(castorder)); - corder->magician.u = u; - corder->familiar = u2; - corder->sp = sp; - corder->level = lev; - corder->force = force; - corder->rt = r; - corder->distance = range; - corder->order = copy_order(ord); - corder->par = p; + corder = calloc(1, sizeof(castorder)); + corder->magician.u = u; + corder->familiar = u2; + corder->sp = sp; + corder->level = lev; + corder->force = force; + corder->rt = r; + corder->distance = range; + corder->order = copy_order(ord); + corder->par = p; - return corder; + return corder; } /* Hänge c-order co an die letze c-order von cll an */ void -add_castorder(castorder **cll, castorder *co) +add_castorder(spellrank *cll, castorder *co) { - castorder *co2; + if (cll->begin==NULL) { + cll->end = &cll->begin; + } + + *cll->end = co; + cll->end = &co->next; - /* Anfang der Liste? */ - if (*cll == NULL) { - *cll = co; - return; - } - - /* suche letztes element */ - for (co2 = *cll; co2->next != NULL; co2 = co2->next) { - } - co2->next = co; - return; + return; } void free_castorders(castorder *co) { - castorder *co2; + castorder *co2; - while(co) { - co2 = co; - co = co->next; - if (co2->par) { - free_spellparameter(co2->par); - } - if (co2->order) free_order(co2->order); - free(co2); - } - return; + while (co) { + co2 = co; + co = co->next; + if (co2->par) { + free_spellparameter(co2->par); + } + if (co2->order) free_order(co2->order); + free(co2); + } + return; } /* ------------------------------------------------------------- */ @@ -2092,8 +2087,8 @@ free_castorders(castorder *co) **/ typedef struct familiar_data { - unit * mage; - unit * familiar; + unit * mage; + unit * familiar; } famililar_data; boolean @@ -2106,27 +2101,27 @@ is_familiar(const unit *u) static void write_unit(const attrib * a, FILE * F) { - unit * u = (unit*)a->data.v; - write_unit_reference(u, F); + unit * u = (unit*)a->data.v; + write_unit_reference(u, F); } static int sm_familiar(const unit * u, const region * r, skill_t sk, int value) /* skillmod */ { - if (sk==SK_MAGIC) return value; - else { - int mod; - unit * familiar = get_familiar(u); - if (familiar==NULL) { - log_error(("[sm_familiar] %s has a familiar-skillmod, but no familiar\n", unitname(u))); - return value; - } - mod = eff_skill(familiar, sk, r)/2; - if (r != familiar->region) { - mod /= distance(r, familiar->region); - } - return value + mod; - } + if (sk==SK_MAGIC) return value; + else { + int mod; + unit * familiar = get_familiar(u); + if (familiar==NULL) { + log_error(("[sm_familiar] %s has a familiar-skillmod, but no familiar\n", unitname(u))); + return value; + } + mod = eff_skill(familiar, sk, r)/2; + if (r != familiar->region) { + mod /= distance(r, familiar->region); + } + return value + mod; + } } static void @@ -2438,6 +2433,212 @@ is_moving_ship(const region * r, const ship *sh) return false; } +static castorder * +cast_cmd(unit * u, order * ord) +{ + region * r = u->region; + region * target_r = r; + int level, range; + unit *familiar = NULL, *mage = u; + const char * s; + spell * sp; + spellparameter *args = NULL; + + if (LongHunger(u)) { + cmistake(u, ord, 224, MSG_MAGIC); + return 0; + } + if (r->planep && fval(r->planep, PFL_NOMAGIC)) { + cmistake(u, ord, 269, MSG_MAGIC); + return 0; + } + level = eff_skill(u, SK_MAGIC, r); + + init_tokens(ord); + skip_token(); + s = getstrtoken(); + /* für Syntax ' STUFE x REGION y z ' */ + if (findparam(s, u->faction->locale) == P_LEVEL) { + s = getstrtoken(); + level = min(atoip(s), level); + if (level < 1) { + /* Fehler "Das macht wenig Sinn" */ + cmistake(u, ord, 10, MSG_MAGIC); + return 0; + } + s = getstrtoken(); + } + if (findparam(s, u->faction->locale) == P_REGION) { + short t_x = (short)atoi(getstrtoken()); + short t_y = (short)atoi(getstrtoken()); + t_x = rel_to_abs(getplane(u->region),u->faction,t_x,0); + t_y = rel_to_abs(getplane(u->region),u->faction,t_y,1); + target_r = findregion(t_x, t_y); + if (!target_r) { + /* Fehler "Die Region konnte nicht verzaubert werden" */ + ADDMSG(&mage->faction->msgs, msg_message("spellregionresists", + "unit region command", mage, mage->region, ord)); + return 0; + } + s = getstrtoken(); + } + /* für Syntax ' REGION x y STUFE z ' + * hier nach REGION nochmal auf STUFE prüfen */ + if (findparam(s, u->faction->locale) == P_LEVEL) { + s = getstrtoken(); + level = min(atoip(s), level); + s = getstrtoken(); + if (level < 1) { + /* Fehler "Das macht wenig Sinn" */ + cmistake(u, ord, 10, MSG_MAGIC); + return 0; + } + } + if (!s[0] || strlen(s) == 0) { + /* Fehler "Es wurde kein Zauber angegeben" */ + cmistake(u, ord, 172, MSG_MAGIC); + return 0; + } + sp = get_spellfromtoken(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 + * die Einheit beherrscht. */ + if (sp == NULL && is_familiar(u)) { + familiar = u; + mage = get_familiar_mage(u); + if (mage!=NULL) sp = get_spellfromtoken(mage, s, mage->faction->locale); + } + + if (sp == NULL) { + /* Fehler 'Spell not found' */ + cmistake(u, ord, 173, MSG_MAGIC); + return 0; + } + /* um testen auf spruchnamen zu unterbinden sollte vor allen + * fehlermeldungen die anzeigen das der magier diesen Spruch + * nur in diese Situation nicht anwenden kann, noch eine + * einfache Sicherheitsprüfung kommen */ + if (!knowsspell(r, u, sp)) { + /* vorsicht! u kann der familiar sein */ + if (!familiar) { + cmistake(u, ord, 173, MSG_MAGIC); + return 0; + } + } + if (sp->sptyp & ISCOMBATSPELL) { + /* Fehler: "Dieser Zauber ist nur im Kampf sinnvoll" */ + cmistake(u, ord, 174, MSG_MAGIC); + return 0; + } + /* Auf dem Ozean Zaubern als quasi-langer Befehl können + * normalerweise nur Meermenschen, ausgenommen explizit als + * OCEANCASTABLE deklarierte Sprüche */ + if (fval(r->terrain, SEA_REGION)) { + if (u->race != new_race[RC_AQUARIAN] + && !fval(u->race, RCF_SWIM) + && !(sp->sptyp & OCEANCASTABLE)) { + /* Fehlermeldung */ + ADDMSG(&u->faction->msgs, msg_message("spellfail_onocean", + "unit region command", u, u->region, ord)); + return 0; + } + /* Auf bewegenden Schiffen kann man nur explizit als + * ONSHIPCAST deklarierte Zauber sprechen */ + } else if (u->ship) { + if (is_moving_ship(r, u->ship)) { + if (!(sp->sptyp & ONSHIPCAST)) { + /* Fehler: "Diesen Spruch kann man nicht auf einem sich + * bewegenden Schiff stehend zaubern" */ + cmistake(u, ord, 175, MSG_MAGIC); + return 0; + } + } + } + /* Farcasting bei nicht farcastbaren Sprüchen abfangen */ + range = farcasting(u, target_r); + if (range > 1) { + if (!(sp->sptyp & FARCASTING)) { + /* Fehler "Diesen Spruch kann man nicht in die Ferne + * richten" */ + cmistake(u, ord, 176, MSG_MAGIC); + return 0; + } + if (range > 1024) { /* (2^10) weiter als 10 Regionen entfernt */ + ADDMSG(&u->faction->msgs, msg_message("spellfail::nocontact", + "mage region command target", u, u->region, ord, + regionname(target_r, u->faction))); + return 0; + } + } + /* Stufenangabe bei nicht Stufenvariierbaren Sprüchen abfangen */ + if (!(sp->sptyp & SPELLLEVEL)) { + int ilevel = eff_skill(u, SK_MAGIC, u->region); + if (ilevel!=level) { + level = ilevel; + ADDMSG(&u->faction->msgs, msg_message("spellfail::nolevel", + "mage region command", u, u->region, ord)); + } + } + /* Vertrautenmagie */ + /* Kennt der Vertraute den Spruch, so zaubert er ganz normal. + * Ansonsten zaubert der Magier durch seinen Vertrauten, dh + * zahlt Komponenten und Aura. Dabei ist die maximale Stufe + * die des Vertrauten! + * Der Spruch wirkt dann auf die Region des Vertrauten und + * gilt nicht als Farcasting. */ + if (familiar || is_familiar(u)) { + if ((sp->sptyp & NOTFAMILIARCAST)) { + /* Fehler: "Diesen Spruch kann der Vertraute nicht zaubern" */ + cmistake(u, ord, 177, MSG_MAGIC); + return 0; + } + if (!knowsspell(r, u, sp)) { /* Magier zaubert durch Vertrauten */ + mage = get_familiar_mage(u); + if (range > 1) { /* Fehler! Versucht zu Farcasten */ + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_farcast", + "mage", mage)); + return 0; + } + if (distance(mage->region, r) > eff_skill(mage, SK_MAGIC, mage->region)) { + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_toofar", + "mage", mage)); + return 0; + } + /* mage auf magier setzen, level anpassen, range für Erhöhung + * der Spruchkosten nutzen, langen Befehl des Magiers + * löschen, zaubern kann er noch */ + range *= 2; + set_order(&mage->thisorder, NULL); + level = min(level, eff_skill(mage, SK_MAGIC, mage->region)/2); + familiar = u; + } + } + /* Weitere Argumente zusammenbasten */ + if (sp->parameter) { + char ** params = malloc(2*sizeof(char*)); + int p = 0, size = 2; + for (;;) { + s = getstrtoken(); + if (*s==0) break; + if (p+1>=size) { + size*=2; + params = realloc(params, sizeof(char*)*size); + } + params[p++] = strdup(s); + } + params[p] = 0; + args = add_spellparameter(target_r, mage, sp->parameter, params, p, ord); + for (p=0;params[p];++p) free(params[p]); + free(params); + if (args==NULL) { + /* Syntax war falsch */ + return 0; + } + } + return new_castorder(mage, familiar, sp, target_r, level, 0, range, ord, args); +} + /* ------------------------------------------------------------- */ /* Damit man keine Rituale in fremden Gebiet machen kann, diese vor * Bewegung zaubern. Magier sind also in einem fremden Gebiet eine Runde @@ -2460,27 +2661,15 @@ void magic(void) { region *r; - region *target_r; - unit *u; /* Aktuelle unit in Region */ - unit *familiar; /* wenn u ein Vertrauter ist */ - unit *mage; /* derjenige, der den Spruch am Ende zaubert */ - spell *sp; - const char *s; - int spellrank; - int range; - short t_x, t_y; + int rank; castorder *co; - castorder *cll[MAX_SPELLRANK]; - spellparameter *args; + spellrank spellranks[MAX_SPELLRANK]; - for (spellrank = 0; spellrank < MAX_SPELLRANK; spellrank++) { - cll[spellrank] = (castorder*)NULL; - } + memset(spellranks, 0, sizeof(spellranks)); for (r = regions; r; r = r->next) { + unit *u; for (u = r->units; u; u = u->next) { - int level; - boolean casted = false; order * ord; if (u->number<=0 || u->race == new_race[RC_SPELL]) @@ -2496,221 +2685,26 @@ magic(void) for (ord = u->orders; ord; ord = ord->next) { if (get_keyword(ord) == K_CAST) { - if (LongHunger(u)) { - cmistake(u, ord, 224, MSG_MAGIC); - continue; + castorder * co = cast_cmd(u, ord); + fset(u, UFL_LONGACTION|UFL_NOTMOVING); + if (co) { + const spell * sp = co->sp; + add_castorder(&spellranks[sp->rank], co); } - if (r->planep && fval(r->planep, PFL_NOMAGIC)) { - cmistake(u, ord, 269, MSG_MAGIC); - continue; - } - casted = true; - target_r = r; - mage = u; - level = eff_skill(u, SK_MAGIC, r); - familiar = NULL; - init_tokens(ord); - skip_token(); - s = getstrtoken(); - /* für Syntax ' STUFE x REGION y z ' */ - if (findparam(s, u->faction->locale) == P_LEVEL) { - s = getstrtoken(); - level = min(atoip(s), level); - if (level < 1) { - /* Fehler "Das macht wenig Sinn" */ - cmistake(u, ord, 10, MSG_MAGIC); - continue; - } - s = getstrtoken(); - } - if (findparam(s, u->faction->locale) == P_REGION) { - t_x = (short)atoi(getstrtoken()); - t_x = rel_to_abs(getplane(u->region),u->faction,t_x,0); - t_y = (short)atoi(getstrtoken()); - t_y = rel_to_abs(getplane(u->region),u->faction,t_y,1); - target_r = findregion(t_x, t_y); - if (!target_r) { - /* Fehler "Die Region konnte nicht verzaubert werden" */ - ADDMSG(&mage->faction->msgs, msg_message("spellregionresists", - "unit region command", mage, mage->region, ord)); - continue; - } - s = getstrtoken(); - } - /* für Syntax ' REGION x y STUFE z ' - * hier nach REGION nochmal auf STUFE prüfen */ - if (findparam(s, u->faction->locale) == P_LEVEL) { - s = getstrtoken(); - level = min(atoip(s), level); - s = getstrtoken(); - if (level < 1) { - /* Fehler "Das macht wenig Sinn" */ - cmistake(u, ord, 10, MSG_MAGIC); - continue; - } - } - if (!s[0] || strlen(s) == 0) { - /* Fehler "Es wurde kein Zauber angegeben" */ - cmistake(u, ord, 172, MSG_MAGIC); - continue; - } - sp = get_spellfromtoken(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 - * die Einheit beherrscht. */ - if (sp == NULL && is_familiar(u)) { - familiar = u; - mage = get_familiar_mage(u); - if (mage!=NULL) sp = get_spellfromtoken(mage, s, mage->faction->locale); - } - - if (sp == NULL) { - /* Fehler 'Spell not found' */ - cmistake(u, ord, 173, MSG_MAGIC); - continue; - } - /* um testen auf spruchnamen zu unterbinden sollte vor allen - * fehlermeldungen die anzeigen das der magier diesen Spruch - * nur in diese Situation nicht anwenden kann, noch eine - * einfache Sicherheitsprüfung kommen */ - if (!knowsspell(r, u, sp)) { - /* vorsicht! u kann der familiar sein */ - if (!familiar) { - cmistake(u, ord, 173, MSG_MAGIC); - continue; - } - } - if (sp->sptyp & ISCOMBATSPELL) { - /* Fehler: "Dieser Zauber ist nur im Kampf sinnvoll" */ - cmistake(u, ord, 174, MSG_MAGIC); - continue; - } - /* Auf dem Ozean Zaubern als quasi-langer Befehl können - * normalerweise nur Meermenschen, ausgenommen explizit als - * OCEANCASTABLE deklarierte Sprüche */ - if (fval(r->terrain, SEA_REGION)) { - if (u->race != new_race[RC_AQUARIAN] - && !fval(u->race, RCF_SWIM) - && !(sp->sptyp & OCEANCASTABLE)) { - /* Fehlermeldung */ - ADDMSG(&u->faction->msgs, msg_message("spellfail_onocean", - "unit region command", u, u->region, ord)); - continue; - } - /* Auf bewegenden Schiffen kann man nur explizit als - * ONSHIPCAST deklarierte Zauber sprechen */ - } else if (u->ship) { - if (is_moving_ship(r, u->ship)) { - if (!(sp->sptyp & ONSHIPCAST)) { - /* Fehler: "Diesen Spruch kann man nicht auf einem sich - * bewegenden Schiff stehend zaubern" */ - cmistake(u, ord, 175, MSG_MAGIC); - continue; - } - } - } - /* Farcasting bei nicht farcastbaren Sprüchen abfangen */ - range = farcasting(u, target_r); - if (range > 1) { - if (!(sp->sptyp & FARCASTING)) { - /* Fehler "Diesen Spruch kann man nicht in die Ferne - * richten" */ - cmistake(u, ord, 176, MSG_MAGIC); - continue; - } - if (range > 1024) { /* (2^10) weiter als 10 Regionen entfernt */ - ADDMSG(&u->faction->msgs, msg_message("spellfail::nocontact", - "mage region command target", u, u->region, ord, - regionname(target_r, u->faction))); - continue; - } - } - /* Stufenangabe bei nicht Stufenvariierbaren Sprüchen abfangen */ - if (!(sp->sptyp & SPELLLEVEL)) { - int ilevel = eff_skill(u, SK_MAGIC, u->region); - if (ilevel!=level) { - level = ilevel; - ADDMSG(&u->faction->msgs, msg_message("spellfail::nolevel", - "mage region command", u, u->region, ord)); - } - } - /* Vertrautenmagie */ - /* Kennt der Vertraute den Spruch, so zaubert er ganz normal. - * Ansonsten zaubert der Magier durch seinen Vertrauten, dh - * zahlt Komponenten und Aura. Dabei ist die maximale Stufe - * die des Vertrauten! - * Der Spruch wirkt dann auf die Region des Vertrauten und - * gilt nicht als Farcasting. */ - if (familiar || is_familiar(u)) { - if ((sp->sptyp & NOTFAMILIARCAST)) { - /* Fehler: "Diesen Spruch kann der Vertraute nicht zaubern" */ - cmistake(u, ord, 177, MSG_MAGIC); - continue; - } - if (!knowsspell(r, u, sp)) { /* Magier zaubert durch Vertrauten */ - mage = get_familiar_mage(u); - if (range > 1) { /* Fehler! Versucht zu Farcasten */ - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_farcast", - "mage", mage)); - continue; - } - if (distance(mage->region, r) > eff_skill(mage, SK_MAGIC, mage->region)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_toofar", - "mage", mage)); - continue; - } - /* mage auf magier setzen, level anpassen, range für Erhöhung - * der Spruchkosten nutzen, langen Befehl des Magiers - * löschen, zaubern kann er noch */ - range *= 2; - set_order(&mage->thisorder, NULL); - level = min(level, eff_skill(mage, SK_MAGIC, mage->region)/2); - familiar = u; - } - } - /* Weitere Argumente zusammenbasten */ - if (sp->parameter) { - char ** params = malloc(2*sizeof(char*)); - int p = 0, size = 2; - for (;;) { - s = getstrtoken(); - if (*s==0) break; - if (p+1>=size) { - size*=2; - params = realloc(params, sizeof(char*)*size); - } - params[p++] = strdup(s); - } - params[p] = 0; - args = add_spellparameter(target_r, mage, sp->parameter, params, p, ord); - for (p=0;params[p];++p) free(params[p]); - free(params); - if (args==NULL) { - /* Syntax war falsch */ - continue; - } - } else { - args = (spellparameter *) NULL; - } - co = new_castorder(mage, familiar, sp, target_r, level, 0, range, - ord, args); - add_castorder(&cll[(int)(sp->rank)], co); } } - if (casted) fset(u, UFL_LONGACTION|UFL_NOTMOVING); } } /* Da sich die Aura und Komponenten in der Zwischenzeit verändert - * haben können und sich durch vorherige Sprüche das Zaubern - * erschwert haben kann, muss beim zaubern erneut geprüft werden, ob der - * Spruch überhaupt gezaubert werden kann. - * (level) die effektive Stärke des Spruchs (= Stufe, auf der der - * Spruch gezaubert wird) */ + * haben können und sich durch vorherige Sprüche das Zaubern + * erschwert haben kann, muss beim zaubern erneut geprüft werden, ob der + * Spruch überhaupt gezaubert werden kann. + * (level) die effektive Stärke des Spruchs (= Stufe, auf der der + * Spruch gezaubert wird) */ - for (spellrank = 0; spellrank < MAX_SPELLRANK; spellrank++) { - for (co = cll[spellrank]; co; co = co->next) { + for (rank = 0; rank < MAX_SPELLRANK; rank++) { + for (co = spellranks[rank].begin; co; co = co->next) { order * ord = co->order; int verify, cast_level = co->level; boolean fumbled = false; @@ -2807,15 +2801,16 @@ magic(void) /* Sind alle Zauber gesprochen gibts Erfahrung */ for (r = regions; r; r = r->next) { + unit *u; for (u = r->units; u; u = u->next) { - if (is_mage(u) && countspells(u,0) > 0) { + if (is_mage(u) && countspells(u, 0) > 0) { produceexp(u, SK_MAGIC, u->number); /* Spruchlistenaktualiesierung ist in Regeneration */ } } } - for (spellrank = 0; spellrank < MAX_SPELLRANK; spellrank++) { - free_castorders(cll[spellrank]); + for (rank = 0; rank < MAX_SPELLRANK; rank++) { + free_castorders(spellranks[rank].begin); } remove_empty_units(); } @@ -2823,13 +2818,13 @@ magic(void) const char * spell_info(const spell * sp, const struct locale * lang) { - return LOC(lang, mkname("spellinfo", sp->sname)); + return LOC(lang, mkname("spellinfo", sp->sname)); } const char * spell_name(const spell * sp, const struct locale * lang) { - return LOC(lang, mkname("spell", sp->sname)); + return LOC(lang, mkname("spell", sp->sname)); } void diff --git a/src/common/kernel/magic.h b/src/common/kernel/magic.h index 412704ada..9b63ae6bf 100644 --- a/src/common/kernel/magic.h +++ b/src/common/kernel/magic.h @@ -155,17 +155,17 @@ typedef struct spell_component { } spell_component; typedef struct spell { - spellid_t id; - char *sname; - char *syntax; - char *parameter; - magic_t magietyp; - int sptyp; - char rank; /* Reihenfolge der Zauber */ - int level; /* Stufe des Zaubers */ - struct spell_component * components; - spell_f sp_function; - void (*patzer) (castorder*); + spellid_t id; + char *sname; + char *syntax; + char *parameter; + magic_t magietyp; + int sptyp; + int rank; /* Reihenfolge der Zauber */ + int level; /* Stufe des Zaubers */ + struct spell_component * components; + spell_f sp_function; + void (*patzer) (castorder*); } spell; typedef struct spell_list { @@ -315,13 +315,18 @@ extern double spellpower(struct region *r, struct unit *u, const spell *sp, int boolean fumble (struct region *r, struct unit *u, const spell *sp, int cast_level); /* true, wenn der Zauber misslingt, bei false gelingt der Zauber */ -/* */ + +typedef struct spellrank { + struct castorder * begin; + struct castorder ** end; +} spellrank; + castorder *new_castorder(void *u, struct unit *familiar, const spell *sp, struct region *r, int lev, double force, int distance, struct order * ord, spellparameter *p); /* Zwischenspreicher für Zauberbefehle, notwendig für Prioritäten */ -void add_castorder(castorder **cll, castorder *co); +void add_castorder(struct spellrank *cll, struct castorder *co); /* Hänge c-order co an die letze c-order von cll an */ -void free_castorders(castorder *co); +void free_castorders(struct castorder *co); /* Speicher wieder freigeben */ /* Prüfroutinen für Zaubern */