diff --git a/scripts/tests/e2/movement.lua b/scripts/tests/e2/movement.lua index 57d2413c4..c8fc92327 100644 --- a/scripts/tests/e2/movement.lua +++ b/scripts/tests/e2/movement.lua @@ -96,7 +96,6 @@ function test_follow_ship() local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r1, 1) local u2 = unit.create(f, r1, 1) - u2.name = 'Xolgrim' u1:add_item("money", 100) u2:add_item("money", 100) u1.ship = ship.create(r1, "boat") diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 5d718247a..70d1bffb4 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -10,6 +10,7 @@ function setup() eressea.settings.set("rules.food.flags", "4") eressea.settings.set("rules.peasants.growth.factor", "0") eressea.settings.set("magic.fumble.enable", "0") + eressea.settings.set("magic.regeneration.enable", "0") end function test_shapeshift() @@ -104,6 +105,52 @@ function test_earn_silver() assert_equal(0, r:get_resource("money")) end +function test_familiar_cast() + local r = region.create(0, 0, "plain") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + local f = faction.create("human") + local u = unit.create(f, r) + u.magic = "gwyrrd" + u:set_skill("magic", 10) + u.aura = 200 + u:add_spell("earn_silver#gwyrrd") + u:add_order('ARBEITE') + local uf = unit.create(f, r) + uf.race = "lynx" + uf:set_skill("magic", 5) + uf:add_order('ZAUBER STUFE 1 Viehheilung') + u.familiar = uf + process_orders() + assert_equal(198, u.aura) -- Fremdzauber, Kosten verdoppelt + assert_equal(10, u:get_item('money')) -- von ARBEITE + assert_equal(50, uf:get_item('money')) -- von Zauber + assert_equal(300, uf.region:get_resource("money")) +end + +function test_familiar_mage_actions() + local r = region.create(0, 0, "plain") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + local f = faction.create("human") + local u = unit.create(f, r) + u.magic = "gwyrrd" + u:set_skill("magic", 10) + u.aura = 200 + u:add_spell("earn_silver#gwyrrd") + u:add_order('ZAUBER STUFE 1 Viehheilung') + local uf = unit.create(f, r) + uf.race = "lynx" + uf:set_skill("magic", 5) + uf:add_order('ZAUBER STUFE 1 Viehheilung') + u.familiar = uf + process_orders() + assert_equal(50, u:get_item('money')) + assert_equal(50, uf:get_item('money')) + assert_equal(250, uf.region:get_resource("money")) + assert_equal(197, u.aura) +end + function test_familiar() local r = region.create(0, 0, "mountain") local f = faction.create("human") @@ -148,3 +195,55 @@ function test_bug_2480() process_orders() assert_equal(0, u1.number); end + +function test_bug_2517() + local r = region.create(0, 0, "plain") + local f = faction.create("elf") + local um = unit.create(f, r, 1) + local uf = nil + eressea.settings.set("magic.familiar.race", "lynx") + f.magic = 'gwyrrd' + um.name = 'Xolgrim' + um.magic = 'gwyrrd' + um.race = 'elf' + um:set_skill('magic', 10) + um:add_spell('summon_familiar') + um:add_spell('earn_silver#gwyrrd') + um:add_order('ZAUBERE Vertrauten~rufen') + um.aura = 200 + process_orders() + uf = um.familiar + assert_not_nil(uf) + assert_equal('lynx', uf.race) + assert_nil(uf.magic) + uf:add_order('LERNE Magie') + um:clear_orders() + um:add_order('ARBEITEN') + process_orders() + assert_nil(uf.magic) + uf:add_order('ZAUBERE STUFE 1 Viehheilung') + process_orders() + assert_equal(50, uf:get_item('money')) +end + +function test_familiar_school() + local r = region.create(0, 0, "plain") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + local f = faction.create("human") + local u = unit.create(f, r) + u.magic = "draig" + u:set_skill("magic", 10) + u.aura = 200 + u:add_spell("fireball") + local uf = unit.create(f, r) + uf.race = "lynx" + u.familiar = uf + + assert_nil(uf.magic) + uf:set_skill("magic", 5) + assert_nil(uf.magic) + uf.aura = 10 + assert_equal(0, uf.aura) + assert_nil(uf.magic) +end diff --git a/src/alchemy.c b/src/alchemy.c index c84374e28..1673d5196 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -67,6 +67,7 @@ void new_potiontype(item_type * itype, int level) potion_type *ptype; ptype = (potion_type *)calloc(1, sizeof(potion_type)); + assert(ptype); itype->flags |= ITF_POTION; ptype->itype = itype; ptype->level = level; diff --git a/src/battle.c b/src/battle.c index 326e05e20..00cece5b0 100644 --- a/src/battle.c +++ b/src/battle.c @@ -134,6 +134,7 @@ static int rule_cavalry_skill; static int rule_population_damage; static int rule_hero_speed; static bool rule_anon_battle; +static bool rule_igjarjuk_curse; static int rule_goblin_bonus; static int rule_tactics_formula; static int rule_nat_armor; @@ -156,6 +157,7 @@ static void init_rules(void) rule_hero_speed = config_get_int("rules.combat.herospeed", 10); rule_population_damage = config_get_int("rules.combat.populationdamage", 20); rule_anon_battle = config_get_int("rules.stealth.anon_battle", 1) != 0; + rule_igjarjuk_curse = config_get_int("rules.combat.igjarjuk_curse", 0) != 0; rule_cavalry_mode = config_get_int("rules.cavalry.mode", 1); rule_cavalry_skill = config_get_int("rules.cavalry.skill", 2); rule_vampire = config_get_int("rules.combat.demon_vampire", 0); @@ -486,7 +488,7 @@ contest_classic(int skilldiff, const armor_type * ar, const armor_type * sh) mod *= (1 + ar->penalty); if (sh != NULL) mod *= (1 + sh->penalty); - vw = (int)(100 - ((100 - vw) * mod)); + vw = (int)(100.0 - ((100.0 - (double)vw) * mod)); do { p = (int)(rng_int() % 100); @@ -1224,7 +1226,7 @@ static void calculate_attack_type(troop dt, troop at, int type, bool missile, static int crit_damage(int attskill, int defskill, const char *damage_formula) { int damage = 0; if (rule_damage & DAMAGE_CRITICAL) { - double kritchance = (attskill * 3 - defskill) / 200.0; + double kritchance = ((double)attskill * 3.0 - (double)defskill) / 200.0; int maxk = 4; kritchance = fmax(kritchance, 0.005); @@ -1748,13 +1750,14 @@ void do_combatmagic(battle * b, combatmagic_t was) memset(spellranks, 0, sizeof(spellranks)); - if (was == DO_PRECOMBATSPELL) { + if (rule_igjarjuk_curse && was == DO_PRECOMBATSPELL) { summon_igjarjuk(b, spellranks); } for (s = b->sides; s != b->sides + b->nsides; ++s) { fighter *fig; for (fig = s->fighters; fig; fig = fig->next) { unit *mage = fig->unit; + unit *caster = mage; if (fig->alive <= 0) continue; /* fighter kann im Kampf get�tet worden sein */ @@ -1788,7 +1791,7 @@ void do_combatmagic(battle * b, combatmagic_t was) continue; } - level = eff_spelllevel(mage, sp, level, 1); + level = eff_spelllevel(mage, caster, sp, level, 1); if (sl > 0 && sl < level) { level = sl; } @@ -1802,11 +1805,11 @@ void do_combatmagic(battle * b, combatmagic_t was) free_order(ord); if (power <= 0) { /* Effekt von Antimagie */ report_failed_spell(b, mage, sp); - pay_spell(mage, sp, level, 1); + pay_spell(mage, NULL, sp, level, 1); } else if (fumble(r, mage, sp, level)) { report_failed_spell(b, mage, sp); - pay_spell(mage, sp, level, 1); + pay_spell(mage, NULL, sp, level, 1); } else { co = create_castorder_combat(0, fig, sp, level, power); @@ -1822,7 +1825,7 @@ void do_combatmagic(battle * b, combatmagic_t was) level = cast_spell(co); if (level > 0) { - pay_spell(fig->unit, sp, level, 1); + pay_spell(fig->unit, NULL, sp, level, 1); } } } @@ -1839,7 +1842,7 @@ static int cast_combatspell(troop at, const spell * sp, int level, double force) level = cast_spell(&co); free_castorder(&co); if (level > 0) { - pay_spell(at.fighter->unit, sp, level, 1); + pay_spell(at.fighter->unit, NULL, sp, level, 1); } return level; } @@ -1848,7 +1851,7 @@ static void do_combatspell(troop at) { const spell *sp; fighter *fi = at.fighter; - unit *caster = fi->unit; + unit *mage = fi->unit; battle *b = fi->side->battle; region *r = b->region; selist *ql; @@ -1857,28 +1860,28 @@ static void do_combatspell(troop at) int fumblechance = 0; order *ord; int sl; - const struct locale *lang = caster->faction->locale; + const struct locale *lang = mage->faction->locale; - sp = get_combatspell(caster, 1); + sp = get_combatspell(mage, 1); if (sp == NULL) { fi->magic = 0; /* Hat keinen Kampfzauber, k�mpft nichtmagisch weiter */ return; } ord = create_order(K_CAST, lang, "'%s'", spell_name(sp, lang)); - if (!cancast(caster, sp, 1, 1, ord)) { + if (!cancast(mage, sp, 1, 1, ord)) { fi->magic = 0; /* Kann nicht mehr Zaubern, k�mpft nichtmagisch weiter */ return; } - level = eff_spelllevel(caster, sp, fi->magic, 1); - sl = get_combatspelllevel(caster, 1); + level = eff_spelllevel(mage, mage, sp, fi->magic, 1); + sl = get_combatspelllevel(mage, 1); if (sl > 0 && sl < level) { level = sl; } - if (fumble(r, caster, sp, level)) { - report_failed_spell(b, caster, sp); - pay_spell(caster, sp, level, 1); + if (fumble(r, mage, sp, level)) { + report_failed_spell(b, mage, sp); + pay_spell(mage, NULL, sp, level, 1); return; } @@ -1894,16 +1897,16 @@ static void do_combatspell(troop at) /* Antimagie die Fehlschlag erh�ht */ if (rng_int() % 100 < fumblechance) { - report_failed_spell(b, caster, sp); - pay_spell(caster, sp, level, 1); + report_failed_spell(b, mage, sp); + pay_spell(mage, NULL, sp, level, 1); free_order(ord); return; } - power = spellpower(r, caster, sp, level, ord); + power = spellpower(r, mage, sp, level, ord); free_order(ord); if (power <= 0) { /* Effekt von Antimagie */ - report_failed_spell(b, caster, sp); - pay_spell(caster, sp, level, 1); + report_failed_spell(b, mage, sp); + pay_spell(mage, NULL, sp, level, 1); return; } @@ -2076,6 +2079,7 @@ void dazzle(battle * b, troop * td) void damage_building(battle * b, building * bldg, int damage_abs) { + assert(bldg); bldg->size = MAX(1, bldg->size - damage_abs); /* Wenn Burg, dann gucken, ob die Leute alle noch in das Geb�ude passen. */ @@ -3425,11 +3429,12 @@ int join_battle(battle * b, unit * u, bool attack, fighter ** cp) battle *make_battle(region * r) { - battle *b = (battle *)calloc(1, sizeof(battle)); unit *u; bfaction *bf; building * bld; + battle *b = (battle *)calloc(1, sizeof(battle)); + assert(b); /* Alle Mann raus aus der Burg! */ for (bld = r->buildings; bld != NULL; bld = bld->next) bld->sizeleft = bld->size; @@ -3447,6 +3452,7 @@ battle *make_battle(region * r) } if (!bf) { bf = (bfaction *)calloc(1, sizeof(bfaction)); + assert(bf); ++b->nfactions; bf->faction = u->faction; bf->next = b->factions; @@ -3470,14 +3476,15 @@ static void free_side(side * si) static void free_fighter(fighter * fig) { + armor **ap = &fig->armors; + while (*ap) { + armor *a = *ap; + *ap = a->next; + free(a); + } while (fig->loot) { i_free(i_remove(&fig->loot, fig->loot)); } - while (fig->armors) { - armor *a = fig->armors; - fig->armors = a->next; - free(a); - } free(fig->person); free(fig->weapons); @@ -3489,13 +3496,14 @@ static void battle_free(battle * b) { assert(b); for (s = b->sides; s != b->sides + b->nsides; ++s) { - fighter *fnext = s->fighters; - while (fnext) { - fighter *fig = fnext; - fnext = fig->next; + fighter **fp = &s->fighters; + while (*fp) { + fighter *fig = *fp; + *fp = fig->next; free_fighter(fig); free(fig); } + s->fighters = NULL; free_side(s); } free(b); diff --git a/src/bind_process.c b/src/bind_process.c index 6a02ac7a5..f9f99284e 100755 --- a/src/bind_process.c +++ b/src/bind_process.c @@ -5,7 +5,6 @@ #include "bind_process.h" #include "battle.h" -#include "contact.h" #include "economy.h" #include "laws.h" #include "magic.h" diff --git a/src/bindings.c b/src/bindings.c index e60b7fe78..e14c13ea5 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include diff --git a/src/kernel/faction.c b/src/kernel/faction.c index f36ef5f8c..c0c908186 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -607,7 +607,7 @@ struct spellbook * faction_get_spellbook(struct faction *f) if (f->magiegebiet != M_GRAY) { return get_spellbook(magic_school[f->magiegebiet]); } - return 0; + return NULL; } static int allied_skillcount(const faction * f, skill_t sk) diff --git a/src/kernel/gamedata.h b/src/kernel/gamedata.h index c6378733f..1d65f5085 100644 --- a/src/kernel/gamedata.h +++ b/src/kernel/gamedata.h @@ -39,8 +39,9 @@ #define FIXATKEYS_VERSION 361 /* remove global.attribs, fix at_keys */ #define FACTION_UID_VERSION 362 /* f->uid contains a database id */ #define CRYPT_VERSION 363 /* passwords are encrypted */ +#define FAMILIAR_FIXMAGE_VERSION 364 /* familiar links are fixed */ -#define RELEASE_VERSION CRYPT_VERSION /* current datafile */ +#define RELEASE_VERSION FAMILIAR_FIXMAGE_VERSION /* current datafile */ #define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ diff --git a/src/kernel/messages.h b/src/kernel/messages.h index ba441250d..7fa6996e2 100644 --- a/src/kernel/messages.h +++ b/src/kernel/messages.h @@ -26,7 +26,6 @@ extern "C" { #include struct faction; - struct msglevel; typedef struct mlist { struct mlist *next; @@ -39,13 +38,6 @@ extern "C" { void free_messagelist(struct mlist *msgs); - typedef struct msglevel { - /* used to set specialized msg-levels */ - struct msglevel *next; - const struct message_type *type; - int level; - } msglevel; - #define MESSAGE_MISSING_IGNORE 0 #define MESSAGE_MISSING_ERROR 1 #define MESSAGE_MISSING_REPLACE 2 diff --git a/src/kernel/save.c b/src/kernel/save.c index 1d67c2860..cfa254bf4 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1293,50 +1293,63 @@ ship *read_ship(gamedata *data) return sh; } +static void fix_fam_mage(unit *u) { + sc_mage *m = get_mage(u); + if (m && m->magietyp != M_GRAY) { + /* unit should be a familiar that has aura and a spell-list */ + if (!m->spellbook) { + m->magietyp = M_GRAY; + } + } +} -static void fix_familiars(void) { +static void fix_fam_triggers(unit *u) { + attrib * a = a_find(u->attribs, &at_mage); + attrib * am = a_find(u->attribs, &at_familiarmage); + if (!am && a) { + /* not a familiar, but magical */ + attrib * ae = a_find(u->attribs, &at_eventhandler); + if (ae) { + trigger **tlist; + tlist = get_triggers(ae, "destroy"); + if (tlist) { + trigger *t; + unit *um = NULL; + for (t = *tlist; t; t = t->next) { + if (t->type == &tt_shock) { + um = (unit *)t->data.v; + break; + } + } + if (um) { + attrib *af = a_find(um->attribs, &at_familiar); + log_error("%s seems to be a broken familiar of %s.", + unitname(u), unitname(um)); + if (af) { + unit * uf = (unit *)af->data.v; + log_error("%s already has a familiar: %s.", + unitname(um), unitname(uf)); + } + else { + set_familiar(um, u); + } + } + else { + log_error("%s seems to be a broken familiar with no trigger.", unitname(u)); + } + } + } + } +} + +static void fix_familiars(void (*callback)(unit *)) { region *r; for (r = regions; r; r = r->next) { unit * u; for (u = r->units; u; u = u->next) { if (u->_race != u->faction->race && (u->_race->flags & RCF_FAMILIAR)) { /* unit is potentially a familiar */ - attrib * a = a_find(u->attribs, &at_mage); - attrib * am = a_find(u->attribs, &at_familiarmage); - if (!am && a) { - /* not a familiar, but magical */ - attrib * ae = a_find(u->attribs, &at_eventhandler); - if (ae) { - trigger **tlist; - tlist = get_triggers(ae, "destroy"); - if (tlist) { - trigger *t; - unit *um = NULL; - for (t = *tlist; t; t = t->next) { - if (t->type == &tt_shock) { - um = (unit *)t->data.v; - break; - } - } - if (um) { - attrib *af = a_find(um->attribs, &at_familiar); - log_error("%s seems to be a broken familiar of %s.", - unitname(u), unitname(um)); - if (af) { - unit * uf = (unit *)af->data.v; - log_error("%s already has a familiar: %s.", - unitname(um), unitname(uf)); - } - else { - set_familiar(um, u); - } - } - else { - log_error("%s seems to be a broken familiar with no trigger.", unitname(u)); - } - } - } - } + callback(u); } } } @@ -1524,7 +1537,10 @@ int read_game(gamedata *data) } if (data->version < FAMILIAR_FIX_VERSION) { - fix_familiars(); + fix_familiars(fix_fam_triggers); + } + if (data->version < FAMILIAR_FIXMAGE_VERSION) { + fix_familiars(fix_fam_mage); } log_debug("Done loading turn %d.", turn); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 637a83a53..4366f95dc 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -208,6 +208,7 @@ static buddy *get_friends(const unit * u, int *numfriends) nf = *fr; if (nf == NULL || nf->faction != u2->faction) { nf = malloc(sizeof(buddy)); + assert(nf); nf->next = *fr; nf->faction = u2->faction; nf->unit = u2; @@ -1004,11 +1005,15 @@ skill *add_skill(unit * u, skill_t sk) skill *sv; int i; + assert(u); for (i = 0; i != u->skill_size; ++i) { sv = u->skills + i; if (sv->id >= sk) break; } - u->skills = realloc(u->skills, (1 + u->skill_size) * sizeof(skill)); + sv = realloc(u->skills, (1 + u->skill_size) * sizeof(skill)); + assert(sv); + u->skills = sv; + sv = u->skills + i; if (i < u->skill_size) { assert(sv->id != sk); @@ -1244,24 +1249,30 @@ int invisible(const unit * target, const unit * viewer) */ void free_unit(unit * u) { + struct reservation **pres = &u->reservations; + assert(!u->region); free(u->_name); free_order(u->thisorder); free_orders(&u->orders); - if (u->skills) + + while (*pres) { + struct reservation *res = *pres; + *pres = res->next; + free(res); + } + if (u->skills) { free(u->skills); + u->skills = NULL; + } while (u->items) { item *it = u->items->next; u->items->next = NULL; i_free(u->items); u->items = it; } - while (u->attribs) + while (u->attribs) { a_remove(&u->attribs, u->attribs); - while (u->reservations) { - struct reservation *res = u->reservations; - u->reservations = res->next; - free(res); } } @@ -1671,7 +1682,7 @@ struct spellbook * unit_get_spellbook(const struct unit * u) return faction_get_spellbook(u->faction); } } - return 0; + return NULL; } int effskill(const unit * u, skill_t sk, const region *r) diff --git a/src/magic.c b/src/magic.c index 3f1d58ae6..0698135f0 100644 --- a/src/magic.c +++ b/src/magic.c @@ -657,8 +657,6 @@ int change_maxspellpoints(unit * u, int csp) /* ------------------------------------------------------------- */ /* Counter für die bereits gezauberte Anzahl Sprüche pro Runde. - * Um nur die Zahl der bereits gezauberten Sprüche zu ermitteln mit - * step = 0 aufrufen. */ int countspells(unit * u, int step) { @@ -666,36 +664,60 @@ int countspells(unit * u, int step) int count; m = get_mage_depr(u); - if (!m) + if (!m) { return 0; - - if (step == 0) + } + if (step == 0) { return m->spellcount; - + } count = m->spellcount + step; m->spellcount = (count > 0) ? count : 0; return m->spellcount; } -/* ------------------------------------------------------------- */ -/* Die für den Spruch benötigte Aura pro Stufe. - * Die Grundkosten pro Stufe werden hier um 2^count erhöht. Der - * Parameter count ist dabei die Anzahl der bereits gezauberten Sprüche +int spellcount(const unit *u) { + sc_mage *m = get_mage_depr(u); + if (m) { + return m->spellcount; + } + return 0; +} + +/** + * Die Grundkosten pro Stufe werden um 2^count erhöht. countspells(u) + * ist dabei die Anzahl der bereits gezauberten Sprüche */ -int spellcost(unit * u, const spell * sp) +int aura_multiplier(const unit * u) { + int count = spellcount(u); + return (1 << count); +} + +int spellcost(const unit * caster, const struct spell_component *spc) { - int k, aura = 0; - int count = countspells(u, 0); const resource_type *r_aura = get_resourcetype(R_AURA); - for (k = 0; sp->components && sp->components[k].type; k++) { - if (sp->components[k].type == r_aura) { - aura = sp->components[k].amount; + if (spc->type == r_aura) { + return spc->amount * aura_multiplier(caster); + } + return spc->amount; +} + +/** + * Die für den Spruch benötigte Aura pro Stufe. + */ +int auracost(const unit *caster, const spell *sp) { + const resource_type *r_aura = get_resourcetype(R_AURA); + if (sp->components) { + int k; + for (k = 0; sp->components[k].type; ++k) { + const struct spell_component *spc = sp->components + k; + if (r_aura == spc->type) { + return spc->amount * aura_multiplier(caster); + } } } - aura *= (1 << count); - return aura; + return 0; } /* ------------------------------------------------------------- */ @@ -726,17 +748,17 @@ static int spl_costtyp(const spell * sp) return costtyp; } -/* ------------------------------------------------------------- */ -/* durch Komponenten und cast_level begrenzter maximal möglicher - * Level +/** + * Durch Komponenten und cast_level begrenzter maximal möglicherLevel. + * * Da die Funktion nicht alle Komponenten durchprobiert sondern beim * ersten Fehler abbricht, muss die Fehlermeldung später mit cancast() * generiert werden. - * */ -int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range) + */ +int eff_spelllevel(unit * u, unit *caster, const spell * sp, int cast_level, int range) { const resource_type *r_aura = get_resourcetype(R_AURA); - int k, maxlevel, needplevel; + int k, maxlevel; int costtyp = SPC_FIX; for (k = 0; sp->components && sp->components[k].type; k++) { @@ -744,17 +766,15 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range) return 0; if (sp->components[k].amount > 0) { - /* Die Kosten für Aura sind auch von der Zahl der bereits - * gezauberten Sprüche abhängig */ + int level_cost = sp->components[k].amount * range; if (sp->components[k].type == r_aura) { - needplevel = spellcost(u, sp) * range; - } - else { - needplevel = sp->components[k].amount * range; + /* Die Kosten fuer Aura sind auch von der Zahl der bereits + * gezauberten Sprueche abhaengig */ + level_cost *= aura_multiplier(caster); } maxlevel = get_pooled(u, sp->components[k].type, GET_DEFAULT, - needplevel * cast_level) / needplevel; + level_cost * cast_level) / level_cost; /* sind die Kosten fix, so muss die Komponente nur einmal vorhanden * sein und der cast_level ändert sich nicht */ @@ -803,27 +823,20 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range) * Je nach Kostenart werden dann die Komponenten noch mit cast_level * multipliziert. */ -void pay_spell(unit * u, const spell * sp, int cast_level, int range) +void pay_spell(unit * mage, const unit *caster, const spell * sp, int cast_level, int range) { - const resource_type *r_aura = get_resourcetype(R_AURA); int k; - int resuse; assert(cast_level > 0); for (k = 0; sp->components && sp->components[k].type; k++) { - if (sp->components[k].type == r_aura) { - resuse = spellcost(u, sp) * range; - } - else { - resuse = sp->components[k].amount * range; - } + const struct spell_component *spc = sp->components + k; + int resuse = spellcost(caster ? caster : mage, spc) * range; - if (sp->components[k].cost == SPC_LINEAR - || sp->components[k].cost == SPC_LEVEL) { + if (spc->cost == SPC_LINEAR || spc->cost == SPC_LEVEL) { resuse *= cast_level; } - use_pooled(u, sp->components[k].type, GET_DEFAULT, resuse); + use_pooled(mage, spc->type, GET_DEFAULT, resuse); } } @@ -851,9 +864,7 @@ bool knowsspell(const region * r, const unit * u, const spell * sp) bool cancast(unit * u, const spell * sp, int level, int range, struct order * ord) { - const resource_type *r_aura = get_resourcetype(R_AURA); int k; - int itemanz; resource *reslist = NULL; if (!knowsspell(u->region, u, sp)) { @@ -869,22 +880,18 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) } for (k = 0; sp->components && sp->components[k].type; ++k) { - if (sp->components[k].amount > 0) { - const resource_type *rtype = sp->components[k].type; - int itemhave; + const struct spell_component *spc = sp->components + k; + if (spc->amount > 0) { + const resource_type *rtype = spc->type; + int itemhave, itemanz; /* Die Kosten für Aura sind auch von der Zahl der bereits * gezauberten Sprüche abhängig */ - if (rtype == r_aura) { - itemanz = spellcost(u, sp) * range; - } - else { - itemanz = sp->components[k].amount * range; - } + itemanz = spellcost(u, spc) * range; /* sind die Kosten stufenabhängig, so muss itemanz noch mit dem * level multipliziert werden */ - switch (sp->components[k].cost) { + switch (spc->cost) { case SPC_LEVEL: case SPC_LINEAR: itemanz *= level; @@ -897,6 +904,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) itemhave = get_pooled(u, rtype, GET_DEFAULT, itemanz); if (itemhave < itemanz) { resource *res = malloc(sizeof(resource)); + assert(res); res->number = itemanz - itemhave; res->type = rtype; res->next = reslist; @@ -1254,8 +1262,8 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) } /* CHAOSPATZERCHANCE 10 : +10% Chance zu Patzern */ - mage = get_mage_depr(u); - if (mage->magietyp == M_DRAIG) { + mage = get_mage(u); + if (mage && mage->magietyp == M_DRAIG) { fumble_chance += CHAOSPATZERCHANCE; } if (is_cursed(u->attribs, &ct_magicboost)) { @@ -1276,11 +1284,11 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) } /* ------------------------------------------------------------- */ -/* Dummy-Zauberpatzer, Platzhalter für speziel auf die Sprüche +/* Dummy-Zauberpatzer, Platzhalter für speziell auf die Sprüche * zugeschnittene Patzer */ static void fumble_default(castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); cmistake(mage, co->order, 180, MSG_MAGIC); @@ -1295,7 +1303,8 @@ static void do_fumble(castorder * co) { curse *c; region *r = co_get_region(co); - unit *u = co->magician.u; + unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); const spell *sp = co->sp; int level = co->level; int duration; @@ -1304,8 +1313,8 @@ static void do_fumble(castorder * co) static int rc_cache; fumble_f fun; - ADDMSG(&u->faction->msgs, - msg_message("patzer", "unit region spell", u, r, sp)); + ADDMSG(&mage->faction->msgs, + msg_message("patzer", "unit region spell", mage, r, sp)); switch (rng_int() % 10) { case 0: /* wenn vorhanden spezieller Patzer, ansonsten nix */ @@ -1325,22 +1334,22 @@ static void do_fumble(castorder * co) * The list of things to happen are attached to a timeout * trigger and that's added to the triggerlit of the mage gone toad. */ - trigger *trestore = trigger_changerace(u, u_race(u), u->irace); + trigger *trestore = trigger_changerace(mage, u_race(mage), mage->irace); if (chance(0.7)) { const resource_type *rtype = rt_find("toadslime"); if (rtype) { - t_add(&trestore, trigger_giveitem(u, rtype->itype, 1)); + t_add(&trestore, trigger_giveitem(mage, rtype->itype, 1)); } } duration = rng_int() % level / 2; if (duration < 2) duration = 2; - add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore)); + add_trigger(&mage->attribs, "timer", trigger_timeout(duration, trestore)); if (rc_changed(&rc_cache)) { rc_toad = get_race(RC_TOAD); } - u_setrace(u, rc_toad); - u->irace = NULL; - ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", u, r, sp)); + u_setrace(mage, rc_toad); + mage->irace = NULL; + ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", mage, r, sp)); break; } /* fall-through is intentional! */ @@ -1350,26 +1359,26 @@ static void do_fumble(castorder * co) duration = rng_int() % level / 2; if (duration < 2) duration = 2; effect = level / -2.0; - c = create_curse(u, &u->attribs, &ct_skillmod, level, + c = create_curse(mage, &mage->attribs, &ct_skillmod, level, duration, effect, 1); c->data.i = SK_MAGIC; - ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r)); + ADDMSG(&mage->faction->msgs, msg_message("patzer2", "unit region", mage, r)); break; case 3: case 4: /* Spruch schlägt fehl, alle Magiepunkte weg */ - set_spellpoints(u, 0); - ADDMSG(&u->faction->msgs, msg_message("patzer3", "unit region spell", - u, r, sp)); + set_spellpoints(mage, 0); + ADDMSG(&mage->faction->msgs, msg_message("patzer3", "unit region spell", + mage, r, sp)); break; case 5: case 6: /* Spruch gelingt, aber alle Magiepunkte weg */ co->level = cast_spell(co); - set_spellpoints(u, 0); - ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell", - u, r, sp)); + set_spellpoints(mage, 0); + ADDMSG(&mage->faction->msgs, msg_message("patzer4", "unit region spell", + mage, r, sp)); break; case 7: @@ -1378,9 +1387,9 @@ static void do_fumble(castorder * co) default: /* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */ co->level = cast_spell(co); - ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell", - u, r, sp)); - countspells(u, 3); + ADDMSG(&mage->faction->msgs, msg_message("patzer5", "unit region spell", + mage, r, sp)); + countspells(caster, 3); } } @@ -1591,7 +1600,7 @@ verify_unit(region * r, unit * mage, const spell * sp, spllprm * spobj, static void verify_targets(castorder * co, int *invalid, int *resist, int *success) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); const spell *sp = co->sp; region *target_r = co_get_region(co); spellparameter *sa = co->par; @@ -2038,6 +2047,10 @@ struct unit * co_get_caster(const struct castorder * co) { return co->_familiar ? co->_familiar : co->magician.u; } +struct unit * co_get_magician(const struct castorder * co) { + return co->magician.u; +} + struct region * co_get_region(const struct castorder * co) { return co->_rtarget; } @@ -2432,7 +2445,7 @@ static castorder *cast_cmd(unit * u, order * ord) spell *sp = 0; plane *pl; spellparameter *args = NULL; - unit * caster = u; + unit * mage = u; param_t param; if (LongHunger(u)) { @@ -2502,15 +2515,15 @@ static castorder *cast_cmd(unit * u, order * ord) * 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) { + mage = get_familiar_mage(u); + if (mage) { familiar = u; - sp = unit_getspell(caster, s, caster->faction->locale); + sp = unit_getspell(mage, s, mage->faction->locale); } else { /* somehow, this familiar has no mage! */ log_error("cast_cmd: familiar %s is without a mage?\n", unitname(u)); - caster = u; + mage = u; } } @@ -2597,24 +2610,22 @@ static castorder *cast_cmd(unit * u, order * ord) cmistake(u, ord, 177, MSG_MAGIC); return 0; } - if (caster != familiar) { /* Magier zaubert durch Vertrauten */ + if (mage != familiar) { /* Magier zaubert durch Vertrauten */ int sk; if (range > 1) { /* Fehler! Versucht zu Farcasten */ ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_farcast", - "mage", caster)); + "mage", mage)); return 0; } - sk = effskill(caster, SK_MAGIC, 0); - if (distance(caster->region, r) > sk) { + sk = effskill(mage, SK_MAGIC, 0); + if (distance(mage->region, r) > sk) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_toofar", - "mage", caster)); + "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 */ + * der Spruchkosten nutzen */ range *= 2; - set_order(&caster->thisorder, NULL); sk /= 2; if (level > sk) level = sk; } @@ -2635,7 +2646,7 @@ static castorder *cast_cmd(unit * u, order * ord) unitname(u), MAX_PARAMETERS, sp->sname); } args = - add_spellparameter(target_r, caster, sp->parameter, + add_spellparameter(target_r, mage, sp->parameter, (const char *const *)params, p, ord); for (i = 0; i != p; ++i) { free(params[i]); @@ -2645,7 +2656,7 @@ static castorder *cast_cmd(unit * u, order * ord) return 0; } } - return create_castorder(0, caster, familiar, sp, target_r, level, 0, range, ord, + return create_castorder(0, mage, familiar, sp, target_r, level, 0, range, ord, args); } @@ -2718,16 +2729,17 @@ void magic(void) order *ord = co->order; int invalid, resist, success, cast_level = co->level; bool fumbled = false; - unit *u = co->magician.u; + unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); const spell *sp = co->sp; region *target_r = co_get_region(co); /* reichen die Komponenten nicht, wird der Level reduziert. */ - co->level = eff_spelllevel(u, sp, cast_level, co->distance); + co->level = eff_spelllevel(mage, caster, sp, cast_level, co->distance); if (co->level < 1) { /* Fehlermeldung mit Komponenten generieren */ - cancast(u, sp, cast_level, co->distance, ord); + cancast(mage, sp, cast_level, co->distance, ord); continue; } @@ -2735,24 +2747,24 @@ void magic(void) /* Sprüche mit Fixkosten werden immer auf Stufe des Spruchs * gezaubert, co->level ist aber defaultmäßig Stufe des Magiers */ if (spl_costtyp(sp) != SPC_FIX) { - ADDMSG(&u->faction->msgs, msg_message("missing_components", - "unit spell level", u, sp, cast_level)); + ADDMSG(&mage->faction->msgs, msg_message("missing_components", + "unit spell level", mage, sp, cast_level)); } } /* Prüfen, ob die realen Kosten für die gewünschten Stufe bezahlt * werden können */ - if (!cancast(u, sp, co->level, co->distance, ord)) { + if (!cancast(mage, sp, co->level, co->distance, ord)) { /* die Fehlermeldung wird in cancast generiert */ continue; } - co->force = MagicPower(spellpower(target_r, u, sp, co->level, ord)); + co->force = MagicPower(spellpower(target_r, mage, sp, co->level, ord)); /* die Stärke kann durch Antimagie auf 0 sinken */ if (co->force <= 0) { co->force = 0; - ADDMSG(&u->faction->msgs, msg_message("missing_force", - "unit spell level", u, sp, co->level)); + ADDMSG(&mage->faction->msgs, msg_message("missing_force", + "unit spell level", mage, sp, co->level)); } /* Ziele auf Existenz prüfen und Magieresistenz feststellen. Wurde @@ -2772,15 +2784,15 @@ void magic(void) co->force = 0; /* zwar wurde mindestens ein Ziel gefunden, das widerstand * jedoch dem Zauber. Kosten abziehen und abbrechen. */ - ADDMSG(&u->faction->msgs, msg_message("spell_resist", - "unit region spell", u, r, sp)); + ADDMSG(&mage->faction->msgs, msg_message("spell_resist", + "unit region spell", mage, r, sp)); } } /* Auch für Patzer gibt es Erfahrung, müssen die Spruchkosten * bezahlt werden und die nachfolgenden Sprüche werden teurer */ if (co->force > 0) { - if (fumble(target_r, u, sp, co->level)) { + if (fumble(target_r, mage, sp, co->level)) { /* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */ fumbled = true; } @@ -2794,12 +2806,12 @@ void magic(void) } /* erst bezahlen, dann Kostenzähler erhöhen */ if (co->level > 0) { - pay_spell(u, sp, co->level, co->distance); + pay_spell(mage, caster, sp, co->level, co->distance); } if (fumbled) { do_fumble(co); } - countspells(u, 1); + countspells(caster, 1); } } @@ -2807,9 +2819,9 @@ void magic(void) 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) && spellcount(u) > 0) { produceexp(u, SK_MAGIC, u->number); - /* Spruchlistenaktualiesierung ist in Regeneration */ + /* Spruchlistenaktualisierung ist in Regeneration */ } } } @@ -2859,33 +2871,22 @@ static void select_spellbook(void **tokens, spellbook *sb, const struct locale * spell *unit_getspell(struct unit *u, const char *name, const struct locale * lang) { - void * tokens = 0; spellbook *sb; sb = unit_get_spellbook(u); if (sb) { + void * tokens = NULL; select_spellbook(&tokens, sb, lang); - } -#if 0 /* TODO: some familiars can cast spells from the mage's spellbook? */ - u = get_familiar_mage(u); - if (u) { - sb = unit_get_spellbook(u); - if (sb) { - select_spellbook(&tokens, sb, lang); - } - } -#endif - - if (tokens) { - variant token; - if (findtoken(tokens, name, &token) != E_TOK_NOMATCH) { + if (tokens) { + variant token; + if (findtoken(tokens, name, &token) != E_TOK_NOMATCH) { + freetokens(tokens); + return (spell *)token.v; + } freetokens(tokens); - return (spell *)token.v; } - freetokens(tokens); } - - return 0; + return NULL; } int cast_spell(struct castorder *co) diff --git a/src/magic.h b/src/magic.h index 654673245..030d21864 100644 --- a/src/magic.h +++ b/src/magic.h @@ -140,6 +140,7 @@ extern "C" { } castorder; struct unit * co_get_caster(const struct castorder * co); + struct unit * co_get_magician(const struct castorder * co); struct region * co_get_region(const struct castorder * co); typedef struct spell_component { @@ -288,9 +289,11 @@ extern "C" { /* Prüfroutinen für Zaubern */ int countspells(struct unit *u, int step); + int spellcount(const struct unit *u); /* 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 struct spell * sp); + int auracost(const struct unit *caster, const struct spell *sp); + int spellcost(const struct unit *caster, const struct spell_component *spc); /* 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 */ @@ -298,12 +301,12 @@ extern "C" { 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 struct spell * sp, int eff_stufe, int distance); + void pay_spell(struct unit *mage, const struct unit *caster, 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 struct spell * sp, int cast_level, - int distance); + int eff_spelllevel(struct unit *mage, struct unit *caster, + 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, * bei Farcasting Stufe*2^Entfernung) */ diff --git a/src/magic.test.c b/src/magic.test.c index 9ca9c013e..fc05f361f 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -123,9 +123,9 @@ void test_pay_spell(CuTest * tc) change_resource(u, get_resourcetype(R_AURA), 3); change_resource(u, get_resourcetype(R_HORSE), 3); - level = eff_spelllevel(u, sp, 3, 1); + level = eff_spelllevel(u, u, sp, 3, 1); CuAssertIntEquals(tc, 3, level); - pay_spell(u, sp, level, 1); + pay_spell(u, NULL, sp, level, 1); CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_SILVER))); CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_AURA))); CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_HORSE))); @@ -157,16 +157,16 @@ void test_pay_spell_failure(CuTest * tc) CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_AURA), 2)); CuAssertIntEquals(tc, 3, change_resource(u, get_resourcetype(R_HORSE), 3)); - level = eff_spelllevel(u, sp, 3, 1); + level = eff_spelllevel(u, u, sp, 3, 1); CuAssertIntEquals(tc, 2, level); - pay_spell(u, sp, level, 1); + pay_spell(u, NULL, sp, level, 1); CuAssertIntEquals(tc, 1, change_resource(u, get_resourcetype(R_SILVER), 1)); CuAssertIntEquals(tc, 3, change_resource(u, get_resourcetype(R_AURA), 3)); CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_HORSE), 1)); - CuAssertIntEquals(tc, 0, eff_spelllevel(u, sp, 3, 1)); + CuAssertIntEquals(tc, 0, eff_spelllevel(u, u, sp, 3, 1)); CuAssertIntEquals(tc, 0, change_resource(u, get_resourcetype(R_SILVER), -1)); - CuAssertIntEquals(tc, 0, eff_spelllevel(u, sp, 2, 1)); + CuAssertIntEquals(tc, 0, eff_spelllevel(u, u, sp, 2, 1)); test_teardown(); } diff --git a/src/spells.c b/src/spells.c index 7d745147f..a628f1949 100644 --- a/src/spells.c +++ b/src/spells.c @@ -476,8 +476,21 @@ report_effect(region * r, unit * mage, message * seen, message * unseen) static const race *select_familiar(const race * magerace, magic_t magiegebiet) { - const race *retval = 0; + const race *retval; int rnd = rng_int() % 100; + static const race *rcfixed; + static int config; + + if (config_changed(&config)) { + const char *rcname = config_get("magic.familiar.race"); + rcfixed = NULL; + if (rcname) { + rcfixed = rc_find(rcname); + } + } + if (rcfixed) { + return rcfixed; + } assert(magerace->familiars[0]); if (rnd >= 70) { @@ -534,19 +547,19 @@ static unit * make_familiar(unit * mage, region *r, const race *rc, const char * static int sp_summon_familiar(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; const race *rc; message *msg; char zText[2048]; - if (get_familiar(mage) != NULL) { - cmistake(mage, co->order, 199, MSG_MAGIC); + if (get_familiar(caster) != NULL) { + cmistake(caster, co->order, 199, MSG_MAGIC); return 0; } - rc = select_familiar(mage->_race, mage->faction->magiegebiet); + rc = select_familiar(caster->_race, caster->faction->magiegebiet); if (rc == NULL) { - log_error("could not find suitable familiar for %s.\n", mage->faction->race->_name); + log_error("could not find suitable familiar for %s.\n", caster->faction->race->_name); return 0; } @@ -555,7 +568,7 @@ static int sp_summon_familiar(castorder * co) int dir, dh; if (coasts == 0) { - cmistake(mage, co->order, 229, MSG_MAGIC); + cmistake(caster, co->order, 229, MSG_MAGIC); return 0; } @@ -574,14 +587,14 @@ static int sp_summon_familiar(castorder * co) } } - msg = msg_message("familiar_name", "unit", mage); - nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction); + msg = msg_message("familiar_name", "unit", caster); + nr_render(msg, caster->faction->locale, zText, sizeof(zText), caster->faction); msg_release(msg); - make_familiar(mage, r, rc, zText); + make_familiar(caster, r, rc, zText); - report_race_skills(rc, zText, sizeof(zText), mage->faction->locale); - ADDMSG(&mage->faction->msgs, msg_message("familiar_describe", - "mage race skills", mage, rc, zText)); + report_race_skills(rc, zText, sizeof(zText), caster->faction->locale); + ADDMSG(&caster->faction->msgs, msg_message("familiar_describe", + "mage race skills", caster, rc, zText)); return cast_level; } @@ -600,7 +613,7 @@ static int sp_summon_familiar(castorder * co) * */ static int sp_destroy_magic(castorder * co) { - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -623,7 +636,7 @@ static int sp_destroy_magic(castorder * co) /* region *tr = pa->param[0]->data.r; -- farcasting! */ region *tr = co_get_region(co); ap = &tr->attribs; - write_regionname(tr, mage->faction, ts, sizeof(ts)); + write_regionname(tr, caster->faction, ts, sizeof(ts)); break; } case SPP_TEMP: @@ -658,13 +671,13 @@ static int sp_destroy_magic(castorder * co) succ = break_curse(ap, cast_level, force, c); if (succ) { - ADDMSG(&mage->faction->msgs, msg_message("destroy_magic_effect", - "unit region command succ target", mage, mage->region, co->order, succ, + ADDMSG(&caster->faction->msgs, msg_message("destroy_magic_effect", + "unit region command succ target", caster, caster->region, co->order, succ, ts)); } else { - ADDMSG(&mage->faction->msgs, msg_message("destroy_magic_noeffect", - "unit region command", mage, mage->region, co->order)); + ADDMSG(&caster->faction->msgs, msg_message("destroy_magic_noeffect", + "unit region command", caster, caster->region, co->order)); } if (succ < 1) succ = 1; @@ -692,12 +705,14 @@ static int sp_destroy_magic(castorder * co) static int sp_transferaura(castorder * co) { int aura, gain, multi = 2; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; unit *u; - sc_mage *scm_dst, *scm_src = get_mage_depr(mage); + sc_mage *scm_dst, *scm_src = get_mage(mage); + assert(scm_src); /* wenn kein Ziel gefunden, Zauber abbrechen */ if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; @@ -714,7 +729,7 @@ static int sp_transferaura(castorder * co) if (scm_dst == NULL) { /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ - cmistake(mage, co->order, 207, MSG_MAGIC); + cmistake(caster, co->order, 207, MSG_MAGIC); return 0; } else if (scm_src->magietyp == M_TYBIED) { @@ -727,13 +742,13 @@ static int sp_transferaura(castorder * co) } else if (scm_dst->magietyp != scm_src->magietyp) { /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ - cmistake(mage, co->order, 207, MSG_MAGIC); + cmistake(caster, co->order, 207, MSG_MAGIC); return 0; } if (aura < multi) { /* "Auraangabe fehlerhaft." */ - cmistake(mage, co->order, 208, MSG_MAGIC); + cmistake(caster, co->order, 208, MSG_MAGIC); return 0; } @@ -745,8 +760,8 @@ static int sp_transferaura(castorder * co) /* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage), gain, unitname(u)); */ - ADDMSG(&mage->faction->msgs, msg_message("auratransfer_success", - "unit target aura", mage, u, gain)); + ADDMSG(&caster->faction->msgs, msg_message("auratransfer_success", + "unit target aura", caster, u, gain)); return cast_level; } @@ -768,7 +783,7 @@ static int sp_transferaura(castorder * co) static int sp_goodwinds(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = cast_level + 1; @@ -785,14 +800,14 @@ static int sp_goodwinds(castorder * co) /* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */ /* NODRIFT bewirkt auch +1 Geschwindigkeit */ - create_curse(mage, &sh->attribs, &ct_nodrift, power, duration, + create_curse(caster, &sh->attribs, &ct_nodrift, power, duration, zero_effect, 0); /* melden, 1x pro Partei */ - freset(mage->faction, FFL_SELECT); + freset(caster->faction, FFL_SELECT); for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - m = msg_message("wind_effect", "mage ship", mage, sh); + m = msg_message("wind_effect", "mage ship", caster, sh); for (u = r->units; u; u = u->next) { if (u->ship != sh) /* nur den Schiffsbesatzungen! */ continue; @@ -801,8 +816,8 @@ static int sp_goodwinds(castorder * co) fset(u->faction, FFL_SELECT); } } - if (!fval(mage->faction, FFL_SELECT)) { - r_addmessage(r, mage->faction, m); + if (!fval(caster->faction, FFL_SELECT)) { + r_addmessage(r, caster->faction, m); } msg_release(m); @@ -824,22 +839,22 @@ static int sp_goodwinds(castorder * co) static int sp_magicstreet(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); if (!fval(r->terrain, LAND_REGION)) { - cmistake(mage, co->order, 186, MSG_MAGIC); + cmistake(caster, co->order, 186, MSG_MAGIC); return 0; } /* wirkt schon in der Zauberrunde! */ - create_curse(mage, &r->attribs, &ct_magicstreet, co->force, + create_curse(caster, &r->attribs, &ct_magicstreet, co->force, co->level + 1, zero_effect, 0); /* melden, 1x pro Partei */ { - message *seen = msg_message("path_effect", "mage region", mage, r); + message *seen = msg_message("path_effect", "mage region", caster, r); message *unseen = msg_message("path_effect", "mage region", (unit *)NULL, r); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -865,7 +880,7 @@ static int sp_magicstreet(castorder * co) static int sp_summonent(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; unit *u; @@ -873,7 +888,7 @@ static int sp_summonent(castorder * co) int ents, p2; if (rtrees(r, 2) == 0) { - cmistake(mage, co->order, 204, MSG_EVENT); + cmistake(caster, co->order, 204, MSG_EVENT); /* nicht ohne baeume */ return 0; } @@ -882,7 +897,7 @@ static int sp_summonent(castorder * co) p2 = (int)(power * power); if (ents > p2) ents = p2; - u = create_unit(r, mage->faction, ents, get_race(RC_TREEMAN), 0, NULL, mage); + u = create_unit(r, caster->faction, ents, get_race(RC_TREEMAN), 0, NULL, caster); a = a_new(&at_unitdissolve); a->data.ca[0] = 2; /* An r->trees. */ @@ -894,9 +909,9 @@ static int sp_summonent(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("ent_effect", "mage amount", mage, ents); + message *seen = msg_message("ent_effect", "mage amount", caster, ents); message *unseen = msg_message("ent_effect", "mage amount", (unit *)NULL, ents); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(unseen); msg_release(seen); } @@ -921,7 +936,7 @@ static int sp_blessstonecircle(castorder * co) { building *b; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *p = co->par; message *msg; @@ -933,20 +948,20 @@ static int sp_blessstonecircle(castorder * co) b = p->param[0]->data.b; if (!is_building_type(b->type, "stonecircle")) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_notstonecircle", "building", b)); return 0; } if (!building_finished(b)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_notcomplete", "building", b)); return 0; } b->type = bt_find("blessedstonecircle"); - msg = msg_message("blessedstonecircle_effect", "mage building", mage, b); + msg = msg_message("blessedstonecircle_effect", "mage building", caster, b); add_message(&r->msgs, msg); msg_release(msg); @@ -970,13 +985,13 @@ static int sp_blessstonecircle(castorder * co) static int sp_maelstrom(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; curse *c; int duration = (int)co->force + 1; if (!fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 205, MSG_MAGIC); + cmistake(caster, co->order, 205, MSG_MAGIC); /* nur auf ozean */ return 0; } @@ -984,13 +999,13 @@ static int sp_maelstrom(castorder * co) /* Attribut auf Region. * Existiert schon ein curse, so wird dieser verstaerkt * (Max(Dauer), Max(Staerke))*/ - c = create_curse(mage, &r->attribs, &ct_maelstrom, co->force, duration, co->force, 0); + c = create_curse(caster, &r->attribs, &ct_maelstrom, co->force, duration, co->force, 0); /* melden, 1x pro Partei */ if (c) { - message *seen = msg_message("maelstrom_effect", "mage", mage); + message *seen = msg_message("maelstrom_effect", "mage", caster); message *unseen = msg_message("maelstrom_effect", "mage", (unit *)NULL); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1013,14 +1028,14 @@ static int sp_mallorn(castorder * co) { region *r = co_get_region(co); int cast_level = co->level; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); if (!fval(r->terrain, LAND_REGION)) { - cmistake(mage, co->order, 186, MSG_MAGIC); + cmistake(caster, co->order, 186, MSG_MAGIC); return 0; } if (fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 191, MSG_MAGIC); + cmistake(caster, co->order, 191, MSG_MAGIC); return 0; } @@ -1032,9 +1047,9 @@ static int sp_mallorn(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("mallorn_effect", "mage", mage); + message *seen = msg_message("mallorn_effect", "mage", caster); message *unseen = msg_message("mallorn_effect", "mage", (unit *)NULL); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1057,19 +1072,19 @@ static int sp_mallorn(castorder * co) static int sp_blessedharvest(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; int duration = (int)co->force + 1; /* Attribut auf Region. * Existiert schon ein curse, so wird dieser verstaerkt * (Max(Dauer), Max(Staerke))*/ - if (create_curse(mage, &r->attribs, &ct_blessedharvest, co->force, + if (create_curse(caster, &r->attribs, &ct_blessedharvest, co->force, duration, 1.0, 0)) { const char * effect = co->sp->sname[0]=='b' ? "harvest_effect" : "raindance_effect"; - message *seen = msg_message(effect, "mage", mage); + message *seen = msg_message(effect, "mage", caster); message *unseen = msg_message(effect, "mage", (unit *)NULL); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1094,16 +1109,16 @@ static int sp_hain(castorder * co) { int trees; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); + cmistake(caster, co->order, 296, MSG_MAGIC); return 0; } if (fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 92, MSG_MAGIC); + cmistake(caster, co->order, 92, MSG_MAGIC); return 0; } @@ -1112,10 +1127,10 @@ static int sp_hain(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("growtree_effect", "mage amount", mage, trees); + message *seen = msg_message("growtree_effect", "mage amount", caster, trees); message *unseen = msg_message("growtree_effect", "mage amount", (unit *)NULL, trees); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1140,16 +1155,16 @@ static int sp_mallornhain(castorder * co) { int trees; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); + cmistake(caster, co->order, 296, MSG_MAGIC); return 0; } if (!fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 91, MSG_MAGIC); + cmistake(caster, co->order, 91, MSG_MAGIC); return 0; } @@ -1158,10 +1173,10 @@ static int sp_mallornhain(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("growtree_effect", "mage amount", mage, trees); + message *seen = msg_message("growtree_effect", "mage amount", caster, trees); message *unseen = msg_message("growtree_effect", "mage amount", (unit *)NULL, trees); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1174,7 +1189,7 @@ static void fumble_ents(const castorder * co) int ents; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); /* int cast_level = co->level; */ double force = co->force; @@ -1240,7 +1255,7 @@ static int sp_rosthauch(castorder * co) int n; int success = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; int force = (int)co->force; spellparameter *pa = co->par; @@ -1293,17 +1308,17 @@ static int sp_rosthauch(castorder * co) if (ironweapon > 0) { /* {$mage mage} legt einen Rosthauch auf {target}. {amount} Waffen * wurden vom Rost zerfressen */ - ADDMSG(&mage->faction->msgs, msg_message("rust_effect", - "mage target amount", mage, u, ironweapon)); + ADDMSG(&caster->faction->msgs, msg_message("rust_effect", + "mage target amount", caster, u, ironweapon)); ADDMSG(&u->faction->msgs, msg_message("rust_effect", "mage target amount", - cansee(u->faction, r, mage, 0) ? mage : NULL, u, ironweapon)); + cansee(u->faction, r, caster, 0) ? caster : NULL, u, ironweapon)); success += ironweapon; } else { /* {$mage mage} legt einen Rosthauch auf {target}, doch der * Rosthauch fand keine Nahrung */ - ADDMSG(&mage->faction->msgs, msg_message("rust_fail", "mage target", mage, + ADDMSG(&caster->faction->msgs, msg_message("rust_fail", "mage target", caster, u)); } } @@ -1338,7 +1353,7 @@ static int sp_kaelteschutz(castorder * co) int n, i = 0; int men; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; double effect; @@ -1369,15 +1384,15 @@ static int sp_kaelteschutz(castorder * co) } effect = 1; - create_curse(mage, &u->attribs, &ct_insectfur, (float)cast_level, + create_curse(caster, &u->attribs, &ct_insectfur, (float)cast_level, duration, effect, men); force -= u->number; - ADDMSG(&mage->faction->msgs, msg_message("heat_effect", "mage target", mage, + ADDMSG(&caster->faction->msgs, msg_message("heat_effect", "mage target", caster, u)); - if (u->faction != mage->faction) + if (u->faction != caster->faction) ADDMSG(&u->faction->msgs, msg_message("heat_effect", "mage target", - cansee(u->faction, r, mage, 0) ? mage : NULL, u)); + cansee(u->faction, r, caster, 0) ? caster : NULL, u)); i = cast_level; } /* Erstattung? */ @@ -1402,7 +1417,7 @@ static int sp_kaelteschutz(castorder * co) static int sp_sparkle(castorder * co) { unit *u; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; int duration = cast_level + 1; @@ -1419,13 +1434,13 @@ static int sp_sparkle(castorder * co) u = pa->param[0]->data.u; effect = (float)(rng_int() % 0xffffff); - create_curse(mage, &u->attribs, &ct_sparkle, (float)cast_level, + create_curse(caster, &u->attribs, &ct_sparkle, (float)cast_level, duration, effect, u->number); - ADDMSG(&mage->faction->msgs, msg_message("sparkle_effect", "mage target", - mage, u)); - if (u->faction != mage->faction) { - ADDMSG(&u->faction->msgs, msg_message("sparkle_effect", "mage target", mage, + ADDMSG(&caster->faction->msgs, msg_message("sparkle_effect", "mage target", + caster, u)); + if (u->faction != caster->faction) { + ADDMSG(&u->faction->msgs, msg_message("sparkle_effect", "mage target", caster, u)); } @@ -1464,7 +1479,7 @@ static int sp_create_irongolem(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; int number = lovar(force * 8 * RESOURCE_QUANTITY); @@ -1480,11 +1495,11 @@ static int sp_create_irongolem(castorder * co) } if (r->terrain == newterrain(T_SWAMP)) { - cmistake(mage, co->order, 188, MSG_MAGIC); + cmistake(caster, co->order, 188, MSG_MAGIC); return 0; } - u2 = create_unit(r, mage->faction, number, golem_rc, 0, NULL, mage); + u2 = create_unit(r, caster->faction, number, golem_rc, 0, NULL, caster); set_level(u2, SK_ARMORER, 1); set_level(u2, SK_WEAPONSMITH, 1); @@ -1494,10 +1509,10 @@ static int sp_create_irongolem(castorder * co) a->data.ca[1] = IRONGOLEM_CRUMBLE; a_add(&u2->attribs, a); - ADDMSG(&mage->faction->msgs, + ADDMSG(&caster->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + caster->region, co->order, caster, number, + LOC(caster->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -1534,7 +1549,7 @@ static int sp_create_stonegolem(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; int number = lovar(co->force * 5 * RESOURCE_QUANTITY); static int cache; @@ -1547,12 +1562,12 @@ static int sp_create_stonegolem(castorder * co) number = 1; if (r->terrain == newterrain(T_SWAMP)) { - cmistake(mage, co->order, 188, MSG_MAGIC); + cmistake(caster, co->order, 188, MSG_MAGIC); return 0; } u2 = - create_unit(r, mage->faction, number, golem_rc, 0, NULL, mage); + create_unit(r, caster->faction, number, golem_rc, 0, NULL, caster); set_level(u2, SK_ROAD_BUILDING, 1); set_level(u2, SK_BUILDING, 1); @@ -1561,10 +1576,10 @@ static int sp_create_stonegolem(castorder * co) a->data.ca[1] = STONEGOLEM_CRUMBLE; a_add(&u2->attribs, a); - ADDMSG(&mage->faction->msgs, + ADDMSG(&caster->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + caster->region, co->order, caster, number, + LOC(caster->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -1602,14 +1617,14 @@ static int sp_great_drought(castorder * co) unit *u; bool terraform = false; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = 2; double effect; if (fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 189, MSG_MAGIC); + cmistake(caster, co->order, 189, MSG_MAGIC); /* TODO: vielleicht einen netten Patzer hier? */ return 0; } @@ -1623,7 +1638,7 @@ static int sp_great_drought(castorder * co) /* Arbeitslohn = 1/4 */ effect = 4.0; /* curses: higher is stronger */ - create_curse(mage, &r->attribs, &ct_drought, force, duration, effect, + create_curse(caster, &r->attribs, &ct_drought, force, duration, effect, 0); /* terraforming */ @@ -1686,14 +1701,14 @@ static int sp_great_drought(castorder * co) else { mtype = "drought_effect_3"; } - msg = msg_message(mtype, "mage region", mage, r); + msg = msg_message(mtype, "mage region", caster, r); add_message(&r->msgs, msg); msg_release(msg); } else { /* possible that all units here get killed so better to inform with a global * message */ - message *msg = msg_message("drought_effect_4", "mage region", mage, r); + message *msg = msg_message("drought_effect_4", "mage region", caster, r); for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); for (u = r->units; u; u = u->next) { @@ -1702,8 +1717,8 @@ static int sp_great_drought(castorder * co) add_message(&u->faction->msgs, msg); } } - if (!fval(mage->faction, FFL_SELECT)) { - add_message(&mage->faction->msgs, msg); + if (!fval(caster->faction, FFL_SELECT)) { + add_message(&caster->faction->msgs, msg); } msg_release(msg); } @@ -1729,7 +1744,7 @@ static int sp_great_drought(castorder * co) static int sp_treewalkenter(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); spellparameter *pa = co->par; double power = co->force; int cast_level = co->level; @@ -1739,19 +1754,19 @@ static int sp_treewalkenter(castorder * co) int erfolg = 0; if (getplane(r) != 0) { - cmistake(mage, co->order, 190, MSG_MAGIC); + cmistake(caster, co->order, 190, MSG_MAGIC); return 0; } if (!r_isforest(r)) { - cmistake(mage, co->order, 191, MSG_MAGIC); + cmistake(caster, co->order, 191, MSG_MAGIC); return 0; } rt = r_standard_to_astral(r); if (rt == NULL || is_cursed(rt->attribs, &ct_astralblock) || fval(rt->terrain, FORBIDDEN_REGION)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralblock", "")); return 0; } @@ -1767,8 +1782,8 @@ static int sp_treewalkenter(castorder * co) continue; } - if (!ucontact(u, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + if (!ucontact(u, caster)) { + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "feedback_no_contact", "target", u)); } else { @@ -1777,13 +1792,13 @@ static int sp_treewalkenter(castorder * co) unit *u2; if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); + cmistake(caster, co->order, 231, MSG_MAGIC); continue; } w = weight(u); if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "fail_tooheavy", "target", u)); continue; } @@ -1855,18 +1870,18 @@ static int sp_treewalkexit(castorder * co) int n; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); double power = co->force; spellparameter *pa = co->par; int cast_level = co->level; if (!is_astral(r)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralonly", "")); return 0; } if (is_cursed(r->attribs, &ct_astralblock)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralblock", "")); return 0; } @@ -1874,7 +1889,7 @@ static int sp_treewalkexit(castorder * co) remaining_cap = (int)(power * 500); if (pa->param[0]->typ != SPP_REGION) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -1898,12 +1913,12 @@ static int sp_treewalkexit(castorder * co) free_regionlist(rl); if (!rt) { - cmistake(mage, co->order, 195, MSG_MAGIC); + cmistake(caster, co->order, 195, MSG_MAGIC); return 0; } if (!r_isforest(rt)) { - cmistake(mage, co->order, 196, MSG_MAGIC); + cmistake(caster, co->order, 196, MSG_MAGIC); return 0; } @@ -1915,17 +1930,17 @@ static int sp_treewalkexit(castorder * co) u = pa->param[n]->data.u; - if (!ucontact(u, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + if (!ucontact(u, caster)) { + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "feedback_no_contact", "target", u)); } else { int w = weight(u); if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); + cmistake(caster, co->order, 231, MSG_MAGIC); } else if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "fail_tooheavy", "target", u)); } else { @@ -1991,14 +2006,14 @@ static int sp_treewalkexit(castorder * co) static int sp_holyground(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; - message *msg = msg_message("sp_holyground_effect", "mage region", mage, r); - report_spell(mage, r, msg); + message *msg = msg_message("sp_holyground_effect", "mage region", caster, r); + report_spell(caster, r, msg); msg_release(msg); - create_curse(mage, &r->attribs, &ct_holyground, power * power, 1, zero_effect, 0); + create_curse(caster, &r->attribs, &ct_holyground, power * power, 1, zero_effect, 0); a_removeall(&r->attribs, &at_deathcount); @@ -2023,38 +2038,38 @@ static int sp_homestone(castorder * co) unit *u; curse *c; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; double effect; message *msg; - if (!mage->building || !is_building_type(mage->building->type, "castle")) { - cmistake(mage, co->order, 197, MSG_MAGIC); + if (!caster->building || !is_building_type(caster->building->type, "castle")) { + cmistake(caster, co->order, 197, MSG_MAGIC); return 0; } - c = create_curse(mage, &mage->building->attribs, &ct_magicwalls, + c = create_curse(caster, &caster->building->attribs, &ct_magicwalls, force * force, 1, zero_effect, 0); if (c == NULL) { - cmistake(mage, co->order, 206, MSG_MAGIC); + cmistake(caster, co->order, 206, MSG_MAGIC); return 0; } /* Magieresistenz der Burg erhoeht sich um 50% */ effect = 50.0F; - c = create_curse(mage, &mage->building->attribs, + c = create_curse(caster, &caster->building->attribs, &ct_magicresistance, force * force, 1, effect, 0); c_setflag(c, CURSE_NOAGE); /* melden, 1x pro Partei in der Burg */ for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - msg = msg_message("homestone_effect", "mage building", mage, mage->building); + msg = msg_message("homestone_effect", "mage building", caster, caster->building); for (u = r->units; u; u = u->next) { if (!fval(u->faction, FFL_SELECT)) { fset(u->faction, FFL_SELECT); - if (u->building == mage->building) { + if (u->building == caster->building) { r_addmessage(r, u->faction, msg); } } @@ -2081,21 +2096,21 @@ static int sp_drought(castorder * co) { curse *c; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = (int)power + 1; message *msg; if (fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 189, MSG_MAGIC); + cmistake(caster, co->order, 189, MSG_MAGIC); /* TODO: vielleicht einen netten Patzer hier? */ return 0; } /* melden, 1x pro Partei */ - msg = msg_message("sp_drought_effect", "mage region", mage, r); - report_spell(mage, r, msg); + msg = msg_message("sp_drought_effect", "mage region", caster, r); + report_spell(caster, r, msg); msg_release(msg); /* Wenn schon Duerre herrscht, dann setzen wir nur den Power-Level @@ -2115,7 +2130,7 @@ static int sp_drought(castorder * co) rsettrees(r, 0, rtrees(r, 0) / 2); rsethorses(r, rhorses(r) / 2); - create_curse(mage, &r->attribs, &ct_drought, power, duration, effect, + create_curse(caster, &r->attribs, &ct_drought, power, duration, effect, 0); } return cast_level; @@ -2144,18 +2159,18 @@ static int sp_ironkeeper(castorder * co) { unit *keeper; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; message *msg; if (r->terrain != newterrain(T_MOUNTAIN) && r->terrain != newterrain(T_GLACIER)) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } keeper = - create_unit(r, mage->faction, 1, get_race(RC_IRONKEEPER), 0, NULL, mage); + create_unit(r, caster->faction, 1, get_race(RC_IRONKEEPER), 0, NULL, caster); /*keeper->age = cast_level + 2; */ unit_setstatus(keeper, ST_AVOID); /* kaempft nicht */ @@ -2172,7 +2187,7 @@ static int sp_ironkeeper(castorder * co) tkill)); } - msg = msg_message("summon_effect", "mage amount race", mage, 1, u_race(keeper)); + msg = msg_message("summon_effect", "mage amount race", caster, 1, u_race(keeper)); r_addmessage(r, NULL, msg); msg_release(msg); @@ -2203,14 +2218,14 @@ static int sp_stormwinds(castorder * co) unit *u; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); double power = co->force; spellparameter *pa = co->par; int n, force = (int)power; message *m = NULL; /* melden vorbereiten */ - freset(mage->faction, FFL_SELECT); + freset(caster->faction, FFL_SELECT); for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); @@ -2226,18 +2241,18 @@ static int sp_stormwinds(castorder * co) /* mit C_SHIP_NODRIFT haben wir kein Problem */ if (is_cursed(sh->attribs, &ct_flyingship)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_spell_on_flying_ship", "ship", sh)) continue; } if (is_cursed(sh->attribs, &ct_shipspeedup)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_spell_on_ship_already", "ship", sh)) continue; } /* Duration = 1, nur diese Runde */ - create_curse(mage, &sh->attribs, &ct_stormwind, power, 1, + create_curse(caster, &sh->attribs, &ct_stormwind, power, 1, zero_effect, 0); /* Da der Spruch nur diese Runde wirkt wird er nie im Report * erscheinen */ @@ -2253,17 +2268,17 @@ static int sp_stormwinds(castorder * co) } } if (erfolg < pa->length) { - ADDMSG(&mage->faction->msgs, msg_message("stormwinds_reduced", - "unit ships maxships", mage, erfolg, pa->length)); + ADDMSG(&caster->faction->msgs, msg_message("stormwinds_reduced", + "unit ships maxships", caster, erfolg, pa->length)); } /* melden, 1x pro Partei auf Schiff und fuer den Magier */ - fset(mage->faction, FFL_SELECT); + fset(caster->faction, FFL_SELECT); for (u = r->units; u; u = u->next) { if (fval(u->faction, FFL_SELECT)) { freset(u->faction, FFL_SELECT); if (erfolg > 0) { if (!m) { - m = msg_message("stormwinds_effect", "unit", mage); + m = msg_message("stormwinds_effect", "unit", caster); } r_addmessage(r, u->faction, m); } @@ -2290,7 +2305,7 @@ static int sp_stormwinds(castorder * co) static int sp_earthquake(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; message *msg; building **blist = &r->buildings; @@ -2300,7 +2315,7 @@ static int sp_earthquake(castorder * co) if (burg->size != 0 && !is_cursed(burg->attribs, &ct_magicwalls)) { /* Magieresistenz */ - if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) { + if (!target_resists_magic(caster, burg, TYP_BUILDING, 0)) { int kaputt = burg->size / 4; if (kaputt > 10 * cast_level) kaputt = 10 * cast_level; if (kaputt < 1) kaputt = 1; @@ -2316,7 +2331,7 @@ static int sp_earthquake(castorder * co) } /* melden, 1x pro Partei */ - msg = msg_message("earthquake_effect", "mage region", mage, r); + msg = msg_message("earthquake_effect", "mage region", caster, r); r_addmessage(r, NULL, msg); msg_release(msg); return cast_level; @@ -2325,13 +2340,12 @@ static int sp_earthquake(castorder * co) /* ------------------------------------------------------------- */ /* CHAOS / M_DRAIG / Draig */ /* ------------------------------------------------------------- */ -void patzer_peasantmob(const castorder * co) +static void patzer_peasantmob(const castorder * co) { unit *u; attrib *a; region *r; - unit *mage = co->magician.u; - + unit *mage = co_get_magician(co); r = mage->region->land ? mage->region : co_get_region(co); if (r->land) { @@ -2396,7 +2410,7 @@ static int sp_forest_fire(castorder * co) region *nr; direction_t i; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double probability; double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ @@ -2406,7 +2420,7 @@ static int sp_forest_fire(castorder * co) int destroyed = (int)(rtrees(r, 2) * percentage); if (destroyed < 1) { - cmistake(mage, co->order, 198, MSG_MAGIC); + cmistake(caster, co->order, 198, MSG_MAGIC); return 0; } @@ -2418,10 +2432,10 @@ static int sp_forest_fire(castorder * co) for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); msg = - msg_message("forestfire_effect", "mage region amount", mage, r, + msg_message("forestfire_effect", "mage region amount", caster, r, destroyed + vernichtet_schoesslinge); r_addmessage(r, NULL, msg); - add_message(&mage->faction->msgs, msg); + add_message(&caster->faction->msgs, msg); msg_release(msg); for (i = 0; i < MAXDIRECTIONS; i++) { @@ -2448,7 +2462,7 @@ static int sp_forest_fire(castorder * co) r, nr, destroyed + vernichtet_schoesslinge); add_message(&r->msgs, m); - add_message(&mage->faction->msgs, m); + add_message(&caster->faction->msgs, m); msg_release(m); rsettrees(nr, 2, rtrees(nr, 2) - destroyed); @@ -2480,7 +2494,7 @@ static int sp_fumblecurse(castorder * co) { unit *target; int duration; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; double effect; @@ -2501,10 +2515,10 @@ static int sp_fumblecurse(castorder * co) ++duration; effect = force / 2; - c = create_curse(mage, &target->attribs, &ct_fumble, + c = create_curse(caster, &target->attribs, &ct_fumble, force, duration, effect, 0); if (c == NULL) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -2514,9 +2528,9 @@ static int sp_fumblecurse(castorder * co) return cast_level; } -void patzer_fumblecurse(const castorder * co) +static void patzer_fumblecurse(const castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (cast_level / 2) + 1; @@ -2554,7 +2568,7 @@ void patzer_fumblecurse(const castorder * co) static int sp_summondragon(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); unit *u; int cast_level = co->level; double power = co->force; @@ -2568,7 +2582,7 @@ static int sp_summondragon(castorder * co) if (r->terrain != newterrain(T_SWAMP) && r->terrain != newterrain(T_DESERT) && r->terrain != newterrain(T_GLACIER)) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -2615,8 +2629,8 @@ static int sp_summondragon(castorder * co) } } - ADDMSG(&mage->faction->msgs, msg_message("summondragon", - "unit region command target", mage, mage->region, co->order, r)); + ADDMSG(&caster->faction->msgs, msg_message("summondragon", + "unit region command target", caster, caster->region, co->order, r)); free_regionlist(rl); return cast_level; @@ -2627,24 +2641,24 @@ static int sp_firewall(castorder * co) connection *b; wall_data *fd; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; direction_t dir; region *r2; - dir = get_direction(pa->param[0]->data.xs, mage->faction->locale); + dir = get_direction(pa->param[0]->data.xs, caster->faction->locale); if (dir < MAXDIRECTIONS && dir != NODIRECTION) { r2 = rconnect(r, dir); } else { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } if (!r2 || r2 == r) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -2658,7 +2672,7 @@ static int sp_firewall(castorder * co) b = new_border(&bt_firewall, r, r2); fd = (wall_data *)b->data.v; fd->force = (int)(force / 2 + 0.5); - fd->mage = mage; + fd->mage = caster; fd->active = false; fd->countdown = cast_level + 1; } @@ -2671,9 +2685,9 @@ static int sp_firewall(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("firewall_effect", "mage region", mage, r); + message *seen = msg_message("firewall_effect", "mage region", caster, r); message *unseen = msg_message("firewall_effect", "mage region", (unit *)NULL, r); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -2718,7 +2732,7 @@ static const race *unholy_race(const race *rc) { static int sp_unholypower(castorder * co) { region * r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; int i; @@ -2739,7 +2753,7 @@ static int sp_unholypower(castorder * co) target_race = unholy_race(u_race(u)); if (!target_race) { - cmistake(mage, co->order, 284, MSG_MAGIC); + cmistake(caster, co->order, 284, MSG_MAGIC); continue; } /* Untote heilen nicht, darum den neuen Untoten maximale hp geben @@ -2752,7 +2766,7 @@ static int sp_unholypower(castorder * co) u_setrace(u, target_race); u->hp = unit_max_hp(u) * u->number - wounds; ADDMSG(&r->msgs, msg_message("unholypower_effect", - "mage target race", mage, u, target_race)); + "mage target race", caster, u, target_race)); } else { unit *un; @@ -2763,7 +2777,7 @@ static int sp_unholypower(castorder * co) * waere es, eine solche Konstruktion irgendwie zu kapseln. */ if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER) || is_cursed(u->attribs, &ct_slavery)) { - cmistake(mage, co->order, 74, MSG_MAGIC); + cmistake(caster, co->order, 74, MSG_MAGIC); continue; } /* Verletzungsanteil der transferierten Personen berechnen */ @@ -2773,7 +2787,7 @@ static int sp_unholypower(castorder * co) transfermen(u, un, n); un->hp = unit_max_hp(un) * n - wounds; ADDMSG(&r->msgs, msg_message("unholypower_limitedeffect", - "mage target race amount", mage, u, target_race, n)); + "mage target race amount", caster, u, target_race, n)); n = 0; } } @@ -2900,7 +2914,7 @@ static int dc_read_compat(variant *var, void *target, gamedata *data) static int sp_deathcloud(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); attrib *a = r->attribs; unit *u; @@ -2908,7 +2922,7 @@ static int sp_deathcloud(castorder * co) if (a->type == &at_curse) { curse *c = a->data.v; if (c->type == &ct_deathcloud) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } a = a->next; @@ -2917,7 +2931,7 @@ static int sp_deathcloud(castorder * co) a = a->nexttype; } - mk_deathcloud(mage, r, co->force, co->level); + mk_deathcloud(caster, r, co->force, co->level); /* melden, 1x pro Partei */ for (u = r->units; u; u = u->next) @@ -2926,13 +2940,13 @@ static int sp_deathcloud(castorder * co) if (!fval(u->faction, FFL_SELECT)) { fset(u->faction, FFL_SELECT); ADDMSG(&u->faction->msgs, msg_message("deathcloud_effect", - "mage region", cansee(u->faction, r, mage, 0) ? mage : NULL, r)); + "mage region", cansee(u->faction, r, caster, 0) ? caster : NULL, r)); } } - if (!fval(mage->faction, FFL_SELECT)) { - ADDMSG(&mage->faction->msgs, msg_message("deathcloud_effect", - "mage region", mage, r)); + if (!fval(caster->faction, FFL_SELECT)) { + ADDMSG(&caster->faction->msgs, msg_message("deathcloud_effect", + "mage region", caster, r)); } return co->level; @@ -2940,7 +2954,7 @@ static int sp_deathcloud(castorder * co) static void patzer_deathcloud(const castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int hp = (mage->hp - 2); change_hitpoints(mage, -(rng_int() % hp)); @@ -2964,13 +2978,13 @@ static void patzer_deathcloud(const castorder * co) static int sp_plague(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; plagues(r); - ADDMSG(&mage->faction->msgs, msg_message("plague_spell", - "region mage", r, mage)); + ADDMSG(&caster->faction->msgs, msg_message("plague_spell", + "region mage", r, caster)); return cast_level; } @@ -2993,22 +3007,22 @@ static int sp_plague(castorder * co) static int sp_summonshadow(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; unit *u; int val, number = (int)(force * force); - u = create_unit(r, mage->faction, number, get_race(RC_SHADOW), 0, NULL, mage); + u = create_unit(r, caster->faction, number, get_race(RC_SHADOW), 0, NULL, caster); /* Bekommen Tarnung = (Magie+Tarnung)/2 und Wahrnehmung 1. */ - val = get_level(mage, SK_MAGIC) + get_level(mage, SK_STEALTH); + val = get_level(caster, SK_MAGIC) + get_level(caster, SK_STEALTH); set_level(u, SK_STEALTH, val); set_level(u, SK_PERCEPTION, 1); - ADDMSG(&mage->faction->msgs, msg_message("summonshadow_effect", - "mage number", mage, number)); + ADDMSG(&caster->faction->msgs, msg_message("summonshadow_effect", + "mage number", caster, number)); return cast_level; } @@ -3034,20 +3048,20 @@ static int sp_summonshadowlords(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; int amount = (int)(force * force); - u = create_unit(r, mage->faction, amount, get_race(RC_SHADOWLORD), 0, - NULL, mage); + u = create_unit(r, caster->faction, amount, get_race(RC_SHADOWLORD), 0, + NULL, caster); /* Bekommen Tarnung = Magie und Wahrnehmung 5. */ - set_level(u, SK_STEALTH, get_level(mage, SK_MAGIC)); + set_level(u, SK_STEALTH, get_level(caster, SK_MAGIC)); set_level(u, SK_PERCEPTION, 5); - ADDMSG(&mage->faction->msgs, msg_message("summon_effect", "mage amount race", - mage, amount, u_race(u))); + ADDMSG(&caster->faction->msgs, msg_message("summon_effect", "mage amount race", + caster, amount, u_race(u))); return cast_level; } @@ -3067,12 +3081,12 @@ static int sp_chaossuction(castorder * co) { region *rt; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; if (rplane(r)) { /* Der Zauber funktioniert nur in der materiellen Welt. */ - cmistake(mage, co->order, 190, MSG_MAGIC); + cmistake(caster, co->order, 190, MSG_MAGIC); return 0; } @@ -3080,11 +3094,11 @@ static int sp_chaossuction(castorder * co) if (rt == NULL || fval(rt->terrain, FORBIDDEN_REGION)) { /* Hier gibt es keine Verbindung zur astralen Welt. */ - cmistake(mage, co->order, 216, MSG_MAGIC); + cmistake(caster, co->order, 216, MSG_MAGIC); return 0; } else if (is_cursed(rt->attribs, &ct_astralblock)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralblock", "")); return 0; } @@ -3094,7 +3108,7 @@ static int sp_chaossuction(castorder * co) create_special_direction(rt, r, 2, "vortex_desc", "vortex", false); new_border(&bt_chaosgate, r, rt); - add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", mage)); + add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", caster)); add_message(&rt->msgs, msg_message("chaosgate_effect_2", "")); return cast_level; } @@ -3123,30 +3137,30 @@ static int sp_chaossuction(castorder * co) static int sp_magicboost(castorder * co) { curse *c; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; double effect; trigger *tsummon; /* fehler, wenn schon ein boost */ - if (is_cursed(mage->attribs, &ct_magicboost)) { - report_failure(mage, co->order); + if (is_cursed(caster->attribs, &ct_magicboost)) { + report_failure(caster, co->order); return 0; } effect = 6; - create_curse(mage, &mage->attribs, &ct_magicboost, power, 10, effect, 1); + create_curse(caster, &caster->attribs, &ct_magicboost, power, 10, effect, 1); /* one aura boost with 200% aura now: */ effect = 200; - c = create_curse(mage, &mage->attribs, &ct_auraboost, power, 4, effect, 1); + c = create_curse(caster, &caster->attribs, &ct_auraboost, power, 4, effect, 1); /* and one aura boost with 50% aura in 5 weeks: */ - tsummon = trigger_createcurse(mage, mage, &ct_auraboost, power, 6, 50, 1); - add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon)); + tsummon = trigger_createcurse(caster, caster, &ct_auraboost, power, 6, 50, 1); + add_trigger(&caster->attribs, "timer", trigger_timeout(5, tsummon)); - ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect", - "unit region command", c->magician, mage->region, co->order)); + ADDMSG(&caster->faction->msgs, msg_message("magicboost_effect", + "unit region command", c->magician, caster->region, co->order)); return cast_level; } @@ -3172,14 +3186,14 @@ static int sp_magicboost(castorder * co) */ static int sp_bloodsacrifice(castorder * co) { - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int cast_level = co->level; int aura; - int skill = effskill(mage, SK_MAGIC, 0); + int skill = effskill(caster, SK_MAGIC, 0); int hp = (int)(co->force * 8); if (hp <= 0) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -3200,17 +3214,17 @@ static int sp_bloodsacrifice(castorder * co) } if (aura <= 0) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } /* sicherheitshalber gibs hier einen HP gratis. sonst schaffen es * garantiert ne ganze reihe von leuten ihren Magier damit umzubringen */ - mage->hp++; - change_spellpoints(mage, aura); - ADDMSG(&mage->faction->msgs, + caster->hp++; + change_spellpoints(caster, aura); + ADDMSG(&caster->faction->msgs, msg_message("sp_bloodsacrifice_effect", - "unit region command amount", mage, mage->region, co->order, aura)); + "unit region command amount", caster, caster->region, co->order, aura)); return cast_level; } @@ -3249,7 +3263,7 @@ static int sp_summonundead(castorder * co) int undead, dc; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; int force = (int)(co->force * 10); const race *race = get_race(RC_SKELETON); @@ -3306,7 +3320,7 @@ static int sp_auraleak(castorder * co) double lost; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; message *msg; @@ -3349,7 +3363,7 @@ static int sp_analysesong_obj(castorder * co) { int obj; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3398,7 +3412,7 @@ static int sp_analysesong_obj(castorder * co) static int sp_analysesong_unit(castorder * co) { unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3483,7 +3497,7 @@ static int sp_charmingsong(castorder * co) unit *target; int duration; skill_t i; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3572,7 +3586,7 @@ static int sp_charmingsong(castorder * co) static int sp_song_resistmagic(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3601,7 +3615,7 @@ static int sp_song_resistmagic(castorder * co) static int sp_song_susceptmagic(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3630,7 +3644,7 @@ static int sp_rallypeasantmob(castorder * co) unit *u, *un; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; message *msg; curse *c; @@ -3683,7 +3697,7 @@ static int sp_raisepeasantmob(castorder * co) int n; int anteil; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int rp, cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3739,7 +3753,7 @@ static int sp_migranten(castorder * co) { unit *target; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; @@ -3807,7 +3821,7 @@ static int sp_song_of_peace(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = 2 + lovar(force / 2); @@ -3856,7 +3870,7 @@ static int sp_generous(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3914,7 +3928,7 @@ static int sp_recruit(castorder * co) region *r = co_get_region(co); int num, maxp = rpeasants(r); double n; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; faction *f = mage->faction; @@ -3969,7 +3983,7 @@ static int sp_bigrecruit(castorder * co) unit *u; region *r = co_get_region(co); int n, maxp = rpeasants(r); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; faction *f = mage->faction; @@ -4024,7 +4038,7 @@ static int sp_pump(castorder * co) unit *u, *target; region *rt; bool see = false; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; @@ -4085,7 +4099,7 @@ static int sp_seduce(castorder * co) const resource_type *rsilver = get_resourcetype(R_SILVER); unit *target; item **itmp, *items = NULL; - unit *u, *mage = co->magician.u; + unit *u, *caster = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; @@ -4098,15 +4112,15 @@ static int sp_seduce(castorder * co) target = pa->param[0]->data.u; /* Zieleinheit */ if (fval(u_race(target), RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_noundead", "")); return 0; } - u = mage; - if (mage->region != target->region) { + u = caster; + if (caster->region != target->region) { for (u = target->region->units; u; u = u->next) { - if (u->faction == mage->faction) { + if (u->faction == caster->faction) { break; } } @@ -4144,7 +4158,7 @@ static int sp_seduce(castorder * co) if (items) { if (u) { - ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items", + ADDMSG(&caster->faction->msgs, msg_message("seduce_effect_0", "mage unit items", u, target, items)); i_freeall(&items); } @@ -4174,7 +4188,7 @@ static int sp_calm_monster(castorder * co) { curse *c; unit *target; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; @@ -4188,21 +4202,21 @@ static int sp_calm_monster(castorder * co) target = pa->param[0]->data.u; /* Zieleinheit */ if (fval(u_race(target), RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_noundead", "")); return 0; } - effect = mage->faction->uid; - c = create_curse(mage, &target->attribs, &ct_calmmonster, force, + effect = caster->faction->uid; + c = create_curse(caster, &target->attribs, &ct_calmmonster, force, (int)force, effect, 0); if (c == NULL) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } - msg = msg_message("calm_effect", "mage unit", mage, target); - r_addmessage(mage->region, mage->faction, msg); + msg = msg_message("calm_effect", "mage unit", caster, target); + r_addmessage(caster->region, caster->faction, msg); msg_release(msg); return cast_level; } @@ -4226,13 +4240,13 @@ static int sp_headache(castorder * co) skill *smax = NULL; int i; unit *target; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; message *msg; /* Macht alle nachfolgenden Zauber doppelt so teuer */ - countspells(mage, 1); + countspells(caster, 1); target = pa->param[0]->data.u; /* Zieleinheit */ @@ -4256,8 +4270,8 @@ static int sp_headache(castorder * co) } set_order(&target->thisorder, NULL); - msg = msg_message("hangover_effect_0", "mage unit", mage, target); - r_addmessage(mage->region, mage->faction, msg); + msg = msg_message("hangover_effect_0", "mage unit", caster, target); + r_addmessage(caster->region, caster->faction, msg); msg_release(msg); msg = msg_message("hangover_effect_1", "unit", target); @@ -4285,13 +4299,13 @@ static int sp_raisepeasants(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); int rp = rpeasants(r), cast_level = co->level; double power = co->force; message *msg; if (rp == 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_nopeasants", "")); return 0; } @@ -4300,8 +4314,8 @@ static int sp_raisepeasants(castorder * co) rsetpeasants(r, rp - bauern); u2 = - create_unit(r, mage->faction, bauern, get_race(RC_PEASANT), 0, - LOC(mage->faction->locale, "furious_mob"), mage); + create_unit(r, caster->faction, bauern, get_race(RC_PEASANT), 0, + LOC(caster->faction->locale, "furious_mob"), caster); fset(u2, UFL_LOCKED); if (rule_stealth_anon()) { @@ -4314,11 +4328,11 @@ static int sp_raisepeasants(castorder * co) a_add(&u2->attribs, a); msg = - msg_message("sp_raisepeasants_effect", "mage region amount", mage, r, + msg_message("sp_raisepeasants_effect", "mage region amount", caster, r, u2->number); r_addmessage(r, NULL, msg); - if (mage->region != r) { - add_message(&mage->faction->msgs, msg); + if (caster->region != r) { + add_message(&caster->faction->msgs, msg); } msg_release(msg); @@ -4339,7 +4353,7 @@ static int sp_raisepeasants(castorder * co) static int sp_depression(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -4373,7 +4387,7 @@ static int sp_depression(castorder * co) int sp_puttorest(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int dead = deathcount(r); int laid_to_rest = dice((int)(co->force * 2), 100); message *seen = msg_message("puttorest", "mage", mage); @@ -4405,7 +4419,7 @@ int sp_icastle(castorder * co) building *b; const building_type *type; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4473,7 +4487,7 @@ int sp_illusionary_shapeshift(castorder * co) { unit *u; const race *rc; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4530,7 +4544,7 @@ int sp_illusionary_shapeshift(castorder * co) int sp_analysedream(castorder * co) { unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; @@ -4552,7 +4566,7 @@ int sp_analysedream(castorder * co) static int sp_gbdreams(castorder * co, int effect) { int duration; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; region *r = co_get_region(co); @@ -4624,7 +4638,7 @@ int sp_clonecopy(castorder * co) unit *clone; region *r = co_get_region(co); region *target_region = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; message *msg; char name[NAMESIZE]; @@ -4656,7 +4670,7 @@ int sp_dreamreading(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; double power = co->force; @@ -4703,7 +4717,7 @@ int sp_dreamreading(castorder * co) int sp_sweetdreams(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4753,7 +4767,7 @@ int sp_sweetdreams(castorder * co) int sp_disturbingdreams(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = 1 + (int)(power / 6); @@ -4841,7 +4855,7 @@ int sp_analysemagic(castorder * co) int sp_itemcloak(castorder * co) { unit *target; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; double power = co->force; @@ -4882,7 +4896,7 @@ int sp_resist_magic_bonus(castorder * co) unit *u; int n, m; int duration = 6; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4939,7 +4953,7 @@ int sp_enterastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5054,7 +5068,7 @@ int sp_pullastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5196,7 +5210,7 @@ int sp_leaveastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5322,7 +5336,7 @@ int sp_leaveastral(castorder * co) int sp_fetchastral(castorder * co) { int n; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = 0; spellparameter *pa = co->par; double power = co->force; @@ -5372,6 +5386,7 @@ int sp_fetchastral(castorder * co) ro = u->region; } + assert(ro); cast_level = co->level; /* at least one unit could have been teleported */ if (is_cursed(ro->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, @@ -5459,7 +5474,7 @@ int sp_showastral(castorder * co) int c = 0; region_list *rl, *rl2; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; @@ -5545,7 +5560,7 @@ int sp_viewreality(castorder * co) { region_list *rl, *rl2; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; message *m; @@ -5582,7 +5597,7 @@ int sp_disruptastral(castorder * co) region *rt; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = (int)(power / 3) + 1; @@ -5646,8 +5661,9 @@ int sp_disruptastral(castorder * co) int c = rng_int() % inhab_regions; /* Zufaellige Zielregion suchen */ - while (c-- != 0) + while (c-- != 0) { trl2 = trl2->next; + } tr = trl2->data; if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { @@ -5689,7 +5705,7 @@ static int sp_eternizewall(castorder * co) curse *c; building *b; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5732,6 +5748,14 @@ static int sp_eternizewall(castorder * co) return cast_level; } +static magic_t get_magic_type(const struct unit *u) { + sc_mage *mage = get_mage(u); + if (mage) { + return mage->magietyp; + } + return M_GRAY; +} + /* ------------------------------------------------------------- */ /* Name: Opfere Kraft * Stufe: 15 @@ -5754,7 +5778,8 @@ int sp_permtransfer(castorder * co) { int aura, i; unit *tu; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; const spell *sp = co->sp; @@ -5775,27 +5800,26 @@ int sp_permtransfer(castorder * co) if (!is_mage(tu)) { /* sprintf(buf, "%s in %s: 'ZAUBER %s': Einheit ist kein Magier." , unitname(mage), regionname(mage->region, mage->faction),sa->strings[0]); */ - cmistake(mage, co->order, 214, MSG_MAGIC); + cmistake(caster, co->order, 214, MSG_MAGIC); return 0; } - i = get_spellpoints(mage) - spellcost(mage, sp); + i = get_spellpoints(mage) - auracost(mage, sp); if (aura > i) aura = i; change_maxspellpoints(mage, -aura); change_spellpoints(mage, -aura); - if (get_mage_depr(tu)->magietyp == get_mage_depr(mage)->magietyp) { + if (get_magic_type(tu) == get_magic_type(mage)) { change_maxspellpoints(tu, aura / 2); } else { change_maxspellpoints(tu, aura / 3); } - msg = - msg_message("sp_permtransfer_effect", "mage target amount", mage, tu, aura); - add_message(&mage->faction->msgs, msg); - if (tu->faction != mage->faction) { + msg = msg_message("sp_permtransfer_effect", "mage target amount", mage, tu, aura); + add_message(&caster->faction->msgs, msg); + if (tu->faction != caster->faction) { add_message(&tu->faction->msgs, msg); } msg_release(msg); @@ -5813,7 +5837,7 @@ int sp_movecastle(castorder * co) region *target_region; unit *u, *unext; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; message *msg; @@ -5896,7 +5920,8 @@ int sp_stealaura(castorder * co) { int taura; unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5909,8 +5934,8 @@ int sp_stealaura(castorder * co) u = pa->param[0]->data.u; if (!get_mage_depr(u)) { - ADDMSG(&mage->faction->msgs, msg_message("stealaura_fail", "unit target", - mage, u)); + ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target", + caster, u)); ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u)); return 0; } @@ -5918,20 +5943,20 @@ int sp_stealaura(castorder * co) taura = (get_mage_depr(u)->spellpoints * (rng_int() % (int)(3 * power) + 1)) / 100; if (taura > 0) { - get_mage_depr(u)->spellpoints -= taura; - get_mage_depr(mage)->spellpoints += taura; + change_spellpoints(u, -taura); + change_spellpoints(mage, taura); /* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), taura); */ - ADDMSG(&mage->faction->msgs, msg_message("stealaura_success", - "mage target aura", mage, u, taura)); + ADDMSG(&caster->faction->msgs, msg_message("stealaura_success", + "mage target aura", caster, u, taura)); /* sprintf(buf, "%s fuehlt seine magischen Kraefte schwinden und verliert %d " "Aura.", unitname(u), taura); */ ADDMSG(&u->faction->msgs, msg_message("stealaura_detect", "unit aura", u, taura)); } else { - ADDMSG(&mage->faction->msgs, msg_message("stealaura_fail", "unit target", - mage, u)); + ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target", + caster, u)); ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u)); } return cast_level; @@ -5966,7 +5991,7 @@ int sp_antimagiczone(castorder * co) double power; double effect; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -6023,7 +6048,7 @@ int sp_antimagiczone(castorder * co) static int sp_magicrunes(castorder * co) { int duration; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6083,7 +6108,7 @@ int sp_speed2(castorder * co) { int n, maxmen, used = 0, dur, men; unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6143,7 +6168,7 @@ int sp_break_curse(castorder * co) int obj; curse *c; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6300,7 +6325,7 @@ static int sp_babbler(castorder * co) { unit *target; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; message *msg; @@ -6347,7 +6372,7 @@ static int sp_babbler(castorder * co) static int sp_readmind(castorder * co) { unit *target; - unit *mage = co->magician.u; + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c index 2b830da2e..4dc186dc5 100644 --- a/src/spells/flyingship.c +++ b/src/spells/flyingship.c @@ -38,7 +38,7 @@ int sp_flying_ship(castorder * co) ship *sh; unit *u; region *r; - unit *mage; + unit *caster; int cast_level; double power; spellparameter *pa; @@ -47,7 +47,7 @@ int sp_flying_ship(castorder * co) assert(co); r = co_get_region(co); - mage = co->magician.u; + caster = co_get_caster(co); cast_level = co->level; power = co->force; pa = co->par; @@ -57,22 +57,22 @@ int sp_flying_ship(castorder * co) return 0; sh = pa->param[0]->data.sh; if (sh->type->construction->maxsize > 50) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_flying_ship_too_big", "ship", sh)); return 0; } /* Duration = 1, nur diese Runde */ - cno = levitate_ship(sh, mage, power, 1); + cno = levitate_ship(sh, caster, power, 1); if (cno == 0) { if (is_cursed(sh->attribs, &ct_flyingship)) { /* Auf dem Schiff befindet liegt bereits so ein Zauber. */ - cmistake(mage, co->order, 211, MSG_MAGIC); + cmistake(caster, co->order, 211, MSG_MAGIC); } else if (is_cursed(sh->attribs, &ct_shipspeedup)) { /* Es ist zu gefaehrlich, ein sturmgepeitschtes Schiff fliegen zu lassen. */ - cmistake(mage, co->order, 210, MSG_MAGIC); + cmistake(caster, co->order, 210, MSG_MAGIC); } return 0; } @@ -86,7 +86,7 @@ int sp_flying_ship(castorder * co) if (!(u->faction->flags & FFL_SELECT)) { u->faction->flags |= FFL_SELECT; if (!m) { - m = msg_message("flying_ship_result", "mage ship", mage, sh); + m = msg_message("flying_ship_result", "mage ship", caster, sh); } add_message(&u->faction->msgs, m); } diff --git a/src/study.c b/src/study.c index 5ac5ac7ff..90cc001ec 100644 --- a/src/study.c +++ b/src/study.c @@ -784,13 +784,7 @@ int study_cmd(unit * u, order * ord) show_potions(f, skill); } } - else if (sk == SK_MAGIC) { - sc_mage *mage = get_mage_depr(u); - if (!mage) { - mage = create_mage(u, u->faction->magiegebiet); - } - } - init_order_depr(NULL); + init_order(NULL, NULL); return 0; } diff --git a/src/vortex.c b/src/vortex.c index 805b407c4..c743ad857 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -51,6 +51,7 @@ void register_special_direction(struct locale *lang, const char *name) if (lang == locales) { dir_lookup *dl = malloc(sizeof(dir_lookup)); + assert(dl); dl->name = str; dl->oldname = token; dl->next = dir_name_lookup;