eliminate spell->id.

clean up some spell functions used by more than one spell.
This commit is contained in:
Enno Rehling 2017-05-01 17:04:28 +02:00
parent 3b11067825
commit fa7a3e246b
13 changed files with 112 additions and 242 deletions

View File

@ -23,7 +23,7 @@ void test_equipment(CuTest * tc)
enable_skill(SK_MAGIC, true); enable_skill(SK_MAGIC, true);
it_horses = test_create_itemtype("horse"); it_horses = test_create_itemtype("horse");
CuAssertPtrNotNull(tc, it_horses); CuAssertPtrNotNull(tc, it_horses);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
CuAssertPtrNotNull(tc, sp); CuAssertPtrNotNull(tc, sp);
CuAssertPtrEquals(tc, 0, get_equipment("herpderp")); CuAssertPtrEquals(tc, 0, get_equipment("herpderp"));

View File

@ -588,8 +588,8 @@ static void json_spells(cJSON *json) {
for (child = json->child; child; child = child->next) { for (child = json->child; child; child = child->next) {
if (child->type == cJSON_Object) { if (child->type == cJSON_Object) {
spell *sp; spell *sp;
cJSON * item = cJSON_GetObjectItem(child, "index"); cJSON * item;
sp = create_spell(child->string, item ? item->valueint : 0); sp = create_spell(child->string);
for (item = child->child; item; item = item->next) { for (item = child->child; item; item = item->next) {
if (strcmp(item->string, "index") == 0) { if (strcmp(item->string, "index") == 0) {
continue; continue;

View File

@ -85,7 +85,7 @@ void add_spell(struct selist **slistp, spell * sp)
} }
} }
spell * create_spell(const char * name, unsigned int id) spell * create_spell(const char * name)
{ {
spell * sp; spell * sp;
char buffer[64]; char buffer[64];
@ -100,7 +100,6 @@ spell * create_spell(const char * name, unsigned int id)
sp = (spell *)calloc(1, sizeof(spell)); sp = (spell *)calloc(1, sizeof(spell));
len = cb_new_kv(name, len, &sp, sizeof(sp), buffer); len = cb_new_kv(name, len, &sp, sizeof(sp), buffer);
if (cb_insert(&cb_spells, buffer, len) == CB_SUCCESS) { if (cb_insert(&cb_spells, buffer, len) == CB_SUCCESS) {
sp->id = id ? id : hashstring(name);
sp->sname = strdup(name); sp->sname = strdup(name);
add_spell(&spells, sp); add_spell(&spells, sp);
return sp; return sp;
@ -144,31 +143,6 @@ spell *find_spell(const char *name)
return sp; return sp;
} }
spell *find_spellbyid(unsigned int id)
{
selist *ql;
int qi;
if (id == 0)
return NULL;
for (qi = 0, ql = spells; ql; selist_advance(&ql, &qi, 1)) {
spell *sp = (spell *)selist_get(ql, qi);
if (sp->id == id) {
return sp;
}
}
for (qi = 0, ql = spells; ql; selist_advance(&ql, &qi, 1)) {
spell *sp = (spell *)selist_get(ql, qi);
unsigned int hashid = hashstring(sp->sname);
if (hashid == id) {
return sp;
}
}
log_warning("cannot find spell by id: %u\n", id);
return NULL;
}
struct spellref *spellref_create(spell *sp, const char *name) struct spellref *spellref_create(spell *sp, const char *name)
{ {
spellref *spref = malloc(sizeof(spellref)); spellref *spref = malloc(sizeof(spellref));

View File

@ -34,7 +34,6 @@ extern "C" {
typedef void(*fumble_f)(const struct castorder * co); typedef void(*fumble_f)(const struct castorder * co);
typedef struct spell { typedef struct spell {
unsigned int id;
char *sname; char *sname;
char *syntax; char *syntax;
char *parameter; char *parameter;
@ -58,9 +57,8 @@ extern "C" {
int sp_antimagiczone(struct castorder *co); int sp_antimagiczone(struct castorder *co);
struct spell * create_spell(const char * name, unsigned int id); struct spell * create_spell(const char * name);
struct spell * find_spell(const char *name); struct spell * find_spell(const char *name);
struct spell * find_spellbyid(unsigned int i);
void add_spell(struct selist **slistp, spell * sp); void add_spell(struct selist **slistp, spell * sp);
void free_spells(void); void free_spells(void);

View File

@ -19,7 +19,7 @@ static void test_create_a_spell(CuTest * tc)
CuAssertPtrEquals(tc, 0, spells); CuAssertPtrEquals(tc, 0, spells);
CuAssertPtrEquals(tc, 0, find_spell("testspell")); CuAssertPtrEquals(tc, 0, find_spell("testspell"));
sp = create_spell("testspell", 0); sp = create_spell("testspell");
CuAssertPtrEquals(tc, sp, find_spell("testspell")); CuAssertPtrEquals(tc, sp, find_spell("testspell"));
CuAssertPtrNotNull(tc, spells); CuAssertPtrNotNull(tc, spells);
test_cleanup(); test_cleanup();
@ -37,8 +37,8 @@ static void test_create_duplicate_spell(CuTest * tc)
CuAssertPtrEquals(tc, 0, find_spell("testspell")); CuAssertPtrEquals(tc, 0, find_spell("testspell"));
sp = create_spell("testspell", 0); sp = create_spell("testspell");
CuAssertPtrEquals(tc, 0, create_spell("testspell", 0)); CuAssertPtrEquals(tc, 0, create_spell("testspell"));
CuAssertPtrNotNull(tc, sl); CuAssertPtrNotNull(tc, sl);
CuAssertStrEquals(tc, "create_spell: duplicate name '%s'", sl->s); CuAssertStrEquals(tc, "create_spell: duplicate name '%s'", sl->s);
CuAssertPtrEquals(tc, 0, sl->next); CuAssertPtrEquals(tc, 0, sl->next);
@ -47,28 +47,6 @@ static void test_create_duplicate_spell(CuTest * tc)
test_cleanup(); test_cleanup();
} }
static void test_create_spell_with_id(CuTest * tc)
{
spell *sp;
struct log_t *log;
strlist *sl = 0;
test_setup();
test_log_stderr(0);
log = test_log_start(LOG_CPERROR, &sl);
CuAssertPtrEquals(tc, 0, find_spellbyid(42));
sp = create_spell("testspell", 42);
CuAssertPtrEquals(tc, sp, find_spellbyid(42));
CuAssertPtrEquals(tc, 0, create_spell("testspell", 47));
CuAssertPtrEquals(tc, 0, find_spellbyid(47));
CuAssertPtrNotNull(tc, sl);
CuAssertStrEquals(tc, "create_spell: duplicate name '%s'", sl->s);
CuAssertPtrEquals(tc, 0, sl->next);
test_log_stop(log, sl);
test_cleanup();
}
static void test_spellref(CuTest *tc) static void test_spellref(CuTest *tc)
{ {
spellref *ref; spellref *ref;
@ -79,7 +57,7 @@ static void test_spellref(CuTest *tc)
CuAssertPtrEquals(tc, NULL, ref->sp); CuAssertPtrEquals(tc, NULL, ref->sp);
CuAssertStrEquals(tc, "hodor", ref->name); CuAssertStrEquals(tc, "hodor", ref->name);
CuAssertPtrEquals(tc, NULL, spellref_get(ref)); CuAssertPtrEquals(tc, NULL, spellref_get(ref));
sp = create_spell("hodor", 0); sp = create_spell("hodor");
CuAssertPtrNotNull(tc, sp); CuAssertPtrNotNull(tc, sp);
CuAssertPtrEquals(tc, sp, spellref_get(ref)); CuAssertPtrEquals(tc, sp, spellref_get(ref));
spellref_free(ref); spellref_free(ref);
@ -113,6 +91,5 @@ CuSuite *get_spell_suite(void)
SUITE_ADD_TEST(suite, test_fumbles); SUITE_ADD_TEST(suite, test_fumbles);
SUITE_ADD_TEST(suite, test_create_a_spell); SUITE_ADD_TEST(suite, test_create_a_spell);
SUITE_ADD_TEST(suite, test_create_duplicate_spell); SUITE_ADD_TEST(suite, test_create_duplicate_spell);
SUITE_ADD_TEST(suite, test_create_spell_with_id);
return suite; return suite;
} }

View File

@ -33,7 +33,7 @@ void test_named_spellbooks(CuTest * tc)
CuAssertPtrNotNull(tc, sb); CuAssertPtrNotNull(tc, sb);
CuAssertStrEquals(tc, "spells", sb->name); CuAssertStrEquals(tc, "spells", sb->name);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
spellbook_add(sb, sp, 1); spellbook_add(sb, sp, 1);
CuAssertPtrNotNull(tc, sb->spells); CuAssertPtrNotNull(tc, sb->spells);

View File

@ -1328,14 +1328,12 @@ static int parse_spells(xmlDocPtr doc)
int k; int k;
spell_component *component; spell_component *component;
spell *sp; spell *sp;
unsigned int index;
static int modes[] = { 0, PRECOMBATSPELL, COMBATSPELL, POSTCOMBATSPELL }; static int modes[] = { 0, PRECOMBATSPELL, COMBATSPELL, POSTCOMBATSPELL };
/* spellname */ /* spellname */
index = xml_ivalue(node, "index", 0);
propValue = xmlGetProp(node, BAD_CAST "name"); propValue = xmlGetProp(node, BAD_CAST "name");
assert(propValue != NULL); assert(propValue != NULL);
sp = create_spell((const char *)propValue, index); sp = create_spell((const char *)propValue);
xmlFree(propValue); xmlFree(propValue);
if (!sp) { if (!sp) {
continue; continue;

View File

@ -339,23 +339,16 @@ sc_mage *get_mage(const unit * u)
static int read_seenspell(attrib * a, void *owner, struct gamedata *data) static int read_seenspell(attrib * a, void *owner, struct gamedata *data)
{ {
storage *store = data->store; storage *store = data->store;
int i;
spell *sp = 0; spell *sp = 0;
char token[32]; char token[32];
READ_TOK(store, token, sizeof(token)); READ_TOK(store, token, sizeof(token));
i = atoip(token); if (data->version < UNIQUE_SPELLS_VERSION) {
if (i != 0) { READ_INT(store, 0); /* ignore mtype */
sp = find_spellbyid((unsigned int)i);
} }
else { sp = find_spell(token);
if (data->version < UNIQUE_SPELLS_VERSION) { if (!sp) {
READ_INT(store, 0); /* ignore mtype */ log_warning("read_seenspell: could not find spell '%s'\n", token);
}
sp = find_spell(token);
if (!sp) {
log_warning("read_seenspell: could not find spell '%s'\n", token);
}
} }
if (!sp) { if (!sp) {
return AT_READ_FAIL; return AT_READ_FAIL;
@ -898,9 +891,7 @@ void pay_spell(unit * u, const spell * sp, int cast_level, int range)
bool knowsspell(const region * r, const unit * u, const spell * sp) bool knowsspell(const region * r, const unit * u, const spell * sp)
{ {
/* Ist überhaupt ein gültiger Spruch angegeben? */ /* Ist überhaupt ein gültiger Spruch angegeben? */
if (!sp || sp->id == 0) { assert(sp);
return false;
}
/* steht der Spruch in der Spruchliste? */ /* steht der Spruch in der Spruchliste? */
return u_hasspell(u, sp) != 0; return u_hasspell(u, sp) != 0;
} }

View File

@ -34,7 +34,7 @@ void test_updatespells(CuTest * tc)
test_create_race("human"); test_create_race("human");
f = test_create_faction(0); f = test_create_faction(0);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
CuAssertPtrNotNull(tc, sp); CuAssertPtrNotNull(tc, sp);
book = create_spellbook("spells"); book = create_spellbook("spells");
@ -67,7 +67,7 @@ void test_spellbooks(CuTest * tc)
CuAssertStrEquals(tc, "herp", herp->name); CuAssertStrEquals(tc, "herp", herp->name);
CuAssertStrEquals(tc, "derp", derp->name); CuAssertStrEquals(tc, "derp", derp->name);
sp = create_spell(sname, 0); sp = create_spell(sname);
spellbook_add(herp, sp, 1); spellbook_add(herp, sp, 1);
CuAssertPtrNotNull(tc, sp); CuAssertPtrNotNull(tc, sp);
entry = spellbook_get(herp, sp); entry = spellbook_get(herp, sp);
@ -170,7 +170,7 @@ void test_getspell_unit(CuTest * tc)
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
lang = test_create_locale(); lang = test_create_locale();
sp = create_spell("testspell", 0); sp = create_spell("testspell");
locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp");
CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang));
@ -199,7 +199,7 @@ void test_getspell_faction(CuTest * tc)
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
lang = test_create_locale(); lang = test_create_locale();
sp = create_spell("testspell", 0); sp = create_spell("testspell");
locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp");
CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang));
@ -229,7 +229,7 @@ void test_getspell_school(CuTest * tc)
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
lang = test_create_locale(); lang = test_create_locale();
sp = create_spell("testspell", 0); sp = create_spell("testspell");
locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp");
CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang));
@ -256,7 +256,7 @@ void test_set_pre_combatspell(CuTest * tc)
u = test_create_unit(f, r); u = test_create_unit(f, r);
enable_skill(SK_MAGIC, true); enable_skill(SK_MAGIC, true);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
sp->sptyp |= PRECOMBATSPELL; sp->sptyp |= PRECOMBATSPELL;
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, 0, sp, 1);
@ -288,7 +288,7 @@ void test_set_main_combatspell(CuTest * tc)
u = test_create_unit(f, r); u = test_create_unit(f, r);
enable_skill(SK_MAGIC, true); enable_skill(SK_MAGIC, true);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
sp->sptyp |= COMBATSPELL; sp->sptyp |= COMBATSPELL;
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, 0, sp, 1);
@ -320,7 +320,7 @@ void test_set_post_combatspell(CuTest * tc)
u = test_create_unit(f, r); u = test_create_unit(f, r);
enable_skill(SK_MAGIC, true); enable_skill(SK_MAGIC, true);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
sp->sptyp |= POSTCOMBATSPELL; sp->sptyp |= POSTCOMBATSPELL;
unit_add_spell(u, 0, sp, 1); unit_add_spell(u, 0, sp, 1);
@ -350,7 +350,7 @@ void test_hasspell(CuTest * tc)
f->magiegebiet = M_TYBIED; f->magiegebiet = M_TYBIED;
u = test_create_unit(f, r); u = test_create_unit(f, r);
enable_skill(SK_MAGIC, true); enable_skill(SK_MAGIC, true);
sp = create_spell("testspell", 0); sp = create_spell("testspell");
sp->sptyp |= POSTCOMBATSPELL; sp->sptyp |= POSTCOMBATSPELL;
unit_add_spell(u, 0, sp, 2); unit_add_spell(u, 0, sp, 2);
@ -379,7 +379,7 @@ void test_multi_cast(CuTest *tc) {
struct locale * lang; struct locale * lang;
test_setup(); test_setup();
sp = create_spell("fireball", 0); sp = create_spell("fireball");
sp->cast_fun = cast_fireball; sp->cast_fun = cast_fireball;
CuAssertPtrEquals(tc, sp, find_spell("fireball")); CuAssertPtrEquals(tc, sp, find_spell("fireball"));

View File

@ -6444,6 +6444,54 @@ int sp_break_curse(castorder * co)
return cast_level; return cast_level;
} }
static int sp_flee(castorder *co) {
if (co->force <= 0) {
return 0;
}
return flee_spell(co, 4);
}
static int sp_song_of_fear(castorder *co) {
if (co->force <= 0) {
return 0;
}
return flee_spell(co, 3);
}
static int sp_aura_of_fear(castorder *co) {
if (co->force <= 0) {
return 0;
}
return flee_spell(co, 5);
}
static int sp_armor_shield(struct castorder * co) {
return armor_spell(co, 3, 20);
}
static int sp_bark_skin(struct castorder * co) {
return armor_spell(co, 4, 1);
}
static int sp_kampfzauber(castorder *co) {
const spell * sp = co->sp;
if (co->force <= 0) {
return 0;
}
else if (strcmp(sp->sname, "fireball") == 0) {
return damage_spell(co, 0, 0);
}
else if (strcmp(sp->sname, "hail") == 0) {
return damage_spell(co, 2, 4);
}
else if (strcmp(sp->sname, "meteor_rain") == 0) {
return damage_spell(co, 1, 1);
}
else {
return damage_spell(co, 10, 10);
}
}
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
int sp_becomewyrm(castorder * co) int sp_becomewyrm(castorder * co)
{ {
@ -6486,7 +6534,7 @@ static spelldata spell_functions[] = {
{ "holyground", sp_holyground, 0 }, { "holyground", sp_holyground, 0 },
{ "summonent", sp_summonent, 0 }, { "summonent", sp_summonent, 0 },
{ "blessstonecircle", sp_blessstonecircle, 0 }, { "blessstonecircle", sp_blessstonecircle, 0 },
{ "barkskin", sp_armorshield, 0 }, { "barkskin", sp_bark_skin, 0 },
{ "summonfireelemental", sp_drought, 0 }, { "summonfireelemental", sp_drought, 0 },
{ "maelstrom", sp_maelstrom, 0 }, { "maelstrom", sp_maelstrom, 0 },
{ "magic_roots", sp_mallorn, 0 }, { "magic_roots", sp_mallorn, 0 },
@ -6539,7 +6587,7 @@ static spelldata spell_functions[] = {
{ "appeasement", sp_denyattack, 0 }, { "appeasement", sp_denyattack, 0 },
{ "song_of_healing", sp_healing, 0 }, { "song_of_healing", sp_healing, 0 },
{ "generous", sp_generous, 0 }, { "generous", sp_generous, 0 },
{ "song_of_fear", sp_flee, 0 }, { "song_of_fear", sp_song_of_fear, 0 },
{ "courting", sp_recruit, 0 }, { "courting", sp_recruit, 0 },
{ "song_of_confusion", sp_chaosrow, 0 }, { "song_of_confusion", sp_chaosrow, 0 },
{ "heroic_song", sp_hero, 0 }, { "heroic_song", sp_hero, 0 },
@ -6591,7 +6639,7 @@ static spelldata spell_functions[] = {
{ "combat_speed", sp_speed, 0 }, { "combat_speed", sp_speed, 0 },
{ "view_reality", sp_viewreality, 0 }, { "view_reality", sp_viewreality, 0 },
{ "double_time", sp_speed2, 0 }, { "double_time", sp_speed2, 0 },
{ "armor_shield", sp_armorshield, 0 }, { "armor_shield", sp_armor_shield, 0 },
{ "living_rock", sp_movecastle, 0 }, { "living_rock", sp_movecastle, 0 },
{ "astral_disruption", sp_disruptastral, 0 }, { "astral_disruption", sp_disruptastral, 0 },
{ "sacrifice_strength", sp_permtransfer, 0 }, { "sacrifice_strength", sp_permtransfer, 0 },
@ -6603,7 +6651,7 @@ static spelldata spell_functions[] = {
{ "icy_dragonbreath", sp_dragonodem, 0 }, { "icy_dragonbreath", sp_dragonodem, 0 },
{ "powerful_dragonbreath", sp_dragonodem, 0 }, { "powerful_dragonbreath", sp_dragonodem, 0 },
{ "drain_skills", sp_dragonodem, 0 }, { "drain_skills", sp_dragonodem, 0 },
{ "aura_of_fear", sp_flee, 0 }, { "aura_of_fear", sp_aura_of_fear, 0 },
{ "immolation", sp_immolation, 0 }, { "immolation", sp_immolation, 0 },
{ "firestorm", sp_immolation, 0 }, { "firestorm", sp_immolation, 0 },
{ "coldfront", sp_immolation, 0 }, { "coldfront", sp_immolation, 0 },

View File

@ -47,31 +47,6 @@
#define EFFECT_HEALING_SPELL 5 #define EFFECT_HEALING_SPELL 5
/* Some spells with a fixed, known ID (in XML).
* TODO: this method of identifying spells is error-prone,
* do not use it for new spells. */
enum {
SPL_FIREBALL = 4,
SPL_HAGEL = 5,
SPL_CHAOSROW = 18,
SPL_FLEE = 20,
SPL_SONG_OF_FEAR = 21,
SPL_BERSERK = 22,
SPL_BLOODTHIRST = 23,
SPL_WINDSHIELD = 59,
SPL_HERO = 76,
SPL_METEORRAIN = 108,
SPL_REDUCESHIELD = 109,
SPL_ARMORSHIELD = 110,
SPL_DRAIG_FUMBLESHIELD = 143,
SPL_GWYRRD_FUMBLESHIELD = 144,
SPL_CERDDOR_FUMBLESHIELD = 145,
SPL_TYBIED_FUMBLESHIELD = 146,
SPL_SHADOWKNIGHTS = 147,
SPL_SHOCKWAVE = 163,
SPL_AURA_OF_FEAR = 175
};
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Kampfzauberfunktionen */ /* Kampfzauberfunktionen */
@ -134,44 +109,23 @@ static double get_force(double power, int formel)
} }
/* Generischer Kampfzauber */ /* Generischer Kampfzauber */
int sp_kampfzauber(struct castorder * co) int damage_spell(struct castorder * co, int dmg, int strength)
{ {
fighter * fi = co->magician.fig; fighter * fi = co->magician.fig;
int level = co->level; int level = co->level;
double power = co->force;
const spell * sp = co->sp; const spell * sp = co->sp;
double power = co->force;
battle *b = fi->side->battle; battle *b = fi->side->battle;
troop at, dt; troop at, dt;
message *m; message *m;
/* Immer aus der ersten Reihe nehmen */ /* Immer aus der ersten Reihe nehmen */
int force, enemies; int enemies, killed = 0;
int killed = 0; int force = lovar(get_force(power, strength));
const char *damage; const char *damage = spell_damage(dmg);
if (power <= 0)
return 0;
at.fighter = fi; at.fighter = fi;
at.index = 0; at.index = 0;
switch (sp->id) {
/* lovar halbiert im Schnitt! */
case SPL_FIREBALL:
damage = spell_damage(0);
force = lovar(get_force(power, 0));
break;
case SPL_HAGEL:
damage = spell_damage(2);
force = lovar(get_force(power, 4));
break;
case SPL_METEORRAIN:
damage = spell_damage(1);
force = lovar(get_force(power, 1));
break;
default:
damage = spell_damage(10);
force = lovar(get_force(power, 10));
}
enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
if (enemies == 0) { if (enemies == 0) {
message *m = message *m =
@ -257,13 +211,7 @@ int sp_stun(struct castorder * co)
if (power <= 0) if (power <= 0)
return 0; return 0;
switch (sp->id) { force = lovar(get_force(power, 1));
case SPL_SHOCKWAVE:
force = lovar(get_force(power, 1));
break;
default:
assert(0);
}
enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
@ -956,6 +904,7 @@ int sp_chaosrow(struct castorder * co)
message *m; message *m;
const char *mtype; const char *mtype;
int qi, k = 0; int qi, k = 0;
bool chaosrow = strcmp(sp->sname, "chaosrow") == 0;
if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE | SELECT_FIND)) { if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE | SELECT_FIND)) {
m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
@ -964,10 +913,7 @@ int sp_chaosrow(struct castorder * co)
return 0; return 0;
} }
if (sp->id == SPL_CHAOSROW) power = chaosrow ? (power * 40) : get_force(power, 5);
power *= 40;
else
power = get_force(power, 5);
fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY); fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY);
scramble_fighters(fgs); scramble_fighters(fgs);
@ -1019,7 +965,7 @@ int sp_chaosrow(struct castorder * co)
} }
selist_free(fgs); selist_free(fgs);
if (sp->id == SPL_CHAOSROW) { if (chaosrow) {
mtype = (k > 0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0"; mtype = (k > 0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0";
} }
else { else {
@ -1034,33 +980,20 @@ int sp_chaosrow(struct castorder * co)
/* Gesang der Furcht (Kampfzauber) */ /* Gesang der Furcht (Kampfzauber) */
/* Panik (Pr<50>kampfzauber) */ /* Panik (Pr<50>kampfzauber) */
int sp_flee(struct castorder * co) int flee_spell(struct castorder * co, int strength)
{ {
fighter * fi = co->magician.fig; fighter * fi = co->magician.fig;
int level = co->level; int level = co->level;
double power = co->force;
const spell * sp = co->sp; const spell * sp = co->sp;
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
selist *fgs, *ql; selist *fgs, *ql;
int force, n, qi; int n, qi, panik = 0;
int panik = 0;
message *msg; message *msg;
double power = co->force;
int force;
switch (sp->id) { force = (int)get_force(power, strength);
case SPL_FLEE:
force = (int)get_force(power, 4);
break;
case SPL_SONG_OF_FEAR:
force = (int)get_force(power, 3);
break;
case SPL_AURA_OF_FEAR:
force = (int)get_force(power, 5);
break;
default:
force = (int)get_force(power, 10);
}
if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) { if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) {
msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp); msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp);
message_all(b, msg); message_all(b, msg);
@ -1116,16 +1049,8 @@ int sp_hero(struct castorder * co)
int targets = 0; int targets = 0;
message *m; message *m;
switch (sp->id) { df_bonus = (int)(power / 5);
case SPL_HERO: force = MAX(1, lovar(get_force(power, 4)));
df_bonus = (int)(power / 5);
force = MAX(1, lovar(get_force(power, 4)));
break;
default:
df_bonus = 1;
force = MAX(1, (int)power);
}
allies = allies =
count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY); count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY);
@ -1170,19 +1095,9 @@ int sp_berserk(struct castorder * co)
int targets = 0; int targets = 0;
message *m; message *m;
switch (sp->id) { at_bonus = MAX(1, level / 3);
case SPL_BERSERK: df_malus = 2;
case SPL_BLOODTHIRST: force = (int)get_force(power, 2);
at_bonus = MAX(1, level / 3);
df_malus = 2;
force = (int)get_force(power, 2);
break;
default:
at_bonus = 1;
df_malus = 0;
force = (int)power;
}
allies = allies =
count_allies(fi->side, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE, ALLY_ANY); count_allies(fi->side, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE, ALLY_ANY);
@ -1327,16 +1242,9 @@ int sp_windshield(struct castorder * co)
int enemies; int enemies;
message *m; message *m;
switch (sp->id) { force = (int)get_force(power, 4);
case SPL_WINDSHIELD: at_malus = level / 4;
force = (int)get_force(power, 4);
at_malus = level / 4;
break;
default:
force = (int)power;
at_malus = 2;
}
enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE); enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
@ -1429,7 +1337,7 @@ static void do_meffect(fighter * af, int typ, int effect, int duration)
me->duration = duration; me->duration = duration;
} }
int sp_armorshield(struct castorder * co) int armor_spell(struct castorder * co, int per_level, int time_multi)
{ {
fighter * fi = co->magician.fig; fighter * fi = co->magician.fig;
int level = co->level; int level = co->level;
@ -1445,16 +1353,8 @@ int sp_armorshield(struct castorder * co)
/* gibt R<>stung +effect f<>r duration Treffer */ /* gibt R<>stung +effect f<>r duration Treffer */
switch (sp->id) { effect = level / per_level;
case SPL_ARMORSHIELD: duration = (int)(time_multi * power * power);
effect = level / 3;
duration = (int)(20 * power * power);
break;
default:
effect = level / 4;
duration = (int)(power * power);
}
do_meffect(fi, SHIELD_ARMOR, effect, duration); do_meffect(fi, SHIELD_ARMOR, effect, duration);
return level; return level;
} }
@ -1475,16 +1375,9 @@ int sp_reduceshield(struct castorder * co)
/* jeder Schaden wird um effect% reduziert bis der Schild duration /* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */ * Trefferpunkte aufgefangen hat */
switch (sp->id) { effect = 50;
case SPL_REDUCESHIELD: duration = (int)(50 * power * power);
effect = 50;
duration = (int)(50 * power * power);
break;
default:
effect = level * 3;
duration = (int)get_force(power, 5);
}
do_meffect(fi, SHIELD_REDUCE, effect, duration); do_meffect(fi, SHIELD_REDUCE, effect, duration);
return level; return level;
} }
@ -1503,20 +1396,9 @@ int sp_fumbleshield(struct castorder * co)
msg_release(m); msg_release(m);
/* der erste Zauber schl<68>gt mit 100% fehl */ /* der erste Zauber schl<68>gt mit 100% fehl */
duration = 100;
effect = MAX(1, 25 - level);
switch (sp->id) {
case SPL_DRAIG_FUMBLESHIELD:
case SPL_GWYRRD_FUMBLESHIELD:
case SPL_CERDDOR_FUMBLESHIELD:
case SPL_TYBIED_FUMBLESHIELD:
duration = 100;
effect = MAX(1, 25 - level);
break;
default:
duration = 100;
effect = 10;
}
do_meffect(fi, SHIELD_BLOCK, effect, duration); do_meffect(fi, SHIELD_BLOCK, effect, duration);
return level; return level;
} }

View File

@ -23,12 +23,10 @@ extern "C" {
int sp_fumbleshield(struct castorder * co); int sp_fumbleshield(struct castorder * co);
int sp_shadowknights(struct castorder * co); int sp_shadowknights(struct castorder * co);
int sp_combatrosthauch(struct castorder * co); int sp_combatrosthauch(struct castorder * co);
int sp_kampfzauber(struct castorder * co);
int sp_healing(struct castorder * co); int sp_healing(struct castorder * co);
int sp_keeploot(struct castorder * co); int sp_keeploot(struct castorder * co);
int sp_reanimate(struct castorder * co); int sp_reanimate(struct castorder * co);
int sp_chaosrow(struct castorder * co); int sp_chaosrow(struct castorder * co);
int sp_flee(struct castorder * co);
int sp_berserk(struct castorder * co); int sp_berserk(struct castorder * co);
int sp_tiredsoldiers(struct castorder * co); int sp_tiredsoldiers(struct castorder * co);
int sp_reeling_arrows(struct castorder * co); int sp_reeling_arrows(struct castorder * co);
@ -51,6 +49,10 @@ extern "C" {
int sp_undeadhero(struct castorder * co); int sp_undeadhero(struct castorder * co);
int sp_immolation(struct castorder * co); int sp_immolation(struct castorder * co);
int flee_spell(struct castorder * co, int strength);
int damage_spell(struct castorder * co, int dmg, int strength);
int armor_spell(struct castorder * co, int per_level, int time_multi);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -356,7 +356,7 @@ void test_create_castorder(castorder *co, unit *u, int level, float force, int r
spell * test_create_spell(void) spell * test_create_spell(void)
{ {
spell *sp; spell *sp;
sp = create_spell("testspell", 0); sp = create_spell("testspell");
sp->components = (spell_component *)calloc(4, sizeof(spell_component)); sp->components = (spell_component *)calloc(4, sizeof(spell_component));
assert_alloc(sp->components); assert_alloc(sp->components);