forked from github/server
Bug 2517: Vertraute ohne eigene Zauber reparieren
Trennung von caster und mage in spells.c
This commit is contained in:
parent
b181618b53
commit
d2389fa87b
10 changed files with 424 additions and 353 deletions
|
@ -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")
|
||||
|
|
|
@ -117,7 +117,6 @@ function test_familiar_cast()
|
|||
u:add_spell("earn_silver#gwyrrd")
|
||||
u:add_order('ARBEITE')
|
||||
local uf = unit.create(f, r)
|
||||
uf.magic = "gwyrrd"
|
||||
uf.race = "lynx"
|
||||
uf:set_skill("magic", 5)
|
||||
uf:add_order('ZAUBER STUFE 1 Viehheilung')
|
||||
|
@ -141,13 +140,10 @@ function test_familiar_mage_actions()
|
|||
u:add_spell("earn_silver#gwyrrd")
|
||||
u:add_order('ZAUBER STUFE 1 Viehheilung')
|
||||
local uf = unit.create(f, r)
|
||||
uf.magic = "gwyrrd"
|
||||
uf.race = "lynx"
|
||||
uf:set_skill("magic", 5)
|
||||
uf:add_order('ZAUBER STUFE 1 Viehheilung')
|
||||
u.familiar = uf
|
||||
u.name = 'Xolgrim'
|
||||
uf.name = 'Zonk'
|
||||
process_orders()
|
||||
assert_equal(50, u:get_item('money'))
|
||||
assert_equal(50, uf:get_item('money'))
|
||||
|
@ -199,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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1671,7 +1671,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)
|
||||
|
|
|
@ -904,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;
|
||||
|
@ -2874,7 +2875,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan
|
|||
|
||||
sb = unit_get_spellbook(u);
|
||||
if (sb) {
|
||||
void * tokens = 0;
|
||||
void * tokens = NULL;
|
||||
select_spellbook(&tokens, sb, lang);
|
||||
if (tokens) {
|
||||
variant token;
|
||||
|
@ -2885,7 +2886,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan
|
|||
freetokens(tokens);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cast_spell(struct castorder *co)
|
||||
|
|
594
src/spells.c
594
src/spells.c
File diff suppressed because it is too large
Load diff
|
@ -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_get_magician(co);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue