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)) {
|
for (ql = spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
|
||||||
spell *sp = (spell *) ql_get(ql, qi);
|
spell *sp = (spell *) ql_get(ql, qi);
|
||||||
if (strcmp(name, sp->sname) == 0) {
|
if (strcmp(name, sp->sname) == 0) {
|
||||||
if (sp->sp_function == NULL) {
|
if (!sp->cast) {
|
||||||
log_error(("spell '%s' has no function.\n", sp->sname));
|
log_error(("spell '%s' has no function.\n", sp->sname));
|
||||||
} else {
|
} else {
|
||||||
castorder co;
|
castorder co;
|
||||||
create_castorder(&co, u, 0, sp, u->region, sp->level, sp->level, 0, 0, 0);
|
create_castorder(&co, u, 0, sp, u->region, sp->level, sp->level * MagicPower(), 0, 0, 0);
|
||||||
sp->sp_function(&co);
|
sp->cast(&co);
|
||||||
free_castorder(&co);
|
free_castorder(&co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,7 +698,7 @@ static int tolua_write_spells(lua_State * L)
|
||||||
int qi;
|
int qi;
|
||||||
for (ql = spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
|
for (ql = spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
|
||||||
spell *sp = (spell *) ql_get(ql, qi);
|
spell *sp = (spell *) ql_get(ql, qi);
|
||||||
if (sp->sp_function != fun) {
|
if (sp->cast != fun) {
|
||||||
int combat = 0;
|
int combat = 0;
|
||||||
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "spell");
|
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "spell");
|
||||||
xmlNewProp(node, BAD_CAST "name", BAD_CAST sp->sname);
|
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;
|
fighter *fig = co->magician.fig;
|
||||||
const spell *sp = co->sp;
|
const spell *sp = co->sp;
|
||||||
int level = co->level;
|
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));
|
log_error(("spell '%s' has no function.\n", sp->sname));
|
||||||
} else {
|
} else {
|
||||||
level = ((cspell_f) sp->sp_function) (fig, level, power, sp);
|
level = sp->cast(co);
|
||||||
if (level > 0) {
|
if (level > 0) {
|
||||||
pay_spell(fig->unit, sp, level, 1);
|
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
|
#ifndef SIMPLE_COMBAT
|
||||||
af->action_counter++;
|
af->action_counter++;
|
||||||
af->side->bf->lastturn = turn;
|
af->side->bf->lastturn = af->side->battle->turn;
|
||||||
#endif
|
#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)
|
static void do_combatspell(troop at)
|
||||||
{
|
{
|
||||||
const spell *sp;
|
const spell *sp;
|
||||||
fighter *fi = at.fighter;
|
fighter *fi = at.fighter;
|
||||||
unit *mage = fi->unit;
|
unit *caster = fi->unit;
|
||||||
battle *b = fi->side->battle;
|
battle *b = fi->side->battle;
|
||||||
region *r = b->region;
|
region *r = b->region;
|
||||||
quicklist *ql;
|
quicklist *ql;
|
||||||
|
@ -1814,26 +1828,26 @@ static void do_combatspell(troop at)
|
||||||
int fumblechance = 0;
|
int fumblechance = 0;
|
||||||
order *ord;
|
order *ord;
|
||||||
int sl;
|
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) {
|
if (sp == NULL) {
|
||||||
fi->magic = 0; /* Hat keinen Kampfzauber, kämpft nichtmagisch weiter */
|
fi->magic = 0; /* Hat keinen Kampfzauber, kämpft nichtmagisch weiter */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ord = create_order(K_CAST, lang, "'%s'", spell_name(sp, lang));
|
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 */
|
fi->magic = 0; /* Kann nicht mehr Zaubern, kämpft nichtmagisch weiter */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
level = eff_spelllevel(mage, sp, fi->magic, 1);
|
level = eff_spelllevel(caster, sp, fi->magic, 1);
|
||||||
if ((sl = get_combatspelllevel(mage, 1)) > 0)
|
if ((sl = get_combatspelllevel(caster, 1)) > 0)
|
||||||
level = MIN(level, sl);
|
level = MIN(level, sl);
|
||||||
|
|
||||||
if (fumble(r, mage, sp, sp->level) == true) {
|
if (fumble(r, caster, sp, sp->level) == true) {
|
||||||
report_failed_spell(b, mage, sp);
|
report_failed_spell(b, caster, sp);
|
||||||
pay_spell(mage, sp, level, 1);
|
pay_spell(caster, sp, level, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1849,27 +1863,23 @@ static void do_combatspell(troop at)
|
||||||
|
|
||||||
/* Antimagie die Fehlschlag erhöht */
|
/* Antimagie die Fehlschlag erhöht */
|
||||||
if (rng_int() % 100 < fumblechance) {
|
if (rng_int() % 100 < fumblechance) {
|
||||||
report_failed_spell(b, mage, sp);
|
report_failed_spell(b, caster, sp);
|
||||||
pay_spell(mage, sp, level, 1);
|
pay_spell(caster, sp, level, 1);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
power = spellpower(r, mage, sp, level, ord);
|
power = spellpower(r, caster, sp, level, ord);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
if (power <= 0) { /* Effekt von Antimagie */
|
if (power <= 0) { /* Effekt von Antimagie */
|
||||||
report_failed_spell(b, mage, sp);
|
report_failed_spell(b, caster, sp);
|
||||||
pay_spell(mage, sp, level, 1);
|
pay_spell(caster, sp, level, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp->sp_function == NULL) {
|
if (!sp->cast) {
|
||||||
log_error(("spell '%s' has no function.\n", sp->sname));
|
log_error(("spell '%s' has no function.\n", sp->sname));
|
||||||
} else {
|
} else {
|
||||||
level = ((cspell_f) sp->sp_function) (fi, level, power, sp);
|
level = cast_combatspell(at, sp, level, power);
|
||||||
if (level > 0) {
|
|
||||||
pay_spell(mage, sp, level, 1);
|
|
||||||
combat_action(at.fighter, b->turn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1881,14 +1891,11 @@ static void do_combatspell(troop at)
|
||||||
static void do_extra_spell(troop at, const att * a)
|
static void do_extra_spell(troop at, const att * a)
|
||||||
{
|
{
|
||||||
const spell *sp = a->data.sp;
|
const spell *sp = a->data.sp;
|
||||||
fighter *fi = at.fighter;
|
|
||||||
double power;
|
|
||||||
|
|
||||||
power = sp->level * MagicPower();
|
if (sp->cast == NULL) {
|
||||||
if (sp->sp_function == NULL) {
|
|
||||||
log_error(("spell '%s' has no function.\n", sp->sname));
|
log_error(("spell '%s' has no function.\n", sp->sname));
|
||||||
} else {
|
} 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;
|
af->catmsg += dead;
|
||||||
if (!standard_attack && af->person[ta.index].last_action < b->turn) {
|
if (!standard_attack && af->person[ta.index].last_action < b->turn) {
|
||||||
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) {
|
if (standard_attack) {
|
||||||
|
@ -2197,7 +2204,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
|
||||||
return;
|
return;
|
||||||
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
||||||
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;
|
reload = true;
|
||||||
if (hits(ta, td, wp)) {
|
if (hits(ta, td, wp)) {
|
||||||
|
@ -2230,7 +2237,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
|
||||||
return;
|
return;
|
||||||
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
||||||
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)) {
|
if (hits(ta, td, NULL)) {
|
||||||
terminate(td, ta, a->type, a->data.dice, false);
|
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;
|
return;
|
||||||
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
||||||
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)) {
|
if (hits(ta, td, NULL)) {
|
||||||
int c = dice_rand(a->data.dice);
|
int c = dice_rand(a->data.dice);
|
||||||
|
@ -2262,7 +2269,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
|
||||||
return;
|
return;
|
||||||
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
||||||
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)) {
|
if (hits(ta, td, NULL)) {
|
||||||
drain_exp(td.fighter->unit, dice_rand(a->data.dice));
|
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;
|
return;
|
||||||
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
||||||
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)) {
|
if (hits(ta, td, NULL)) {
|
||||||
dazzle(b, &td);
|
dazzle(b, &td);
|
||||||
|
@ -2286,7 +2293,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
|
||||||
return;
|
return;
|
||||||
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
if (ta.fighter->person[ta.index].last_action < b->turn) {
|
||||||
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) {
|
if (td.fighter->unit->ship) {
|
||||||
/* FIXME should use damage_ship here? */
|
/* FIXME should use damage_ship here? */
|
||||||
|
|
|
@ -1432,11 +1432,7 @@ static void do_fumble(castorder * co)
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
/* Spruch gelingt, aber alle Magiepunkte weg */
|
/* Spruch gelingt, aber alle Magiepunkte weg */
|
||||||
if (sp->sp_function == NULL) {
|
sp->cast(co);
|
||||||
log_error(("spell '%s' has no function.\n", sp->sname));
|
|
||||||
} else {
|
|
||||||
((nspell_f) sp->sp_function) (co);
|
|
||||||
}
|
|
||||||
set_spellpoints(u, 0);
|
set_spellpoints(u, 0);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell",
|
ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell",
|
||||||
u, r, sp));
|
u, r, sp));
|
||||||
|
@ -1447,11 +1443,7 @@ static void do_fumble(castorder * co)
|
||||||
case 9:
|
case 9:
|
||||||
default:
|
default:
|
||||||
/* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */
|
/* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */
|
||||||
if (sp->sp_function == NULL) {
|
sp->cast(co);
|
||||||
log_error(("spell '%s' has no function.\n", sp->sname));
|
|
||||||
} else {
|
|
||||||
((nspell_f) sp->sp_function) (co);
|
|
||||||
}
|
|
||||||
ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell",
|
ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell",
|
||||||
u, r, sp));
|
u, r, sp));
|
||||||
countspells(u, 3);
|
countspells(u, 3);
|
||||||
|
@ -1788,7 +1780,7 @@ verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
||||||
* Magieresistenz der Region prüfen. */
|
* Magieresistenz der Region prüfen. */
|
||||||
if ((sp->sptyp & REGIONSPELL)) {
|
if ((sp->sptyp & REGIONSPELL)) {
|
||||||
/* Zielobjekt Region anlegen */
|
/* Zielobjekt Region anlegen */
|
||||||
spllprm *spobj = malloc(sizeof(spllprm));
|
spllprm *spobj = (spllprm *)malloc(sizeof(spllprm));
|
||||||
spobj->flag = 0;
|
spobj->flag = 0;
|
||||||
spobj->typ = SPP_REGION;
|
spobj->typ = SPP_REGION;
|
||||||
spobj->data.r = target_r;
|
spobj->data.r = target_r;
|
||||||
|
@ -1908,7 +1900,7 @@ addparam_region(const char *const param[], spllprm ** spobjp, const unit * u,
|
||||||
rt = findregion(x, y);
|
rt = findregion(x, y);
|
||||||
|
|
||||||
if (rt != NULL) {
|
if (rt != NULL) {
|
||||||
spllprm *spobj = *spobjp = malloc(sizeof(spllprm));
|
spllprm *spobj = *spobjp = (spllprm *)malloc(sizeof(spllprm));
|
||||||
|
|
||||||
spobj->flag = 0;
|
spobj->flag = 0;
|
||||||
spobj->typ = SPP_REGION;
|
spobj->typ = SPP_REGION;
|
||||||
|
@ -2903,12 +2895,7 @@ void magic(void)
|
||||||
/* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */
|
/* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */
|
||||||
fumbled = true;
|
fumbled = true;
|
||||||
} else {
|
} else {
|
||||||
if (sp->sp_function == NULL) {
|
co->level = sp->cast(co);
|
||||||
log_error(("spell '%s' has no function.\n", sp->sname));
|
|
||||||
co->level = 0;
|
|
||||||
} else {
|
|
||||||
co->level = ((nspell_f) sp->sp_function) (co);
|
|
||||||
}
|
|
||||||
if (co->level <= 0) {
|
if (co->level <= 0) {
|
||||||
/* Kosten nur für real benötige Stufe berechnen */
|
/* Kosten nur für real benötige Stufe berechnen */
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -144,22 +144,15 @@ typedef struct sc_mage {
|
||||||
struct unit * co_get_caster(struct castorder * co);
|
struct unit * co_get_caster(struct castorder * co);
|
||||||
struct region * co_get_region(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 {
|
typedef struct spell_component {
|
||||||
const struct resource_type *type;
|
const struct resource_type *type;
|
||||||
int amount;
|
int amount;
|
||||||
int cost;
|
int cost;
|
||||||
} spell_component;
|
} spell_component;
|
||||||
|
|
||||||
|
typedef int (*spell_f)(castorder * co);
|
||||||
|
typedef void(*fumble_f)(castorder * co);
|
||||||
|
|
||||||
typedef struct spell {
|
typedef struct spell {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
char *sname;
|
char *sname;
|
||||||
|
@ -170,8 +163,8 @@ typedef struct sc_mage {
|
||||||
int rank; /* Reihenfolge der Zauber */
|
int rank; /* Reihenfolge der Zauber */
|
||||||
int level; /* Stufe des Zaubers */
|
int level; /* Stufe des Zaubers */
|
||||||
struct spell_component *components;
|
struct spell_component *components;
|
||||||
spell_f sp_function;
|
spell_f cast;
|
||||||
void (*patzer) (castorder *);
|
fumble_f patzer;
|
||||||
} spell;
|
} spell;
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
|
@ -1568,9 +1568,9 @@ static int parse_spells(xmlDocPtr doc)
|
||||||
}
|
}
|
||||||
assert(propValue != NULL);
|
assert(propValue != NULL);
|
||||||
if (strcmp((const char *)propValue, "cast") == 0) {
|
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) {
|
} else if (strcmp((const char *)propValue, "fumble") == 0) {
|
||||||
sp->patzer = (pspell_f) fun;
|
sp->patzer = (fumble_f) fun;
|
||||||
} else {
|
} else {
|
||||||
log_error(("unknown function type '%s' for spell %s\n",
|
log_error(("unknown function type '%s' for spell %s\n",
|
||||||
(const char *)propValue, sp->sname));
|
(const char *)propValue, sp->sname));
|
||||||
|
|
Loading…
Reference in a new issue