combat spell functions have the same interface as spells now.

This commit is contained in:
Enno Rehling 2012-05-09 18:28:33 -07:00
parent 06e0d2b3b6
commit 67ef4c52a3
6 changed files with 60 additions and 73 deletions

View file

@ -461,12 +461,12 @@ static void unit_castspell(unit * u, const char *name)
for (ql = spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
spell *sp = (spell *) ql_get(ql, qi);
if (strcmp(name, sp->sname) == 0) {
if (sp->sp_function == NULL) {
if (!sp->cast) {
log_error(("spell '%s' has no function.\n", sp->sname));
} else {
castorder co;
create_castorder(&co, u, 0, sp, u->region, sp->level, sp->level, 0, 0, 0);
sp->sp_function(&co);
create_castorder(&co, u, 0, sp, u->region, sp->level, sp->level * MagicPower(), 0, 0, 0);
sp->cast(&co);
free_castorder(&co);
}
}

View file

@ -698,7 +698,7 @@ static int tolua_write_spells(lua_State * L)
int qi;
for (ql = spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
spell *sp = (spell *) ql_get(ql, qi);
if (sp->sp_function != fun) {
if (sp->cast != fun) {
int combat = 0;
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "spell");
xmlNewProp(node, BAD_CAST "name", BAD_CAST sp->sname);

View file

@ -1776,12 +1776,11 @@ void do_combatmagic(battle * b, combatmagic_t was)
fighter *fig = co->magician.fig;
const spell *sp = co->sp;
int level = co->level;
double power = co->force;
if (sp->sp_function == NULL) {
if (!sp->cast) {
log_error(("spell '%s' has no function.\n", sp->sname));
} else {
level = ((cspell_f) sp->sp_function) (fig, level, power, sp);
level = sp->cast(co);
if (level > 0) {
pay_spell(fig->unit, sp, level, 1);
}
@ -1793,19 +1792,34 @@ void do_combatmagic(battle * b, combatmagic_t was)
}
}
static void combat_action(fighter * af, int turn)
static void combat_action(fighter * af)
{
#ifndef SIMPLE_COMBAT
af->action_counter++;
af->side->bf->lastturn = turn;
af->side->bf->lastturn = af->side->battle->turn;
#endif
}
static int cast_combatspell(troop at, const spell * sp, int level, double force)
{
castorder co;
create_castorder(&co, at.fighter->unit, 0, sp, at.fighter->unit->region, level, force, 0, 0, 0);
co.magician.fig = at.fighter;
level = sp->cast(&co);
free_castorder(&co);
if (level > 0) {
pay_spell(at.fighter->unit, sp, level, 1);
combat_action(at.fighter);
}
return level;
}
static void do_combatspell(troop at)
{
const spell *sp;
fighter *fi = at.fighter;
unit *mage = fi->unit;
unit *caster = fi->unit;
battle *b = fi->side->battle;
region *r = b->region;
quicklist *ql;
@ -1814,26 +1828,26 @@ static void do_combatspell(troop at)
int fumblechance = 0;
order *ord;
int sl;
const struct locale *lang = mage->faction->locale;
const struct locale *lang = caster->faction->locale;
sp = get_combatspell(mage, 1);
sp = get_combatspell(caster, 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(mage, sp, 1, 1, ord) == false) {
if (cancast(caster, sp, 1, 1, ord) == false) {
fi->magic = 0; /* Kann nicht mehr Zaubern, kämpft nichtmagisch weiter */
return;
}
level = eff_spelllevel(mage, sp, fi->magic, 1);
if ((sl = get_combatspelllevel(mage, 1)) > 0)
level = eff_spelllevel(caster, sp, fi->magic, 1);
if ((sl = get_combatspelllevel(caster, 1)) > 0)
level = MIN(level, sl);
if (fumble(r, mage, sp, sp->level) == true) {
report_failed_spell(b, mage, sp);
pay_spell(mage, sp, level, 1);
if (fumble(r, caster, sp, sp->level) == true) {
report_failed_spell(b, caster, sp);
pay_spell(caster, sp, level, 1);
return;
}
@ -1849,27 +1863,23 @@ static void do_combatspell(troop at)
/* Antimagie die Fehlschlag erhöht */
if (rng_int() % 100 < fumblechance) {
report_failed_spell(b, mage, sp);
pay_spell(mage, sp, level, 1);
report_failed_spell(b, caster, sp);
pay_spell(caster, sp, level, 1);
free_order(ord);
return;
}
power = spellpower(r, mage, sp, level, ord);
power = spellpower(r, caster, sp, level, ord);
free_order(ord);
if (power <= 0) { /* Effekt von Antimagie */
report_failed_spell(b, mage, sp);
pay_spell(mage, sp, level, 1);
report_failed_spell(b, caster, sp);
pay_spell(caster, sp, level, 1);
return;
}
if (sp->sp_function == NULL) {
if (!sp->cast) {
log_error(("spell '%s' has no function.\n", sp->sname));
} else {
level = ((cspell_f) sp->sp_function) (fi, level, power, sp);
if (level > 0) {
pay_spell(mage, sp, level, 1);
combat_action(at.fighter, b->turn);
}
level = cast_combatspell(at, sp, level, power);
}
}
@ -1881,14 +1891,11 @@ static void do_combatspell(troop at)
static void do_extra_spell(troop at, const att * a)
{
const spell *sp = a->data.sp;
fighter *fi = at.fighter;
double power;
power = sp->level * MagicPower();
if (sp->sp_function == NULL) {
if (sp->cast == NULL) {
log_error(("spell '%s' has no function.\n", sp->sname));
} else {
((cspell_f) sp->sp_function) (fi, sp->level, power, sp);
cast_combatspell(at, sp, sp->level, sp->level * MagicPower());
}
}
@ -2181,7 +2188,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
af->catmsg += dead;
if (!standard_attack && af->person[ta.index].last_action < b->turn) {
af->person[ta.index].last_action = b->turn;
combat_action(af, b->turn);
combat_action(af);
}
}
if (standard_attack) {
@ -2197,7 +2204,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
return;
if (ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn;
combat_action(ta.fighter, b->turn);
combat_action(ta.fighter);
}
reload = true;
if (hits(ta, td, wp)) {
@ -2230,7 +2237,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
return;
if (ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn;
combat_action(ta.fighter, b->turn);
combat_action(ta.fighter);
}
if (hits(ta, td, NULL)) {
terminate(td, ta, a->type, a->data.dice, false);
@ -2242,7 +2249,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
return;
if (ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn;
combat_action(ta.fighter, b->turn);
combat_action(ta.fighter);
}
if (hits(ta, td, NULL)) {
int c = dice_rand(a->data.dice);
@ -2262,7 +2269,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
return;
if (ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn;
combat_action(ta.fighter, b->turn);
combat_action(ta.fighter);
}
if (hits(ta, td, NULL)) {
drain_exp(td.fighter->unit, dice_rand(a->data.dice));
@ -2274,7 +2281,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
return;
if (ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn;
combat_action(ta.fighter, b->turn);
combat_action(ta.fighter);
}
if (hits(ta, td, NULL)) {
dazzle(b, &td);
@ -2286,7 +2293,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
return;
if (ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn;
combat_action(ta.fighter, b->turn);
combat_action(ta.fighter);
}
if (td.fighter->unit->ship) {
/* FIXME should use damage_ship here? */

View file

@ -1432,11 +1432,7 @@ static void do_fumble(castorder * co)
case 5:
case 6:
/* Spruch gelingt, aber alle Magiepunkte weg */
if (sp->sp_function == NULL) {
log_error(("spell '%s' has no function.\n", sp->sname));
} else {
((nspell_f) sp->sp_function) (co);
}
sp->cast(co);
set_spellpoints(u, 0);
ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell",
u, r, sp));
@ -1447,11 +1443,7 @@ static void do_fumble(castorder * co)
case 9:
default:
/* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */
if (sp->sp_function == NULL) {
log_error(("spell '%s' has no function.\n", sp->sname));
} else {
((nspell_f) sp->sp_function) (co);
}
sp->cast(co);
ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell",
u, r, sp));
countspells(u, 3);
@ -1788,7 +1780,7 @@ verify_targets(castorder * co, int *invalid, int *resist, int *success)
* Magieresistenz der Region prüfen. */
if ((sp->sptyp & REGIONSPELL)) {
/* Zielobjekt Region anlegen */
spllprm *spobj = malloc(sizeof(spllprm));
spllprm *spobj = (spllprm *)malloc(sizeof(spllprm));
spobj->flag = 0;
spobj->typ = SPP_REGION;
spobj->data.r = target_r;
@ -1908,7 +1900,7 @@ addparam_region(const char *const param[], spllprm ** spobjp, const unit * u,
rt = findregion(x, y);
if (rt != NULL) {
spllprm *spobj = *spobjp = malloc(sizeof(spllprm));
spllprm *spobj = *spobjp = (spllprm *)malloc(sizeof(spllprm));
spobj->flag = 0;
spobj->typ = SPP_REGION;
@ -2903,12 +2895,7 @@ void magic(void)
/* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */
fumbled = true;
} else {
if (sp->sp_function == NULL) {
log_error(("spell '%s' has no function.\n", sp->sname));
co->level = 0;
} else {
co->level = ((nspell_f) sp->sp_function) (co);
}
co->level = sp->cast(co);
if (co->level <= 0) {
/* Kosten nur für real benötige Stufe berechnen */
continue;

View file

@ -144,22 +144,15 @@ typedef struct sc_mage {
struct unit * co_get_caster(struct castorder * co);
struct region * co_get_region(struct castorder * co);
/* irgendwelche zauber: */
typedef void (*spell_f) (void *);
/* normale zauber: */
typedef int (*nspell_f) (castorder *);
/* kampfzauber: */
typedef int (*cspell_f) (struct fighter *, int, double,
const struct spell * sp);
/* zauber-patzer: */
typedef void (*pspell_f) (castorder *);
typedef struct spell_component {
const struct resource_type *type;
int amount;
int cost;
} spell_component;
typedef int (*spell_f)(castorder * co);
typedef void(*fumble_f)(castorder * co);
typedef struct spell {
unsigned int id;
char *sname;
@ -170,8 +163,8 @@ typedef struct sc_mage {
int rank; /* Reihenfolge der Zauber */
int level; /* Stufe des Zaubers */
struct spell_component *components;
spell_f sp_function;
void (*patzer) (castorder *);
spell_f cast;
fumble_f patzer;
} spell;
/* ------------------------------------------------------------- */

View file

@ -1568,9 +1568,9 @@ static int parse_spells(xmlDocPtr doc)
}
assert(propValue != NULL);
if (strcmp((const char *)propValue, "cast") == 0) {
sp->sp_function = (spell_f) fun;
sp->cast = (spell_f) fun;
} else if (strcmp((const char *)propValue, "fumble") == 0) {
sp->patzer = (pspell_f) fun;
sp->patzer = (fumble_f) fun;
} else {
log_error(("unknown function type '%s' for spell %s\n",
(const char *)propValue, sp->sname));