forked from github/server
combat spell functions have the same interface as spells now.
This commit is contained in:
parent
06e0d2b3b6
commit
67ef4c52a3
6 changed files with 60 additions and 73 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue