Merge branch 'develop' of github.com:ennorehling/eressea into develop

This commit is contained in:
Enno Rehling 2018-11-23 12:35:24 +01:00
commit 037113b35d
21 changed files with 359 additions and 324 deletions

View file

@ -132,7 +132,7 @@ function equip_unit(u, name, flags)
end end
local spells = set['spells'] local spells = set['spells']
if spells then if spells then
for name, level in ipairs(spells) do for name, level in pairs(spells) do
u:add_spell(name, level) u:add_spell(name, level)
end end
end end

View file

@ -215,12 +215,12 @@ function test_bug_2517()
uf = um.familiar uf = um.familiar
assert_not_nil(uf) assert_not_nil(uf)
assert_equal('lynx', uf.race) assert_equal('lynx', uf.race)
assert_nil(uf.magic) assert_equal('gray', uf.magic)
uf:add_order('LERNE Magie') uf:add_order('LERNE Magie')
um:clear_orders() um:clear_orders()
um:add_order('ARBEITEN') um:add_order('ARBEITEN')
process_orders() process_orders()
assert_nil(uf.magic) assert_equal('gray', uf.magic)
uf:add_order('ZAUBERE STUFE 1 Viehheilung') uf:add_order('ZAUBERE STUFE 1 Viehheilung')
process_orders() process_orders()
assert_equal(50, uf:get_item('money')) assert_equal(50, uf:get_item('money'))

View file

@ -276,8 +276,12 @@ static int tolua_unit_set_guard(lua_State * L)
static const char *unit_getmagic(const unit * u) static const char *unit_getmagic(const unit * u)
{ {
sc_mage *mage = get_mage_depr(u); struct sc_mage *mage = get_mage(u);
return mage ? magic_school[mage->magietyp] : NULL; if (mage) {
magic_t mtype = mage_get_type(mage);
return magic_school[mtype];
}
return NULL;
} }
static int tolua_unit_get_magic(lua_State * L) static int tolua_unit_get_magic(lua_State * L)
@ -289,16 +293,15 @@ static int tolua_unit_get_magic(lua_State * L)
static void unit_setmagic(unit * u, const char *type) static void unit_setmagic(unit * u, const char *type)
{ {
sc_mage *mage = get_mage(u); struct sc_mage *mage = get_mage(u);
if (mage == NULL) {
int mtype; int mtype;
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) { for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
if (strcmp(magic_school[mtype], type) == 0) if (strcmp(magic_school[mtype], type) == 0) {
break; create_mage(u, (magic_t)mtype);
}
if (mtype == MAXMAGIETYP)
return; return;
if (mage == NULL) { }
mage = create_mage(u, (magic_t)mtype); }
} }
} }
@ -521,7 +524,7 @@ static int tolua_unit_addspell(lua_State * L)
return EINVAL; return EINVAL;
} }
else { else {
unit_add_spell(u, 0, sp, level); unit_add_spell(u, sp, level);
} }
lua_pushinteger(L, err); lua_pushinteger(L, err);
@ -748,8 +751,8 @@ static int tolua_unit_get_items(lua_State * L)
static int tolua_unit_get_spells(lua_State * L) static int tolua_unit_get_spells(lua_State * L)
{ {
unit *self = (unit *) tolua_tousertype(L, 1, 0); unit *self = (unit *) tolua_tousertype(L, 1, 0);
sc_mage *mage = self ? get_mage_depr(self) : 0; struct sc_mage *mage = self ? get_mage(self) : NULL;
spellbook *sb = mage ? mage->spellbook : 0; spellbook *sb = mage_get_spellbook(mage);
selist *slist = 0; selist *slist = 0;
if (sb) { if (sb) {
selist **slist_ptr = &sb->spells; selist **slist_ptr = &sb->spells;

View file

@ -880,7 +880,7 @@ void cr_output_unit(stream *out, const faction * f,
const char *xc; const char *xc;
const char *c; const char *c;
int i; int i;
sc_mage *mage; struct sc_mage *mage;
i = ualias(u); i = ualias(u);
if (i > 0) if (i > 0)
@ -957,19 +957,23 @@ void cr_output_unit(stream *out, const faction * f,
} }
/* spells that this unit can cast */ /* spells that this unit can cast */
mage = get_mage_depr(u); mage = get_mage(u);
if (mage) { if (mage) {
int maxlevel = effskill(u, SK_MAGIC, 0); int maxlevel = effskill(u, SK_MAGIC, 0);
cr_output_spells(out, u, maxlevel); cr_output_spells(out, u, maxlevel);
for (i = 0; i != MAXCOMBATSPELLS; ++i) { for (i = 0; i != MAXCOMBATSPELLS; ++i) {
const spell *sp = mage->combatspells[i].sp; int level;
const spell *sp = mage_get_combatspell(mage, i, &level);
if (sp) { if (sp) {
const char *name = const char *name;
translate(mkname("spell", sp->sname), spell_name(sp, lang)); if (level > maxlevel) {
level = maxlevel;
}
stream_printf(out, "KAMPFZAUBER %d\n", i); stream_printf(out, "KAMPFZAUBER %d\n", i);
name = translate(mkname("spell", sp->sname), spell_name(sp, lang));
stream_printf(out, "\"%s\";name\n", name); stream_printf(out, "\"%s\";name\n", name);
stream_printf(out, "%d;level\n", mage->combatspells[i].level); stream_printf(out, "%d;level\n", level);
} }
} }
} }

View file

@ -587,14 +587,12 @@ void give_unit(unit * u, unit * u2, order * ord)
} }
} }
if (has_skill(u, SK_MAGIC)) { if (has_skill(u, SK_MAGIC)) {
sc_mage *mage;
if (count_skill(u2->faction, SK_MAGIC) + u->number > if (count_skill(u2->faction, SK_MAGIC) + u->number >
skill_limit(u2->faction, SK_MAGIC)) { skill_limit(u2->faction, SK_MAGIC)) {
cmistake(u, ord, 155, MSG_COMMERCE); cmistake(u, ord, 155, MSG_COMMERCE);
return; return;
} }
mage = get_mage_depr(u); if (u2->faction->magiegebiet != unit_get_magic(u)) {
if (!mage || u2->faction->magiegebiet != mage->magietyp) {
cmistake(u, ord, 157, MSG_COMMERCE); cmistake(u, ord, 157, MSG_COMMERCE);
return; return;
} }

View file

@ -25,7 +25,7 @@ static void test_manacrystal(CuTest *tc) {
CuAssertIntEquals(tc, -1, use_manacrystal(u, itype, 1, NULL)); CuAssertIntEquals(tc, -1, use_manacrystal(u, itype, 1, NULL));
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error295")); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error295"));
test_clear_messages(u->faction); test_clear_messages(u->faction);
create_mage(u, M_GRAY); create_mage(u, M_GWYRRD);
set_level(u, SK_MAGIC, 5); set_level(u, SK_MAGIC, 5);
CuAssertIntEquals(tc, 0, get_spellpoints(u)); CuAssertIntEquals(tc, 0, get_spellpoints(u));
CuAssertIntEquals(tc, 1, use_manacrystal(u, itype, 1, NULL)); CuAssertIntEquals(tc, 1, use_manacrystal(u, itype, 1, NULL));

View file

@ -1293,16 +1293,6 @@ ship *read_ship(gamedata *data)
return sh; 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_fam_triggers(unit *u) { static void fix_fam_triggers(unit *u) {
attrib * a = a_find(u->attribs, &at_mage); attrib * a = a_find(u->attribs, &at_mage);
attrib * am = a_find(u->attribs, &at_familiarmage); attrib * am = a_find(u->attribs, &at_familiarmage);
@ -1507,20 +1497,18 @@ int read_game(gamedata *data)
assert(f->units); assert(f->units);
for (u = f->units; u; u = u->nextF) { for (u = f->units; u; u = u->nextF) {
if (data->version < SPELL_LEVEL_VERSION) { if (data->version < SPELL_LEVEL_VERSION) {
sc_mage *mage = get_mage_depr(u); struct sc_mage *mage = get_mage(u);
if (mage) { if (mage) {
faction *f = u->faction; faction *f = u->faction;
int skl = effskill(u, SK_MAGIC, 0); int skl = effskill(u, SK_MAGIC, 0);
if (f->magiegebiet == M_GRAY) { if (f->magiegebiet == M_GRAY) {
log_error("faction %s had magic=gray, fixing (%s)", factionname(f), magic_school[mage->magietyp]); f->magiegebiet = mage_get_type(mage);
f->magiegebiet = mage->magietyp; log_error("faction %s had magic=gray, fixing (%s)",
factionname(f), magic_school[f->magiegebiet]);
} }
if (f->max_spelllevel < skl) { if (f->max_spelllevel < skl) {
f->max_spelllevel = skl; f->max_spelllevel = skl;
} }
if (mage->spellcount < 0) {
mage->spellcount = 0;
}
} }
} }
if (u->number > 0) { if (u->number > 0) {

View file

@ -117,7 +117,7 @@ enum {
MAXOPTIONS MAXOPTIONS
}; };
typedef enum { typedef enum magic_t {
M_GRAY = 0, /* Gray */ M_GRAY = 0, /* Gray */
M_ILLAUN = 1, /* Illaun */ M_ILLAUN = 1, /* Illaun */
M_TYBIED = 2, /* Tybied */ M_TYBIED = 2, /* Tybied */

View file

@ -1657,34 +1657,6 @@ void u_setrace(struct unit *u, const struct race *rc)
} }
} }
void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level)
{
sc_mage *mage = m ? m : get_mage_depr(u);
if (!mage) {
log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u));
mage = create_mage(u, u->faction ? u->faction->magiegebiet : M_GRAY);
}
if (!mage->spellbook) {
mage->spellbook = create_spellbook(0);
}
spellbook_add(mage->spellbook, sp, level);
}
struct spellbook * unit_get_spellbook(const struct unit * u)
{
sc_mage * mage = get_mage_depr(u);
if (mage) {
if (mage->spellbook) {
return mage->spellbook;
}
if (mage->magietyp != M_GRAY) {
return faction_get_spellbook(u->faction);
}
}
return NULL;
}
int effskill(const unit * u, skill_t sk, const region *r) int effskill(const unit * u, skill_t sk, const region *r)
{ {
assert(u); assert(u);

View file

@ -228,8 +228,6 @@ extern "C" {
int unit_max_hp(const struct unit *u); int unit_max_hp(const struct unit *u);
void scale_number(struct unit *u, int n); void scale_number(struct unit *u, int n);
struct spellbook * unit_get_spellbook(const struct unit * u);
void unit_add_spell(struct unit * u, struct sc_mage * m, struct spell * sp, int level);
void remove_empty_units_in_region(struct region * r); void remove_empty_units_in_region(struct region * r);
void remove_empty_units(void); void remove_empty_units(void);

View file

@ -2419,8 +2419,23 @@ int combatspell_cmd(unit * u, struct order *ord)
} }
else { else {
/* KAMPFZAUBER "<Spruchname>" setzt diesen Kampfzauber */ /* KAMPFZAUBER "<Spruchname>" setzt diesen Kampfzauber */
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */
if (!knowsspell(u->region, u, sp)) {
/* Fehler 'Spell not found' */
cmistake(u, ord, 173, MSG_MAGIC);
}
else if (!u_hasspell(u, sp)) {
/* Diesen Zauber kennt die Einheit nicht */
cmistake(u, ord, 169, MSG_MAGIC);
}
else if (!(sp->sptyp & ISCOMBATSPELL)) {
/* Diesen Kampfzauber gibt es nicht */
cmistake(u, ord, 171, MSG_MAGIC);
}
else {
set_combatspell(u, sp, ord, level); set_combatspell(u, sp, ord, level);
} }
}
return 0; return 0;
} }
@ -3169,8 +3184,8 @@ static int faction_getmages(faction * f, unit ** results, int numresults)
for (u = f->units; u; u = u->nextF) { for (u = f->units; u; u = u->nextF) {
if (u->number > 0) { if (u->number > 0) {
sc_mage *mage = get_mage_depr(u); struct sc_mage * mage = get_mage(u);
if (mage) { if (mage && mage_get_spellbook(mage)) {
int level = effskill(u, SK_MAGIC, 0); int level = effskill(u, SK_MAGIC, 0);
if (level > maxlevel) { if (level > maxlevel) {
maxlevel = level; maxlevel = level;
@ -3229,11 +3244,12 @@ static void update_spells(void)
unit *mages[MAXMAGES]; unit *mages[MAXMAGES];
int i; int i;
int maxlevel = faction_getmages(f, mages, MAXMAGES); int maxlevel = faction_getmages(f, mages, MAXMAGES);
struct spellbook *fsb;
if (maxlevel && FactionSpells()) { if (maxlevel && FactionSpells()) {
spellbook * book = get_spellbook(magic_school[f->magiegebiet]); spellbook * book = get_spellbook(magic_school[f->magiegebiet]);
if (!f->spellbook) { if (!f->spellbook) {
f->spellbook = create_spellbook(0); f->spellbook = create_spellbook(NULL);
} }
copy_spells(book, f->spellbook, maxlevel); copy_spells(book, f->spellbook, maxlevel);
if (maxlevel > f->max_spelllevel) { if (maxlevel > f->max_spelllevel) {
@ -3241,13 +3257,14 @@ static void update_spells(void)
pick_random_spells(f, maxlevel, common_spells, COMMONSPELLS); pick_random_spells(f, maxlevel, common_spells, COMMONSPELLS);
} }
} }
show_new_spells(f, maxlevel, faction_get_spellbook(f)); fsb = faction_get_spellbook(f);
show_new_spells(f, maxlevel, fsb);
for (i = 0; i != MAXMAGES && mages[i]; ++i) { for (i = 0; i != MAXMAGES && mages[i]; ++i) {
unit * u = mages[i]; unit * u = mages[i];
sc_mage *mage = get_mage_depr(u); spellbook *sb = unit_get_spellbook(u);
if (mage && mage->spellbook) { if (sb != fsb) {
int level = effskill(u, SK_MAGIC, 0); int level = effskill(u, SK_MAGIC, NULL);
show_new_spells(f, level, mage->spellbook); show_new_spells(f, level, sb);
} }
} }
} }

View file

@ -103,6 +103,78 @@ const char *magic_school[MAXMAGIETYP] = {
"common" "common"
}; };
struct combatspell {
int level;
const struct spell *sp;
};
typedef struct sc_mage {
magic_t magietyp;
int spellpoints;
int spchange;
int spellcount;
struct combatspell combatspells[MAXCOMBATSPELLS];
struct spellbook *spellbook;
} sc_mage;
int mage_get_spellpoints(const sc_mage *m)
{
return m ? m->spellpoints : 0;
}
int mage_change_spellpoints(sc_mage *m, int delta)
{
if (m) {
int val = m->spellpoints + delta;
return m->spellpoints = (val >= 0) ? val : m->spellpoints;
}
return 0;
}
magic_t mage_get_type(const sc_mage *m)
{
return m ? m->magietyp : M_GRAY;
}
const spell *mage_get_combatspell(const sc_mage *mage, int nr, int *level)
{
assert(nr < MAXCOMBATSPELLS);
if (mage) {
if (level) {
*level = mage->combatspells[nr].level;
}
return mage->combatspells[nr].sp;
}
return NULL;
}
void unit_set_magic(struct unit *u, enum magic_t mtype)
{
sc_mage *mage = get_mage(u);
if (mage) {
mage->magietyp = mtype;
}
}
magic_t unit_get_magic(const unit *u)
{
return mage_get_type(get_mage(u));
}
void unit_add_spell(unit * u, struct spell * sp, int level)
{
sc_mage *mage = get_mage(u);
if (!mage) {
log_error("adding new spell %s to a previously non-magical unit %s\n", sp->sname, unitname(u));
mage = create_mage(u, M_GRAY);
}
if (!mage->spellbook) {
mage->spellbook = create_spellbook(0);
}
spellbook_add(mage->spellbook, sp, level);
}
/** /**
** at_icastle ** at_icastle
** TODO: separate castle-appearance from illusion-effects ** TODO: separate castle-appearance from illusion-effects
@ -199,6 +271,23 @@ const building_type *icastle_type(const struct attrib *a) {
extern int dice(int count, int value); extern int dice(int count, int value);
bool FactionSpells(void)
{
static int config, rule;
if (config_changed(&config)) {
rule = config_get_int("rules.magic.factionlist", 0);
}
return rule != 0;
}
int get_spell_level_mage(const spell * sp, void * cbdata)
{
sc_mage *mage = (sc_mage *)cbdata;
spellbook *book = get_spellbook(magic_school[mage->magietyp]);
spellbook_entry *sbe = spellbook_get(book, sp);
return sbe ? sbe->level : 0;
}
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* aus dem alten System übriggebliegene Funktionen, die bei der /* aus dem alten System übriggebliegene Funktionen, die bei der
* Umwandlung von alt nach neu gebraucht werden */ * Umwandlung von alt nach neu gebraucht werden */
@ -219,23 +308,6 @@ static void free_mage(variant *var)
free(mage); free(mage);
} }
bool FactionSpells(void)
{
static int config, rule;
if (config_changed(&config)) {
rule = config_get_int("rules.magic.factionlist", 0);
}
return rule != 0;
}
int get_spell_level_mage(const spell * sp, void * cbdata)
{
sc_mage *mage = (sc_mage *)cbdata;
spellbook *book = get_spellbook(magic_school[mage->magietyp]);
spellbook_entry *sbe = spellbook_get(book, sp);
return sbe ? sbe->level : 0;
}
static int read_mage(variant *var, void *owner, struct gamedata *data) static int read_mage(variant *var, void *owner, struct gamedata *data)
{ {
storage *store = data->store; storage *store = data->store;
@ -278,7 +350,7 @@ static int read_mage(variant *var, void *owner, struct gamedata *data)
read_spellbook(&mage->spellbook, data, get_spell_level_mage, mage); read_spellbook(&mage->spellbook, data, get_spell_level_mage, mage);
} }
else { else {
read_spellbook(0, data, 0, mage); read_spellbook(NULL, data, NULL, mage);
} }
return AT_READ_OK; return AT_READ_OK;
} }
@ -312,9 +384,10 @@ attrib_type at_mage = {
ATF_UNIQUE ATF_UNIQUE
}; };
bool is_mage(const unit * u) bool is_mage(const struct unit * u)
{ {
return get_mage_depr(u) != NULL; sc_mage *m = get_mage(u);
return (m && m->magietyp != M_GRAY);
} }
sc_mage *get_mage(const unit * u) sc_mage *get_mage(const unit * u)
@ -326,12 +399,22 @@ sc_mage *get_mage(const unit * u)
return NULL; return NULL;
} }
sc_mage *get_mage_depr(const unit * u) struct spellbook * mage_get_spellbook(const struct sc_mage * mage) {
if (mage) {
return mage->spellbook;
}
return NULL;
}
struct spellbook * unit_get_spellbook(const struct unit * u)
{ {
if (has_skill(u, SK_MAGIC)) { sc_mage * mage = get_mage(u);
attrib *a = a_find(u->attribs, &at_mage); if (mage) {
if (a) { if (mage->spellbook) {
return (sc_mage *)a->data.v; return mage->spellbook;
}
if (mage->magietyp != M_GRAY) {
return faction_get_spellbook(u->faction);
} }
} }
return NULL; return NULL;
@ -436,17 +519,15 @@ int u_hasspell(const unit *u, const struct spell *sp)
int get_combatspelllevel(const unit * u, int nr) int get_combatspelllevel(const unit * u, int nr)
{ {
sc_mage *m = get_mage_depr(u); int level;
if (mage_get_combatspell(get_mage(u), nr, &level) != NULL) {
assert(nr < MAXCOMBATSPELLS); int maxlevel = effskill(u, SK_MAGIC, 0);
if (m) { if (level > maxlevel) {
int level = effskill(u, SK_MAGIC, 0); return maxlevel;
if (level < m->combatspells[nr].level) { }
return level; return level;
} }
return m->combatspells[nr].level; return 0;
}
return -1;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -454,40 +535,15 @@ int get_combatspelllevel(const unit * u, int nr)
const spell *get_combatspell(const unit * u, int nr) const spell *get_combatspell(const unit * u, int nr)
{ {
sc_mage *m; return mage_get_combatspell(get_mage(u), nr, NULL);
assert(nr < MAXCOMBATSPELLS);
m = get_mage_depr(u);
if (m) {
return m->combatspells[nr].sp;
}
return NULL;
} }
void set_combatspell(unit * u, spell * sp, struct order *ord, int level) void set_combatspell(unit * u, spell * sp, struct order *ord, int level)
{ {
sc_mage *mage = get_mage_depr(u); sc_mage *mage = get_mage(u);
int i = -1; int i = -1;
assert(mage || !"trying to set a combat spell for non-mage"); assert(mage || !"trying to set a combat spell for non-mage");
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */
if (!knowsspell(u->region, u, sp)) {
/* Fehler 'Spell not found' */
cmistake(u, ord, 173, MSG_MAGIC);
return;
}
if (!u_hasspell(u, sp)) {
/* Diesen Zauber kennt die Einheit nicht */
cmistake(u, ord, 169, MSG_MAGIC);
return;
}
if (!(sp->sptyp & ISCOMBATSPELL)) {
/* Diesen Kampfzauber gibt es nicht */
cmistake(u, ord, 171, MSG_MAGIC);
return;
}
if (sp->sptyp & PRECOMBATSPELL) if (sp->sptyp & PRECOMBATSPELL)
i = 0; i = 0;
else if (sp->sptyp & COMBATSPELL) else if (sp->sptyp & COMBATSPELL)
@ -502,13 +558,12 @@ void set_combatspell(unit * u, spell * sp, struct order *ord, int level)
void unset_combatspell(unit * u, spell * sp) void unset_combatspell(unit * u, spell * sp)
{ {
sc_mage *m;
int nr = 0; int nr = 0;
sc_mage *m = get_mage(u);
m = get_mage_depr(u); if (!m) {
if (!m)
return; return;
}
if (!sp) { if (!sp) {
int i; int i;
for (i = 0; i < MAXCOMBATSPELLS; i++) { for (i = 0; i < MAXCOMBATSPELLS; i++) {
@ -540,26 +595,15 @@ void unset_combatspell(unit * u, spell * sp)
/* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zurück */ /* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zurück */
int get_spellpoints(const unit * u) int get_spellpoints(const unit * u)
{ {
sc_mage *m; return mage_get_spellpoints(get_mage(u));
m = get_mage_depr(u);
if (!m)
return 0;
return m->spellpoints;
} }
void set_spellpoints(unit * u, int sp) void set_spellpoints(unit * u, int sp)
{ {
sc_mage *m; sc_mage *m = get_mage(u);
if (m) {
m = get_mage_depr(u);
if (!m)
return;
m->spellpoints = sp; m->spellpoints = sp;
}
return;
} }
/* /*
@ -567,23 +611,7 @@ void set_spellpoints(unit * u, int sp)
*/ */
int change_spellpoints(unit * u, int mp) int change_spellpoints(unit * u, int mp)
{ {
sc_mage *m; return mage_change_spellpoints(get_mage(u), mp);
int sp;
m = get_mage_depr(u);
if (!m) {
return 0;
}
/* verhindere negative Magiepunkte */
sp = m->spellpoints + mp;
if (sp > 0) {
m->spellpoints = sp;
}
else {
m->spellpoints = 0;
}
return sp;
} }
/* bietet die Möglichkeit, die maximale Anzahl der Magiepunkte mit /* bietet die Möglichkeit, die maximale Anzahl der Magiepunkte mit
@ -593,11 +621,8 @@ static int get_spchange(const unit * u)
{ {
sc_mage *m; sc_mage *m;
m = get_mage_depr(u); m = get_mage(u);
if (!m) return m ? m->spchange : 0;
return 0;
return m->spchange;
} }
/* ein Magier kann normalerweise maximal Stufe^2.1/1.2+1 Magiepunkte /* ein Magier kann normalerweise maximal Stufe^2.1/1.2+1 Magiepunkte
@ -645,9 +670,7 @@ int max_spellpoints(const region * r, const unit * u)
int change_maxspellpoints(unit * u, int csp) int change_maxspellpoints(unit * u, int csp)
{ {
sc_mage *m; sc_mage *m = get_mage(u);
m = get_mage_depr(u);
if (!m) { if (!m) {
return 0; return 0;
} }
@ -660,30 +683,24 @@ int change_maxspellpoints(unit * u, int csp)
*/ */
int countspells(unit * u, int step) int countspells(unit * u, int step)
{ {
sc_mage *m; sc_mage * m = get_mage(u);
if (m) {
int count; int count;
m = get_mage_depr(u);
if (!m) {
return 0;
}
if (step == 0) { if (step == 0) {
return m->spellcount; return m->spellcount;
} }
count = m->spellcount + step; count = m->spellcount + step;
m->spellcount = (count > 0) ? count : 0; m->spellcount = (count > 0) ? count : 0;
return m->spellcount; return m->spellcount;
}
int spellcount(const unit *u) {
sc_mage *m = get_mage_depr(u);
if (m) {
return m->spellcount;
} }
return 0; return 0;
} }
int spellcount(const unit *u) {
sc_mage *m = get_mage(u);
return m ? m->spellcount : 0;
}
/** /**
* Die Grundkosten pro Stufe werden um 2^count erhöht. countspells(u) * Die Grundkosten pro Stufe werden um 2^count erhöht. countspells(u)
* ist dabei die Anzahl der bereits gezauberten Sprüche * ist dabei die Anzahl der bereits gezauberten Sprüche
@ -2193,18 +2210,67 @@ void remove_familiar(unit * mage)
} }
} }
void create_newfamiliar(unit * mage, unit * fam) static void equip_familiar(unit *fam) {
{ /* items, skills and spells: */
/* skills and spells: */
char eqname[64]; char eqname[64];
const race *rc = u_race(fam); const race *rc = u_race(fam);
set_familiar(mage, fam);
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name); snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name);
if (!equip_unit(fam, eqname)) { if (!equip_unit(fam, eqname)) {
log_info("could not perform initialization for familiar %s.\n", rc->_name); log_info("could not perform initialization for familiar %s.\n", rc->_name);
} }
}
static int copy_spell_cb(spellbook_entry *sbe, void *udata) {
spellbook *sb = (spellbook *)udata;
spell * sp = spellref_get(&sbe->spref);
if (!spellbook_get(sb, sp)) {
spellbook_add(sb, sp, sbe->level);
}
return 0;
}
/**
* Einmalige Reparatur von Vertrauten (Bugs 2451, 2517).
*/
void fix_fam_mage(unit *u) {
sc_mage *dmage;
unit *du = unit_create(0);
u_setrace(du, u_race(u));
dmage = create_mage(du, M_GRAY);
equip_familiar(du);
if (dmage) {
sc_mage *mage = get_mage(u);
if (!mage) {
mage = create_mage(u, dmage->magietyp);
}
else if (dmage->magietyp != mage->magietyp) {
mage->magietyp = dmage->magietyp;
}
if (dmage->spellbook) {
if (!mage->spellbook) {
mage->spellbook = create_spellbook(NULL);
spellbook_foreach(dmage->spellbook, copy_spell_cb, mage->spellbook);
}
}
else {
if (mage->spellbook) {
spellbook_clear(mage->spellbook);
mage->spellbook = NULL;
}
}
}
free_unit(du);
}
void create_newfamiliar(unit * mage, unit * fam)
{
create_mage(fam, M_GRAY);
set_familiar(mage, fam);
equip_familiar(fam);
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */ /* TODO: Diese Attribute beim Tod des Familiars entfernen: */
/* Wenn der Magier stirbt, dann auch der Vertraute */ /* Wenn der Magier stirbt, dann auch der Vertraute */
add_trigger(&mage->attribs, "destroy", trigger_killunit(fam)); add_trigger(&mage->attribs, "destroy", trigger_killunit(fam));

View file

@ -27,18 +27,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" { extern "C" {
#endif #endif
/* ------------------------------------------------------------- */
#define MAXCOMBATSPELLS 3 /* PRECOMBAT COMBAT POSTCOMBAT */ #define MAXCOMBATSPELLS 3 /* PRECOMBAT COMBAT POSTCOMBAT */
#define MAX_SPELLRANK 9 /* Standard-Rank 5 */ #define MAX_SPELLRANK 9 /* Standard-Rank 5 */
#define MAXINGREDIENT 5 /* bis zu 5 Komponenten pro Zauber */ #define MAXINGREDIENT 5 /* bis zu 5 Komponenten pro Zauber */
#define CHAOSPATZERCHANCE 10 /* +10% Chance zu Patzern */ #define CHAOSPATZERCHANCE 10 /* +10% Chance zu Patzern */
/* ------------------------------------------------------------- */
#define IRONGOLEM_CRUMBLE 15 /* monatlich Chance zu zerfallen */ #define IRONGOLEM_CRUMBLE 15 /* monatlich Chance zu zerfallen */
#define STONEGOLEM_CRUMBLE 10 /* monatlich Chance zu zerfallen */ #define STONEGOLEM_CRUMBLE 10 /* monatlich Chance zu zerfallen */
struct sc_mage;
struct unit;
extern const char *magic_school[MAXMAGIETYP]; extern const char *magic_school[MAXMAGIETYP];
extern struct attrib_type at_familiar; extern struct attrib_type at_familiar;
extern struct attrib_type at_familiarmage; extern struct attrib_type at_familiarmage;
@ -99,26 +97,12 @@ extern "C" {
* - Spruchliste * - Spruchliste
*/ */
typedef struct combatspell {
int level;
const struct spell *sp;
} combatspell;
typedef struct spell_names { typedef struct spell_names {
struct spell_names *next; struct spell_names *next;
const struct locale *lang; const struct locale *lang;
void * tokens; void * tokens;
} spell_names; } spell_names;
typedef struct sc_mage {
magic_t magietyp;
int spellpoints;
int spchange;
int spellcount;
combatspell combatspells[MAXCOMBATSPELLS];
struct spellbook *spellbook;
} sc_mage;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* Zauberliste */ /* Zauberliste */
@ -217,12 +201,22 @@ extern "C" {
*/ */
/* Magier */ /* Magier */
sc_mage *create_mage(struct unit *u, magic_t mtyp); struct sc_mage *create_mage(struct unit *u, magic_t mtyp);
/* macht die struct unit zu einem neuen Magier: legt die struct u->mage an /* macht die struct unit zu einem neuen Magier: legt die struct u->mage an
* und initialisiert den Magiertypus mit mtyp. */ * und initialisiert den Magiertypus mit mtyp. */
sc_mage *get_mage(const struct unit *u); struct sc_mage *get_mage(const struct unit *u);
sc_mage *get_mage_depr(const struct unit *u);
/* gibt u->mage zurück, bei nicht-Magiern *NULL */ enum magic_t mage_get_type(const struct sc_mage *mage);
const struct spell *mage_get_combatspell(const struct sc_mage *mage, int nr, int *level);
struct spellbook * mage_get_spellbook(const struct sc_mage * mage);
int mage_get_spellpoints(const struct sc_mage *m);
int mage_change_spellpoints(struct sc_mage *m, int delta);
enum magic_t unit_get_magic(const struct unit *u);
void unit_set_magic(struct unit *u, enum magic_t mtype);
struct spellbook * unit_get_spellbook(const struct unit * u);
void unit_add_spell(struct unit * u, struct spell * sp, int level);
bool is_mage(const struct unit *u); bool is_mage(const struct unit *u);
/* gibt true, wenn u->mage gesetzt. */ /* gibt true, wenn u->mage gesetzt. */
bool is_familiar(const struct unit *u); bool is_familiar(const struct unit *u);
@ -332,7 +326,8 @@ extern "C" {
void remove_familiar(struct unit *mage); void remove_familiar(struct unit *mage);
void create_newfamiliar(struct unit *mage, struct unit *familiar); void create_newfamiliar(struct unit *mage, struct unit *familiar);
void create_newclone(struct unit *mage, struct unit *familiar); void create_newclone(struct unit *mage, struct unit *familiar);
struct unit *has_clone(struct unit *mage);
void fix_fam_mage(struct unit *u);
const char *spell_info(const struct spell *sp, const char *spell_info(const struct spell *sp,
const struct locale *lang); const struct locale *lang);

View file

@ -117,7 +117,7 @@ void test_pay_spell(CuTest * tc)
CuAssertPtrNotNull(tc, sp); CuAssertPtrNotNull(tc, sp);
set_level(u, SK_MAGIC, 5); set_level(u, SK_MAGIC, 5);
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
change_resource(u, get_resourcetype(R_SILVER), 1); change_resource(u, get_resourcetype(R_SILVER), 1);
change_resource(u, get_resourcetype(R_AURA), 3); change_resource(u, get_resourcetype(R_AURA), 3);
@ -151,7 +151,7 @@ void test_pay_spell_failure(CuTest * tc)
CuAssertPtrNotNull(tc, sp); CuAssertPtrNotNull(tc, sp);
set_level(u, SK_MAGIC, 5); set_level(u, SK_MAGIC, 5);
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
CuAssertIntEquals(tc, 1, change_resource(u, get_resourcetype(R_SILVER), 1)); CuAssertIntEquals(tc, 1, change_resource(u, get_resourcetype(R_SILVER), 1));
CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_AURA), 2)); CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_AURA), 2));
@ -182,7 +182,7 @@ void test_getspell_unit(CuTest * tc)
r = test_create_region(0, 0, NULL); r = test_create_region(0, 0, NULL);
f = test_create_faction(NULL); f = test_create_faction(NULL);
u = test_create_unit(f, r); u = test_create_unit(f, r);
create_mage(u, M_GRAY); create_mage(u, M_GWYRRD);
enable_skill(SK_MAGIC, true); enable_skill(SK_MAGIC, true);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
@ -193,7 +193,7 @@ void test_getspell_unit(CuTest * tc)
CuAssertPtrEquals(tc, NULL, unit_getspell(u, "Herp-a-derp", lang)); CuAssertPtrEquals(tc, NULL, unit_getspell(u, "Herp-a-derp", lang));
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
CuAssertPtrNotNull(tc, unit_getspell(u, "Herp-a-derp", lang)); CuAssertPtrNotNull(tc, unit_getspell(u, "Herp-a-derp", lang));
test_teardown(); test_teardown();
} }
@ -277,7 +277,7 @@ void test_set_pre_combatspell(CuTest * tc)
sp = create_spell("testspell"); sp = create_spell("testspell");
sp->sptyp |= PRECOMBATSPELL; sp->sptyp |= PRECOMBATSPELL;
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
set_combatspell(u, sp, 0, 2); set_combatspell(u, sp, 0, 2);
CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index)); CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index));
@ -309,7 +309,7 @@ void test_set_main_combatspell(CuTest * tc)
sp = create_spell("testspell"); sp = create_spell("testspell");
sp->sptyp |= COMBATSPELL; sp->sptyp |= COMBATSPELL;
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
set_combatspell(u, sp, 0, 2); set_combatspell(u, sp, 0, 2);
CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index)); CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index));
@ -341,7 +341,7 @@ void test_set_post_combatspell(CuTest * tc)
sp = create_spell("testspell"); sp = create_spell("testspell");
sp->sptyp |= POSTCOMBATSPELL; sp->sptyp |= POSTCOMBATSPELL;
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
set_combatspell(u, sp, 0, 2); set_combatspell(u, sp, 0, 2);
CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index)); CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index));
@ -371,7 +371,7 @@ void test_hasspell(CuTest * tc)
sp = create_spell("testspell"); sp = create_spell("testspell");
sp->sptyp |= POSTCOMBATSPELL; sp->sptyp |= POSTCOMBATSPELL;
unit_add_spell(u, 0, sp, 2); unit_add_spell(u, sp, 2);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
CuAssertTrue(tc, !u_hasspell(u, sp)); CuAssertTrue(tc, !u_hasspell(u, sp));
@ -407,7 +407,7 @@ void test_multi_cast(CuTest *tc) {
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
set_level(u, SK_MAGIC, 10); set_level(u, SK_MAGIC, 10);
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, sp, 1);
CuAssertPtrEquals(tc, sp, unit_getspell(u, "Feuerball", lang)); CuAssertPtrEquals(tc, sp, unit_getspell(u, "Feuerball", lang));
unit_addorder(u, create_order(K_CAST, u->faction->locale, "Feuerball")); unit_addorder(u, create_order(K_CAST, u->faction->locale, "Feuerball"));
@ -451,7 +451,7 @@ static void test_max_spellpoints(CuTest *tc) {
CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u));
rc->maxaura = 200; rc->maxaura = 200;
CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u));
create_mage(u, M_GRAY); create_mage(u, M_GWYRRD);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
CuAssertIntEquals(tc, 3, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 3, max_spellpoints(u->region, u));
set_level(u, SK_MAGIC, 2); set_level(u, SK_MAGIC, 2);
@ -485,7 +485,7 @@ static void test_illusioncastle(CuTest *tc)
static void test_is_mage(CuTest *tc) { static void test_is_mage(CuTest *tc) {
unit *u; unit *u;
sc_mage *mage; struct sc_mage *mage;
test_setup(); test_setup();
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
@ -502,18 +502,13 @@ static void test_is_mage(CuTest *tc) {
static void test_get_mage(CuTest *tc) { static void test_get_mage(CuTest *tc) {
unit *u; unit *u;
sc_mage *mage; struct sc_mage *mage;
test_setup(); test_setup();
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
CuAssertPtrEquals(tc, NULL, get_mage(u)); CuAssertPtrEquals(tc, NULL, get_mage(u));
CuAssertPtrEquals(tc, NULL, get_mage_depr(u));
CuAssertPtrNotNull(tc, mage = create_mage(u, M_CERDDOR)); CuAssertPtrNotNull(tc, mage = create_mage(u, M_CERDDOR));
CuAssertPtrEquals(tc, mage, get_mage(u)); CuAssertPtrEquals(tc, mage, get_mage(u));
CuAssertPtrEquals(tc, NULL, get_mage_depr(u));
set_level(u, SK_MAGIC, 1);
CuAssertPtrEquals(tc, mage, get_mage(u));
CuAssertPtrEquals(tc, mage, get_mage_depr(u));
test_teardown(); test_teardown();
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright (c) 1998-2014, Copyright (c) 1998-2018,
Enno Rehling <enno@eressea.de> Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
@ -1430,9 +1430,10 @@ int movement_speed(const unit * u)
/* Im Astralraum sind Tyb und Ill-Magier doppelt so schnell. /* Im Astralraum sind Tyb und Ill-Magier doppelt so schnell.
* Nicht kumulativ mit anderen Beschleunigungen! */ * Nicht kumulativ mit anderen Beschleunigungen! */
if (mp * dk <= BP_WALKING * u_race(u)->speed && is_astral(u->region)) { if (mp * dk <= BP_WALKING * u_race(u)->speed && is_astral(u->region)) {
sc_mage *mage = get_mage(u); struct sc_mage *mage = get_mage(u);
if (mage && (mage->magietyp == M_TYBIED || mage->magietyp == M_ILLAUN)) { if (mage) {
if (has_skill(u, SK_MAGIC)) { magic_t mtype = mage_get_type(mage);
if (mtype == M_TYBIED || mtype == M_ILLAUN) {
mp *= 2; mp *= 2;
} }
} }

View file

@ -637,10 +637,10 @@ static size_t spskill(char *buffer, size_t size, const struct locale * lang,
bufp = STRLCPY(bufp, " ", size); bufp = STRLCPY(bufp, " ", size);
if (sv->id == SK_MAGIC) { if (sv->id == SK_MAGIC) {
sc_mage *mage = get_mage(u); magic_t mtype = unit_get_magic(u);
if (mage && mage->magietyp != M_GRAY) { if (mtype != M_GRAY) {
bufp = STRLCPY(bufp, LOC(lang, mkname("school", bufp = STRLCPY(bufp,
magic_school[mage->magietyp])), size); LOC(lang, mkname("school", magic_school[mtype])), size);
bufp = STRLCPY(bufp, " ", size); bufp = STRLCPY(bufp, " ", size);
} }
} }

View file

@ -704,13 +704,13 @@ static int sp_destroy_magic(castorder * co)
static int sp_transferaura(castorder * co) static int sp_transferaura(castorder * co)
{ {
int aura, gain, multi = 2; int aura, used, multi = 2;
unit *caster = co_get_caster(co); unit *caster = co_get_caster(co);
unit *mage = co_get_magician(co); unit *mage = co_get_magician(co);
int cast_level = co->level; int cast_level = co->level;
spellparameter *pa = co->par; spellparameter *pa = co->par;
unit *u; unit *u;
sc_mage *scm_dst, *scm_src = get_mage(mage); struct sc_mage *scm_dst, *scm_src = get_mage(mage);
assert(scm_src); assert(scm_src);
/* wenn kein Ziel gefunden, Zauber abbrechen */ /* wenn kein Ziel gefunden, Zauber abbrechen */
@ -725,26 +725,30 @@ static int sp_transferaura(castorder * co)
/* Wieviel Transferieren? */ /* Wieviel Transferieren? */
aura = pa->param[1]->data.i; aura = pa->param[1]->data.i;
u = pa->param[0]->data.u; u = pa->param[0]->data.u;
scm_dst = get_mage_depr(u); scm_dst = get_mage(u);
if (scm_dst == NULL) { if (scm_dst == NULL) {
/* "Zu dieser Einheit kann ich keine Aura uebertragen." */ /* "Zu dieser Einheit kann ich keine Aura uebertragen." */
cmistake(caster, co->order, 207, MSG_MAGIC); cmistake(caster, co->order, 207, MSG_MAGIC);
return 0; return 0;
} }
else if (scm_src->magietyp == M_TYBIED) { else {
if (scm_src->magietyp != scm_dst->magietyp) magic_t src = mage_get_type(scm_src);
magic_t dst = mage_get_type(scm_dst);
if (src != dst) {
if (src == M_TYBIED) {
multi = 3; multi = 3;
} }
else if (scm_src->magietyp == M_GRAY) { else if (src == M_GRAY) {
if (scm_src->magietyp != scm_dst->magietyp)
multi = 4; multi = 4;
} }
else if (scm_dst->magietyp != scm_src->magietyp) { else {
/* "Zu dieser Einheit kann ich keine Aura uebertragen." */ /* "Zu dieser Einheit kann ich keine Aura uebertragen." */
cmistake(caster, co->order, 207, MSG_MAGIC); cmistake(caster, co->order, 207, MSG_MAGIC);
return 0; return 0;
} }
}
}
if (aura < multi) { if (aura < multi) {
/* "Auraangabe fehlerhaft." */ /* "Auraangabe fehlerhaft." */
@ -752,16 +756,15 @@ static int sp_transferaura(castorder * co)
return 0; return 0;
} }
gain = scm_src->spellpoints; used = mage_get_spellpoints(scm_src);
if (gain > aura) gain = aura; if (used > aura) used = aura;
gain = gain / multi; mage_change_spellpoints(scm_src, -used);
scm_src->spellpoints -= gain * multi; mage_change_spellpoints(scm_dst, used / multi);
scm_dst->spellpoints += gain;
/* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage), /* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage),
gain, unitname(u)); */ gain, unitname(u)); */
ADDMSG(&caster->faction->msgs, msg_message("auratransfer_success", ADDMSG(&caster->faction->msgs, msg_message("auratransfer_success",
"unit target aura", caster, u, gain)); "unit target aura", caster, u, used));
return cast_level; return cast_level;
} }
@ -5748,14 +5751,6 @@ static int sp_eternizewall(castorder * co)
return cast_level; 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 /* Name: Opfere Kraft
* Stufe: 15 * Stufe: 15
@ -5810,7 +5805,7 @@ int sp_permtransfer(castorder * co)
change_maxspellpoints(mage, -aura); change_maxspellpoints(mage, -aura);
change_spellpoints(mage, -aura); change_spellpoints(mage, -aura);
if (get_magic_type(tu) == get_magic_type(mage)) { if (unit_get_magic(tu) == unit_get_magic(mage)) {
change_maxspellpoints(tu, aura / 2); change_maxspellpoints(tu, aura / 2);
} }
else { else {
@ -5925,6 +5920,7 @@ int sp_stealaura(castorder * co)
int cast_level = co->level; int cast_level = co->level;
double power = co->force; double power = co->force;
spellparameter *pa = co->par; spellparameter *pa = co->par;
struct sc_mage *scm;
/* wenn kein Ziel gefunden, Zauber abbrechen */ /* wenn kein Ziel gefunden, Zauber abbrechen */
if (pa->param[0]->flag == TARGET_NOTFOUND) if (pa->param[0]->flag == TARGET_NOTFOUND)
@ -5933,17 +5929,18 @@ int sp_stealaura(castorder * co)
/* Zieleinheit */ /* Zieleinheit */
u = pa->param[0]->data.u; u = pa->param[0]->data.u;
if (!get_mage_depr(u)) { scm = get_mage(u);
if (!scm) {
ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target", ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target",
caster, u)); caster, u));
ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u)); ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u));
return 0; return 0;
} }
taura = (get_mage_depr(u)->spellpoints * (rng_int() % (int)(3 * power) + 1)) / 100; taura = (mage_get_spellpoints(scm) * (rng_int() % (int)(3 * power) + 1)) / 100;
if (taura > 0) { if (taura > 0) {
change_spellpoints(u, -taura); mage_change_spellpoints(scm, -taura);
change_spellpoints(mage, taura); change_spellpoints(mage, taura);
/* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), /* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u),
taura); */ taura); */

View file

@ -72,11 +72,11 @@ void spy_message(int spy, const unit * u, const unit * target)
ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u, ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u,
target, status)); target, status));
if (spy > 20) { if (spy > 20) {
sc_mage *mage = get_mage_depr(target); magic_t mtype = unit_get_magic(target);
/* for mages, spells and magic school */ /* for mages, spells and magic school */
if (mage) { if (mtype != M_GRAY) {
ADDMSG(&u->faction->msgs, msg_message("spyreport_mage", "spy target type", u, ADDMSG(&u->faction->msgs, msg_message("spyreport_mage", "spy target type", u,
target, magic_school[mage->magietyp])); target, magic_school[mtype]));
} }
} }
if (spy > 6) { if (spy > 6) {

View file

@ -420,10 +420,10 @@ int teach_cmd(unit * teacher, struct order *ord)
if (sk == SK_MAGIC) { if (sk == SK_MAGIC) {
/* ist der Magier schon spezialisiert, so versteht er nur noch /* ist der Magier schon spezialisiert, so versteht er nur noch
* Lehrer seines Gebietes */ * Lehrer seines Gebietes */
sc_mage *mage1 = get_mage_depr(teacher); magic_t mage2 = unit_get_magic(scholar);
sc_mage *mage2 = get_mage_depr(scholar); if (mage2 != M_GRAY) {
if (mage2 && mage1 && mage2->magietyp != M_GRAY magic_t mage1 = unit_get_magic(teacher);
&& mage1->magietyp != mage2->magietyp) { if (mage1 != mage2) {
if (feedback) { if (feedback) {
ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord,
"error_different_magic", "target", scholar)); "error_different_magic", "target", scholar));
@ -431,6 +431,7 @@ int teach_cmd(unit * teacher, struct order *ord)
continue; continue;
} }
} }
}
sk_academy = sk; sk_academy = sk;
teaching -= teach_unit(teacher, scholar, teaching, sk, false, &academy_students); teaching -= teach_unit(teacher, scholar, teaching, sk, false, &academy_students);
} }
@ -622,7 +623,7 @@ int study_cmd(unit * u, order * ord)
} }
if (sk == SK_MAGIC) { if (sk == SK_MAGIC) {
magic_t mtyp; magic_t mtype;
if (u->number > 1) { if (u->number > 1) {
cmistake(u, ord, 106, MSG_MAGIC); cmistake(u, ord, 106, MSG_MAGIC);
return -1; return -1;
@ -630,7 +631,7 @@ int study_cmd(unit * u, order * ord)
if (is_familiar(u)) { if (is_familiar(u)) {
/* Vertraute zaehlen nicht zu den Magiern einer Partei, /* Vertraute zaehlen nicht zu den Magiern einer Partei,
* koennen aber nur Graue Magie lernen */ * koennen aber nur Graue Magie lernen */
mtyp = M_GRAY; mtype = M_GRAY;
} }
else if (!has_skill(u, SK_MAGIC)) { else if (!has_skill(u, SK_MAGIC)) {
int mmax = skill_limit(u->faction, SK_MAGIC); int mmax = skill_limit(u->faction, SK_MAGIC);
@ -640,24 +641,24 @@ int study_cmd(unit * u, order * ord)
"amount", mmax)); "amount", mmax));
return -1; return -1;
} }
mtyp = getmagicskill(u->faction->locale); mtype = getmagicskill(u->faction->locale);
if (mtyp == M_NONE || mtyp == M_GRAY) { if (mtype == M_NONE || mtype == M_GRAY) {
/* wurde kein Magiegebiet angegeben, wird davon /* wurde kein Magiegebiet angegeben, wird davon
* ausgegangen, dass das normal gelernt werden soll */ * ausgegangen, dass das normal gelernt werden soll */
if (u->faction->magiegebiet != 0) { if (u->faction->magiegebiet != 0) {
mtyp = u->faction->magiegebiet; mtype = u->faction->magiegebiet;
} }
else { else {
/* Es wurde kein Magiegebiet angegeben und die Partei /* Es wurde kein Magiegebiet angegeben und die Partei
* hat noch keins gewaehlt. */ * hat noch keins gewaehlt. */
mtyp = getmagicskill(u->faction->locale); mtype = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) { if (mtype == M_NONE) {
cmistake(u, ord, 178, MSG_MAGIC); cmistake(u, ord, 178, MSG_MAGIC);
return -1; return -1;
} }
} }
} }
if (mtyp != u->faction->magiegebiet) { if (mtype != u->faction->magiegebiet) {
/* Es wurde versucht, ein anderes Magiegebiet zu lernen /* Es wurde versucht, ein anderes Magiegebiet zu lernen
* als das der Partei */ * als das der Partei */
if (u->faction->magiegebiet != 0) { if (u->faction->magiegebiet != 0) {
@ -667,25 +668,25 @@ int study_cmd(unit * u, order * ord)
else { else {
/* Lernt zum ersten mal Magie und legt damit das /* Lernt zum ersten mal Magie und legt damit das
* Magiegebiet der Partei fest */ * Magiegebiet der Partei fest */
u->faction->magiegebiet = mtyp; u->faction->magiegebiet = mtype;
} }
} }
create_mage(u, mtyp); create_mage(u, mtype);
} }
else { else {
/* ist schon ein Magier und kein Vertrauter */ /* ist schon ein Magier und kein Vertrauter */
if (u->faction->magiegebiet == 0) { if (u->faction->magiegebiet == 0) {
/* die Partei hat noch kein Magiegebiet gewaehlt. */ /* die Partei hat noch kein Magiegebiet gewaehlt. */
mtyp = getmagicskill(u->faction->locale); mtype = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) { if (mtype == M_NONE) {
mtyp = getmagicskill(u->faction->locale); mtype = getmagicskill(u->faction->locale);
if (mtyp == M_NONE) { if (mtype == M_NONE) {
cmistake(u, ord, 178, MSG_MAGIC); cmistake(u, ord, 178, MSG_MAGIC);
return -1; return -1;
} }
} }
/* Legt damit das Magiegebiet der Partei fest */ /* Legt damit das Magiegebiet der Partei fest */
u->faction->magiegebiet = mtyp; u->faction->magiegebiet = mtype;
} }
} }
} }

View file

@ -429,9 +429,9 @@ static void test_study_magic(CuTest *tc) {
CuAssertIntEquals(tc, 0, study_cmd(u, u->thisorder)); CuAssertIntEquals(tc, 0, study_cmd(u, u->thisorder));
CuAssertIntEquals(tc, M_GWYRRD, f->magiegebiet); CuAssertIntEquals(tc, M_GWYRRD, f->magiegebiet);
CuAssertIntEquals(tc, 0, i_get(u->items, itype)); CuAssertIntEquals(tc, 0, i_get(u->items, itype));
CuAssertPtrNotNull(tc, get_mage_depr(u)); CuAssertPtrNotNull(tc, get_mage(u));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error65")); CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error65"));
CuAssertIntEquals(tc, M_GWYRRD, get_mage_depr(u)->magietyp); CuAssertIntEquals(tc, M_GWYRRD, unit_get_magic(u));
test_teardown(); test_teardown();
} }

View file

@ -23,7 +23,7 @@ static void test_shock(CuTest *tc) {
test_setup(); test_setup();
shock_setup(); shock_setup();
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
create_mage(u, M_GRAY); create_mage(u, M_GWYRRD);
set_level(u, SK_MAGIC, 5); set_level(u, SK_MAGIC, 5);
set_spellpoints(u, 10); set_spellpoints(u, 10);
u->hp = 10; u->hp = 10;
@ -44,7 +44,7 @@ static void test_shock_low(CuTest *tc) {
test_setup(); test_setup();
shock_setup(); shock_setup();
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
create_mage(u, M_GRAY); create_mage(u, M_GWYRRD);
set_level(u, SK_MAGIC, 5); set_level(u, SK_MAGIC, 5);
set_spellpoints(u, 1); set_spellpoints(u, 1);
u->hp = 1; u->hp = 1;