summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2012-06-30 08:51:51 +0200
committerBardur Arantsson <bardur@scientician.net>2012-06-30 20:40:26 +0200
commit763a1c383895f5f04d025ba6ebf79aee9425df70 (patch)
treebaaed2501a0a9815ee95261d856661244128c682
parentf7e87bc98111f97ca489e1f13999058a7df8171e (diff)
Change spell_type to a semi-ADT
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/angband.h1
-rw-r--r--src/cmd5.c5
-rw-r--r--src/cmd6.c40
-rw-r--r--src/dungeon.c5
-rw-r--r--src/externs.h12
-rw-r--r--src/lua_bind.c32
-rw-r--r--src/object1.c36
-rw-r--r--src/object2.c44
-rw-r--r--src/spell_type.c465
-rw-r--r--src/spell_type.h103
-rw-r--r--src/spell_type_fwd.h27
-rw-r--r--src/spells1.c4
-rw-r--r--src/spells3.c52
-rw-r--r--src/spells4.c143
-rw-r--r--src/spells5.c3020
-rw-r--r--src/spells6.c178
-rw-r--r--src/store.c5
-rw-r--r--src/types.h66
-rw-r--r--src/variable.c2
20 files changed, 2262 insertions, 1979 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 50bb33de..03c1771b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,6 +8,7 @@ SET(SRCS
monster1.c monster2.c monster3.c
xtra1.c xtra2.c skills.c powers.c gods.c
spells1.c spells2.c spells3.c spells4.c spells5.c spells6.c
+ spell_type.c
corrupt.c joke.c mimic.c
status.c files.c notes.c loadsave.c string_list.c
cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c
diff --git a/src/angband.h b/src/angband.h
index 93e3b76e..6bfbb984 100644
--- a/src/angband.h
+++ b/src/angband.h
@@ -55,6 +55,7 @@ extern "C" {
*/
#include "defines.h"
#include "types.h"
+#include "spell_type_fwd.h"
#include "externs.h"
#include "plots.h"
diff --git a/src/cmd5.c b/src/cmd5.c
index c32d5690..9571ce99 100644
--- a/src/cmd5.c
+++ b/src/cmd5.c
@@ -15,6 +15,7 @@
#include <assert.h>
+#include "spell_type.h"
#include "quark.h"
/* Maximum number of tries for teleporting */
@@ -2135,7 +2136,7 @@ bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr)
return FALSE;
}
- if (o_ptr->pval < spell->minimum_pval)
+ if (o_ptr->pval < spell_type_minimum_pval(spell))
{
return FALSE;
}
@@ -2454,7 +2455,7 @@ void do_cmd_copy_spell()
if (spell == -1) return;
/* Spells that cannot be randomly created cannot be copied */
- if (can_spell_random(spell) <= 0)
+ if (spell_type_random_type(spell_at(spell)) <= 0)
{
msg_print("This spell cannot be copied.");
return;
diff --git a/src/cmd6.c b/src/cmd6.c
index 5377ef38..f15860b9 100644
--- a/src/cmd6.c
+++ b/src/cmd6.c
@@ -12,6 +12,7 @@
#include "angband.h"
+#include "spell_type.h"
/*
* Forward declare
@@ -3666,9 +3667,8 @@ static void activate_stick(s16b s, bool_ *obvious, bool_ *use_charge)
assert(obvious != NULL);
assert(use_charge != NULL);
- assert(spell->effect_func != NULL);
- ret = spell->effect_func(-1);
+ ret = spell_type_produce_effect(spell, -1);
switch (ret)
{
@@ -5029,35 +5029,6 @@ void do_cmd_activate(void)
msg_print("Oops. That object cannot be activated.");
}
-
-static void get_activation_desc(char *buf, int spl)
-{
- spell_type *spell = spell_at(spl);
- char turns[32];
-
- dice_print(&spell->activation_duration, turns);
-
- assert(spell->description != NULL);
- assert(spell->description->s != NULL);
-
- sprintf(buf, "%s every %s turns",
- spell->description->s,
- turns);
-}
-
-static int get_activation_timeout(int spl)
-{
- spell_type *spell = spell_at(spl);
- return dice_roll(&spell->activation_duration);
-}
-
-static void activate_activation(long s, int item)
-{
- spell_type *spell = spell_at(s);
- assert(spell->effect_func != NULL);
- spell->effect_func(item);
-}
-
const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
static char buf[256];
@@ -5100,14 +5071,15 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
/* Negative means a unified spell index */
if (spell < 0)
{
+ struct spell_type *spell_ptr = spell_at(-spell);
if (doit)
{
- activate_activation(-spell, item);
- o_ptr->timeout = get_activation_timeout(-spell);
+ spell_type_produce_effect(spell_ptr, item);
+ o_ptr->timeout = spell_type_activation_roll_timeout(spell_ptr);
}
else
{
- get_activation_desc(buf, -spell);
+ spell_type_activation_description(spell_ptr, buf);
return buf;
}
}
diff --git a/src/dungeon.c b/src/dungeon.c
index ae8d6912..a74fed2c 100644
--- a/src/dungeon.c
+++ b/src/dungeon.c
@@ -15,6 +15,7 @@
#include <assert.h>
#include "quark.h"
+#include "spell_type.h"
#define TY_CURSE_CHANCE 100
#define DG_CURSE_CHANCE 50
@@ -801,9 +802,7 @@ bool_ decays(object_type *o_ptr)
static int process_lasting_spell(s16b music)
{
spell_type *spell = spell_at(-music);
-
- assert(spell->lasting_func != NULL);
- return spell->lasting_func();
+ return spell_type_produce_effect_lasting(spell);
}
static void gere_class_special()
diff --git a/src/externs.h b/src/externs.h
index cab134d7..290a3152 100644
--- a/src/externs.h
+++ b/src/externs.h
@@ -542,7 +542,7 @@ extern int max_bg_idx;
extern s32b extra_savefile_parts;
extern bool_ player_char_health;
extern s16b school_spells_count;
-extern spell_type school_spells[SCHOOL_SPELLS_MAX];
+extern spell_type *school_spells[SCHOOL_SPELLS_MAX];
extern s16b schools_count;
extern school_type schools[SCHOOLS_MAX];
extern int project_time;
@@ -1894,7 +1894,6 @@ char *varda_star_kindler_info();
/* spells4.c */
SGLIB_DEFINE_LIST_PROTOTYPES(spell_idx_list, compare_spell_idx, next);
-SGLIB_DEFINE_LIST_PROTOTYPES(school_idx, compare_school_idx, next);
extern s32b SCHOOL_AIR;
extern s32b SCHOOL_AULE;
@@ -1922,10 +1921,6 @@ extern s32b SCHOOL_VARDA;
extern s32b SCHOOL_WATER;
extern s32b SCHOOL_YAVANNA;
-void school_idx_init(school_idx *e, s32b i);
-school_idx *school_idx_new(s32b i);
-void school_idx_add_new(school_idx **list, s32b i);
-
void print_spell_desc(int s, int y);
void init_school_books();
school_book_type *school_books_at(int sval);
@@ -1938,7 +1933,6 @@ int spell_x(int sval, int pval, int i);
bool_ school_book_contains_spell(int sval, s32b spell_idx);
void lua_cast_school_spell(s32b spell_idx, bool_ no_cost);
-void spell_description_add_line(s32b spell_idx, cptr line);
void device_allocation_init(device_allocation *device_allocation, byte tval);
device_allocation *device_allocation_new(byte tval);
@@ -1952,7 +1946,6 @@ void dice_print(dice_type *dice, char *buf);
void school_spells_init();
spell_type *spell_at(s32b index);
s16b get_random_spell(s16b random_type, int lev);
-bool_ check_spell_depends(spell_type *spell);
/* spells6.c */
@@ -2330,7 +2323,6 @@ extern int find_module(cptr name);
/* lua_bind.c */
-extern s16b can_spell_random(s16b spell_idx);
extern bool_ get_magic_power(int *sn, magic_power *powers, int max_powers, void (*power_info)(char *p, int power), int plev, int cast_stat);
extern s16b add_new_power(cptr name, cptr desc, cptr gain, cptr lose, byte level, byte cost, byte stat, byte diff);
@@ -2366,8 +2358,6 @@ extern timer_type *TIMER_AGGRAVATE_EVIL;
void timer_aggravate_evil_enable();
void timer_aggravate_evil_callback();
-cptr get_spell_info(s32b s);
-
/* skills.c */
extern void dump_skills(FILE *fff);
extern s16b find_skill(cptr name);
diff --git a/src/lua_bind.c b/src/lua_bind.c
index d6657bff..a15e9eb8 100644
--- a/src/lua_bind.c
+++ b/src/lua_bind.c
@@ -11,12 +11,10 @@
*/
#include "angband.h"
+
#include <assert.h>
-s16b can_spell_random(s16b spell_idx)
-{
- return spell_at(spell_idx)->random_type;
-}
+#include "spell_type.h"
/*
* Monsters
@@ -42,7 +40,7 @@ s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus)
{
s32b tmp;
- tmp = lvl - ((spell->skill_level - 1) * (SKILL_STEP / 10));
+ tmp = lvl - ((spell_type_skill_level(spell) - 1) * (SKILL_STEP / 10));
if (tmp >= (SKILL_STEP / 10)) /* We require at least one spell level */
tmp += bonus;
@@ -80,9 +78,9 @@ s32b get_level_device(s32b s, s32b max, s32b min)
lvl = lvl + (get_level_use_stick * SKILL_STEP);
/* Sticks are limited */
- if (lvl - ((spell->skill_level + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP)
+ if (lvl - ((spell_type_skill_level(spell) + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP)
{
- lvl = (get_level_max_stick + spell->skill_level - 1) * SKILL_STEP;
+ lvl = (get_level_max_stick + spell_type_skill_level(spell) - 1) * SKILL_STEP;
}
/* / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative
@@ -97,20 +95,22 @@ s32b get_level_device(s32b s, s32b max, s32b min)
int get_mana(s32b s)
{
spell_type *spell = spell_at(s);
- return get_level(s, spell->mana_range.max, spell->mana_range.min);
+ range_type mana_range;
+ spell_type_mana_range(spell, &mana_range);
+ return get_level(s, mana_range.max, mana_range.min);
}
/** Returns spell chance of failure for spell */
s32b spell_chance(s32b s)
{
- spell_type *s_ptr = &school_spells[s];
+ spell_type *s_ptr = spell_at(s);
int level = get_level(s, 50, 1);
/* Extract the base spell failure rate */
if (get_level_use_stick > -1)
{
int minfail;
- s32b chance = s_ptr->failure_rate;
+ s32b chance = spell_type_failure_rate(s_ptr);
/* Reduce failure rate by "effective" level adjustment */
chance -= (level - 1);
@@ -123,10 +123,10 @@ s32b spell_chance(s32b s)
}
else
{
- s32b chance = s_ptr->failure_rate;
+ s32b chance = spell_type_failure_rate(s_ptr);
int mana = get_mana(s);
int cur_mana = get_power(s);
- int stat = s_ptr->casting_stat;
+ int stat = spell_type_casting_stat(s_ptr);
int stat_ind = p_ptr->stat_ind[stat];
int minfail;
@@ -340,11 +340,3 @@ void timer_aggravate_evil_callback()
dispel_evil(0);
}
}
-
-cptr get_spell_info(s32b s)
-{
- spell_type *spell = spell_at(s);
-
- assert(spell->info_func != NULL);
- return spell->info_func();
-}
diff --git a/src/object1.c b/src/object1.c
index 3b17e8c2..504bc9c9 100644
--- a/src/object1.c
+++ b/src/object1.c
@@ -13,6 +13,7 @@
#include "angband.h"
#include "quark.h"
+#include "spell_type.h"
/*
* Hack -- note that "TERM_MULTI" is now just "TERM_VIOLET".
@@ -1662,7 +1663,10 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
case TV_BOOK:
{
basenm = k_name + k_ptr->name;
- if (o_ptr->sval == 255) modstr = school_spells[o_ptr->pval].name;
+ if (o_ptr->sval == 255)
+ {
+ modstr = spell_type_name(spell_at(o_ptr->pval));
+ }
break;
}
@@ -1941,7 +1945,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF)))
{
- t = object_desc_str(t, school_spells[o_ptr->pval2].name);
+ t = object_desc_str(t, spell_type_name(spell_at(o_ptr->pval2)));
if (mode >= 1)
{
s32b bonus = o_ptr->pval3 & 0xFFFF;
@@ -2021,7 +2025,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* It contains a spell */
if ((known) && (f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 != -1))
{
- t = object_desc_str(t, format(" [%s]", school_spells[o_ptr->pval2].name));
+ t = object_desc_str(t, format(" [%s]", spell_type_name(spell_at(o_ptr->pval2))));
}
/* Add symbiote hp here, after the "fake-artifact" name. --dsb */
@@ -2799,20 +2803,12 @@ void display_ammo_damage(object_type *o_ptr)
}
/*
- * Describe the device spell
+ * Output spell description
*/
-static void print_device_desc(int s)
+static void print_device_desc_callback(void *data, cptr text)
{
- string_list *sl;
- struct sglib_string_list_iterator it;
-
- for (sl = sglib_string_list_it_init(&it, school_spells[s].description);
- sl != NULL;
- sl = sglib_string_list_it_next(&it))
- {
- text_out("\n");
- text_out(sl->s);
- }
+ text_out("\n");
+ text_out(text);
}
/*
@@ -2828,22 +2824,24 @@ void describe_device(object_type *o_ptr)
/* Enter device mode */
set_stick_mode(o_ptr);
- text_out("\nSpell description:");
- print_device_desc(o_ptr->pval2);
+ text_out("\nSpell description:\n");
+ spell_type_description_foreach(spell_at(o_ptr->pval2),
+ print_device_desc_callback,
+ NULL);
text_out("\nSpell level: ");
sprintf(buf, FMTs32b, get_level(o_ptr->pval2, 50, 0));
text_out_c(TERM_L_BLUE, buf);
text_out("\nMinimum Magic Device level to increase spell level: ");
- text_out_c(TERM_L_BLUE, format("%d", school_spells[o_ptr->pval2].skill_level));
+ text_out_c(TERM_L_BLUE, format("%d", spell_type_skill_level(spell_at(o_ptr->pval2))));
text_out("\nSpell fail: ");
sprintf(buf, FMTs32b, spell_chance(o_ptr->pval2));
text_out_c(TERM_GREEN, buf);
text_out("\nSpell info: ");
- text_out_c(TERM_YELLOW, get_spell_info(o_ptr->pval2));
+ text_out_c(TERM_YELLOW, spell_type_info(spell_at(o_ptr->pval2)));
/* Leave device mode */
unset_stick_mode();
diff --git a/src/object2.c b/src/object2.c
index cf413c4c..b82691ea 100644
--- a/src/object2.c
+++ b/src/object2.c
@@ -12,6 +12,8 @@
#include "angband.h"
+#include "spell_type.h"
+
/*
* Calculate the player's total inventory weight.
*/
@@ -1200,7 +1202,7 @@ s32b object_value_real(object_type *o_ptr)
if (f5 & TR5_SPELL_CONTAIN)
{
if (o_ptr->pval2 != -1)
- value += 5000 + 500 * school_spells[o_ptr->pval2].skill_level;
+ value += 5000 + 500 * spell_type_skill_level(spell_at(o_ptr->pval2));
else
value += 5000;
}
@@ -1282,7 +1284,7 @@ s32b object_value_real(object_type *o_ptr)
case TV_WAND:
{
/* Par for the spell */
- value *= school_spells[o_ptr->pval2].skill_level;
+ value *= spell_type_skill_level(spell_at(o_ptr->pval2));
/* Take the average of the base and max spell levels */
value *= (((o_ptr->pval3 >> 16) & 0xFFFF) + (o_ptr->pval3 & 0xFFFF)) / 2;
/* Hack */
@@ -1297,7 +1299,7 @@ s32b object_value_real(object_type *o_ptr)
case TV_STAFF:
{
/* Par for the spell */
- value *= school_spells[o_ptr->pval2].skill_level;
+ value *= spell_type_skill_level(spell_at(o_ptr->pval2));
/* Take the average of the base and max spell levels */
value *= (((o_ptr->pval3 >> 16) & 0xFFFF) + (o_ptr->pval3 & 0xFFFF)) / 2;
/* Hack */
@@ -1314,7 +1316,7 @@ s32b object_value_real(object_type *o_ptr)
if (o_ptr->sval == 255)
{
/* Pay extra for the spell */
- value = value * school_spells[o_ptr->pval].skill_level;
+ value = value * spell_type_skill_level(spell_at(o_ptr->pval));
}
/* Done */
break;
@@ -2536,7 +2538,7 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
void charge_stick(object_type *o_ptr)
{
spell_type *spell = spell_at(o_ptr->pval2);
- o_ptr->pval = dice_roll(&spell->device_charges);
+ o_ptr->pval = spell_type_roll_charges(spell);
}
/*
@@ -3225,28 +3227,6 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
}
}
-
-/*
- * Get device allocation for a given spell and tval
- */
-static device_allocation *get_device_allocation(spell_type *spell, byte tval)
-{
- struct sglib_device_allocation_iterator it;
- device_allocation *device_allocation;
-
- for (device_allocation = sglib_device_allocation_it_init(&it, spell->device_allocation);
- device_allocation != NULL;
- device_allocation = sglib_device_allocation_it_next(&it))
- {
- if (device_allocation->tval == tval)
- {
- return device_allocation;
- }
- }
-
- return NULL;
-}
-
/*
* Get a spell for a given stick(wand, staff, rod)
*/
@@ -3258,10 +3238,10 @@ long get_random_stick(byte tval, int level)
{
long spell_idx = rand_int(school_spells_count);
spell_type *spell = spell_at(spell_idx);
- device_allocation *device_allocation = get_device_allocation(spell, tval);
+ device_allocation *device_allocation = spell_type_device_allocation(spell, tval);
if ((device_allocation != NULL) &&
- (rand_int(spell->skill_level * 3) < level) &&
+ (rand_int(spell_type_skill_level(spell) * 3) < level) &&
(magik(100 - device_allocation->rarity)))
{
return spell_idx;
@@ -3299,7 +3279,8 @@ static int randomized_level_in_range(range_type *range, int level)
static int get_stick_base_level(byte tval, int level, int spl)
{
spell_type *spell = spell_at(spl);
- device_allocation *device_allocation = get_device_allocation(spell, tval);
+ device_allocation *device_allocation = spell_type_device_allocation(spell, tval);
+ assert(device_allocation != NULL);
return randomized_level_in_range(&device_allocation->base_level, level);
}
@@ -3309,7 +3290,8 @@ static int get_stick_base_level(byte tval, int level, int spl)
static int get_stick_max_level(byte tval, int level, int spl)
{
spell_type *spell = spell_at(spl);
- device_allocation *device_allocation = get_device_allocation(spell, tval);
+ device_allocation *device_allocation = spell_type_device_allocation(spell, tval);
+ assert(device_allocation != NULL);
return randomized_level_in_range(&device_allocation->max_level, level);
}
diff --git a/src/spell_type.c b/src/spell_type.c
new file mode 100644
index 00000000..b8bec0cd
--- /dev/null
+++ b/src/spell_type.c
@@ -0,0 +1,465 @@
+#include "spell_type.h"
+
+#include "angband.h"
+
+#define SCHOOL_IDXS_MAX 3
+
+/**
+ * Spell type definition.
+ */
+struct spell_type
+{
+ cptr name; /* Name */
+ byte skill_level; /* Required level (to learn) */
+ string_list *description; /* List of strings */
+
+ casting_result (*effect_func)(int o_idx); /* Spell effect function */
+ char* (*info_func)(); /* Information function */
+ int (*lasting_func)(); /* Lasting effect function */
+ bool_ (*depend_func)(); /* Check dependencies */
+
+ s16b minimum_pval; /* Minimum required pval for item-based spells */
+
+ casting_type casting_type; /* Type of casting required */
+ s16b casting_stat; /* Stat used for casting */
+
+ bool_ castable_while_blind;
+ bool_ castable_while_confused;
+
+ dice_type device_charges; /* Number of charges for devices */
+ device_allocation *device_allocation; /* Allocation table for devices */
+
+ s16b random_type; /* Type of random items in which skill may appear */
+
+ s32b failure_rate; /* Failure rate */
+
+ s32b inertia_difficulty; /* Mana cost when used in Inertia Control */
+ s32b inertia_delay; /* Delay between castings */
+
+ range_type mana_range;
+
+ dice_type activation_timeout; /* Timeout for activation (if any) */
+
+ int school_idxs_count;
+ s32b school_idxs[3];
+};
+
+static void school_idx_add_new(spell_type *spell, s32b i)
+{
+ assert(spell != NULL);
+ assert(spell->school_idxs_count < SCHOOL_IDXS_MAX);
+
+ spell->school_idxs[spell->school_idxs_count] = i;
+ spell->school_idxs_count++;
+}
+
+void spell_type_init(spell_type *spell, cptr name)
+{
+ assert(spell != NULL);
+
+ memset(spell, 0, sizeof(spell_type));
+
+ spell->name = name;
+ spell->description = NULL;
+ spell->effect_func = NULL;
+ spell->info_func = NULL;
+ spell->lasting_func = NULL;
+ spell->depend_func = NULL;
+
+ spell->device_allocation = NULL;
+
+ spell->school_idxs_count = 0;
+
+ spell->random_type = -1;
+
+ spell->castable_while_blind = FALSE;
+ spell->castable_while_confused = FALSE;
+
+ spell_type_set_inertia(spell, -1, -1);
+}
+
+void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay)
+{
+ assert(spell != NULL);
+ spell->inertia_difficulty = difficulty;
+ spell->inertia_delay = delay;
+}
+
+void spell_type_init_music(spell_type *spell,
+ s16b minimum_pval,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx))
+{
+ assert(spell != NULL);
+
+ /* Set up callbacks */
+ spell->info_func = info_func;
+ spell->effect_func = effect_func;
+
+ /* Use spell points, but CHR for success/failure calculations */
+ spell->casting_type = USE_SPELL_POINTS;
+ spell->casting_stat = A_CHR;
+ spell->random_type = SKILL_MUSIC;
+ spell->minimum_pval = minimum_pval;
+ /* Add school */
+ school_idx_add_new(spell, SCHOOL_MUSIC);
+}
+
+void spell_type_init_music_lasting(spell_type *spell,
+ s16b minimum_pval,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx),
+ int (*lasting_func)())
+{
+ spell_type_init_music(
+ spell,
+ minimum_pval,
+ info_func,
+ effect_func);
+
+ spell->lasting_func = lasting_func;
+}
+
+void spell_type_init_mage(spell_type *spell,
+ random_type random_type,
+ s32b school_idx,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx))
+{
+ assert(spell != NULL);
+
+ spell->info_func = info_func;
+ spell->effect_func = effect_func;
+
+ spell->casting_type = USE_SPELL_POINTS;
+ spell->casting_stat = A_INT;
+
+ switch (random_type)
+ {
+ case RANDOM:
+ spell->random_type = SKILL_MAGIC;
+ break;
+ case NO_RANDOM:
+ spell->random_type = -1;
+ break;
+ default:
+ /* Cannot happen */
+ assert(FALSE);
+ }
+
+ /* Add first school */
+ spell_type_add_school(spell, school_idx);
+}
+
+void spell_type_init_priest(spell_type *spell,
+ s32b school_idx,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx))
+{
+ assert(spell != NULL);
+
+ spell->info_func = info_func;
+ spell->effect_func = effect_func;
+
+ spell->random_type = SKILL_SPIRITUALITY;
+ spell->casting_type = USE_PIETY;
+ spell->casting_stat = A_WIS;
+
+ school_idx_add_new(spell, school_idx);
+}
+
+void spell_type_init_device(spell_type *spell,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx))
+{
+ assert(spell != NULL);
+
+ spell_type_init_mage(spell,
+ NO_RANDOM,
+ SCHOOL_DEVICE,
+ info_func,
+ effect_func);
+}
+
+void spell_type_init_demonology(spell_type *spell,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx))
+{
+ spell_type_init_mage(spell,
+ NO_RANDOM,
+ SCHOOL_DEMON,
+ info_func,
+ effect_func);
+}
+
+void spell_type_init_geomancy(spell_type *spell,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx),
+ bool_ (*depend_func)())
+{
+ spell_type_init_mage(spell,
+ NO_RANDOM,
+ SCHOOL_GEOMANCY,
+ info_func,
+ effect_func);
+
+ spell->depend_func = depend_func;
+}
+
+void spell_type_set_activation_timeout(spell_type *spell, cptr timeout_s)
+{
+ assert(spell != NULL);
+
+ dice_parse_checked(&spell->activation_timeout, timeout_s);
+}
+
+void spell_type_set_difficulty(spell_type *spell, byte skill_level, s32b failure_rate)
+{
+ assert(spell != NULL);
+
+ spell->skill_level = skill_level;
+ spell->failure_rate = failure_rate;
+}
+
+void spell_type_set_mana(spell_type *spell, s32b min, s32b max)
+{
+ assert(spell != NULL);
+
+ range_init(&spell->mana_range, min, max);
+}
+
+void spell_type_set_castable_while_blind(spell_type *spell, bool_ value)
+{
+ assert(spell != NULL);
+
+ spell->castable_while_blind = value;
+}
+
+void spell_type_set_castable_while_confused(spell_type *spell, bool_ value)
+{
+ assert(spell != NULL);
+
+ spell->castable_while_confused = value;
+}
+
+void spell_type_describe(spell_type *spell, cptr line)
+{
+ assert(spell != NULL);
+
+ string_list_append(&spell->description, line);
+}
+
+void spell_type_add_school(spell_type *spell, s32b school_idx)
+{
+ school_idx_add_new(spell, school_idx);
+}
+
+void spell_type_set_device_charges(spell_type *spell, cptr charges_s)
+{
+ assert(spell != NULL);
+
+ dice_parse_checked(&spell->device_charges, charges_s);
+}
+
+void spell_type_add_device_allocation(spell_type *spell, struct device_allocation *a)
+{
+ assert(spell != NULL);
+ assert(a != NULL);
+
+ sglib_device_allocation_add(&spell->device_allocation, a);
+}
+
+spell_type *spell_type_new(cptr name)
+{
+ spell_type *spell = malloc(sizeof(spell_type));
+ assert(spell != NULL);
+ spell_type_init(spell, name);
+ return spell;
+}
+
+int spell_type_produce_effect_lasting(spell_type *spell)
+{
+ assert(spell->lasting_func != NULL);
+ return spell->lasting_func();
+}
+
+casting_result spell_type_produce_effect(spell_type *spell, int o_idx)
+{
+ assert(spell->effect_func != NULL);
+ return spell->effect_func(o_idx);
+}
+
+cptr spell_type_name(spell_type *spell)
+{
+ assert(spell != NULL);
+
+ return spell->name;
+}
+
+int spell_type_skill_level(spell_type *spell)
+{
+ assert(spell != NULL);
+
+ return spell->skill_level;
+}
+
+void spell_type_description_foreach(spell_type *spell, void (*callback)(void *data, cptr text), void *data)
+{
+ string_list *sl;
+ struct sglib_string_list_iterator it;
+
+ assert(callback != NULL);
+
+ for (sl = sglib_string_list_it_init(&it, spell->description);
+ sl != NULL;
+ sl = sglib_string_list_it_next(&it))
+ {
+ callback(data, sl->s);
+ }
+}
+
+long spell_type_roll_charges(spell_type *spell)
+{
+ return dice_roll(&spell->device_charges);
+}
+
+void spell_type_activation_description(spell_type *spell, char *buf)
+{
+ char turns[32];
+
+ dice_print(&spell->activation_timeout, turns);
+
+ assert(spell->description != NULL);
+ assert(spell->description->s != NULL);
+
+ sprintf(buf, "%s every %s turns", spell->description->s, turns);
+}
+
+int spell_type_activation_roll_timeout(spell_type *spell)
+{
+ return dice_roll(&spell->activation_timeout);
+}
+
+device_allocation *spell_type_device_allocation(spell_type *spell, byte tval)
+{
+ struct sglib_device_allocation_iterator it;
+ device_allocation *device_allocation;
+
+ for (device_allocation = sglib_device_allocation_it_init(&it, spell->device_allocation);
+ device_allocation != NULL;
+ device_allocation = sglib_device_allocation_it_next(&it))
+ {
+ if (device_allocation->tval == tval)
+ {
+ return device_allocation;
+ }
+ }
+
+ return NULL;
+}
+
+bool_ spell_type_uses_piety_to_cast(spell_type *spell)
+{
+ assert(spell != NULL);
+ return spell->casting_type == USE_PIETY;
+}
+
+bool_ spell_type_castable_while_blind(spell_type *spell)
+{
+ assert(spell != NULL);
+ return spell->castable_while_blind;
+}
+
+bool_ spell_type_castable_while_confused(spell_type *spell)
+{
+ assert(spell != NULL);
+ return spell->castable_while_confused;
+}
+
+s16b spell_type_minimum_pval(spell_type *spell)
+{
+ return spell->minimum_pval;
+}
+
+s16b spell_type_random_type(spell_type *spell)
+{
+ return spell->random_type;
+}
+
+bool_ spell_type_school_foreach(spell_type *spell, bool_ (*callback)(void *data, s32b school_idx), void *data)
+{
+ int i;
+
+ for (i = 0; i < spell->school_idxs_count; i++)
+ {
+ if (!callback(data, spell->school_idxs[i]))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay)
+{
+ if ((spell->inertia_difficulty < 0) ||
+ (spell->inertia_delay < 0))
+ {
+ return FALSE;
+ }
+
+ if (difficulty != NULL)
+ {
+ *difficulty = spell->inertia_difficulty;
+ }
+
+ if (delay != NULL)
+ {
+ *delay = spell->inertia_delay;
+ }
+
+ return TRUE;
+}
+
+cptr spell_type_info(spell_type *spell)
+{
+ assert(spell != NULL);
+
+ return spell->info_func();
+}
+
+s32b spell_type_failure_rate(spell_type *spell)
+{
+ assert(spell != NULL);
+
+ return spell->failure_rate;
+}
+
+s16b spell_type_casting_stat(spell_type *spell)
+{
+ assert(spell != NULL);
+
+ return spell->casting_stat;
+}
+
+void spell_type_mana_range(spell_type *spell, range_type *range)
+{
+ assert(spell != NULL);
+
+ if (range != NULL)
+ {
+ *range = spell->mana_range;
+ }
+}
+
+bool_ spell_type_dependencies_satisfied(spell_type *spell)
+{
+ assert(spell != NULL);
+
+ if (spell->depend_func != NULL) {
+ return spell->depend_func();
+ } else {
+ return TRUE;
+ }
+}
diff --git a/src/spell_type.h b/src/spell_type.h
new file mode 100644
index 00000000..32d6c7b6
--- /dev/null
+++ b/src/spell_type.h
@@ -0,0 +1,103 @@
+#ifndef H_e7e01ebf_e19f_439d_b88d_cad51446a7a0
+#define H_e7e01ebf_e19f_439d_b88d_cad51446a7a0
+
+#include "spell_type_fwd.h"
+
+#include "h-type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Forward declarations
+ */
+struct device_allocation;
+struct range_type;
+
+/*
+ * Casting type
+ */
+typedef enum { USE_SPELL_POINTS, USE_PIETY } casting_type;
+
+/*
+ * Does the spell appear on spell random books?
+ */
+typedef enum { RANDOM, NO_RANDOM } random_type;
+
+/*
+ * Spell functions
+ */
+
+void spell_type_init(spell_type *spell, cptr name);
+void spell_type_init_music(spell_type *spell,
+ s16b minimum_pval,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx));
+void spell_type_init_music_lasting(spell_type *spell,
+ s16b minimum_pval,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx),
+ int (*lasting_func)());
+void spell_type_init_mage(spell_type *spell,
+ random_type random_type,
+ s32b school_idx,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx));
+void spell_type_init_priest(spell_type *spell,
+ s32b school_idx,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx));
+void spell_type_init_device(spell_type *spell,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx));
+void spell_type_init_demonology(spell_type *spell,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx));
+void spell_type_init_geomancy(spell_type *spell,
+ char* (*info_func)(),
+ casting_result (*effect_func)(int o_idx),
+ bool_ (*depend_func)());
+
+void spell_type_set_activation_timeout(spell_type *spell, cptr timeout_s);
+void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay);
+void spell_type_set_difficulty(spell_type *spell, byte skill_level, s32b failure_rate);
+void spell_type_set_mana(spell_type *spell, s32b min, s32b max);
+void spell_type_set_castable_while_blind(spell_type *spell, bool_ value);
+void spell_type_set_castable_while_confused(spell_type *spell, bool_ value);
+void spell_type_describe(spell_type *spell, cptr line);
+
+void spell_type_add_school(spell_type *spell, s32b school_idx);
+
+void spell_type_set_device_charges(spell_type *spell, cptr charges_s);
+void spell_type_add_device_allocation(spell_type *spell, struct device_allocation *a);
+
+spell_type *spell_type_new(cptr name);
+
+int spell_type_produce_effect_lasting(spell_type *spell);
+casting_result spell_type_produce_effect(spell_type *spell, int o_idx);
+cptr spell_type_name(spell_type *spell);
+int spell_type_skill_level(spell_type *spell);
+void spell_type_description_foreach(spell_type *spell, void (*callback)(void *data, cptr text), void *data);
+long spell_type_roll_charges(spell_type *spell);
+void spell_type_activation_description(spell_type *spell, char *buf);
+int spell_type_activation_roll_timeout(spell_type *spell);
+struct device_allocation *spell_type_device_allocation(spell_type *spell, byte tval);
+bool_ spell_type_uses_piety_to_cast(spell_type *spell);
+bool_ spell_type_castable_while_blind(spell_type *spell);
+bool_ spell_type_castable_while_confused(spell_type *spell);
+s16b spell_type_minimum_pval(spell_type *spell);
+s16b spell_type_random_type(spell_type *spell);
+bool_ spell_type_school_foreach(spell_type *spell, bool_ (*callback)(void *data, s32b school_idx), void *data);
+bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay);
+s32b spell_type_failure_rate(spell_type *spell);
+s16b spell_type_casting_stat(spell_type *spell);
+cptr spell_type_info(spell_type *spell);
+void spell_type_mana_range(spell_type *spell, struct range_type *range);
+bool_ spell_type_dependencies_satisfied(spell_type *spell);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/src/spell_type_fwd.h b/src/spell_type_fwd.h
new file mode 100644
index 00000000..4664592c
--- /dev/null
+++ b/src/spell_type_fwd.h
@@ -0,0 +1,27 @@
+#ifndef H_ce003b12_cf58_444f_a927_5451f6dd8af1
+#define H_ce003b12_cf58_444f_a927_5451f6dd8af1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Spell effect function result
+ */
+typedef enum {
+ NO_CAST, /* Spell not cast; user aborted */
+ CAST_OBVIOUS, /* Cast; caster discovers effect (devices) */
+ CAST_HIDDEN /* Cast; caster does NOT discover effect (devices) */
+} casting_result;
+
+/*
+ * Forward declaration of the spell_type
+ */
+typedef struct spell_type spell_type;
+struct spell_type;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/src/spells1.c b/src/spells1.c
index e82d708a..9981f2be 100644
--- a/src/spells1.c
+++ b/src/spells1.c
@@ -12,6 +12,8 @@
#include "angband.h"
+#include "spell_type.h"
+
/* 1/x chance of reducing stats (for elemental attacks) */
#define HURT_CHANCE 32
@@ -1258,7 +1260,7 @@ void spellbinder_trigger()
cmsg_print(TERM_L_GREEN, "The spellbinder is triggered!");
for (i = 0; i < p_ptr->spellbinder_num; i++)
{
- msg_format("Triggering spell %s.", school_spells[p_ptr->spellbinder[i]].name);
+ msg_format("Triggering spell %s.", spell_type_name(spell_at(p_ptr->spellbinder[i])));
lua_cast_school_spell(p_ptr->spellbinder[i], TRUE);
}
p_ptr->spellbinder_num = 0;
diff --git a/src/spells3.c b/src/spells3.c
index bb67ac61..269e861a 100644
--- a/src/spells3.c
+++ b/src/spells3.c
@@ -2,6 +2,8 @@
#include <assert.h>
+#include "spell_type.h"
+
s32b NOXIOUSCLOUD = -1; /* Identifier */
s32b AIRWINGS = -1; /* Identifier */
s32b INVISIBILITY;
@@ -2357,7 +2359,7 @@ casting_result meta_spellbinder(int item)
msg_print("With the spells: ");
for (i = 0; i < p_ptr->spellbinder_num; i++)
{
- msg_print(school_spells[p_ptr->spellbinder[i]].name);
+ msg_print(spell_type_name(spell_at(p_ptr->spellbinder[i])));
}
/* Doesn't cost anything */
@@ -2400,7 +2402,7 @@ casting_result meta_spellbinder(int item)
p_ptr->spellbinder_num = 0;
return CAST_OBVIOUS;
} else {
- if (school_spells[s].skill_level > 7 + get_level_s(SPELLBINDER, 35))
+ if (spell_type_skill_level(spell_at(s)) > 7 + get_level_s(SPELLBINDER, 35))
{
msg_format("You are only allowed spells with a base level of " FMTs32b ".", (7 + get_level_s(SPELLBINDER, 35)));
return CAST_OBVIOUS;
@@ -2503,7 +2505,7 @@ void meta_inertia_control_hook_birth_objects()
casting_result meta_inertia_control(int item)
{
- s32b s;
+ s32b s, difficulty, delay;
spell_type *spell;
if (p_ptr->inertia_controlled_spell != -1)
@@ -2522,27 +2524,26 @@ casting_result meta_inertia_control(int item)
spell = spell_at(s);
- if ((spell->inertia_difficulty < 0) ||
- (spell->inertia_delay < 0))
+ if (!spell_type_inertia(spell, &difficulty, &delay))
{
msg_print("This spell inertia flow can not be controlled.");
stop_inertia_controlled_spell();
return NO_CAST;
}
- if (spell->inertia_difficulty > get_level_s(INERTIA_CONTROL, 10))
+ if (difficulty > get_level_s(INERTIA_CONTROL, 10))
{
- msg_format("This spell inertia flow(%d) is too strong to be controlled by your current spell.", spell->inertia_difficulty);
+ msg_format("This spell inertia flow(" FMTs32b ") is too strong to be controlled by your current spell.", difficulty);
stop_inertia_controlled_spell();
return NO_CAST;
}
p_ptr->inertia_controlled_spell = s;
TIMER_INERTIA_CONTROL->enabled = TRUE;
- TIMER_INERTIA_CONTROL->delay = spell->inertia_delay;
- TIMER_INERTIA_CONTROL->countdown = TIMER_INERTIA_CONTROL->delay;
+ TIMER_INERTIA_CONTROL->delay = delay;
+ TIMER_INERTIA_CONTROL->countdown = delay;
p_ptr->update |= PU_MANA;
- msg_format("Inertia flow controlling spell %s.", school_spells[s].name);
+ msg_format("Inertia flow controlling spell %s.", spell_type_name(spell_at(s)));
return CAST_OBVIOUS;
}
@@ -2938,6 +2939,20 @@ char *tulkas_whirlwind_info()
return "";
}
+static bool_ check_school_is_udun(void *data, s32b school_idx)
+{
+ int *count = (int *) data;
+
+ if ((school_idx == SCHOOL_UDUN) ||
+ (school_idx == SCHOOL_MELKOR))
+ {
+ (*count)++;
+ }
+
+ /* Keep going */
+ return TRUE;
+}
+
/* Return the number of Udun/Melkor spells in a given book */
int udun_in_book(s32b sval, s32b pval)
{
@@ -2957,20 +2972,7 @@ int udun_in_book(s32b sval, s32b pval)
spell_idx = sglib_spell_idx_list_it_next(&it))
{
spell_type *spell = spell_at(spell_idx->i);
- school_idx *school_idx = NULL;
- struct sglib_school_idx_iterator sit;
-
- for (school_idx = sglib_school_idx_it_init(&sit, spell->schools);
- school_idx != NULL;
- school_idx = sglib_school_idx_it_next(&sit))
- {
- int sch = school_idx->i;
- if ((sch == SCHOOL_UDUN) ||
- (sch == SCHOOL_MELKOR))
- {
- count++;
- }
- }
+ spell_type_school_foreach(spell, check_school_is_udun, &count);
}
return count;
@@ -2996,7 +2998,7 @@ int levels_in_book(s32b sval, s32b pval)
s32b s = spell_idx->i;
spell_type *spell = spell_at(s);
- levels += spell->skill_level;
+ levels += spell_type_skill_level(spell);
}
return levels;
diff --git a/src/spells4.c b/src/spells4.c
index f3809b7b..c977742d 100644
--- a/src/spells4.c
+++ b/src/spells4.c
@@ -2,6 +2,8 @@
#include <assert.h>
+#include "spell_type.h"
+
school_book_type school_books[SCHOOL_BOOKS_SIZE];
s32b SCHOOL_AIR;
@@ -37,52 +39,9 @@ static int compare_spell_idx(spell_idx_list *a, spell_idx_list *b)
SGLIB_DEFINE_LIST_FUNCTIONS(spell_idx_list, compare_spell_idx, next);
-static int compare_school_idx(school_idx *a, school_idx *b)
-{
- return SGLIB_NUMERIC_COMPARATOR(a->i, b->i);
-}
-
-SGLIB_DEFINE_LIST_FUNCTIONS(school_idx, compare_school_idx, next);
-
-void school_idx_init(school_idx *e, s32b i)
-{
- assert(e != NULL);
-
- e->i = i;
- e->next = NULL;
-}
-
-school_idx *school_idx_new(s32b i)
-{
- school_idx *e = malloc(sizeof(school_idx));
- assert(e != NULL);
-
- school_idx_init(e, i);
-
- return e;
-}
-
-void school_idx_add_new(school_idx **list, s32b i)
-{
- school_idx *e = school_idx_new(i);
- assert(e != NULL);
-
- sglib_school_idx_add(list, e);
-}
-
static bool_ uses_piety_to_cast(int s)
{
- return spell_at(s)->casting_type == USE_PIETY;
-}
-
-static bool_ castable_while_blind(int s)
-{
- return spell_at(s)->castable_while_blind;
-}
-
-static bool_ castable_while_confused(int s)
-{
- return spell_at(s)->castable_while_confused;
+ return spell_type_uses_piety_to_cast(spell_at(s));
}
/** Describe what type of energy the spell uses for casting */
@@ -110,31 +69,36 @@ s32b get_power(s32b s)
return uses_piety_to_cast(s) ? p_ptr->grace : p_ptr->csp;
}
+static void print_spell_desc_callback(void *data, cptr text)
+{
+ int *y = (int *) data;
+
+ c_prt(TERM_L_BLUE, text, *y, 0);
+ (*y) += 1;
+}
+
/* Output the describtion when it is used as a spell */
void print_spell_desc(int s, int y)
{
- string_list *sl;
- struct sglib_string_list_iterator it;
+ spell_type *spell = spell_at(s);
- for (sl = sglib_string_list_it_init(&it, school_spells[s].description);
- sl != NULL;
- sl = sglib_string_list_it_next(&it))
- {
- c_prt(TERM_L_BLUE, sl->s, y, 0);
- y++;
- }
+ spell_type_description_foreach(spell,
+ print_spell_desc_callback,
+ &y);
- if (uses_piety_to_cast(s))
+ if (spell_type_uses_piety_to_cast(spell))
{
c_prt(TERM_L_WHITE, "It uses piety to cast.", y, 0);
y++;
}
- if (castable_while_blind(s))
+
+ if (spell_type_castable_while_blind(spell))
{
c_prt(TERM_ORANGE, "It is castable even while blinded.", y, 0);
y++;
}
- if (castable_while_confused(s))
+
+ if (spell_type_castable_while_confused(spell))
{
c_prt(TERM_ORANGE, "It is castable even while confused.", y, 0);
y++;
@@ -478,30 +442,30 @@ void random_book_setup(s16b sval, s32b spell_idx)
}
}
-static void spell_school_name(char *buf, spell_type *spell)
+static bool_ spell_school_name_callback(void *data, s32b sch)
{
- school_idx *school_idx = NULL;
- struct sglib_school_idx_iterator sit;
- bool_ first = TRUE;
-
- buf[0] = '\0';
+ school_type *school = school_at(sch);
+ char *buf = (char *) data;
- for (school_idx = sglib_school_idx_it_init(&sit, spell->schools);
- school_idx != NULL;
- school_idx = sglib_school_idx_it_next(&sit))
+ /* Add separator? */
+ if (buf[0] != '\0')
{
- int sch = school_idx->i;
- school_type *school = school_at(sch);
- /* Add separator? */
- if (!first)
- {
- strcat(buf, "/");
- }
- first = FALSE;
-
- /* Add school name */
- strcat(buf, school->name);
+ strcat(buf, "/");
}
+
+ /* Add school name */
+ strcat(buf, school->name);
+
+ /* Keep going */
+ return TRUE;
+}
+
+static void spell_school_name(char *buf, spell_type *spell)
+{
+ buf[0] = '\0';
+ spell_type_school_foreach(spell,
+ spell_school_name_callback,
+ buf);
}
int print_spell(cptr label_, byte color, int y, s32b s)
@@ -510,7 +474,7 @@ int print_spell(cptr label_, byte color, int y, s32b s)
bool_ na;
spell_type *spell = spell_at(s);
char sch_str[128];
- cptr spell_info = get_spell_info(s);
+ cptr spell_info = spell_type_info(spell);
cptr label = (label_ == NULL) ? "" : label_;
char level_str[8] = "n/a";
char buf[128];
@@ -525,7 +489,7 @@ int print_spell(cptr label_, byte color, int y, s32b s)
sprintf(buf, "%s%-20s%-16s %s %4d %3d%% %s",
label,
- school_spells[s].name,
+ spell_type_name(spell_at(s)),
sch_str,
level_str,
get_mana(s),
@@ -575,16 +539,10 @@ int print_book(s16b sval, s32b pval, object_type *obj)
return y;
}
-static bool_ call_spell_function(s32b s)
-{
- spell_type *spell = spell_at(s);
- assert(spell->effect_func != NULL);
- return (spell->effect_func(-1) != NO_CAST);
-}
-
void lua_cast_school_spell(s32b s, bool_ no_cost)
{
bool_ use = FALSE;
+ spell_type *spell = spell_at(s);
/* No magic? */
if (p_ptr->antimagic > 0)
@@ -604,14 +562,16 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
if (!no_cost)
{
/* Require lite */
- if (!castable_while_blind(s) && ((p_ptr->blind > 0) || no_lite()))
+ if (!spell_type_castable_while_blind(spell) &&
+ ((p_ptr->blind > 0) || no_lite()))
{
msg_print("You cannot see!");
return;
}
/* Not when confused */
- if (!castable_while_confused(s) && (p_ptr->confused > 0))
+ if (!spell_type_castable_while_confused(spell) &&
+ (p_ptr->confused > 0))
{
msg_print("You are too confused!");
return;
@@ -634,7 +594,7 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
/* Invoke the spell effect */
if (!magik(spell_chance(s)))
{
- use = call_spell_function(s);
+ use = (spell_type_produce_effect(spell, -1) != NO_CAST);
}
else
{
@@ -652,7 +612,7 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
}
else
{
- call_spell_function(s);
+ spell_type_produce_effect(spell, -1);
}
/* Use the mana/piety */
@@ -670,11 +630,6 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
p_ptr->window |= PW_PLAYER;
}
-void spell_description_add_line(s32b spell_idx, cptr line)
-{
- string_list_append(&school_spells[spell_idx].description, line);
-}
-
void device_allocation_init(device_allocation *device_allocation, byte tval)
{
assert(device_allocation != NULL);
diff --git a/src/spells5.c b/src/spells5.c
index d2d9eda2..7ad0d3b9 100644
--- a/src/spells5.c
+++ b/src/spells5.c
@@ -1,45 +1,15 @@
#include <angband.h>
-#include <assert.h>
-
-typedef enum { RANDOM, NO_RANDOM } random_type;
-
-static void spell_inertia_init(spell_type *spell, s32b diff, s32b delay)
-{
- spell->inertia_difficulty = diff;
- spell->inertia_delay = delay;
-}
-
-static void spell_init(spell_type *spell)
-{
- memset(spell, 0, sizeof(spell_type));
-
- spell->name = NULL;
- spell->description = NULL;
- spell->effect_func = NULL;
- spell->info_func = NULL;
- spell->lasting_func = NULL;
- spell->depend_func = NULL;
-
- spell->device_allocation = NULL;
- spell->schools = NULL;
- spell->random_type = -1;
-
- spell_inertia_init(spell, -1, -1);
+#include <assert.h>
- spell->castable_while_blind = FALSE;
- spell->castable_while_confused = FALSE;
-}
+#include "spell_type.h"
static spell_type *spell_new(s32b *index, cptr id, cptr name)
{
assert(school_spells_count < SCHOOL_SPELLS_MAX);
- spell_type *spell = &school_spells[school_spells_count];
-
- spell_init(spell);
- spell->name = name;
-
+ spell_type *spell = spell_type_new(name);
+ school_spells[school_spells_count] = spell;
*index = school_spells_count;
school_spells_count++;
@@ -51,7 +21,7 @@ spell_type *spell_at(s32b index)
assert(index >= 0);
assert(index < school_spells_count);
- return &school_spells[index];
+ return school_spells[index];
}
int find_spell(cptr name)
@@ -60,8 +30,7 @@ int find_spell(cptr name)
for (i = 0; i < school_spells_count; i++)
{
- spell_type *spell = spell_at(i);
- if (streq(spell->name, name))
+ if (streq(spell_type_name(spell_at(i)), name))
{
return i;
}
@@ -80,8 +49,8 @@ s16b get_random_spell(s16b random_type, int level)
s16b spl = rand_int(school_spells_count);
spell_type *spell = spell_at(spl);
- if ((can_spell_random(spl) == random_type) &&
- (rand_int(spell->skill_level * 3) < level))
+ if ((spell_type_random_type(spell) == random_type) &&
+ (rand_int(spell_type_skill_level(spell) * 3) < level))
{
return spl;
}
@@ -90,106 +59,47 @@ s16b get_random_spell(s16b random_type, int level)
return -1;
}
-bool_ check_spell_depends(spell_type *spell)
-{
- assert(spell != NULL);
-
- if (spell->depend_func != NULL) {
- return spell->depend_func();
- } else {
- return TRUE;
- }
-}
-
-static void spell_init_music(spell_type *spell, s16b minimum_pval)
-{
- assert(spell != NULL);
- /* Use spell points, but CHR for success/failure calculations */
- spell->casting_type = USE_SPELL_POINTS;
- spell->casting_stat = A_CHR;
- spell->random_type = SKILL_MUSIC;
- spell->minimum_pval = minimum_pval;
- /* Add school */
- school_idx_add_new(&spell->schools, SCHOOL_MUSIC);
-}
-
-static void spell_init_mage(spell_type *spell, random_type random_type)
-{
- assert(spell != NULL);
-
- spell->casting_type = USE_SPELL_POINTS;
- spell->casting_stat = A_INT;
-
- switch (random_type)
- {
- case RANDOM:
- spell->random_type = SKILL_MAGIC;
- break;
- case NO_RANDOM:
- spell->random_type = -1;
- break;
- default:
- /* Cannot happen */
- assert(FALSE);
- }
-}
-
-static void spell_init_priest(spell_type *spell)
-{
- assert(spell != NULL);
-
- spell->random_type = SKILL_SPIRITUALITY;
- spell->casting_type = USE_PIETY;
- spell->casting_stat = A_WIS;
-}
-
static void spells_init_tome()
{
{
spell_type *spell = spell_new(&DEVICE_LEBOHAUM, "DEVICE_LEBOHAUM", "Artifact Lebauhaum");
- dice_parse_checked(&spell->activation_duration, "3");
- string_list_append(&spell->description, "sing a cheerful song");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = device_lebohaum_info;
- spell->effect_func = device_lebohaum;
- spell->failure_rate = 0;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_set_activation_timeout(spell, "3");
+ spell_type_describe(spell, "sing a cheerful song");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 0);
+ spell_type_init_device(spell,
+ device_lebohaum_info,
+ device_lebohaum);
}
{
spell_type *spell = spell_new(&DEVICE_DURANDIL, "DEVICE_DURANDIL", "Artifact Durandil");
- dice_parse_checked(&spell->activation_duration, "3");
- string_list_append(&spell->description, "sing a cheerful song");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = device_durandil_info;
- spell->effect_func = device_durandil;
- spell->failure_rate = 0;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_set_activation_timeout(spell, "3");
+ spell_type_describe(spell, "sing a cheerful song");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 0);
+ spell_type_init_device(spell,
+ device_durandil_info,
+ device_durandil);
}
{
spell_type *spell = spell_new(&DEVICE_THUNDERLORDS, "DEVICE_THUNDERLORDS", "Artifact Thunderlords");
- string_list_append(&spell->description, "A thunderlord will appear to transport you quickly to the surface.");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 1, 1);
- spell->info_func = device_thunderlords_info;
- spell->effect_func = device_thunderlords;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "A thunderlord will appear to transport you quickly to the surface.");
+ spell_type_set_mana(spell, 1, 1);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_device(spell,
+ device_thunderlords_info,
+ device_thunderlords);
- dice_parse_checked(&spell->device_charges, "3+d3");
+ spell_type_set_device_charges(spell, "3+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 999;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 1, 1);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
}
@@ -198,2139 +108,2073 @@ static void spells_init_theme()
{
{
spell_type *spell = spell_new(&GROW_ATHELAS, "GROW_ATHELAS", "Grow Athelas");
- string_list_append(&spell->description, "Cures the Black Breath");
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 60, 100);
- spell->info_func = nature_grow_athelas_info;
- spell->effect_func = nature_grow_athelas;
- spell->failure_rate = 95;
- spell->skill_level = 30;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Cures the Black Breath");
+ spell_type_set_mana(spell, 60, 100);
+ spell_type_set_difficulty(spell, 30, 95);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_NATURE,
+ nature_grow_athelas_info,
+ nature_grow_athelas);
- dice_parse_checked(&spell->device_charges, "1+d3");
+ spell_type_set_device_charges(spell, "1+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 85;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 15, 45);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&AULE_FIREBRAND, "AULE_FIREBRAND", "Firebrand");
- string_list_append(&spell->description, "Imbues your melee weapon with fire to deal more damage");
- string_list_append(&spell->description, "At level 15 it spreads over a 1 radius zone around your target");
- string_list_append(&spell->description, "At level 30 it deals holy fire damage");
- school_idx_add_new(&spell->schools, SCHOOL_AULE);
- range_init(&spell->mana_range, 10, 100);
- spell->info_func = aule_firebrand_info;
- spell->effect_func = aule_firebrand_spell;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Imbues your melee weapon with fire to deal more damage");
+ spell_type_describe(spell, "At level 15 it spreads over a 1 radius zone around your target");
+ spell_type_describe(spell, "At level 30 it deals holy fire damage");
+ spell_type_set_mana(spell, 10, 100);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_AULE,
+ aule_firebrand_info,
+ aule_firebrand_spell);
}
{
spell_type *spell = spell_new(&AULE_ENCHANT_WEAPON, "AULE_ENCHANT_WEAPON", "Enchant Weapon");
- string_list_append(&spell->description, "Tries to enchant a weapon to-hit");
- string_list_append(&spell->description, "At level 5 it also enchants to-dam");
- string_list_append(&spell->description, "At level 45 it enhances the special powers of magical weapons");
- string_list_append(&spell->description, "The might of the enchantment increases with the level");
- school_idx_add_new(&spell->schools, SCHOOL_AULE);
- range_init(&spell->mana_range, 100, 200);
- spell->info_func = aule_enchant_weapon_info;
- spell->effect_func = aule_enchant_weapon_spell;
- spell->failure_rate = 20;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Tries to enchant a weapon to-hit");
+ spell_type_describe(spell, "At level 5 it also enchants to-dam");
+ spell_type_describe(spell, "At level 45 it enhances the special powers of magical weapons");
+ spell_type_describe(spell, "The might of the enchantment increases with the level");
+ spell_type_set_mana(spell, 100, 200);
+ spell_type_set_difficulty(spell, 10, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_AULE,
+ aule_enchant_weapon_info,
+ aule_enchant_weapon_spell);
}
{
spell_type *spell = spell_new(&AULE_ENCHANT_ARMOUR, "AULE_ENCHANT_ARMOUR", "Enchant Armour");
- string_list_append(&spell->description, "Tries to enchant a piece of armour");
- string_list_append(&spell->description, "At level 20 it also enchants to-hit and to-dam");
- string_list_append(&spell->description, "At level 40 it enhances the special powers of magical armour");
- string_list_append(&spell->description, "The might of the enchantment increases with the level");
- school_idx_add_new(&spell->schools, SCHOOL_AULE);
- range_init(&spell->mana_range, 100, 200);
- spell->info_func = aule_enchant_armour_info;
- spell->effect_func = aule_enchant_armour_spell;
- spell->failure_rate = 20;
- spell->skill_level = 15;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Tries to enchant a piece of armour");
+ spell_type_describe(spell, "At level 20 it also enchants to-hit and to-dam");
+ spell_type_describe(spell, "At level 40 it enhances the special powers of magical armour");
+ spell_type_describe(spell, "The might of the enchantment increases with the level");
+ spell_type_set_mana(spell, 100, 200);
+ spell_type_set_difficulty(spell, 15, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_AULE,
+ aule_enchant_armour_info,
+ aule_enchant_armour_spell);
}
{
spell_type *spell = spell_new(&AULE_CHILD, "AULE_CHILD", "Child of Aule");
- string_list_append(&spell->description, "Summons a levelled Dwarven warrior to help you battle the forces");
- string_list_append(&spell->description, "of Morgoth");
- school_idx_add_new(&spell->schools, SCHOOL_AULE);
- range_init(&spell->mana_range, 200, 500);
- spell->info_func = aule_child_info;
- spell->effect_func = aule_child_spell;
- spell->failure_rate = 40;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Summons a levelled Dwarven warrior to help you battle the forces");
+ spell_type_describe(spell, "of Morgoth");
+ spell_type_set_mana(spell, 200, 500);
+ spell_type_set_difficulty(spell, 20, 40);
+ spell_type_init_priest(spell,
+ SCHOOL_AULE,
+ aule_child_info,
+ aule_child_spell);
}
{
spell_type *spell = spell_new(&VARDA_LIGHT_VALINOR, "VARDA_LIGHT_VALINOR", "Light of Valinor");
- string_list_append(&spell->description, "Lights a room");
- string_list_append(&spell->description, "At level 3 it starts damaging monsters");
- string_list_append(&spell->description, "At level 15 it starts creating a more powerful kind of light");
- school_idx_add_new(&spell->schools, SCHOOL_VARDA);
- range_init(&spell->mana_range, 1, 100);
- spell->info_func = varda_light_of_valinor_info;
- spell->effect_func = varda_light_of_valinor_spell;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Lights a room");
+ spell_type_describe(spell, "At level 3 it starts damaging monsters");
+ spell_type_describe(spell, "At level 15 it starts creating a more powerful kind of light");
+ spell_type_set_mana(spell, 1, 100);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_VARDA,
+ varda_light_of_valinor_info,
+ varda_light_of_valinor_spell);
}
{
spell_type *spell = spell_new(&VARDA_CALL_ALMAREN, "VARDA_CALL_ALMAREN", "Call of Almaren");
- string_list_append(&spell->description, "Banishes evil beings");
- string_list_append(&spell->description, "At level 20 it dispels evil beings");
- school_idx_add_new(&spell->schools, SCHOOL_VARDA);
- range_init(&spell->mana_range, 5, 150);
- spell->info_func = varda_call_of_almaren_info;
- spell->effect_func = varda_call_of_almaren_spell;
- spell->failure_rate = 20;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Banishes evil beings");
+ spell_type_describe(spell, "At level 20 it dispels evil beings");
+ spell_type_set_mana(spell, 5, 150);
+ spell_type_set_difficulty(spell, 10, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_VARDA,
+ varda_call_of_almaren_info,
+ varda_call_of_almaren_spell);
}
{
spell_type *spell = spell_new(&VARDA_EVENSTAR, "VARDA_EVENSTAR", "Evenstar");
- string_list_append(&spell->description, "Maps and lights the whole level.");
- string_list_append(&spell->description, "At level 40 it maps and lights the whole level,");
- string_list_append(&spell->description, "in addition to letting you know yourself better");
- string_list_append(&spell->description, "and identifying your whole pack.");
- school_idx_add_new(&spell->schools, SCHOOL_VARDA);
- range_init(&spell->mana_range, 20, 200);
- spell->info_func = varda_evenstar_info;
- spell->effect_func = varda_evenstar_spell;
- spell->failure_rate = 20;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Maps and lights the whole level.");
+ spell_type_describe(spell, "At level 40 it maps and lights the whole level,");
+ spell_type_describe(spell, "in addition to letting you know yourself better");
+ spell_type_describe(spell, "and identifying your whole pack.");
+ spell_type_set_mana(spell, 20, 200);
+ spell_type_set_difficulty(spell, 20, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_VARDA,
+ varda_evenstar_info,
+ varda_evenstar_spell);
}
{
spell_type *spell = spell_new(&VARDA_STARKINDLER, "VARDA_STARKINDLER", "Star Kindler");
- string_list_append(&spell->description, "Does multiple bursts of light damage.");
- string_list_append(&spell->description, "The damage increases with level.");
- school_idx_add_new(&spell->schools, SCHOOL_VARDA);
- range_init(&spell->mana_range, 50, 250);
- spell->info_func = varda_star_kindler_info;
- spell->effect_func = varda_star_kindler_spell;
- spell->failure_rate = 20;
- spell->skill_level = 30;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Does multiple bursts of light damage.");
+ spell_type_describe(spell, "The damage increases with level.");
+ spell_type_set_mana(spell, 50, 250);
+ spell_type_set_difficulty(spell, 30, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_VARDA,
+ varda_star_kindler_info,
+ varda_star_kindler_spell);
}
{
spell_type *spell = spell_new(&ULMO_BELEGAER, "ULMO_BELEGAER", "Song of Belegaer");
- string_list_append(&spell->description, "Channels the power of the Great Sea into your fingertips.");
- string_list_append(&spell->description, "Sometimes it can blast through its first target.");
- school_idx_add_new(&spell->schools, SCHOOL_ULMO);
- range_init(&spell->mana_range, 1, 100);
- spell->info_func = ulmo_song_of_belegaer_info;
- spell->effect_func = ulmo_song_of_belegaer_spell;
- spell->failure_rate = 25;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Channels the power of the Great Sea into your fingertips.");
+ spell_type_describe(spell, "Sometimes it can blast through its first target.");
+ spell_type_set_mana(spell, 1, 100);
+ spell_type_set_difficulty(spell, 1, 25);
+ spell_type_init_priest(spell,
+ SCHOOL_ULMO,
+ ulmo_song_of_belegaer_info,
+ ulmo_song_of_belegaer_spell);
}
{
spell_type *spell = spell_new(&ULMO_DRAUGHT_ULMONAN, "ULMO_DRAUGHT_ULMONAN", "Draught of Ulmonan");
- string_list_append(&spell->description, "Fills you with a draught with powerful curing effects,");
- string_list_append(&spell->description, "prepared by Ulmo himself.");
- string_list_append(&spell->description, "Level 1: blindness, poison, cuts and stunning");
- string_list_append(&spell->description, "Level 10: drained STR, DEX and CON");
- string_list_append(&spell->description, "Level 20: parasites and mimicry");
- school_idx_add_new(&spell->schools, SCHOOL_ULMO);
- range_init(&spell->mana_range, 25, 200);
- spell->info_func = ulmo_draught_of_ulmonan_info;
- spell->effect_func = ulmo_draught_of_ulmonan_spell;
- spell->failure_rate = 50;
- spell->skill_level = 15;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Fills you with a draught with powerful curing effects,");
+ spell_type_describe(spell, "prepared by Ulmo himself.");
+ spell_type_describe(spell, "Level 1: blindness, poison, cuts and stunning");
+ spell_type_describe(spell, "Level 10: drained STR, DEX and CON");
+ spell_type_describe(spell, "Level 20: parasites and mimicry");
+ spell_type_set_mana(spell, 25, 200);
+ spell_type_set_difficulty(spell, 15, 50);
+ spell_type_init_priest(spell,
+ SCHOOL_ULMO,
+ ulmo_draught_of_ulmonan_info,
+ ulmo_draught_of_ulmonan_spell);
}
{
spell_type *spell = spell_new(&ULMO_CALL_ULUMURI, "ULMO_CALL_ULUMURI", "Call of the Ulumuri");
- string_list_append(&spell->description, "Summons a leveled water spirit or elemental");
- string_list_append(&spell->description, "to fight for you");
- school_idx_add_new(&spell->schools, SCHOOL_ULMO);
- range_init(&spell->mana_range, 50, 300);
- spell->info_func = ulmo_call_of_the_ulumuri_info;
- spell->effect_func = ulmo_call_of_the_ulumuri_spell;
- spell->failure_rate = 75;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Summons a leveled water spirit or elemental");
+ spell_type_describe(spell, "to fight for you");
+ spell_type_set_mana(spell, 50, 300);
+ spell_type_set_difficulty(spell, 20, 75);
+ spell_type_init_priest(spell,
+ SCHOOL_ULMO,
+ ulmo_call_of_the_ulumuri_info,
+ ulmo_call_of_the_ulumuri_spell);
}
{
spell_type *spell = spell_new(&ULMO_WRATH, "ULMO_WRATH", "Wrath of Ulmo");
- string_list_append(&spell->description, "Conjures up a sea storm.");
- string_list_append(&spell->description, "At level 30 it turns into a more forceful storm.");
- school_idx_add_new(&spell->schools, SCHOOL_ULMO);
- range_init(&spell->mana_range, 100, 400);
- spell->info_func = ulmo_wrath_of_ulmo_info;
- spell->effect_func = ulmo_wrath_of_ulmo_spell;
- spell->failure_rate = 95;
- spell->skill_level = 30;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Conjures up a sea storm.");
+ spell_type_describe(spell, "At level 30 it turns into a more forceful storm.");
+ spell_type_set_mana(spell, 100, 400);
+ spell_type_set_difficulty(spell, 30, 95);
+ spell_type_init_priest(spell,
+ SCHOOL_ULMO,
+ ulmo_wrath_of_ulmo_info,
+ ulmo_wrath_of_ulmo_spell);
}
{
spell_type *spell = spell_new(&MANDOS_TEARS_LUTHIEN, "MANDOS_TEARS_LUTHIEN", "Tears of Luthien");
- string_list_append(&spell->description, "Calls upon the spirit of Luthien to ask Mandos for healing and succour.");
- school_idx_add_new(&spell->schools, SCHOOL_MANDOS);
- range_init(&spell->mana_range, 10, 100);
- spell->info_func = mandos_tears_of_luthien_info;
- spell->effect_func = mandos_tears_of_luthien_spell;
- spell->failure_rate = 25;
- spell->skill_level = 5;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Calls upon the spirit of Luthien to ask Mandos for healing and succour.");
+ spell_type_set_mana(spell, 10, 100);
+ spell_type_set_difficulty(spell, 5, 25);
+ spell_type_init_priest(spell,
+ SCHOOL_MANDOS,
+ mandos_tears_of_luthien_info,
+ mandos_tears_of_luthien_spell);
}
{
spell_type *spell = spell_new(&MANDOS_SPIRIT_FEANTURI, "MANDOS_SPIRIT_FEANTURI", "Feanturi");
- string_list_append(&spell->description, "Channels the power of Mandos to cure fear and confusion.");
- string_list_append(&spell->description, "At level 20 it restores lost INT and WIS");
- string_list_append(&spell->description, "At level 30 it cures hallucinations and restores a percentage of lost sanity");
- school_idx_add_new(&spell->schools, SCHOOL_MANDOS);
- range_init(&spell->mana_range, 40, 200);
- spell->info_func = mandos_spirit_of_the_feanturi_info;
- spell->effect_func = mandos_spirit_of_the_feanturi_spell;
- spell->failure_rate = 50;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Channels the power of Mandos to cure fear and confusion.");
+ spell_type_describe(spell, "At level 20 it restores lost INT and WIS");
+ spell_type_describe(spell, "At level 30 it cures hallucinations and restores a percentage of lost sanity");
+ spell_type_set_mana(spell, 40, 200);
+ spell_type_set_difficulty(spell, 10, 50);
+ spell_type_init_priest(spell,
+ SCHOOL_MANDOS,
+ mandos_spirit_of_the_feanturi_info,
+ mandos_spirit_of_the_feanturi_spell);
}
{
spell_type *spell = spell_new(&MANDOS_TALE_DOOM, "MANDOS_TALE_DOOM", "Tale of Doom");
- string_list_append(&spell->description, "Allows you to predict the future for a short time.");
- school_idx_add_new(&spell->schools, SCHOOL_MANDOS);
- range_init(&spell->mana_range, 60, 300);
- spell->info_func = mandos_tale_of_doom_info;
- spell->effect_func = mandos_tale_of_doom_spell;
- spell->failure_rate = 75;
- spell->skill_level = 25;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Allows you to predict the future for a short time.");
+ spell_type_set_mana(spell, 60, 300);
+ spell_type_set_difficulty(spell, 25, 75);
+ spell_type_init_priest(spell,
+ SCHOOL_MANDOS,
+ mandos_tale_of_doom_info,
+ mandos_tale_of_doom_spell);
}
{
spell_type *spell = spell_new(&MANDOS_CALL_HALLS, "MANDOS_CALL_HALLS", "Call to the Halls");
- string_list_append(&spell->description, "Summons a leveled spirit from the Halls of Mandos");
- string_list_append(&spell->description, "to fight for you.");
- school_idx_add_new(&spell->schools, SCHOOL_MANDOS);
- range_init(&spell->mana_range, 80, 400);
- spell->info_func = mandos_call_to_the_halls_info;
- spell->effect_func = mandos_call_to_the_halls_spell;
- spell->failure_rate = 95;
- spell->skill_level = 30;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Summons a leveled spirit from the Halls of Mandos");
+ spell_type_describe(spell, "to fight for you.");
+ spell_type_set_mana(spell, 80, 400);
+ spell_type_set_difficulty(spell, 30, 95);
+ spell_type_init_priest(spell,
+ SCHOOL_MANDOS,
+ mandos_call_to_the_halls_info,
+ mandos_call_to_the_halls_spell);
}
{
spell_type *spell = spell_new(&DEVICE_THUNDERLORDS, "DEVICE_THUNDERLORDS", "Artifact Thunderlords");
- string_list_append(&spell->description, "An Eagle of Manwe will appear to transport you quickly to the town.");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 1, 1);
- spell->info_func = device_thunderlords_info;
- spell->effect_func = device_thunderlords;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "An Eagle of Manwe will appear to transport you quickly to the town.");
+ spell_type_set_mana(spell, 1, 1);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_device(spell,
+ device_thunderlords_info,
+ device_thunderlords);
- dice_parse_checked(&spell->device_charges, "5+d5");
+ spell_type_set_device_charges(spell, "5+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 999;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 1, 1);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_RADAGAST, "DEVICE_RADAGAST", "Artifact Radagast");
- dice_parse_checked(&spell->activation_duration, "15000");
- string_list_append(&spell->description, "purity and health");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = device_radagast_info;
- spell->effect_func = device_radagast;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_set_activation_timeout(spell, "15000");
+ spell_type_describe(spell, "purity and health");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_device(spell,
+ device_radagast_info,
+ device_radagast);
}
{
spell_type *spell = spell_new(&DEVICE_VALAROMA, "DEVICE_VALAROMA", "Artifact Valaroma");
- dice_parse_checked(&spell->activation_duration, "250");
- string_list_append(&spell->description, "banish evil (level x5)");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = device_valaroma_info;
- spell->effect_func = device_valaroma;
- spell->failure_rate = 25;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_set_activation_timeout(spell, "250");
+ spell_type_describe(spell, "banish evil (level x5)");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 25);
+ spell_type_init_device(spell,
+ device_valaroma_info,
+ device_valaroma);
}
}
void school_spells_init()
{
+ /* Zero out spell array */
+ {
+ int i = 0;
+ for (i = 0; i < SCHOOL_SPELLS_MAX; i++)
+ {
+ school_spells[i] = NULL;
+ }
+ }
+
+ /* Spells */
{
spell_type *spell = spell_new(&GLOBELIGHT, "GLOBELIGHT", "Globe of Light");
- string_list_append(&spell->description, "Creates a globe of pure light");
- string_list_append(&spell->description, "At level 3 it starts damaging monsters");
- string_list_append(&spell->description, "At level 15 it starts creating a more powerful kind of light");
- school_idx_add_new(&spell->schools, SCHOOL_FIRE);
- range_init(&spell->mana_range, 2, 15);
- spell_inertia_init(spell, 1, 40);
- spell->info_func = fire_globe_of_light_info;
- spell->effect_func = fire_globe_of_light;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "10+d5");
+ spell_type_describe(spell, "Creates a globe of pure light");
+ spell_type_describe(spell, "At level 3 it starts damaging monsters");
+ spell_type_describe(spell, "At level 15 it starts creating a more powerful kind of light");
+ spell_type_set_mana(spell, 2, 15);
+ spell_type_set_inertia(spell, 1, 40);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_FIRE,
+ fire_globe_of_light_info,
+ fire_globe_of_light);
+
+ spell_type_set_device_charges(spell, "10+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 7;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 10, 45);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&FIREFLASH, "FIREFLASH", "Fireflash");
- string_list_append(&spell->description, "Conjures a ball of fire to burn your foes to ashes");
- string_list_append(&spell->description, "At level 20 it turns into a ball of holy fire");
- school_idx_add_new(&spell->schools, SCHOOL_FIRE);
- range_init(&spell->mana_range, 5, 70);
- spell->info_func = fire_fireflash_info;
- spell->effect_func = fire_fireflash;
- spell->failure_rate = 35;
- spell->skill_level = 10;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d5");
+ spell_type_describe(spell, "Conjures a ball of fire to burn your foes to ashes");
+ spell_type_describe(spell, "At level 20 it turns into a ball of holy fire");
+ spell_type_set_mana(spell, 5, 70);
+ spell_type_set_difficulty(spell, 10, 35);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_FIRE,
+ fire_fireflash_info,
+ fire_fireflash);
+
+ spell_type_set_device_charges(spell, "5+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 35;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 15, 35);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&FIERYAURA, "FIERYAURA", "Fiery Shield");
- string_list_append(&spell->description, "Creates a shield of fierce flames around you");
- string_list_append(&spell->description, "At level 8 it turns into a greater kind of flame that can not be resisted");
- school_idx_add_new(&spell->schools, SCHOOL_FIRE);
- range_init(&spell->mana_range, 20, 60);
- spell_inertia_init(spell, 2, 15);
- spell->info_func = fire_fiery_shield_info;
- spell->effect_func = fire_fiery_shield;
- spell->failure_rate = 50;
- spell->skill_level = 20;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d5");
+ spell_type_describe(spell, "Creates a shield of fierce flames around you");
+ spell_type_describe(spell, "At level 8 it turns into a greater kind of flame that can not be resisted");
+ spell_type_set_mana(spell, 20, 60);
+ spell_type_set_inertia(spell, 2, 15);
+ spell_type_set_difficulty(spell, 20, 50);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_FIRE,
+ fire_fiery_shield_info,
+ fire_fiery_shield);
+
+ spell_type_set_device_charges(spell, "3+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 50;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 5, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&FIREWALL, "FIREWALL", "Firewall");
- string_list_append(&spell->description, "Creates a fiery wall to incinerate monsters stupid enough to attack you");
- string_list_append(&spell->description, "At level 6 it turns into a wall of hell fire");
- school_idx_add_new(&spell->schools, SCHOOL_FIRE);
- range_init(&spell->mana_range, 25, 100);
- spell->info_func = fire_firewall_info;
- spell->effect_func = fire_firewall;
- spell->failure_rate = 40;
- spell->skill_level = 15;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "4+d5");
+ spell_type_describe(spell, "Creates a fiery wall to incinerate monsters stupid enough to attack you");
+ spell_type_describe(spell, "At level 6 it turns into a wall of hell fire");
+ spell_type_set_mana(spell, 25, 100);
+ spell_type_set_difficulty(spell, 15, 40);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_FIRE,
+ fire_firewall_info,
+ fire_firewall);
+
+ spell_type_set_device_charges(spell, "4+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 55;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 5, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&FIREGOLEM, "FIREGOLEM", "Fire Golem");
- string_list_append(&spell->description, "Creates a fiery golem and controls it");
- string_list_append(&spell->description, "During the control the available keylist is:");
- string_list_append(&spell->description, "Movement keys: movement of the golem(depending on its speed");
- string_list_append(&spell->description, " it can move more than one square)");
- string_list_append(&spell->description, ", : pickup all items on the floor");
- string_list_append(&spell->description, "d : drop all carried items");
- string_list_append(&spell->description, "i : list all carried items");
- string_list_append(&spell->description, "m : end the possession/use golem powers");
- string_list_append(&spell->description, "Most of the other keys are disabled, you cannot interact with your");
- string_list_append(&spell->description, "real body while controlling the golem");
- string_list_append(&spell->description, "But to cast the spell you will need a lantern or a wooden torch to");
- string_list_append(&spell->description, "Create the golem from");
- school_idx_add_new(&spell->schools, SCHOOL_FIRE);
- school_idx_add_new(&spell->schools, SCHOOL_MIND);
- range_init(&spell->mana_range, 16, 70);
- spell->info_func = fire_golem_info;
- spell->effect_func = fire_golem;
- spell->failure_rate = 40;
- spell->skill_level = 7;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Creates a fiery golem and controls it");
+ spell_type_describe(spell, "During the control the available keylist is:");
+ spell_type_describe(spell, "Movement keys: movement of the golem(depending on its speed");
+ spell_type_describe(spell, " it can move more than one square)");
+ spell_type_describe(spell, ", : pickup all items on the floor");
+ spell_type_describe(spell, "d : drop all carried items");
+ spell_type_describe(spell, "i : list all carried items");
+ spell_type_describe(spell, "m : end the possession/use golem powers");
+ spell_type_describe(spell, "Most of the other keys are disabled, you cannot interact with your");
+ spell_type_describe(spell, "real body while controlling the golem");
+ spell_type_describe(spell, "But to cast the spell you will need a lantern or a wooden torch to");
+ spell_type_describe(spell, "Create the golem from");
+ spell_type_add_school(spell, SCHOOL_MIND);
+ spell_type_set_mana(spell, 16, 70);
+ spell_type_set_difficulty(spell, 7, 40);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_FIRE,
+ fire_golem_info,
+ fire_golem);
}
{
spell_type *spell = spell_new(&MANATHRUST, "MANATHRUST", "Manathrust");
- string_list_append(&spell->description, "Conjures up mana into a powerful bolt");
- string_list_append(&spell->description, "The damage is irresistible and will increase with level");
- school_idx_add_new(&spell->schools, SCHOOL_MANA);
- range_init(&spell->mana_range, 1, 25);
- spell->info_func = mana_manathrust_info;
- spell->effect_func = mana_manathrust;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "7+d10");
+ spell_type_describe(spell, "Conjures up mana into a powerful bolt");
+ spell_type_describe(spell, "The damage is irresistible and will increase with level");
+ spell_type_set_mana(spell, 1, 25);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MANA,
+ mana_manathrust_info,
+ mana_manathrust);
+
+ spell_type_set_device_charges(spell, "7+d10");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 5;
range_init(&device_allocation->base_level, 1, 20);
range_init(&device_allocation->max_level, 15, 33);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DELCURSES, "DELCURSES", "Remove Curses");
- string_list_append(&spell->description, "Remove curses of worn objects");
- string_list_append(&spell->description, "At level 20 switches to *remove curses*");
- school_idx_add_new(&spell->schools, SCHOOL_MANA);
- range_init(&spell->mana_range, 20, 40);
- spell_inertia_init(spell, 1, 10);
- spell->info_func = mana_remove_curses_info;
- spell->effect_func = mana_remove_curses;
- spell->failure_rate = 30;
- spell->skill_level = 10;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d8");
+ spell_type_describe(spell, "Remove curses of worn objects");
+ spell_type_describe(spell, "At level 20 switches to *remove curses*");
+ spell_type_set_mana(spell, 20, 40);
+ spell_type_set_inertia(spell, 1, 10);
+ spell_type_set_difficulty(spell, 10, 30);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MANA,
+ mana_remove_curses_info,
+ mana_remove_curses);
+
+ spell_type_set_device_charges(spell, "3+d8");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 70;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 15, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&RESISTS, "RESISTS", "Elemental Shield");
- string_list_append(&spell->description, "Provide resistances to the four basic elements");
- school_idx_add_new(&spell->schools, SCHOOL_MANA);
- range_init(&spell->mana_range, 17, 20);
- spell_inertia_init(spell, 2, 25);
- spell->info_func = mana_elemental_shield_info;
- spell->effect_func = mana_elemental_shield;
- spell->failure_rate = 40;
- spell->skill_level = 20;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Provide resistances to the four basic elements");
+ spell_type_set_mana(spell, 17, 20);
+ spell_type_set_inertia(spell, 2, 25);
+ spell_type_set_difficulty(spell, 20, 40);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MANA,
+ mana_elemental_shield_info,
+ mana_elemental_shield);
}
{
spell_type *spell = spell_new(&MANASHIELD, "MANASHIELD", "Disruption Shield");
- string_list_append(&spell->description, "Uses mana instead of hp to take damage");
- string_list_append(&spell->description, "At level 5 switches to Globe of Invulnerability.");
- string_list_append(&spell->description, "The spell breaks as soon as a melee, shooting, throwing or magical");
- string_list_append(&spell->description, "skill action is attempted, and lasts only a short time.");
- school_idx_add_new(&spell->schools, SCHOOL_MANA);
- range_init(&spell->mana_range, 50, 50);
- spell_inertia_init(spell, 9, 10);
- spell->info_func = mana_disruption_shield_info;
- spell->effect_func = mana_disruption_shield;
- spell->failure_rate = 90;
- spell->skill_level = 45;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Uses mana instead of hp to take damage");
+ spell_type_describe(spell, "At level 5 switches to Globe of Invulnerability.");
+ spell_type_describe(spell, "The spell breaks as soon as a melee, shooting, throwing or magical");
+ spell_type_describe(spell, "skill action is attempted, and lasts only a short time.");
+ spell_type_set_mana(spell, 50, 50);
+ spell_type_set_inertia(spell, 9, 10);
+ spell_type_set_difficulty(spell, 45, 90);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MANA,
+ mana_disruption_shield_info,
+ mana_disruption_shield);
}
{
spell_type *spell = spell_new(&TIDALWAVE, "TIDALWAVE", "Tidal Wave");
- string_list_append(&spell->description, "Summons a monstrous tidal wave that will expand and crush the");
- string_list_append(&spell->description, "monsters under its mighty waves.");
- school_idx_add_new(&spell->schools, SCHOOL_WATER);
- range_init(&spell->mana_range, 16, 40);
- spell_inertia_init(spell, 4, 100);
- spell->info_func = water_tidal_wave_info;
- spell->effect_func = water_tidal_wave;
- spell->failure_rate = 65;
- spell->skill_level = 16;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "6+d5");
+ spell_type_describe(spell, "Summons a monstrous tidal wave that will expand and crush the");
+ spell_type_describe(spell, "monsters under its mighty waves.");
+ spell_type_set_mana(spell, 16, 40);
+ spell_type_set_inertia(spell, 4, 100);
+ spell_type_set_difficulty(spell, 16, 65);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_WATER,
+ water_tidal_wave_info,
+ water_tidal_wave);
+
+ spell_type_set_device_charges(spell, "6+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 54;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&ICESTORM, "ICESTORM", "Ice Storm");
- string_list_append(&spell->description, "Engulfs you in a storm of roaring cold that strikes your foes.");
- string_list_append(&spell->description, "At level 10 it turns into shards of ice.");
- school_idx_add_new(&spell->schools, SCHOOL_WATER);
- range_init(&spell->mana_range, 30, 60);
- spell_inertia_init(spell, 3, 40);
- spell->info_func = water_ice_storm_info;
- spell->effect_func = water_ice_storm;
- spell->failure_rate = 80;
- spell->skill_level = 22;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d7");
+ spell_type_describe(spell, "Engulfs you in a storm of roaring cold that strikes your foes.");
+ spell_type_describe(spell, "At level 10 it turns into shards of ice.");
+ spell_type_set_mana(spell, 30, 60);
+ spell_type_set_inertia(spell, 3, 40);
+ spell_type_set_difficulty(spell, 22, 80);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_WATER,
+ water_ice_storm_info,
+ water_ice_storm);
+
+ spell_type_set_device_charges(spell, "3+d7");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 65;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 25, 45);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&ENTPOTION, "ENTPOTION", "Ent's Potion");
- string_list_append(&spell->description, "Fills up your stomach.");
- string_list_append(&spell->description, "At level 5 it boldens your heart.");
- string_list_append(&spell->description, "At level 12 it makes you heroic.");
- school_idx_add_new(&spell->schools, SCHOOL_WATER);
- range_init(&spell->mana_range, 7, 15);
- spell_inertia_init(spell, 1, 30);
- spell->info_func = water_ent_potion_info;
- spell->effect_func = water_ent_potion;
- spell->failure_rate = 35;
- spell->skill_level = 6;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Fills up your stomach.");
+ spell_type_describe(spell, "At level 5 it boldens your heart.");
+ spell_type_describe(spell, "At level 12 it makes you heroic.");
+ spell_type_set_mana(spell, 7, 15);
+ spell_type_set_inertia(spell, 1, 30);
+ spell_type_set_difficulty(spell, 6, 35);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_WATER,
+ water_ent_potion_info,
+ water_ent_potion);
}
{
spell_type *spell = spell_new(&VAPOR, "VAPOR", "Vapor");
- string_list_append(&spell->description, "Fills the air with toxic moisture to eradicate annoying critters.");
- school_idx_add_new(&spell->schools, SCHOOL_WATER);
- range_init(&spell->mana_range, 2, 12);
- spell_inertia_init(spell, 1, 30);
- spell->info_func = water_vapor_info;
- spell->effect_func = water_vapor;
- spell->failure_rate = 20;
- spell->skill_level = 2;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Fills the air with toxic moisture to eradicate annoying critters.");
+ spell_type_set_mana(spell, 2, 12);
+ spell_type_set_inertia(spell, 1, 30);
+ spell_type_set_difficulty(spell, 2, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_WATER,
+ water_vapor_info,
+ water_vapor);
}
{
spell_type *spell = spell_new(&GEYSER, "GEYSER", "Geyser");
- string_list_append(&spell->description, "Shoots a geyser of water from your fingertips.");
- string_list_append(&spell->description, "Sometimes it can blast through its first target.");
- school_idx_add_new(&spell->schools, SCHOOL_WATER);
- range_init(&spell->mana_range, 1, 35);
- spell->info_func = water_geyser_info;
- spell->effect_func = water_geyser;
- spell->failure_rate = 5;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Shoots a geyser of water from your fingertips.");
+ spell_type_describe(spell, "Sometimes it can blast through its first target.");
+ spell_type_set_mana(spell, 1, 35);
+ spell_type_set_difficulty(spell, 1, 5);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_WATER,
+ water_geyser_info,
+ water_geyser);
}
{
spell_type *spell = spell_new(&NOXIOUSCLOUD, "NOXIOUSCLOUD", "Noxious Cloud");
- string_list_append(&spell->description, "Creates a cloud of poison");
- string_list_append(&spell->description, "The cloud will persist for some turns, damaging all monsters passing by");
- string_list_append(&spell->description, "At spell level 30 it turns into a thick gas attacking all living beings");
- school_idx_add_new(&spell->schools, SCHOOL_AIR);
- range_init(&spell->mana_range, 3, 30);
- spell->info_func = air_noxious_cloud_info;
- spell->effect_func = air_noxious_cloud;
- spell->failure_rate = 20;
- spell->skill_level = 3;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d7");
+ spell_type_describe(spell, "Creates a cloud of poison");
+ spell_type_describe(spell, "The cloud will persist for some turns, damaging all monsters passing by");
+ spell_type_describe(spell, "At spell level 30 it turns into a thick gas attacking all living beings");
+ spell_type_set_mana(spell, 3, 30);
+ spell_type_set_difficulty(spell, 3, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_AIR,
+ air_noxious_cloud_info,
+ air_noxious_cloud);
+
+ spell_type_set_device_charges(spell, "5+d7");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 15;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 25, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&AIRWINGS, "AIRWINGS", "Wings of Winds");
- string_list_append(&spell->description, "Grants the power of levitation");
- string_list_append(&spell->description, "At level 16 it grants the power of controlled flight");
- school_idx_add_new(&spell->schools, SCHOOL_AIR);
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 30, 40);
- spell_inertia_init(spell, 1, 10);
- spell->info_func = air_wings_of_winds_info;
- spell->effect_func = air_wings_of_winds;
- spell->failure_rate = 60;
- spell->skill_level = 22;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "7+d5");
+ spell_type_describe(spell, "Grants the power of levitation");
+ spell_type_describe(spell, "At level 16 it grants the power of controlled flight");
+ spell_type_add_school(spell, SCHOOL_CONVEYANCE);
+ spell_type_set_mana(spell, 30, 40);
+ spell_type_set_inertia(spell, 1, 10);
+ spell_type_set_difficulty(spell, 22, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_AIR,
+ air_wings_of_winds_info,
+ air_wings_of_winds);
+
+ spell_type_set_device_charges(spell, "7+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 27;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&INVISIBILITY, "INVISIBILITY", "Invisibility");
- string_list_append(&spell->description, "Grants invisibility");
- school_idx_add_new(&spell->schools, SCHOOL_AIR);
- range_init(&spell->mana_range, 10, 20);
- spell_inertia_init(spell, 1, 30);
- spell->info_func = air_invisibility_info;
- spell->effect_func = air_invisibility;
- spell->failure_rate = 50;
- spell->skill_level = 16;
- spell_init_mage(spell, RANDOM);
-
+ spell_type_describe(spell, "Grants invisibility");
+ spell_type_set_mana(spell, 10, 20);
+ spell_type_set_inertia(spell, 1, 30);
+ spell_type_set_difficulty(spell, 16, 50);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_AIR,
+ air_invisibility_info,
+ air_invisibility);
}
{
spell_type *spell = spell_new(&POISONBLOOD, "POISONBLOOD", "Poison Blood");
- string_list_append(&spell->description, "Grants resist poison");
- string_list_append(&spell->description, "At level 15 it provides poison branding to wielded weapon");
- school_idx_add_new(&spell->schools, SCHOOL_AIR);
- range_init(&spell->mana_range, 10, 20);
- spell_inertia_init(spell, 1, 35);
- spell->info_func = air_poison_blood_info;
- spell->effect_func = air_poison_blood;
- spell->failure_rate = 30;
- spell->skill_level = 12;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "10+d15");
+ spell_type_describe(spell, "Grants resist poison");
+ spell_type_describe(spell, "At level 15 it provides poison branding to wielded weapon");
+ spell_type_set_mana(spell, 10, 20);
+ spell_type_set_inertia(spell, 1, 35);
+ spell_type_set_difficulty(spell, 12, 30);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_AIR,
+ air_poison_blood_info,
+ air_poison_blood);
+
+ spell_type_set_device_charges(spell, "10+d15");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 45;
range_init(&device_allocation->base_level, 1, 25);
range_init(&device_allocation->max_level, 35, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&THUNDERSTORM, "THUNDERSTORM", "Thunderstorm");
- string_list_append(&spell->description, "Charges up the air around you with electricity");
- string_list_append(&spell->description, "Each turn it will throw a thunder bolt at a random monster in sight");
- string_list_append(&spell->description, "The thunder does 3 types of damage, one third of lightning");
- string_list_append(&spell->description, "one third of sound and one third of light");
- school_idx_add_new(&spell->schools, SCHOOL_AIR);
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 40, 60);
- spell_inertia_init(spell, 2, 15);
- spell->info_func = air_thunderstorm_info;
- spell->effect_func = air_thunderstorm;
- spell->failure_rate = 60;
- spell->skill_level = 25;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d5");
+ spell_type_describe(spell, "Charges up the air around you with electricity");
+ spell_type_describe(spell, "Each turn it will throw a thunder bolt at a random monster in sight");
+ spell_type_describe(spell, "The thunder does 3 types of damage, one third of lightning");
+ spell_type_describe(spell, "one third of sound and one third of light");
+ spell_type_add_school(spell, SCHOOL_NATURE);
+ spell_type_set_mana(spell, 40, 60);
+ spell_type_set_inertia(spell, 2, 15);
+ spell_type_set_difficulty(spell, 25, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_AIR,
+ air_thunderstorm_info,
+ air_thunderstorm);
+
+ spell_type_set_device_charges(spell, "5+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 85;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 25, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&STERILIZE, "STERILIZE", "Sterilize");
- string_list_append(&spell->description, "Prevents explosive breeding for a while.");
- school_idx_add_new(&spell->schools, SCHOOL_AIR);
- range_init(&spell->mana_range, 10, 100);
- spell->info_func = air_sterilize_info;
- spell->effect_func = air_sterilize;
- spell->failure_rate = 50;
- spell->skill_level = 20;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Prevents explosive breeding for a while.");
+ spell_type_set_mana(spell, 10, 100);
+ spell_type_set_difficulty(spell, 20, 50);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_AIR,
+ air_sterilize_info,
+ air_sterilize);
- dice_parse_checked(&spell->device_charges, "7+d5");
+ spell_type_set_device_charges(spell, "7+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 20;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&STONESKIN, "STONESKIN", "Stone Skin");
- string_list_append(&spell->description, "Creates a shield of earth around you to protect you");
- string_list_append(&spell->description, "At level 25 it starts dealing damage to attackers");
- school_idx_add_new(&spell->schools, SCHOOL_EARTH);
- range_init(&spell->mana_range, 1, 50);
- spell_inertia_init(spell, 2, 50);
- spell->info_func = earth_stone_skin_info;
- spell->effect_func = earth_stone_skin;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Creates a shield of earth around you to protect you");
+ spell_type_describe(spell, "At level 25 it starts dealing damage to attackers");
+ spell_type_set_mana(spell, 1, 50);
+ spell_type_set_inertia(spell, 2, 50);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_EARTH,
+ earth_stone_skin_info,
+ earth_stone_skin);
}
{
spell_type *spell = spell_new(&DIG, "DIG", "Dig");
- string_list_append(&spell->description, "Digs a hole in a wall much faster than any shovels");
- school_idx_add_new(&spell->schools, SCHOOL_EARTH);
- range_init(&spell->mana_range, 14, 14);
- spell->info_func = earth_dig_info;
- spell->effect_func = earth_dig;
- spell->failure_rate = 20;
- spell->skill_level = 12;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Digs a hole in a wall much faster than any shovels");
+ spell_type_set_mana(spell, 14, 14);
+ spell_type_set_difficulty(spell, 12, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_EARTH,
+ earth_dig_info,
+ earth_dig);
- dice_parse_checked(&spell->device_charges, "15+d5");
+ spell_type_set_device_charges(spell, "15+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 25;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 1, 1);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&STONEPRISON, "STONEPRISON", "Stone Prison");
- string_list_append(&spell->description, "Creates a prison of walls around you");
- string_list_append(&spell->description, "At level 10 it allows you to target a monster");
- school_idx_add_new(&spell->schools, SCHOOL_EARTH);
- range_init(&spell->mana_range, 30, 50);
- spell->info_func = earth_stone_prison_info;
- spell->effect_func = earth_stone_prison;
- spell->failure_rate = 65;
- spell->skill_level = 25;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d3");
+ spell_type_describe(spell, "Creates a prison of walls around you");
+ spell_type_describe(spell, "At level 10 it allows you to target a monster");
+ spell_type_set_mana(spell, 30, 50);
+ spell_type_set_difficulty(spell, 25, 65);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_EARTH,
+ earth_stone_prison_info,
+ earth_stone_prison);
+
+ spell_type_set_device_charges(spell, "5+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 57;
range_init(&device_allocation->base_level, 1, 3);
range_init(&device_allocation->max_level, 5, 20);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&STRIKE, "STRIKE", "Strike");
- string_list_append(&spell->description, "Creates a micro-ball of force that will push monsters backwards");
- string_list_append(&spell->description, "If the monster is caught near a wall, it'll be crushed against it");
- string_list_append(&spell->description, "At level 12 it turns into a ball of radius 1");
- school_idx_add_new(&spell->schools, SCHOOL_EARTH);
- range_init(&spell->mana_range, 30, 50);
- spell->info_func = earth_strike_info;
- spell->effect_func = earth_strike;
- spell->failure_rate = 60;
- spell->skill_level = 30;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "2+d6");
+ spell_type_describe(spell, "Creates a micro-ball of force that will push monsters backwards");
+ spell_type_describe(spell, "If the monster is caught near a wall, it'll be crushed against it");
+ spell_type_describe(spell, "At level 12 it turns into a ball of radius 1");
+ spell_type_set_mana(spell, 30, 50);
+ spell_type_set_difficulty(spell, 30, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_EARTH,
+ earth_strike_info,
+ earth_strike);
+
+ spell_type_set_device_charges(spell, "2+d6");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 635;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 10, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&SHAKE, "SHAKE", "Shake");
- string_list_append(&spell->description, "Creates a localised earthquake");
- string_list_append(&spell->description, "At level 10 it can be targeted at any location");
- school_idx_add_new(&spell->schools, SCHOOL_EARTH);
- range_init(&spell->mana_range, 25, 30);
- spell_inertia_init(spell, 2, 50);
- spell->info_func = earth_shake_info;
- spell->effect_func = earth_shake;
- spell->failure_rate = 60;
- spell->skill_level = 27;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d10");
+ spell_type_describe(spell, "Creates a localised earthquake");
+ spell_type_describe(spell, "At level 10 it can be targeted at any location");
+ spell_type_set_mana(spell, 25, 30);
+ spell_type_set_inertia(spell, 2, 50);
+ spell_type_set_difficulty(spell, 27, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_EARTH,
+ earth_shake_info,
+ earth_shake);
+
+ spell_type_set_device_charges(spell, "5+d10");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 75;
range_init(&device_allocation->base_level, 1, 3);
range_init(&device_allocation->max_level, 9, 20);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&BLINK, "BLINK", "Phase Door");
- string_list_append(&spell->description, "Teleports you on a small scale range");
- string_list_append(&spell->description, "At level 30 it creates void jumpgates");
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 1, 3);
- spell_inertia_init(spell, 1, 5);
- spell->info_func = convey_blink_info;
- spell->effect_func = convey_blink;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Teleports you on a small scale range");
+ spell_type_describe(spell, "At level 30 it creates void jumpgates");
+ spell_type_set_mana(spell, 1, 3);
+ spell_type_set_inertia(spell, 1, 5);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_CONVEYANCE,
+ convey_blink_info,
+ convey_blink);
}
{
spell_type *spell = spell_new(&DISARM, "DISARM", "Disarm");
- string_list_append(&spell->description, "Destroys doors and traps");
- string_list_append(&spell->description, "At level 10 it destroys doors and traps, then reveals and unlocks any secret");
- string_list_append(&spell->description, "doors");
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 2, 4);
- spell->info_func = convey_disarm_info;
- spell->effect_func = convey_disarm;
- spell->failure_rate = 15;
- spell->skill_level = 3;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "10+d15");
+ spell_type_describe(spell, "Destroys doors and traps");
+ spell_type_describe(spell, "At level 10 it destroys doors and traps, then reveals and unlocks any secret");
+ spell_type_describe(spell, "doors");
+ spell_type_set_mana(spell, 2, 4);
+ spell_type_set_difficulty(spell, 3, 15);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_CONVEYANCE,
+ convey_disarm_info,
+ convey_disarm);
+
+ spell_type_set_device_charges(spell, "10+d15");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 4;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 10, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&TELEPORT, "TELEPORT", "Teleportation");
- string_list_append(&spell->description, "Teleports you around the level. The casting time decreases with level");
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 8, 14);
- spell_inertia_init(spell, 1, 10);
- spell->info_func = convey_teleport_info;
- spell->effect_func = convey_teleport;
- spell->failure_rate = 30;
- spell->skill_level = 10;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "7+d7");
+ spell_type_describe(spell, "Teleports you around the level. The casting time decreases with level");
+ spell_type_set_mana(spell, 8, 14);
+ spell_type_set_inertia(spell, 1, 10);
+ spell_type_set_difficulty(spell, 10, 30);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_CONVEYANCE,
+ convey_teleport_info,
+ convey_teleport);
+
+ spell_type_set_device_charges(spell, "7+d7");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 50;
range_init(&device_allocation->base_level, 1, 20);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&TELEAWAY, "TELEAWAY", "Teleport Away");
- string_list_append(&spell->description, "Teleports a line of monsters away");
- string_list_append(&spell->description, "At level 10 it turns into a ball");
- string_list_append(&spell->description, "At level 20 it teleports all monsters in sight");
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 15, 40);
- spell->info_func = convey_teleport_away_info;
- spell->effect_func = convey_teleport_away;
- spell->failure_rate = 60;
- spell->skill_level = 23;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d5");
+ spell_type_describe(spell, "Teleports a line of monsters away");
+ spell_type_describe(spell, "At level 10 it turns into a ball");
+ spell_type_describe(spell, "At level 20 it teleports all monsters in sight");
+ spell_type_set_mana(spell, 15, 40);
+ spell_type_set_difficulty(spell, 23, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_CONVEYANCE,
+ convey_teleport_away_info,
+ convey_teleport_away);
+
+ spell_type_set_device_charges(spell, "3+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 75;
range_init(&device_allocation->base_level, 1, 20);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&RECALL, "RECALL", "Recall");
- string_list_append(&spell->description, "Cast on yourself it will recall you to the surface/dungeon.");
- string_list_append(&spell->description, "Cast at a monster you will swap positions with the monster.");
- string_list_append(&spell->description, "Cast at an object it will fetch the object to you.");
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 25, 25);
- spell->info_func = convey_recall_info;
- spell->effect_func = convey_recall;
- spell->failure_rate = 60;
- spell->skill_level = 30;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Cast on yourself it will recall you to the surface/dungeon.");
+ spell_type_describe(spell, "Cast at a monster you will swap positions with the monster.");
+ spell_type_describe(spell, "Cast at an object it will fetch the object to you.");
+ spell_type_set_mana(spell, 25, 25);
+ spell_type_set_difficulty(spell, 30, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_CONVEYANCE,
+ convey_recall_info,
+ convey_recall);
}
{
spell_type *spell = spell_new(&PROBABILITY_TRAVEL, "PROBABILITY_TRAVEL", "Probability Travel");
- string_list_append(&spell->description, "Renders you immaterial, when you hit a wall you travel through it and");
- string_list_append(&spell->description, "instantly appear on the other side of it. You can also float up and down");
- string_list_append(&spell->description, "at will");
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 30, 50);
- spell_inertia_init(spell, 6, 40);
- spell->info_func = convey_probability_travel_info;
- spell->effect_func = convey_probability_travel;
- spell->failure_rate = 90;
- spell->skill_level = 35;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "1+d2");
+ spell_type_describe(spell, "Renders you immaterial, when you hit a wall you travel through it and");
+ spell_type_describe(spell, "instantly appear on the other side of it. You can also float up and down");
+ spell_type_describe(spell, "at will");
+ spell_type_set_mana(spell, 30, 50);
+ spell_type_set_inertia(spell, 6, 40);
+ spell_type_set_difficulty(spell, 35, 90);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_CONVEYANCE,
+ convey_probability_travel_info,
+ convey_probability_travel);
+
+ spell_type_set_device_charges(spell, "1+d2");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 97;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 8, 25);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&GROWTREE, "GROWTREE", "Grow Trees");
- string_list_append(&spell->description, "Makes trees grow extremely quickly around you");
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- school_idx_add_new(&spell->schools, SCHOOL_TEMPORAL);
- range_init(&spell->mana_range, 6, 30);
- spell_inertia_init(spell, 5, 50);
- spell->info_func = nature_grow_trees_info;
- spell->effect_func = nature_grow_trees;
- spell->failure_rate = 35;
- spell->skill_level = 6;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Makes trees grow extremely quickly around you");
+ spell_type_add_school(spell, SCHOOL_TEMPORAL);
+ spell_type_set_mana(spell, 6, 30);
+ spell_type_set_inertia(spell, 5, 50);
+ spell_type_set_difficulty(spell, 6, 35);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_NATURE,
+ nature_grow_trees_info,
+ nature_grow_trees);
}
{
spell_type *spell = spell_new(&HEALING, "HEALING", "Healing");
- string_list_append(&spell->description, "Heals a percent of hitpoints");
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 15, 50);
- spell->info_func = nature_healing_info;
- spell->effect_func = nature_healing;
- spell->failure_rate = 45;
- spell->skill_level = 10;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Heals a percent of hitpoints");
+ spell_type_set_mana(spell, 15, 50);
+ spell_type_set_difficulty(spell, 10, 45);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_NATURE,
+ nature_healing_info,
+ nature_healing);
- dice_parse_checked(&spell->device_charges, "2+d3");
+ spell_type_set_device_charges(spell, "2+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 90;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 20, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&RECOVERY, "RECOVERY", "Recovery");
- string_list_append(&spell->description, "Reduces the length of time that you are poisoned");
- string_list_append(&spell->description, "At level 5 it cures poison and cuts");
- string_list_append(&spell->description, "At level 10 it restores drained stats");
- string_list_append(&spell->description, "At level 15 it restores lost experience");
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 10, 25);
- spell_inertia_init(spell, 2, 100);
- spell->info_func = nature_recovery_info;
- spell->effect_func = nature_recovery;
- spell->failure_rate = 60;
- spell->skill_level = 15;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d10");
+ spell_type_describe(spell, "Reduces the length of time that you are poisoned");
+ spell_type_describe(spell, "At level 5 it cures poison and cuts");
+ spell_type_describe(spell, "At level 10 it restores drained stats");
+ spell_type_describe(spell, "At level 15 it restores lost experience");
+ spell_type_set_mana(spell, 10, 25);
+ spell_type_set_inertia(spell, 2, 100);
+ spell_type_set_difficulty(spell, 15, 60);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_NATURE,
+ nature_recovery_info,
+ nature_recovery);
+
+ spell_type_set_device_charges(spell, "5+d10");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 50;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 10, 30);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&REGENERATION, "REGENERATION", "Regeneration");
- string_list_append(&spell->description, "Increases your body's regeneration rate");
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 30, 55);
- spell_inertia_init(spell, 4, 40);
- spell->info_func = nature_regeneration_info;
- spell->effect_func = nature_regeneration;
- spell->failure_rate = 70;
- spell->skill_level = 20;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Increases your body's regeneration rate");
+ spell_type_set_mana(spell, 30, 55);
+ spell_type_set_inertia(spell, 4, 40);
+ spell_type_set_difficulty(spell, 20, 70);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_NATURE,
+ nature_regeneration_info,
+ nature_regeneration);
}
{
spell_type *spell = spell_new(&SUMMONANNIMAL, "SUMMONANNIMAL", "Summon Animal");
- string_list_append(&spell->description, "Summons a leveled animal to your aid");
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 25, 50);
- spell->info_func = nature_summon_animal_info;
- spell->effect_func = nature_summon_animal;
- spell->failure_rate = 90;
- spell->skill_level = 25;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Summons a leveled animal to your aid");
+ spell_type_set_mana(spell, 25, 50);
+ spell_type_set_difficulty(spell, 25, 90);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_NATURE,
+ nature_summon_animal_info,
+ nature_summon_animal);
- dice_parse_checked(&spell->device_charges, "1+d3");
+ spell_type_set_device_charges(spell, "1+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 85;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 15, 45);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&STARIDENTIFY, "STARIDENTIFY", "Greater Identify");
- string_list_append(&spell->description, "Asks for an object and fully identify it, providing the full list of powers");
- string_list_append(&spell->description, "Cast at yourself it will reveal your powers");
- school_idx_add_new(&spell->schools, SCHOOL_DIVINATION);
- range_init(&spell->mana_range, 30, 30);
- spell->info_func = divination_greater_identify_info;
- spell->effect_func = divination_greater_identify;
- spell->failure_rate = 80;
- spell->skill_level = 35;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Asks for an object and fully identify it, providing the full list of powers");
+ spell_type_describe(spell, "Cast at yourself it will reveal your powers");
+ spell_type_set_mana(spell, 30, 30);
+ spell_type_set_difficulty(spell, 35, 80);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_DIVINATION,
+ divination_greater_identify_info,
+ divination_greater_identify);
}
{
spell_type *spell = spell_new(&IDENTIFY, "IDENTIFY", "Identify");
- string_list_append(&spell->description, "Asks for an object and identifies it");
- string_list_append(&spell->description, "At level 17 it identifies all objects in the inventory");
- string_list_append(&spell->description, "At level 27 it identifies all objects in the inventory and in a");
- string_list_append(&spell->description, "radius on the floor, as well as probing monsters in that radius");
- school_idx_add_new(&spell->schools, SCHOOL_DIVINATION);
- range_init(&spell->mana_range, 10, 50);
- spell->info_func = divination_identify_info;
- spell->effect_func = divination_identify;
- spell->failure_rate = 40;
- spell->skill_level = 8;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "7+d10");
+ spell_type_describe(spell, "Asks for an object and identifies it");
+ spell_type_describe(spell, "At level 17 it identifies all objects in the inventory");
+ spell_type_describe(spell, "At level 27 it identifies all objects in the inventory and in a");
+ spell_type_describe(spell, "radius on the floor, as well as probing monsters in that radius");
+ spell_type_set_mana(spell, 10, 50);
+ spell_type_set_difficulty(spell, 8, 40);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_DIVINATION,
+ divination_identify_info,
+ divination_identify);
+
+ spell_type_set_device_charges(spell, "7+d10");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 45;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 15, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&VISION, "VISION", "Vision");
- string_list_append(&spell->description, "Detects the layout of the surrounding area");
- string_list_append(&spell->description, "At level 25 it maps and lights the whole level");
- school_idx_add_new(&spell->schools, SCHOOL_DIVINATION);
- range_init(&spell->mana_range, 7, 55);
- spell_inertia_init(spell, 2, 200);
- spell->info_func = divination_vision_info;
- spell->effect_func = divination_vision;
- spell->failure_rate = 45;
- spell->skill_level = 15;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "4+d6");
+ spell_type_describe(spell, "Detects the layout of the surrounding area");
+ spell_type_describe(spell, "At level 25 it maps and lights the whole level");
+ spell_type_set_mana(spell, 7, 55);
+ spell_type_set_inertia(spell, 2, 200);
+ spell_type_set_difficulty(spell, 15, 45);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_DIVINATION,
+ divination_vision_info,
+ divination_vision);
+
+ spell_type_set_device_charges(spell, "4+d6");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 60;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 10, 30);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&SENSEHIDDEN, "SENSEHIDDEN", "Sense Hidden");
- string_list_append(&spell->description, "Detects the traps in a certain radius around you");
- string_list_append(&spell->description, "At level 15 it allows you to sense invisible for a while");
- school_idx_add_new(&spell->schools, SCHOOL_DIVINATION);
- range_init(&spell->mana_range, 2, 10);
- spell_inertia_init(spell, 1, 10);
- spell->info_func = divination_sense_hidden_info;
- spell->effect_func = divination_sense_hidden;
- spell->failure_rate = 25;
- spell->skill_level = 5;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "1+d15");
+ spell_type_describe(spell, "Detects the traps in a certain radius around you");
+ spell_type_describe(spell, "At level 15 it allows you to sense invisible for a while");
+ spell_type_set_mana(spell, 2, 10);
+ spell_type_set_inertia(spell, 1, 10);
+ spell_type_set_difficulty(spell, 5, 25);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_DIVINATION,
+ divination_sense_hidden_info,
+ divination_sense_hidden);
+
+ spell_type_set_device_charges(spell, "1+d15");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 20;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 10, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&REVEALWAYS, "REVEALWAYS", "Reveal Ways");
- string_list_append(&spell->description, "Detects the doors/stairs/ways in a certain radius around you");
- school_idx_add_new(&spell->schools, SCHOOL_DIVINATION);
- range_init(&spell->mana_range, 3, 15);
- spell_inertia_init(spell, 1, 10);
- spell->info_func = divination_reveal_ways_info;
- spell->effect_func = divination_reveal_ways;
- spell->failure_rate = 20;
- spell->skill_level = 9;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "6+d6");
+ spell_type_describe(spell, "Detects the doors/stairs/ways in a certain radius around you");
+ spell_type_set_mana(spell, 3, 15);
+ spell_type_set_inertia(spell, 1, 10);
+ spell_type_set_difficulty(spell, 9, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_DIVINATION,
+ divination_reveal_ways_info,
+ divination_reveal_ways);
+
+ spell_type_set_device_charges(spell, "6+d6");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 35;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 25, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&SENSEMONSTERS, "SENSEMONSTERS", "Sense Monsters");
- string_list_append(&spell->description, "Detects all monsters near you");
- string_list_append(&spell->description, "At level 30 it allows you to sense monster minds for a while");
- school_idx_add_new(&spell->schools, SCHOOL_DIVINATION);
- range_init(&spell->mana_range, 1, 20);
- spell_inertia_init(spell, 1, 10);
- spell->info_func = divination_sense_monsters_info;
- spell->effect_func = divination_sense_monsters;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d10");
+ spell_type_describe(spell, "Detects all monsters near you");
+ spell_type_describe(spell, "At level 30 it allows you to sense monster minds for a while");
+ spell_type_set_mana(spell, 1, 20);
+ spell_type_set_inertia(spell, 1, 10);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_DIVINATION,
+ divination_sense_monsters_info,
+ divination_sense_monsters);
+
+ spell_type_set_device_charges(spell, "5+d10");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 37;
range_init(&device_allocation->base_level, 1, 10);
range_init(&device_allocation->max_level, 15, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&MAGELOCK, "MAGELOCK", "Magelock");
- string_list_append(&spell->description, "Magically locks a door");
- string_list_append(&spell->description, "At level 30 it creates a glyph of warding");
- string_list_append(&spell->description, "At level 40 the glyph can be placed anywhere in the field of vision");
- school_idx_add_new(&spell->schools, SCHOOL_TEMPORAL);
- range_init(&spell->mana_range, 1, 35);
- spell->info_func = tempo_magelock_info;
- spell->effect_func = tempo_magelock;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "7+d5");
+ spell_type_describe(spell, "Magically locks a door");
+ spell_type_describe(spell, "At level 30 it creates a glyph of warding");
+ spell_type_describe(spell, "At level 40 the glyph can be placed anywhere in the field of vision");
+ spell_type_set_mana(spell, 1, 35);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_TEMPORAL,
+ tempo_magelock_info,
+ tempo_magelock);
+
+ spell_type_set_device_charges(spell, "7+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 30;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 15, 45);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&SLOWMONSTER, "SLOWMONSTER", "Slow Monster");
- string_list_append(&spell->description, "Magically slows down the passing of time around a monster");
- string_list_append(&spell->description, "At level 20 it affects a zone");
- school_idx_add_new(&spell->schools, SCHOOL_TEMPORAL);
- range_init(&spell->mana_range, 10, 15);
- spell->info_func = tempo_slow_monster_info;
- spell->effect_func = tempo_slow_monster;
- spell->failure_rate = 35;
- spell->skill_level = 10;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d5");
+ spell_type_describe(spell, "Magically slows down the passing of time around a monster");
+ spell_type_describe(spell, "At level 20 it affects a zone");
+ spell_type_set_mana(spell, 10, 15);
+ spell_type_set_difficulty(spell, 10, 35);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_TEMPORAL,
+ tempo_slow_monster_info,
+ tempo_slow_monster);
+
+ spell_type_set_device_charges(spell, "5+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 23;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&ESSENCESPEED, "ESSENCESPEED", "Essence of Speed");
- string_list_append(&spell->description, "Magically decreases the passing of time around you, making you move faster with");
- string_list_append(&spell->description, "respect to the rest of the universe.");
- school_idx_add_new(&spell->schools, SCHOOL_TEMPORAL);
- range_init(&spell->mana_range, 20, 40);
- spell_inertia_init(spell, 5, 20);
- spell->info_func = tempo_essence_of_speed_info;
- spell->effect_func = tempo_essence_of_speed;
- spell->failure_rate = 50;
- spell->skill_level = 15;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d3");
+ spell_type_describe(spell, "Magically decreases the passing of time around you, making you move faster with");
+ spell_type_describe(spell, "respect to the rest of the universe.");
+ spell_type_set_mana(spell, 20, 40);
+ spell_type_set_inertia(spell, 5, 20);
+ spell_type_set_difficulty(spell, 15, 50);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_TEMPORAL,
+ tempo_essence_of_speed_info,
+ tempo_essence_of_speed);
+
+ spell_type_set_device_charges(spell, "3+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 80;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 10, 39);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&BANISHMENT, "BANISHMENT", "Banishment");
- string_list_append(&spell->description, "Disrupts the space/time continuum in your area and teleports all monsters away.");
- string_list_append(&spell->description, "At level 15 it may also lock them in a time bubble for a while.");
- school_idx_add_new(&spell->schools, SCHOOL_TEMPORAL);
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 30, 40);
- spell_inertia_init(spell, 5, 50);
- spell->info_func = tempo_banishment_info;
- spell->effect_func = tempo_banishment;
- spell->failure_rate = 95;
- spell->skill_level = 30;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "1+d3");
+ spell_type_describe(spell, "Disrupts the space/time continuum in your area and teleports all monsters away.");
+ spell_type_describe(spell, "At level 15 it may also lock them in a time bubble for a while.");
+ spell_type_add_school(spell, SCHOOL_CONVEYANCE);
+ spell_type_set_mana(spell, 30, 40);
+ spell_type_set_inertia(spell, 5, 50);
+ spell_type_set_difficulty(spell, 30, 95);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_TEMPORAL,
+ tempo_banishment_info,
+ tempo_banishment);
+
+ spell_type_set_device_charges(spell, "1+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 98;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 10, 36);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&RECHARGE, "RECHARGE", "Recharge");
- string_list_append(&spell->description, "Taps on the ambient mana to recharge an object's power (charges or mana)");
- school_idx_add_new(&spell->schools, SCHOOL_META);
- range_init(&spell->mana_range, 10, 100);
- spell->info_func = meta_recharge_info;
- spell->effect_func = meta_recharge;
- spell->failure_rate = 20;
- spell->skill_level = 5;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Taps on the ambient mana to recharge an object's power (charges or mana)");
+ spell_type_set_mana(spell, 10, 100);
+ spell_type_set_difficulty(spell, 5, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_META,
+ meta_recharge_info,
+ meta_recharge);
}
{
spell_type *spell = spell_new(&SPELLBINDER, "SPELLBINDER", "Spellbinder");
- string_list_append(&spell->description, "Stores spells in a trigger.");
- string_list_append(&spell->description, "When the condition is met all spells fire off at the same time");
- string_list_append(&spell->description, "This spell takes a long time to cast so you are advised to prepare it");
- string_list_append(&spell->description, "in a safe area.");
- string_list_append(&spell->description, "Also it will use the mana for the Spellbinder and the mana for the");
- string_list_append(&spell->description, "selected spells");
- school_idx_add_new(&spell->schools, SCHOOL_META);
- range_init(&spell->mana_range, 100, 300);
- spell->info_func = meta_spellbinder_info;
- spell->effect_func = meta_spellbinder;
- spell->failure_rate = 85;
- spell->skill_level = 20;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Stores spells in a trigger.");
+ spell_type_describe(spell, "When the condition is met all spells fire off at the same time");
+ spell_type_describe(spell, "This spell takes a long time to cast so you are advised to prepare it");
+ spell_type_describe(spell, "in a safe area.");
+ spell_type_describe(spell, "Also it will use the mana for the Spellbinder and the mana for the");
+ spell_type_describe(spell, "selected spells");
+ spell_type_set_mana(spell, 100, 300);
+ spell_type_set_difficulty(spell, 20, 85);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_META,
+ meta_spellbinder_info,
+ meta_spellbinder);
}
{
spell_type *spell = spell_new(&DISPERSEMAGIC, "DISPERSEMAGIC", "Disperse Magic");
- string_list_append(&spell->description, "Dispels a lot of magic that can affect you, be it good or bad");
- string_list_append(&spell->description, "Level 1: blindness and light");
- string_list_append(&spell->description, "Level 5: confusion and hallucination");
- string_list_append(&spell->description, "Level 10: speed (both bad or good) and light speed");
- string_list_append(&spell->description, "Level 15: stunning, meditation, cuts");
- string_list_append(&spell->description, "Level 20: hero, super hero, bless, shields, afraid, parasites, mimicry");
- school_idx_add_new(&spell->schools, SCHOOL_META);
- range_init(&spell->mana_range, 30, 60);
- spell_inertia_init(spell, 1, 5);
- spell->info_func = meta_disperse_magic_info;
- spell->effect_func = meta_disperse_magic;
- spell->failure_rate = 40;
- spell->skill_level = 15;
- spell->castable_while_blind = TRUE;
- spell->castable_while_confused = TRUE;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "5+d5");
+ spell_type_describe(spell, "Dispels a lot of magic that can affect you, be it good or bad");
+ spell_type_describe(spell, "Level 1: blindness and light");
+ spell_type_describe(spell, "Level 5: confusion and hallucination");
+ spell_type_describe(spell, "Level 10: speed (both bad or good) and light speed");
+ spell_type_describe(spell, "Level 15: stunning, meditation, cuts");
+ spell_type_describe(spell, "Level 20: hero, super hero, bless, shields, afraid, parasites, mimicry");
+ spell_type_set_mana(spell, 30, 60);
+ spell_type_set_inertia(spell, 1, 5);
+ spell_type_set_difficulty(spell, 15, 40);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_set_castable_while_confused(spell, TRUE);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_META,
+ meta_disperse_magic_info,
+ meta_disperse_magic);
+
+ spell_type_set_device_charges(spell, "5+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 25;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 5, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&TRACKER, "TRACKER", "Tracker");
- string_list_append(&spell->description, "Tracks down the last teleportation that happened on the level and teleports");
- string_list_append(&spell->description, "you to it");
- school_idx_add_new(&spell->schools, SCHOOL_META);
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 50, 50);
- spell->info_func = meta_tracker_info;
- spell->effect_func = meta_tracker;
- spell->failure_rate = 95;
- spell->skill_level = 30;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Tracks down the last teleportation that happened on the level and teleports");
+ spell_type_describe(spell, "you to it");
+ spell_type_add_school(spell, SCHOOL_CONVEYANCE);
+ spell_type_set_mana(spell, 50, 50);
+ spell_type_set_difficulty(spell, 30, 95);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_META,
+ meta_tracker_info,
+ meta_tracker);
}
{
spell_type *spell = spell_new(&INERTIA_CONTROL, "INERTIA_CONTROL", "Inertia Control");
- string_list_append(&spell->description, "Changes the energy flow of a spell to be continuously recasted");
- string_list_append(&spell->description, "at a given interval. The inertia controlled spell reduces your");
- string_list_append(&spell->description, "maximum mana by four times its cost.");
- school_idx_add_new(&spell->schools, SCHOOL_META);
- range_init(&spell->mana_range, 300, 700);
- spell->info_func = meta_inertia_control_info;
- spell->effect_func = meta_inertia_control;
- spell->failure_rate = 95;
- spell->skill_level = 37;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Changes the energy flow of a spell to be continuously recasted");
+ spell_type_describe(spell, "at a given interval. The inertia controlled spell reduces your");
+ spell_type_describe(spell, "maximum mana by four times its cost.");
+ spell_type_set_mana(spell, 300, 700);
+ spell_type_set_difficulty(spell, 37, 95);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_META,
+ meta_inertia_control_info,
+ meta_inertia_control);
}
{
spell_type *spell = spell_new(&CHARM, "CHARM", "Charm");
- string_list_append(&spell->description, "Tries to manipulate the mind of a monster to make it friendly");
- string_list_append(&spell->description, "At level 15 it turns into a ball");
- string_list_append(&spell->description, "At level 35 it affects all monsters in sight");
- school_idx_add_new(&spell->schools, SCHOOL_MIND);
- range_init(&spell->mana_range, 1, 20);
- spell->info_func = mind_charm_info;
- spell->effect_func = mind_charm;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "7+d5");
+ spell_type_describe(spell, "Tries to manipulate the mind of a monster to make it friendly");
+ spell_type_describe(spell, "At level 15 it turns into a ball");
+ spell_type_describe(spell, "At level 35 it affects all monsters in sight");
+ spell_type_set_mana(spell, 1, 20);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MIND,
+ mind_charm_info,
+ mind_charm);
+
+ spell_type_set_device_charges(spell, "7+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 35;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 20, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&CONFUSE, "CONFUSE", "Confuse");
- string_list_append(&spell->description, "Tries to manipulate the mind of a monster to confuse it");
- string_list_append(&spell->description, "At level 15 it turns into a ball");
- string_list_append(&spell->description, "At level 35 it affects all monsters in sight");
- school_idx_add_new(&spell->schools, SCHOOL_MIND);
- range_init(&spell->mana_range, 5, 30);
- spell->info_func = mind_confuse_info;
- spell->effect_func = mind_confuse;
- spell->failure_rate = 20;
- spell->skill_level = 5;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d4");
+ spell_type_describe(spell, "Tries to manipulate the mind of a monster to confuse it");
+ spell_type_describe(spell, "At level 15 it turns into a ball");
+ spell_type_describe(spell, "At level 35 it affects all monsters in sight");
+ spell_type_set_mana(spell, 5, 30);
+ spell_type_set_difficulty(spell, 5, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MIND,
+ mind_confuse_info,
+ mind_confuse);
+
+ spell_type_set_device_charges(spell, "3+d4");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 45;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 20, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&ARMOROFFEAR, "ARMOROFFEAR", "Armor of Fear");
- string_list_append(&spell->description, "Creates a shield of pure fear around you. Any monster attempting to hit you");
- string_list_append(&spell->description, "must save or flee");
- school_idx_add_new(&spell->schools, SCHOOL_MIND);
- range_init(&spell->mana_range, 10, 50);
- spell_inertia_init(spell, 2, 20);
- spell->info_func = mind_armor_of_fear_info;
- spell->effect_func = mind_armor_of_fear;
- spell->failure_rate = 35;
- spell->skill_level = 10;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Creates a shield of pure fear around you. Any monster attempting to hit you");
+ spell_type_describe(spell, "must save or flee");
+ spell_type_set_mana(spell, 10, 50);
+ spell_type_set_inertia(spell, 2, 20);
+ spell_type_set_difficulty(spell, 10, 35);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MIND,
+ mind_armor_of_fear_info,
+ mind_armor_of_fear);
}
{
spell_type *spell = spell_new(&STUN, "STUN", "Stun");
- string_list_append(&spell->description, "Tries to manipulate the mind of a monster to stun it");
- string_list_append(&spell->description, "At level 20 it turns into a ball");
- school_idx_add_new(&spell->schools, SCHOOL_MIND);
- range_init(&spell->mana_range, 10, 90);
- spell->info_func = mind_stun_info;
- spell->effect_func = mind_stun;
- spell->failure_rate = 45;
- spell->skill_level = 15;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Tries to manipulate the mind of a monster to stun it");
+ spell_type_describe(spell, "At level 20 it turns into a ball");
+ spell_type_set_mana(spell, 10, 90);
+ spell_type_set_difficulty(spell, 15, 45);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_MIND,
+ mind_stun_info,
+ mind_stun);
}
{
spell_type *spell = spell_new(&DRAIN, "DRAIN", "Drain");
- string_list_append(&spell->description, "Drains the mana contained in wands, staves and rods to increase yours");
- school_idx_add_new(&spell->schools, SCHOOL_UDUN);
- school_idx_add_new(&spell->schools, SCHOOL_MANA);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = udun_drain_info;
- spell->effect_func = udun_drain;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Drains the mana contained in wands, staves and rods to increase yours");
+ spell_type_add_school(spell, SCHOOL_MANA);
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_UDUN,
+ udun_drain_info,
+ udun_drain);
}
{
spell_type *spell = spell_new(&GENOCIDE, "GENOCIDE", "Genocide");
- string_list_append(&spell->description, "Genocides all monsters of a race on the level");
- string_list_append(&spell->description, "At level 10 it can genocide all monsters near you");
- school_idx_add_new(&spell->schools, SCHOOL_UDUN);
- school_idx_add_new(&spell->schools, SCHOOL_NATURE);
- range_init(&spell->mana_range, 50, 50);
- spell->info_func = udun_genocide_info;
- spell->effect_func = udun_genocide;
- spell->failure_rate = 90;
- spell->skill_level = 25;
- spell_init_mage(spell, RANDOM);
-
- dice_parse_checked(&spell->device_charges, "2+d2");
+ spell_type_describe(spell, "Genocides all monsters of a race on the level");
+ spell_type_describe(spell, "At level 10 it can genocide all monsters near you");
+ spell_type_add_school(spell, SCHOOL_NATURE);
+ spell_type_set_mana(spell, 50, 50);
+ spell_type_set_difficulty(spell, 25, 90);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_UDUN,
+ udun_genocide_info,
+ udun_genocide);
+
+ spell_type_set_device_charges(spell, "2+d2");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 85;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 5, 15);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&WRAITHFORM, "WRAITHFORM", "Wraithform");
- string_list_append(&spell->description, "Turns you into an immaterial being");
- school_idx_add_new(&spell->schools, SCHOOL_UDUN);
- school_idx_add_new(&spell->schools, SCHOOL_CONVEYANCE);
- range_init(&spell->mana_range, 20, 40);
- spell_inertia_init(spell, 4, 30);
- spell->info_func = udun_wraithform_info;
- spell->effect_func = udun_wraithform;
- spell->failure_rate = 95;
- spell->skill_level = 30;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Turns you into an immaterial being");
+ spell_type_add_school(spell, SCHOOL_CONVEYANCE);
+ spell_type_set_mana(spell, 20, 40);
+ spell_type_set_inertia(spell, 4, 30);
+ spell_type_set_difficulty(spell, 30, 95);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_UDUN,
+ udun_wraithform_info,
+ udun_wraithform);
}
{
spell_type *spell = spell_new(&FLAMEOFUDUN, "FLAMEOFUDUN", "Flame of Udun");
- string_list_append(&spell->description, "Turns you into a powerful Balrog");
- school_idx_add_new(&spell->schools, SCHOOL_UDUN);
- school_idx_add_new(&spell->schools, SCHOOL_FIRE);
- range_init(&spell->mana_range, 70, 100);
- spell_inertia_init(spell, 7, 15);
- spell->info_func = udun_flame_of_udun_info;
- spell->effect_func = udun_flame_of_udun;
- spell->failure_rate = 95;
- spell->skill_level = 35;
- spell_init_mage(spell, RANDOM);
+ spell_type_describe(spell, "Turns you into a powerful Balrog");
+ spell_type_add_school(spell, SCHOOL_FIRE);
+ spell_type_set_mana(spell, 70, 100);
+ spell_type_set_inertia(spell, 7, 15);
+ spell_type_set_difficulty(spell, 35, 95);
+ spell_type_init_mage(spell,
+ RANDOM,
+ SCHOOL_UDUN,
+ udun_flame_of_udun_info,
+ udun_flame_of_udun);
}
{
spell_type *spell = spell_new(&CALL_THE_ELEMENTS, "CALL_THE_ELEMENTS", "Call the Elements");
- string_list_append(&spell->description, "Randomly creates various elements around you");
- string_list_append(&spell->description, "Each type of element chance is controlled by your level");
- string_list_append(&spell->description, "in the corresponding skill");
- string_list_append(&spell->description, "At level 17 it can be targeted");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 2, 20);
- spell->info_func = geomancy_call_the_elements_info;
- spell->effect_func = geomancy_call_the_elements;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Randomly creates various elements around you");
+ spell_type_describe(spell, "Each type of element chance is controlled by your level");
+ spell_type_describe(spell, "in the corresponding skill");
+ spell_type_describe(spell, "At level 17 it can be targeted");
+ spell_type_set_mana(spell, 2, 20);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_mage(spell,
+ NO_RANDOM,
+ SCHOOL_GEOMANCY,
+ geomancy_call_the_elements_info,
+ geomancy_call_the_elements);
}
{
spell_type *spell = spell_new(&CHANNEL_ELEMENTS, "CHANNEL_ELEMENTS", "Channel Elements");
- string_list_append(&spell->description, "Draws on the caster's immediate environs to form an attack or other effect.");
- string_list_append(&spell->description, "Grass/Flower heals.");
- string_list_append(&spell->description, "Water creates water bolt attacks.");
- string_list_append(&spell->description, "Ice creates ice bolt attacks.");
- string_list_append(&spell->description, "Sand creates a wall of thick, blinding, burning sand around you.");
- string_list_append(&spell->description, "Lava creates fire bolt attacks.");
- string_list_append(&spell->description, "Deep lava creates fire ball attacks.");
- string_list_append(&spell->description, "Chasm creates darkness bolt attacks.");
- string_list_append(&spell->description, "At Earth level 18, darkness becomes nether.");
- string_list_append(&spell->description, "At Water level 8, water attacks become beams with a striking effect.");
- string_list_append(&spell->description, "At Water level 12, ice attacks become balls of ice shards.");
- string_list_append(&spell->description, "At Water level 18, water attacks push monsters back.");
- string_list_append(&spell->description, "At Fire level 15, fire become hellfire.");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 3, 30);
- spell->info_func = geomancy_channel_elements_info;
- spell->effect_func = geomancy_channel_elements;
- spell->failure_rate = 20;
- spell->skill_level = 3;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Draws on the caster's immediate environs to form an attack or other effect.");
+ spell_type_describe(spell, "Grass/Flower heals.");
+ spell_type_describe(spell, "Water creates water bolt attacks.");
+ spell_type_describe(spell, "Ice creates ice bolt attacks.");
+ spell_type_describe(spell, "Sand creates a wall of thick, blinding, burning sand around you.");
+ spell_type_describe(spell, "Lava creates fire bolt attacks.");
+ spell_type_describe(spell, "Deep lava creates fire ball attacks.");
+ spell_type_describe(spell, "Chasm creates darkness bolt attacks.");
+ spell_type_describe(spell, "At Earth level 18, darkness becomes nether.");
+ spell_type_describe(spell, "At Water level 8, water attacks become beams with a striking effect.");
+ spell_type_describe(spell, "At Water level 12, ice attacks become balls of ice shards.");
+ spell_type_describe(spell, "At Water level 18, water attacks push monsters back.");
+ spell_type_describe(spell, "At Fire level 15, fire become hellfire.");
+ spell_type_set_mana(spell, 3, 30);
+ spell_type_set_difficulty(spell, 3, 20);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_mage(spell,
+ NO_RANDOM,
+ SCHOOL_GEOMANCY,
+ geomancy_channel_elements_info,
+ geomancy_channel_elements);
}
{
spell_type *spell = spell_new(&ELEMENTAL_WAVE, "ELEMENTAL_WAVE", "Elemental Wave");
- string_list_append(&spell->description, "Draws on an adjacent special square to project a slow-moving");
- string_list_append(&spell->description, "wave of that element in that direction");
- string_list_append(&spell->description, "Abyss squares cannot be channeled into a wave.");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 15, 50);
- spell->info_func = geomancy_elemental_wave_info;
- spell->effect_func = geomancy_elemental_wave;
- spell->failure_rate = 20;
- spell->skill_level = 15;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Draws on an adjacent special square to project a slow-moving");
+ spell_type_describe(spell, "wave of that element in that direction");
+ spell_type_describe(spell, "Abyss squares cannot be channeled into a wave.");
+ spell_type_set_mana(spell, 15, 50);
+ spell_type_set_difficulty(spell, 15, 20);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_mage(spell,
+ NO_RANDOM,
+ SCHOOL_GEOMANCY,
+ geomancy_elemental_wave_info,
+ geomancy_elemental_wave);
}
{
spell_type *spell = spell_new(&VAPORIZE, "VAPORIZE", "Vaporize");
- string_list_append(&spell->description, "Draws upon your immediate environs to form a cloud of damaging vapors");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 3, 30);
- spell->info_func = geomancy_vaporize_info;
- spell->effect_func = geomancy_vaporize;
- spell->depend_func = geomancy_vaporize_depends;
- spell->failure_rate = 15;
- spell->skill_level = 4;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Draws upon your immediate environs to form a cloud of damaging vapors");
+ spell_type_set_mana(spell, 3, 30);
+ spell_type_set_difficulty(spell, 4, 15);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_geomancy(
+ spell,
+ geomancy_vaporize_info,
+ geomancy_vaporize,
+ geomancy_vaporize_depends);
}
{
spell_type *spell = spell_new(&GEOLYSIS, "GEOLYSIS", "Geolysis");
- string_list_append(&spell->description, "Burrows deeply and slightly at random into a wall,");
- string_list_append(&spell->description, "leaving behind tailings of various different sorts of walls in the passage.");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 15, 40);
- spell->info_func = geomancy_geolysis_info;
- spell->effect_func = geomancy_geolysis;
- spell->depend_func = geomancy_geolysis_depends;
- spell->failure_rate = 15;
- spell->skill_level = 7;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Burrows deeply and slightly at random into a wall,");
+ spell_type_describe(spell, "leaving behind tailings of various different sorts of walls in the passage.");
+ spell_type_set_mana(spell, 15, 40);
+ spell_type_set_difficulty(spell, 7, 15);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_geomancy(
+ spell,
+ geomancy_geolysis_info,
+ geomancy_geolysis,
+ geomancy_geolysis_depends);
}
{
spell_type *spell = spell_new(&DRIPPING_TREAD, "DRIPPING_TREAD", "Dripping Tread");
- string_list_append(&spell->description, "Causes you to leave random elemental forms behind as you walk");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 15, 25);
- spell->info_func = geomancy_dripping_tread_info;
- spell->effect_func = geomancy_dripping_tread;
- spell->depend_func = geomancy_dripping_tread_depends;
- spell->failure_rate = 15;
- spell->skill_level = 10;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Causes you to leave random elemental forms behind as you walk");
+ spell_type_set_mana(spell, 15, 25);
+ spell_type_set_difficulty(spell, 10, 15);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_geomancy(
+ spell,
+ geomancy_dripping_tread_info,
+ geomancy_dripping_tread,
+ geomancy_dripping_tread_depends);
}
{
spell_type *spell = spell_new(&GROW_BARRIER, "GROW_BARRIER", "Grow Barrier");
- string_list_append(&spell->description, "Creates impassable terrain (walls, trees, etc.) around you.");
- string_list_append(&spell->description, "At level 20 it can be projected around another area.");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 30, 40);
- spell->info_func = geomancy_grow_barrier_info;
- spell->effect_func = geomancy_grow_barrier;
- spell->depend_func = geomancy_grow_barrier_depends;
- spell->failure_rate = 15;
- spell->skill_level = 12;
- spell->castable_while_blind = TRUE;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Creates impassable terrain (walls, trees, etc.) around you.");
+ spell_type_describe(spell, "At level 20 it can be projected around another area.");
+ spell_type_set_mana(spell, 30, 40);
+ spell_type_set_difficulty(spell, 12, 15);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_geomancy(
+ spell,
+ geomancy_grow_barrier_info,
+ geomancy_grow_barrier,
+ geomancy_grow_barrier_depends);
}
{
spell_type *spell = spell_new(&ELEMENTAL_MINION, "ELEMENTAL_MINION", "Elemental Minion");
- string_list_append(&spell->description, "Summons a minion from a nearby element.");
- string_list_append(&spell->description, "Walls can summon Earth elmentals, Xorns and Xarens");
- string_list_append(&spell->description, "Dark Pits can summon Air elementals, Ancient blue dragons, Great Storm Wyrms");
- string_list_append(&spell->description, "and Sky Drakes");
- string_list_append(&spell->description, "Sandwalls and lava can summon Fire elementals and Ancient red dragons");
- string_list_append(&spell->description, "Icewall, and water can summon Water elementals, Water trolls and Water demons");
- school_idx_add_new(&spell->schools, SCHOOL_GEOMANCY);
- range_init(&spell->mana_range, 40, 80);
- spell->info_func = geomancy_elemental_minion_info;
- spell->effect_func = geomancy_elemental_minion;
- spell->failure_rate = 25;
- spell->skill_level = 20;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Summons a minion from a nearby element.");
+ spell_type_describe(spell, "Walls can summon Earth elmentals, Xorns and Xarens");
+ spell_type_describe(spell, "Dark Pits can summon Air elementals, Ancient blue dragons, Great Storm Wyrms");
+ spell_type_describe(spell, "and Sky Drakes");
+ spell_type_describe(spell, "Sandwalls and lava can summon Fire elementals and Ancient red dragons");
+ spell_type_describe(spell, "Icewall, and water can summon Water elementals, Water trolls and Water demons");
+ spell_type_set_mana(spell, 40, 80);
+ spell_type_set_difficulty(spell, 20, 25);
+ spell_type_init_geomancy(
+ spell,
+ geomancy_elemental_minion_info,
+ geomancy_elemental_minion,
+ NULL);
}
{
spell_type *spell = spell_new(&ERU_SEE, "ERU_SEE", "See the Music");
- string_list_append(&spell->description, "Allows you to 'see' the Great Music from which the world");
- string_list_append(&spell->description, "originates, allowing you to see unseen things");
- string_list_append(&spell->description, "At level 10 it allows you to see your surroundings");
- string_list_append(&spell->description, "At level 20 it allows you to cure blindness");
- string_list_append(&spell->description, "At level 30 it allows you to fully see all the level");
- school_idx_add_new(&spell->schools, SCHOOL_ERU);
- range_init(&spell->mana_range, 1, 50);
- spell->info_func = eru_see_the_music_info;
- spell->effect_func = eru_see_the_music;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_priest(spell);
- spell->castable_while_blind = TRUE;
+ spell_type_describe(spell, "Allows you to 'see' the Great Music from which the world");
+ spell_type_describe(spell, "originates, allowing you to see unseen things");
+ spell_type_describe(spell, "At level 10 it allows you to see your surroundings");
+ spell_type_describe(spell, "At level 20 it allows you to cure blindness");
+ spell_type_describe(spell, "At level 30 it allows you to fully see all the level");
+ spell_type_set_mana(spell, 1, 50);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_ERU,
+ eru_see_the_music_info,
+ eru_see_the_music);
+ spell_type_set_castable_while_blind(spell, TRUE);
}
{
spell_type *spell = spell_new(&ERU_LISTEN, "ERU_LISTEN", "Listen to the Music");
- string_list_append(&spell->description, "Allows you to listen to the Great Music from which the world");
- string_list_append(&spell->description, "originates, allowing you to understand the meaning of things");
- string_list_append(&spell->description, "At level 14 it allows you to identify all your pack");
- string_list_append(&spell->description, "At level 30 it allows you to identify all items on the level");
- school_idx_add_new(&spell->schools, SCHOOL_ERU);
- range_init(&spell->mana_range, 15, 200);
- spell->info_func = eru_listen_to_the_music_info;
- spell->effect_func = eru_listen_to_the_music;
- spell->failure_rate = 25;
- spell->skill_level = 7;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Allows you to listen to the Great Music from which the world");
+ spell_type_describe(spell, "originates, allowing you to understand the meaning of things");
+ spell_type_describe(spell, "At level 14 it allows you to identify all your pack");
+ spell_type_describe(spell, "At level 30 it allows you to identify all items on the level");
+ spell_type_set_mana(spell, 15, 200);
+ spell_type_set_difficulty(spell, 7, 25);
+ spell_type_init_priest(spell,
+ SCHOOL_ERU,
+ eru_listen_to_the_music_info,
+ eru_listen_to_the_music);
}
{
spell_type *spell = spell_new(&ERU_UNDERSTAND, "ERU_UNDERSTAND", "Know the Music");
- string_list_append(&spell->description, "Allows you to understand the Great Music from which the world");
- string_list_append(&spell->description, "originates, allowing you to know the full abilities of things");
- string_list_append(&spell->description, "At level 10 it allows you to *identify* all your pack");
- school_idx_add_new(&spell->schools, SCHOOL_ERU);
- range_init(&spell->mana_range, 200, 600);
- spell->info_func = eru_know_the_music_info;
- spell->effect_func = eru_know_the_music;
- spell->failure_rate = 50;
- spell->skill_level = 30;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Allows you to understand the Great Music from which the world");
+ spell_type_describe(spell, "originates, allowing you to know the full abilities of things");
+ spell_type_describe(spell, "At level 10 it allows you to *identify* all your pack");
+ spell_type_set_mana(spell, 200, 600);
+ spell_type_set_difficulty(spell, 30, 50);
+ spell_type_init_priest(spell,
+ SCHOOL_ERU,
+ eru_know_the_music_info,
+ eru_know_the_music);
}
{
spell_type *spell = spell_new(&ERU_PROT, "ERU_PROT", "Lay of Protection");
- string_list_append(&spell->description, "Creates a circle of safety around you");
- school_idx_add_new(&spell->schools, SCHOOL_ERU);
- range_init(&spell->mana_range, 400, 400);
- spell->info_func = eru_lay_of_protection_info;
- spell->effect_func = eru_lay_of_protection;
- spell->failure_rate = 80;
- spell->skill_level = 35;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Creates a circle of safety around you");
+ spell_type_set_mana(spell, 400, 400);
+ spell_type_set_difficulty(spell, 35, 80);
+ spell_type_init_priest(spell,
+ SCHOOL_ERU,
+ eru_lay_of_protection_info,
+ eru_lay_of_protection);
}
{
spell_type *spell = spell_new(&MANWE_SHIELD, "MANWE_SHIELD", "Wind Shield");
- string_list_append(&spell->description, "It surrounds you with a shield of wind that deflects blows from evil monsters");
- string_list_append(&spell->description, "At level 10 it increases your armour rating");
- string_list_append(&spell->description, "At level 20 it retaliates against monsters that melee you");
- school_idx_add_new(&spell->schools, SCHOOL_MANWE);
- range_init(&spell->mana_range, 100, 500);
- spell->info_func = manwe_wind_shield_info;
- spell->effect_func = manwe_wind_shield;
- spell->failure_rate = 30;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It surrounds you with a shield of wind that deflects blows from evil monsters");
+ spell_type_describe(spell, "At level 10 it increases your armour rating");
+ spell_type_describe(spell, "At level 20 it retaliates against monsters that melee you");
+ spell_type_set_mana(spell, 100, 500);
+ spell_type_set_difficulty(spell, 10, 30);
+ spell_type_init_priest(spell,
+ SCHOOL_MANWE,
+ manwe_wind_shield_info,
+ manwe_wind_shield);
}
{
spell_type *spell = spell_new(&MANWE_AVATAR, "MANWE_AVATAR", "Avatar");
- string_list_append(&spell->description, "It turns you into a full grown Maia");
- school_idx_add_new(&spell->schools, SCHOOL_MANWE);
- range_init(&spell->mana_range, 1000, 1000);
- spell->info_func = manwe_avatar_info;
- spell->effect_func = manwe_avatar;
- spell->failure_rate = 80;
- spell->skill_level = 35;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It turns you into a full grown Maia");
+ spell_type_set_mana(spell, 1000, 1000);
+ spell_type_set_difficulty(spell, 35, 80);
+ spell_type_init_priest(spell,
+ SCHOOL_MANWE,
+ manwe_avatar_info,
+ manwe_avatar);
}
{
spell_type *spell = spell_new(&MANWE_BLESS, "MANWE_BLESS", "Manwe's Blessing");
- string_list_append(&spell->description, "Manwe's Blessing removes your fears, blesses you and surrounds you with");
- string_list_append(&spell->description, "holy light");
- string_list_append(&spell->description, "At level 10 it also grants heroism");
- string_list_append(&spell->description, "At level 20 it also grants super heroism");
- string_list_append(&spell->description, "At level 30 it also grants holy luck and life protection");
- school_idx_add_new(&spell->schools, SCHOOL_MANWE);
- range_init(&spell->mana_range, 10, 100);
- spell->info_func = manwe_blessing_info;
- spell->effect_func = manwe_blessing;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Manwe's Blessing removes your fears, blesses you and surrounds you with");
+ spell_type_describe(spell, "holy light");
+ spell_type_describe(spell, "At level 10 it also grants heroism");
+ spell_type_describe(spell, "At level 20 it also grants super heroism");
+ spell_type_describe(spell, "At level 30 it also grants holy luck and life protection");
+ spell_type_set_mana(spell, 10, 100);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_MANWE,
+ manwe_blessing_info,
+ manwe_blessing);
}
{
spell_type *spell = spell_new(&MANWE_CALL, "MANWE_CALL", "Manwe's Call");
- string_list_append(&spell->description, "Manwe's Call summons a Great Eagle to help you battle the forces");
- string_list_append(&spell->description, "of Morgoth");
- school_idx_add_new(&spell->schools, SCHOOL_MANWE);
- range_init(&spell->mana_range, 200, 500);
- spell->info_func = manwe_call_info;
- spell->effect_func = manwe_call;
- spell->failure_rate = 40;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Manwe's Call summons a Great Eagle to help you battle the forces");
+ spell_type_describe(spell, "of Morgoth");
+ spell_type_set_mana(spell, 200, 500);
+ spell_type_set_difficulty(spell, 20, 40);
+ spell_type_init_priest(spell,
+ SCHOOL_MANWE,
+ manwe_call_info,
+ manwe_call);
}
{
spell_type *spell = spell_new(&TULKAS_AIM, "TULKAS_AIM", "Divine Aim");
- string_list_append(&spell->description, "It makes you more accurate in combat");
- string_list_append(&spell->description, "At level 20 all your blows are critical hits");
- school_idx_add_new(&spell->schools, SCHOOL_TULKAS);
- range_init(&spell->mana_range, 30, 500);
- spell->info_func = tulkas_divine_aim_info;
- spell->effect_func = tulkas_divine_aim;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It makes you more accurate in combat");
+ spell_type_describe(spell, "At level 20 all your blows are critical hits");
+ spell_type_set_mana(spell, 30, 500);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_TULKAS,
+ tulkas_divine_aim_info,
+ tulkas_divine_aim);
}
{
spell_type *spell = spell_new(&TULKAS_WAVE, "TULKAS_WAVE", "Wave of Power");
- string_list_append(&spell->description, "It allows you to project a number of melee blows across a distance");
- school_idx_add_new(&spell->schools, SCHOOL_TULKAS);
- range_init(&spell->mana_range, 200, 200);
- spell->info_func = tulkas_wave_of_power_info;
- spell->effect_func = tulkas_wave_of_power;
- spell->failure_rate = 75;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It allows you to project a number of melee blows across a distance");
+ spell_type_set_mana(spell, 200, 200);
+ spell_type_set_difficulty(spell, 20, 75);
+ spell_type_init_priest(spell,
+ SCHOOL_TULKAS,
+ tulkas_wave_of_power_info,
+ tulkas_wave_of_power);
}
{
spell_type *spell = spell_new(&TULKAS_SPIN, "TULKAS_SPIN", "Whirlwind");
- string_list_append(&spell->description, "It allows you to spin around and hit all monsters nearby");
- school_idx_add_new(&spell->schools, SCHOOL_TULKAS);
- range_init(&spell->mana_range, 100, 100);
- spell->info_func = tulkas_whirlwind_info;
- spell->effect_func = tulkas_whirlwind;
- spell->failure_rate = 45;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It allows you to spin around and hit all monsters nearby");
+ spell_type_set_mana(spell, 100, 100);
+ spell_type_set_difficulty(spell, 10, 45);
+ spell_type_init_priest(spell,
+ SCHOOL_TULKAS,
+ tulkas_whirlwind_info,
+ tulkas_whirlwind);
}
{
spell_type *spell = spell_new(&MELKOR_CURSE, "MELKOR_CURSE", "Curse");
- string_list_append(&spell->description, "It curses a monster, reducing its melee power");
- string_list_append(&spell->description, "At level 5 it can be auto-casted (with no piety cost) while fighting");
- string_list_append(&spell->description, "At level 15 it also reduces armor");
- string_list_append(&spell->description, "At level 25 it also reduces speed");
- string_list_append(&spell->description, "At level 35 it also reduces max life (but it is never fatal)");
- school_idx_add_new(&spell->schools, SCHOOL_MELKOR);
- range_init(&spell->mana_range, 50, 300);
- spell->info_func = melkor_curse_info;
- spell->effect_func = melkor_curse;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It curses a monster, reducing its melee power");
+ spell_type_describe(spell, "At level 5 it can be auto-casted (with no piety cost) while fighting");
+ spell_type_describe(spell, "At level 15 it also reduces armor");
+ spell_type_describe(spell, "At level 25 it also reduces speed");
+ spell_type_describe(spell, "At level 35 it also reduces max life (but it is never fatal)");
+ spell_type_set_mana(spell, 50, 300);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_priest(spell,
+ SCHOOL_MELKOR,
+ melkor_curse_info,
+ melkor_curse);
}
{
spell_type *spell = spell_new(&MELKOR_CORPSE_EXPLOSION, "MELKOR_CORPSE_EXPLOSION", "Corpse Explosion");
- string_list_append(&spell->description, "It makes corpses in an area around you explode for a percent of their");
- string_list_append(&spell->description, "hit points as damage");
- school_idx_add_new(&spell->schools, SCHOOL_MELKOR);
- range_init(&spell->mana_range, 100, 500);
- spell->info_func = melkor_corpse_explosion_info;
- spell->effect_func = melkor_corpse_explosion;
- spell->failure_rate = 45;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It makes corpses in an area around you explode for a percent of their");
+ spell_type_describe(spell, "hit points as damage");
+ spell_type_set_mana(spell, 100, 500);
+ spell_type_set_difficulty(spell, 10, 45);
+ spell_type_init_priest(spell,
+ SCHOOL_MELKOR,
+ melkor_corpse_explosion_info,
+ melkor_corpse_explosion);
}
{
spell_type *spell = spell_new(&MELKOR_MIND_STEAL, "MELKOR_MIND_STEAL", "Mind Steal");
- string_list_append(&spell->description, "It allows your spirit to temporarily leave your own body, which will");
- string_list_append(&spell->description, "be vulnerable, to control one of your enemies body.");
- school_idx_add_new(&spell->schools, SCHOOL_MELKOR);
- range_init(&spell->mana_range, 1000, 3000);
- spell->info_func = melkor_mind_steal_info;
- spell->effect_func = melkor_mind_steal;
- spell->failure_rate = 90;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It allows your spirit to temporarily leave your own body, which will");
+ spell_type_describe(spell, "be vulnerable, to control one of your enemies body.");
+ spell_type_set_mana(spell, 1000, 3000);
+ spell_type_set_difficulty(spell, 20, 90);
+ spell_type_init_priest(spell,
+ SCHOOL_MELKOR,
+ melkor_mind_steal_info,
+ melkor_mind_steal);
}
{
spell_type *spell = spell_new(&YAVANNA_CHARM_ANIMAL, "YAVANNA_CHARM_ANIMAL", "Charm Animal");
- string_list_append(&spell->description, "It tries to tame an animal");
- school_idx_add_new(&spell->schools, SCHOOL_YAVANNA);
- range_init(&spell->mana_range, 10, 100);
- spell->info_func = yavanna_charm_animal_info;
- spell->effect_func = yavanna_charm_animal;
- spell->failure_rate = 30;
- spell->skill_level = 1;
- spell_init_priest(spell);
+ spell_type_describe(spell, "It tries to tame an animal");
+ spell_type_set_mana(spell, 10, 100);
+ spell_type_set_difficulty(spell, 1, 30);
+ spell_type_init_priest(spell,
+ SCHOOL_YAVANNA,
+ yavanna_charm_animal_info,
+ yavanna_charm_animal);
}
{
spell_type *spell = spell_new(&YAVANNA_GROW_GRASS, "YAVANNA_GROW_GRASS", "Grow Grass");
- string_list_append(&spell->description, "Create a floor of grass around you. While on grass and praying");
- string_list_append(&spell->description, "a worshipper of Yavanna will know a greater regeneration rate");
- school_idx_add_new(&spell->schools, SCHOOL_YAVANNA);
- range_init(&spell->mana_range, 70, 150);
- spell->info_func = yavanna_grow_grass_info;
- spell->effect_func = yavanna_grow_grass;
- spell->failure_rate = 65;
- spell->skill_level = 10;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Create a floor of grass around you. While on grass and praying");
+ spell_type_describe(spell, "a worshipper of Yavanna will know a greater regeneration rate");
+ spell_type_set_mana(spell, 70, 150);
+ spell_type_set_difficulty(spell, 10, 65);
+ spell_type_init_priest(spell,
+ SCHOOL_YAVANNA,
+ yavanna_grow_grass_info,
+ yavanna_grow_grass);
}
{
spell_type *spell = spell_new(&YAVANNA_TREE_ROOTS, "YAVANNA_TREE_ROOTS", "Tree Roots");
- string_list_append(&spell->description, "Creates roots deep in the floor from your feet, making you more stable and able");
- string_list_append(&spell->description, "to make stronger attacks, but prevents any movement (even teleportation).");
- string_list_append(&spell->description, "It also makes you recover from stunning almost immediately.");
- school_idx_add_new(&spell->schools, SCHOOL_YAVANNA);
- range_init(&spell->mana_range, 50, 1000);
- spell->info_func = yavanna_tree_roots_info;
- spell->effect_func = yavanna_tree_roots;
- spell->failure_rate = 70;
- spell->skill_level = 15;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Creates roots deep in the floor from your feet, making you more stable and able");
+ spell_type_describe(spell, "to make stronger attacks, but prevents any movement (even teleportation).");
+ spell_type_describe(spell, "It also makes you recover from stunning almost immediately.");
+ spell_type_set_mana(spell, 50, 1000);
+ spell_type_set_difficulty(spell, 15, 70);
+ spell_type_init_priest(spell,
+ SCHOOL_YAVANNA,
+ yavanna_tree_roots_info,
+ yavanna_tree_roots);
}
{
spell_type *spell = spell_new(&YAVANNA_WATER_BITE, "YAVANNA_WATER_BITE", "Water Bite");
- string_list_append(&spell->description, "Imbues your melee weapon with a natural stream of water");
- string_list_append(&spell->description, "At level 25, it spreads over a 1 radius zone around your target");
- school_idx_add_new(&spell->schools, SCHOOL_YAVANNA);
- range_init(&spell->mana_range, 150, 300);
- spell->info_func = yavanna_water_bite_info;
- spell->effect_func = yavanna_water_bite;
- spell->failure_rate = 90;
- spell->skill_level = 20;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Imbues your melee weapon with a natural stream of water");
+ spell_type_describe(spell, "At level 25, it spreads over a 1 radius zone around your target");
+ spell_type_set_mana(spell, 150, 300);
+ spell_type_set_difficulty(spell, 20, 90);
+ spell_type_init_priest(spell,
+ SCHOOL_YAVANNA,
+ yavanna_water_bite_info,
+ yavanna_water_bite);
}
{
spell_type *spell = spell_new(&YAVANNA_UPROOT, "YAVANNA_UPROOT", "Uproot");
- string_list_append(&spell->description, "Awakes a tree to help you battle the forces of Morgoth");
- school_idx_add_new(&spell->schools, SCHOOL_YAVANNA);
- range_init(&spell->mana_range, 250, 350);
- spell->info_func = yavanna_uproot_info;
- spell->effect_func = yavanna_uproot;
- spell->failure_rate = 95;
- spell->skill_level = 35;
- spell_init_priest(spell);
+ spell_type_describe(spell, "Awakes a tree to help you battle the forces of Morgoth");
+ spell_type_set_mana(spell, 250, 350);
+ spell_type_set_difficulty(spell, 35, 95);
+ spell_type_init_priest(spell,
+ SCHOOL_YAVANNA,
+ yavanna_uproot_info,
+ yavanna_uproot);
}
{
spell_type *spell = spell_new(&DEMON_BLADE, "DEMON_BLADE", "Demon Blade");
- string_list_append(&spell->description, "Imbues your blade with fire to deal more damage");
- string_list_append(&spell->description, "At level 30 it deals hellfire damage");
- string_list_append(&spell->description, "At level 45 it spreads over a 1 radius zone around your target");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 4, 44);
- spell->info_func = demonology_demon_blade_info;
- spell->effect_func = demonology_demon_blade;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
-
- dice_parse_checked(&spell->device_charges, "3+d7");
+ spell_type_describe(spell, "Imbues your blade with fire to deal more damage");
+ spell_type_describe(spell, "At level 30 it deals hellfire damage");
+ spell_type_describe(spell, "At level 45 it spreads over a 1 radius zone around your target");
+ spell_type_set_mana(spell, 4, 44);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_demonology(spell,
+ demonology_demon_blade_info,
+ demonology_demon_blade);
+
+ spell_type_set_device_charges(spell, "3+d7");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 75;
range_init(&device_allocation->base_level, 1, 17);
range_init(&device_allocation->max_level, 20, 40);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEMON_MADNESS, "DEMON_MADNESS", "Demon Madness");
- string_list_append(&spell->description, "Fire 2 balls in opposite directions of randomly chaos, confusion or charm");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 5, 20);
- spell->info_func = demonology_demon_madness_info;
- spell->effect_func = demonology_demon_madness;
- spell->failure_rate = 25;
- spell->skill_level = 10;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Fire 2 balls in opposite directions of randomly chaos, confusion or charm");
+ spell_type_set_mana(spell, 5, 20);
+ spell_type_set_difficulty(spell, 10, 25);
+ spell_type_init_demonology(spell,
+ demonology_demon_madness_info,
+ demonology_demon_madness);
}
{
spell_type *spell = spell_new(&DEMON_FIELD, "DEMON_FIELD", "Demon Field");
- string_list_append(&spell->description, "Fires a cloud of deadly nexus over a radius of 7");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 20, 60);
- spell->info_func = demonology_demon_field_info;
- spell->effect_func = demonology_demon_field;
- spell->failure_rate = 60;
- spell->skill_level = 20;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Fires a cloud of deadly nexus over a radius of 7");
+ spell_type_set_mana(spell, 20, 60);
+ spell_type_set_difficulty(spell, 20, 60);
+ spell_type_init_demonology(spell,
+ demonology_demon_field_info,
+ demonology_demon_field);
}
{
spell_type *spell = spell_new(&DOOM_SHIELD, "DOOM_SHIELD", "Doom Shield");
- string_list_append(&spell->description, "Raises a mirror of pain around you, doing very high damage to your foes");
- string_list_append(&spell->description, "that dare hit you, but greatly reduces your armour class");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 2, 30);
- spell->info_func = demonology_doom_shield_info;
- spell->effect_func = demonology_doom_shield;
- spell->failure_rate = 10;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Raises a mirror of pain around you, doing very high damage to your foes");
+ spell_type_describe(spell, "that dare hit you, but greatly reduces your armour class");
+ spell_type_set_mana(spell, 2, 30);
+ spell_type_set_difficulty(spell, 1, 10);
+ spell_type_init_demonology(spell,
+ demonology_doom_shield_info,
+ demonology_doom_shield);
}
{
spell_type *spell = spell_new(&UNHOLY_WORD, "UNHOLY_WORD", "Unholy Word");
- string_list_append(&spell->description, "Kills a pet to heal you");
- string_list_append(&spell->description, "There is a chance that the pet won't die but will turn against you");
- string_list_append(&spell->description, "it will decrease with higher level");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 15, 45);
- spell->info_func = demonology_unholy_word_info;
- spell->effect_func = demonology_unholy_word;
- spell->failure_rate = 55;
- spell->skill_level = 25;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Kills a pet to heal you");
+ spell_type_describe(spell, "There is a chance that the pet won't die but will turn against you");
+ spell_type_describe(spell, "it will decrease with higher level");
+ spell_type_set_mana(spell, 15, 45);
+ spell_type_set_difficulty(spell, 25, 55);
+ spell_type_init_demonology(spell,
+ demonology_unholy_word_info,
+ demonology_unholy_word);
}
{
spell_type *spell = spell_new(&DEMON_CLOAK, "DEMON_CLOAK", "Demon Cloak");
- string_list_append(&spell->description, "Raises a mirror that can reflect bolts and arrows for a time");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 10, 40);
- spell->info_func = demonology_demon_cloak_info;
- spell->effect_func = demonology_demon_cloak;
- spell->failure_rate = 70;
- spell->skill_level = 20;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Raises a mirror that can reflect bolts and arrows for a time");
+ spell_type_set_mana(spell, 10, 40);
+ spell_type_set_difficulty(spell, 20, 70);
+ spell_type_init_demonology(spell,
+ demonology_demon_cloak_info,
+ demonology_demon_cloak);
}
{
spell_type *spell = spell_new(&DEMON_SUMMON, "DEMON_SUMMON", "Summon Demon");
- string_list_append(&spell->description, "Summons a leveled demon to your side");
- string_list_append(&spell->description, "At level 35 it summons a high demon");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 10, 50);
- spell->info_func = demonology_summon_demon_info;
- spell->effect_func = demonology_summon_demon;
- spell->failure_rate = 30;
- spell->skill_level = 5;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Summons a leveled demon to your side");
+ spell_type_describe(spell, "At level 35 it summons a high demon");
+ spell_type_set_mana(spell, 10, 50);
+ spell_type_set_difficulty(spell, 5, 30);
+ spell_type_init_demonology(spell,
+ demonology_summon_demon_info,
+ demonology_summon_demon);
}
{
spell_type *spell = spell_new(&DISCHARGE_MINION, "DISCHARGE_MINION", "Discharge Minion");
- string_list_append(&spell->description, "The targeted pet will explode in a burst of gravity");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 20, 50);
- spell->info_func = demonology_discharge_minion_info;
- spell->effect_func = demonology_discharge_minion;
- spell->failure_rate = 30;
- spell->skill_level = 10;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "The targeted pet will explode in a burst of gravity");
+ spell_type_set_mana(spell, 20, 50);
+ spell_type_set_difficulty(spell, 10, 30);
+ spell_type_init_demonology(spell,
+ demonology_discharge_minion_info,
+ demonology_discharge_minion);
}
{
spell_type *spell = spell_new(&CONTROL_DEMON, "CONTROL_DEMON", "Control Demon");
- string_list_append(&spell->description, "Attempts to control a demon");
- school_idx_add_new(&spell->schools, SCHOOL_DEMON);
- range_init(&spell->mana_range, 30, 70);
- spell->info_func = demonology_control_demon_info;
- spell->effect_func = demonology_control_demon;
- spell->failure_rate = 55;
- spell->skill_level = 25;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Attempts to control a demon");
+ spell_type_set_mana(spell, 30, 70);
+ spell_type_set_difficulty(spell, 25, 55);
+ spell_type_init_demonology(spell,
+ demonology_control_demon_info,
+ demonology_control_demon);
}
{
spell_type *spell = spell_new(&DEVICE_HEAL_MONSTER, "DEVICE_HEAL_MONSTER", "Heal Monster");
- string_list_append(&spell->description, "Heals a monster");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 5, 20);
- spell->info_func = device_heal_monster_info;
- spell->effect_func = device_heal_monster;
- spell->failure_rate = 15;
- spell->skill_level = 3;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Heals a monster");
+ spell_type_set_mana(spell, 5, 20);
+ spell_type_set_difficulty(spell, 3, 15);
+ spell_type_init_device(spell,
+ device_heal_monster_info,
+ device_heal_monster);
- dice_parse_checked(&spell->device_charges, "10+d10");
+ spell_type_set_device_charges(spell, "10+d10");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 17;
range_init(&device_allocation->base_level, 1, 15);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_SPEED_MONSTER, "DEVICE_SPEED_MONSTER", "Haste Monster");
- string_list_append(&spell->description, "Haste a monster");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 10, 10);
- spell->info_func = device_haste_monster_info;
- spell->effect_func = device_haste_monster;
- spell->failure_rate = 30;
- spell->skill_level = 10;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Haste a monster");
+ spell_type_set_mana(spell, 10, 10);
+ spell_type_set_difficulty(spell, 10, 30);
+ spell_type_init_device(spell,
+ device_haste_monster_info,
+ device_haste_monster);
- dice_parse_checked(&spell->device_charges, "10+d5");
+ spell_type_set_device_charges(spell, "10+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_WAND);
device_allocation->rarity = 7;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 20, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_WISH, "DEVICE_WISH", "Wish");
- string_list_append(&spell->description, "This grants you a wish, beware of what you ask for!");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 400, 400);
- spell->info_func = device_wish_info;
- spell->effect_func = device_wish;
- spell->failure_rate = 99;
- spell->skill_level = 50;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "This grants you a wish, beware of what you ask for!");
+ spell_type_set_mana(spell, 400, 400);
+ spell_type_set_difficulty(spell, 50, 99);
+ spell_type_init_device(spell,
+ device_wish_info,
+ device_wish);
- dice_parse_checked(&spell->device_charges, "1+d2");
+ spell_type_set_device_charges(spell, "1+d2");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 98;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 1, 1);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_SUMMON, "DEVICE_SUMMON", "Summon");
- string_list_append(&spell->description, "Summons hostile monsters near you");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 5, 25);
- spell->info_func = device_summon_monster_info;
- spell->effect_func = device_summon_monster;
- spell->failure_rate = 20;
- spell->skill_level = 5;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Summons hostile monsters near you");
+ spell_type_set_mana(spell, 5, 25);
+ spell_type_set_difficulty(spell, 5, 20);
+ spell_type_init_device(spell,
+ device_summon_monster_info,
+ device_summon_monster);
- dice_parse_checked(&spell->device_charges, "1+d20");
+ spell_type_set_device_charges(spell, "1+d20");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 13;
range_init(&device_allocation->base_level, 1, 40);
range_init(&device_allocation->max_level, 25, 50);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_MANA, "DEVICE_MANA", "Mana");
- string_list_append(&spell->description, "Restores a part(or all) of your mana");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 1, 1);
- spell->info_func = device_mana_info;
- spell->effect_func = device_mana;
- spell->failure_rate = 80;
- spell->skill_level = 30;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "Restores a part(or all) of your mana");
+ spell_type_set_mana(spell, 1, 1);
+ spell_type_set_difficulty(spell, 30, 80);
+ spell_type_init_device(spell,
+ device_mana_info,
+ device_mana);
- dice_parse_checked(&spell->device_charges, "2+d3");
+ spell_type_set_device_charges(spell, "2+d3");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 78;
range_init(&device_allocation->base_level, 1, 5);
range_init(&device_allocation->max_level, 20, 35);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_NOTHING, "DEVICE_NOTHING", "Nothing");
- string_list_append(&spell->description, "It does nothing.");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = device_nothing_info;
- spell->effect_func = device_nothing;
- spell->failure_rate = 0;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_describe(spell, "It does nothing.");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 0);
+ spell_type_init_device(spell,
+ device_nothing_info,
+ device_nothing);
- dice_parse_checked(&spell->device_charges, "0+d0");
+ spell_type_set_device_charges(spell, "0+d0");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 3;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 1, 1);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
{
@@ -2338,228 +2182,230 @@ void school_spells_init()
device_allocation->rarity = 3;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 1, 1);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_MAGGOT, "DEVICE_MAGGOT", "Artifact Maggot");
- dice_parse_checked(&spell->activation_duration, "10+d50");
- string_list_append(&spell->description, "terrify");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 7, 7);
- spell->info_func = device_maggot_info;
- spell->effect_func = device_maggot;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_set_activation_timeout(spell, "10+d50");
+ spell_type_describe(spell, "terrify");
+ spell_type_set_mana(spell, 7, 7);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_init_device(spell,
+ device_maggot_info,
+ device_maggot);
}
{
spell_type *spell = spell_new(&DEVICE_HOLY_FIRE, "DEVICE_HOLY_FIRE", "Holy Fire of Mithrandir");
- string_list_append(&spell->description, "The Holy Fire created by this staff will deeply(double damage) burn");
- string_list_append(&spell->description, "all that is evil.");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 50, 150);
- spell->info_func = device_holy_fire_info;
- spell->effect_func = device_holy_fire;
- spell->failure_rate = 75;
- spell->skill_level = 30;
- spell_init_mage(spell, NO_RANDOM);
-
- dice_parse_checked(&spell->device_charges, "2+d5");
+ spell_type_describe(spell, "The Holy Fire created by this staff will deeply(double damage) burn");
+ spell_type_describe(spell, "all that is evil.");
+ spell_type_set_mana(spell, 50, 150);
+ spell_type_set_difficulty(spell, 30, 75);
+ spell_type_init_device(spell,
+ device_holy_fire_info,
+ device_holy_fire);
+
+ spell_type_set_device_charges(spell, "2+d5");
{
device_allocation *device_allocation = device_allocation_new(TV_STAFF);
device_allocation->rarity = 999;
range_init(&device_allocation->base_level, 1, 1);
range_init(&device_allocation->max_level, 35, 35);
- sglib_device_allocation_add(&spell->device_allocation, device_allocation);
+ spell_type_add_device_allocation(spell, device_allocation);
}
}
{
spell_type *spell = spell_new(&DEVICE_ETERNAL_FLAME, "DEVICE_ETERNAL_FLAME", "Artifact Eternal Flame");
- dice_parse_checked(&spell->activation_duration, "0");
- string_list_append(&spell->description, "Imbuing an object with the eternal fire");
- school_idx_add_new(&spell->schools, SCHOOL_DEVICE);
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = device_eternal_flame_info;
- spell->effect_func = device_eternal_flame;
- spell->failure_rate = 0;
- spell->skill_level = 1;
- spell_init_mage(spell, NO_RANDOM);
+ spell_type_set_activation_timeout(spell, "0");
+ spell_type_describe(spell, "Imbuing an object with the eternal fire");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, 0);
+ spell_type_init_device(spell,
+ device_eternal_flame_info,
+ device_eternal_flame);
}
{
spell_type *spell = spell_new(&MUSIC_STOP, "MUSIC_STOP", "Stop singing(I)");
- string_list_append(&spell->description, "Stops the current song, if any.");
- range_init(&spell->mana_range, 0, 0);
- spell->info_func = music_stop_singing_info;
- spell->effect_func = music_stop_singing_spell;
- spell->failure_rate = -400;
- spell->skill_level = 1;
- spell->castable_while_blind = TRUE;
- spell_init_music(spell, 1);
+ spell_type_describe(spell, "Stops the current song, if any.");
+ spell_type_set_mana(spell, 0, 0);
+ spell_type_set_difficulty(spell, 1, -400);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_music(spell,
+ 1,
+ music_stop_singing_info,
+ music_stop_singing_spell);
}
{
spell_type *spell = spell_new(&MUSIC_HOLD, "MUSIC_HOLD", "Holding Pattern(I)");
- string_list_append(&spell->description, "Slows down all monsters listening the song.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 1, 10);
- spell->info_func = music_holding_pattern_info;
- spell->effect_func = music_holding_pattern_spell;
- spell->lasting_func = music_holding_pattern_lasting;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell->castable_while_blind = TRUE;
- spell_init_music(spell, 1);
+ spell_type_describe(spell, "Slows down all monsters listening the song.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 1, 10);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_music_lasting(
+ spell,
+ 1,
+ music_holding_pattern_info,
+ music_holding_pattern_spell,
+ music_holding_pattern_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_CONF, "MUSIC_CONF", "Illusion Pattern(II)");
- string_list_append(&spell->description, "Tries to confuse all monsters listening the song.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 2, 15);
- spell->info_func = music_illusion_pattern_info;
- spell->effect_func = music_illusion_pattern_spell;
- spell->lasting_func = music_illusion_pattern_lasting;
- spell->failure_rate = 30;
- spell->skill_level = 5;
- spell->castable_while_blind = TRUE;
- spell_init_music(spell, 2);
+ spell_type_describe(spell, "Tries to confuse all monsters listening the song.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 2, 15);
+ spell_type_set_difficulty(spell, 5, 30);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_music_lasting(
+ spell,
+ 2,
+ music_illusion_pattern_info,
+ music_illusion_pattern_spell,
+ music_illusion_pattern_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_STUN, "MUSIC_STUN", "Stun Pattern(IV)");
- string_list_append(&spell->description, "Stuns all monsters listening the song.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 3, 25);
- spell->info_func = music_stun_pattern_info;
- spell->effect_func = music_stun_pattern_spell;
- spell->lasting_func = music_stun_pattern_lasting;
- spell->failure_rate = 45;
- spell->skill_level = 10;
- spell->castable_while_blind = TRUE;
- spell_init_music(spell, 4);
+ spell_type_describe(spell, "Stuns all monsters listening the song.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 3, 25);
+ spell_type_set_difficulty(spell, 10, 45);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_music_lasting(
+ spell,
+ 4,
+ music_stun_pattern_info,
+ music_stun_pattern_spell,
+ music_stun_pattern_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_LITE, "MUSIC_LITE", "Song of the Sun(I)");
- string_list_append(&spell->description, "Provides light as long as you sing.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 1, 1);
- spell->info_func = music_song_of_the_sun_info;
- spell->effect_func = music_song_of_the_sun_spell;
- spell->lasting_func = music_song_of_the_sun_lasting;
- spell->failure_rate = 20;
- spell->skill_level = 1;
- spell->castable_while_blind = TRUE;
- spell_init_music(spell, 1);
+ spell_type_describe(spell, "Provides light as long as you sing.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 1, 1);
+ spell_type_set_difficulty(spell, 1, 20);
+ spell_type_set_castable_while_blind(spell, TRUE);
+ spell_type_init_music_lasting(
+ spell,
+ 1,
+ music_song_of_the_sun_info,
+ music_song_of_the_sun_spell,
+ music_song_of_the_sun_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_HEAL, "MUSIC_HEAL", "Flow of Life(II)");
- string_list_append(&spell->description, "Heals you as long as you sing.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 5, 30);
- spell->info_func = music_flow_of_life_info;
- spell->effect_func = music_flow_of_life_spell;
- spell->lasting_func = music_flow_of_life_lasting;
- spell->failure_rate = 35;
- spell->skill_level = 7;
- spell_init_music(spell, 2);
+ spell_type_describe(spell, "Heals you as long as you sing.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 5, 30);
+ spell_type_set_difficulty(spell, 7, 35);
+ spell_type_init_music_lasting(
+ spell,
+ 2,
+ music_flow_of_life_info,
+ music_flow_of_life_spell,
+ music_flow_of_life_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_HERO, "MUSIC_HERO", "Heroic Ballad(II)");
- string_list_append(&spell->description, "Increases melee accuracy");
- string_list_append(&spell->description, "At level 10 it increases it even more and reduces armour a bit");
- string_list_append(&spell->description, "At level 20 it increases it again");
- string_list_append(&spell->description, "At level 25 it grants protection against chaos and confusion");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 4, 14);
- spell->info_func = music_heroic_ballad_info;
- spell->effect_func = music_heroic_ballad_spell;
- spell->lasting_func = music_heroic_ballad_lasting;
- spell->failure_rate = 45;
- spell->skill_level = 10;
- spell_init_music(spell, 2);
+ spell_type_describe(spell, "Increases melee accuracy");
+ spell_type_describe(spell, "At level 10 it increases it even more and reduces armour a bit");
+ spell_type_describe(spell, "At level 20 it increases it again");
+ spell_type_describe(spell, "At level 25 it grants protection against chaos and confusion");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 4, 14);
+ spell_type_set_difficulty(spell, 10, 45);
+ spell_type_init_music_lasting(
+ spell,
+ 2,
+ music_heroic_ballad_info,
+ music_heroic_ballad_spell,
+ music_heroic_ballad_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_TIME, "MUSIC_TIME", "Hobbit Melodies(III)");
- string_list_append(&spell->description, "Greatly increases your reflexes allowing you to block more melee blows.");
- string_list_append(&spell->description, "At level 15 it also makes you faster.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 10, 30);
- spell->info_func = music_hobbit_melodies_info;
- spell->effect_func = music_hobbit_melodies_spell;
- spell->lasting_func = music_hobbit_melodies_lasting;
- spell->failure_rate = 70;
- spell->skill_level = 20;
- spell_init_music(spell, 3);
+ spell_type_describe(spell, "Greatly increases your reflexes allowing you to block more melee blows.");
+ spell_type_describe(spell, "At level 15 it also makes you faster.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 10, 30);
+ spell_type_set_difficulty(spell, 20, 70);
+ spell_type_init_music_lasting(
+ spell,
+ 3,
+ music_hobbit_melodies_info,
+ music_hobbit_melodies_spell,
+ music_hobbit_melodies_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_MIND, "MUSIC_MIND", "Clairaudience(IV)");
- string_list_append(&spell->description, "Allows you to sense monster minds as long as you sing.");
- string_list_append(&spell->description, "At level 10 it identifies all objects in a radius on the floor,");
- string_list_append(&spell->description, "as well as probing monsters in that radius.");
- string_list_append(&spell->description, "Consumes the amount of mana each turn.");
- range_init(&spell->mana_range, 15, 30);
- spell->info_func = music_clairaudience_info;
- spell->effect_func = music_clairaudience_spell;
- spell->lasting_func = music_clairaudience_lasting;
- spell->failure_rate = 75;
- spell->skill_level = 25;
- spell_init_music(spell, 4);
+ spell_type_describe(spell, "Allows you to sense monster minds as long as you sing.");
+ spell_type_describe(spell, "At level 10 it identifies all objects in a radius on the floor,");
+ spell_type_describe(spell, "as well as probing monsters in that radius.");
+ spell_type_describe(spell, "Consumes the amount of mana each turn.");
+ spell_type_set_mana(spell, 15, 30);
+ spell_type_set_difficulty(spell, 25, 75);
+ spell_type_init_music_lasting(
+ spell,
+ 4,
+ music_clairaudience_info,
+ music_clairaudience_spell,
+ music_clairaudience_lasting);
}
{
spell_type *spell = spell_new(&MUSIC_BLOW, "MUSIC_BLOW", "Blow(I)");
- string_list_append(&spell->description, "Produces a powerful, blowing, sound all around you.");
- range_init(&spell->mana_range, 3, 30);
- spell->info_func = music_blow_info;
- spell->effect_func = music_blow_spell;
- spell->failure_rate = 20;
- spell->skill_level = 4;
- spell_init_music(spell, 1);
+ spell_type_describe(spell, "Produces a powerful, blowing, sound all around you.");
+ spell_type_set_mana(spell, 3, 30);
+ spell_type_set_difficulty(spell, 4, 20);
+ spell_type_init_music(spell,
+ 1,
+ music_blow_info,
+ music_blow_spell);
}
{
spell_type *spell = spell_new(&MUSIC_WIND, "MUSIC_WIND", "Gush of Wind(II)");
- string_list_append(&spell->description, "Produces a outgoing gush of wind that sends monsters away.");
- range_init(&spell->mana_range, 15, 45);
- spell->info_func = music_gush_of_wind_info;
- spell->effect_func = music_gush_of_wind_spell;
- spell->failure_rate = 30;
- spell->skill_level = 14;
- spell_init_music(spell, 2);
+ spell_type_describe(spell, "Produces a outgoing gush of wind that sends monsters away.");
+ spell_type_set_mana(spell, 15, 45);
+ spell_type_set_difficulty(spell, 14, 30);
+ spell_type_init_music(spell,
+ 2,
+ music_gush_of_wind_info,
+ music_gush_of_wind_spell);
}
{
spell_type *spell = spell_new(&MUSIC_YLMIR, "MUSIC_YLMIR", "Horns of Ylmir(III)");
- string_list_append(&spell->description, "Produces an earth shaking sound.");
- range_init(&spell->mana_range, 25, 30);
- spell->info_func = music_horns_of_ylmir_info;
- spell->effect_func = music_horns_of_ylmir_spell;
- spell->failure_rate = 20;
- spell->skill_level = 20;
- spell_init_music(spell, 3);
+ spell_type_describe(spell, "Produces an earth shaking sound.");
+ spell_type_set_mana(spell, 25, 30);
+ spell_type_set_difficulty(spell, 20, 20);
+ spell_type_init_music(spell,
+ 3,
+ music_horns_of_ylmir_info,
+ music_horns_of_ylmir_spell);
}
{
spell_type *spell = spell_new(&MUSIC_AMBARKANTA, "MUSIC_AMBARKANTA", "Ambarkanta(IV)");
- string_list_append(&spell->description, "Produces a reality shaking sound that transports you to a nearly");
- string_list_append(&spell->description, "identical reality.");
- range_init(&spell->mana_range, 70, 70);
- spell->info_func = music_ambarkanta_info;
- spell->effect_func = music_ambarkanta_spell;
- spell->failure_rate = 60;
- spell->skill_level = 25;
- spell_init_music(spell, 4);
+ spell_type_describe(spell, "Produces a reality shaking sound that transports you to a nearly");
+ spell_type_describe(spell, "identical reality.");
+ spell_type_set_mana(spell, 70, 70);
+ spell_type_set_difficulty(spell, 25, 60);
+ spell_type_init_music(spell,
+ 4,
+ music_ambarkanta_info,
+ music_ambarkanta_spell);
}
/* Module-specific spells */
diff --git a/src/spells6.c b/src/spells6.c
index 37e4c42c..5db4e18e 100644
--- a/src/spells6.c
+++ b/src/spells6.c
@@ -2,6 +2,8 @@
#include <assert.h>
+#include "spell_type.h"
+
static int compare_school_provider(school_provider *a, school_provider *b)
{
return SGLIB_NUMERIC_COMPARATOR(a->deity_idx, b->deity_idx);
@@ -150,122 +152,132 @@ long get_provided_levels(school_type *school)
return 0;
}
-void get_level_school(s32b spell_idx, s32b max, s32b min, s32b *level, bool_ *na)
+typedef struct get_level_school_callback_data get_level_school_callback_data;
+struct get_level_school_callback_data {
+ bool_ allow_spell_power;
+ long bonus;
+ long lvl;
+ long num;
+};
+
+static bool_ get_level_school_callback(void *data_, int school_idx)
{
- spell_type *spell = spell_at(spell_idx);
- school_idx *school_idx = NULL;
- struct sglib_school_idx_iterator sit;
- bool_ allow_spell_power = TRUE;
- long lvl, num, bonus;
+ get_level_school_callback_data *data = data_;
+ school_type *school = school_at(school_idx);
+ long r = 0, s = 0, p = 0, ok = 0;
- assert(level != NULL);
- assert(na != NULL);
+ /* Does it require we worship a specific god? */
+ if ((school->deity_idx > 0) &&
+ (school->deity_idx != p_ptr->pgod))
+ {
+ return FALSE;
+ }
- lvl = 0;
- num = 0;
- bonus = 0;
+ /* Take the basic skill value */
+ r = s_info[school->skill].value;
/* Do we pass tests? */
- if (!check_spell_depends(spell))
+ if ((school->depends_satisfied != NULL) &&
+ (!school->depends_satisfied()))
{
- *level = min;
- *na = TRUE;
- return;
+ return FALSE;
}
- /* Go through all the spell's schools. */
- for (school_idx = sglib_school_idx_it_init(&sit, spell->schools);
- school_idx != NULL;
- school_idx = sglib_school_idx_it_next(&sit))
+ /* Include effects of Sorcery (if applicable) */
+ if (school->sorcery)
{
- school_type *school = school_at(school_idx->i);
- long r = 0, s = 0, p = 0, ok = 0;
+ s = s_info[SKILL_SORCERY].value;
+ }
- /* Does it require we worship a specific god? */
- if ((school->deity_idx > 0) &&
- (school->deity_idx != p_ptr->pgod))
- {
- *level = min;
- *na = TRUE;
- return;
- }
+ /* Include effects of Spell Power? Every school must
+ * allow use of Spell Power for it to apply. */
+ if (!school->spell_power)
+ {
+ data->allow_spell_power = FALSE;
+ }
- /* Take the basic skill value */
- r = s_info[school->skill].value;
+ /* Calculate effects of provided levels */
+ p = get_provided_levels(school);
- /* Do we pass tests? */
- if ((school->depends_satisfied != NULL) &&
- (!school->depends_satisfied()))
- {
- *level = min;
- *na = TRUE;
- return;
- }
+ /* Find the highest of Skill, Sorcery and Provided levels. */
+ ok = r;
+ if (ok < s)
+ {
+ ok = s;
+ }
+ if (ok < p)
+ {
+ ok = p;
+ }
- /* Include effects of Sorcery (if applicable) */
- if (school->sorcery)
- {
- s = s_info[SKILL_SORCERY].value;
- }
+ /* Do we need to add a special bonus? */
+ if (school->bonus_levels != NULL)
+ {
+ data->bonus += (school->bonus_levels() * (SKILL_STEP / 10));
+ }
- /* Include effects of Spell Power? Every school must
- * allow use of Spell Power for it to apply. */
- if (!school->spell_power)
- {
- allow_spell_power = FALSE;
- }
+ /* All schools must be non-zero to be able to use it. */
+ if (ok <= 0)
+ {
+ return FALSE;
+ }
- /* Calculate effects of provided levels */
- p = get_provided_levels(school);
+ /* Apply it */
+ data->lvl += ok;
+ data->num += 1;
- /* Find the highest of Skill, Sorcery and Provided levels. */
- ok = r;
- if (ok < s)
- {
- ok = s;
- }
- if (ok < p)
- {
- ok = p;
- }
+ /* Keep going */
+ return TRUE;
+}
- /* Do we need to add a special bonus? */
- if (school->bonus_levels != NULL)
- {
- bonus += (school->bonus_levels() * (SKILL_STEP / 10));
- }
+void get_level_school(s32b spell_idx, s32b max, s32b min, s32b *level, bool_ *na)
+{
+ spell_type *spell = spell_at(spell_idx);
- /* All schools must be non-zero to be able to use it. */
- if (ok <= 0)
- {
- *level = min;
- *na = TRUE;
- return;
- }
+ assert(level != NULL);
+ assert(na != NULL);
- /* Apply it */
- lvl = lvl + ok;
- num = num + 1;
+ /* Do we pass tests? */
+ if (!spell_type_dependencies_satisfied(spell))
+ {
+ *level = min;
+ *na = TRUE;
+ return;
+ }
+
+ /* Set up initial state */
+ get_level_school_callback_data data;
+ data.allow_spell_power = TRUE;
+ data.bonus = 0;
+ data.lvl = 0;
+ data.num = 0;
+
+ /* Go through all the spell's schools. */
+ if (!spell_type_school_foreach(spell, get_level_school_callback, &data))
+ {
+ *level = min;
+ *na = TRUE;
+ return;
}
/* Add the Spellpower skill as a bonus on top */
- if (allow_spell_power)
+ if (data.allow_spell_power)
{
- bonus += (get_skill_scale(SKILL_SPELL, 20) * (SKILL_STEP / 10));
+ data.bonus += (get_skill_scale(SKILL_SPELL, 20) * (SKILL_STEP / 10));
}
/* Add bonus from objects */
- bonus += (p_ptr->to_s * (SKILL_STEP / 10));
+ data.bonus += (p_ptr->to_s * (SKILL_STEP / 10));
/* We divide by 10 because otherwise we can overflow a s32b
* and we can use a u32b because the value can be negative.
* The loss of information should be negligible since 1 skill
* point is 1000 internally. */
- lvl = (lvl / num) / 10;
- lvl = lua_get_level(spell, lvl, max, min, bonus);
+ data.lvl = (data.lvl / data.num) / 10;
+ data.lvl = lua_get_level(spell, data.lvl, max, min, data.bonus);
/* Result */
- *level = lvl;
+ *level = data.lvl;
*na = FALSE;
}
diff --git a/src/store.c b/src/store.c
index 3114380c..6cdaad4a 100644
--- a/src/store.c
+++ b/src/store.c
@@ -12,6 +12,7 @@
#include "angband.h"
+#include "spell_type.h"
#include "quark.h"
#define STORE_GENERAL_STORE "General Store"
@@ -834,7 +835,7 @@ static bool_ store_will_buy(object_type *o_ptr)
if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval == BOOK_RANDOM) &&
- (can_spell_random(o_ptr->pval) == SKILL_SPIRITUALITY))
+ (spell_type_random_type(spell_at(o_ptr->pval)) == SKILL_SPIRITUALITY))
{
return TRUE;
}
@@ -892,7 +893,7 @@ static bool_ store_will_buy(object_type *o_ptr)
if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval == BOOK_RANDOM) &&
- (can_spell_random(o_ptr->pval) == SKILL_MAGIC))
+ (spell_type_random_type(spell_at(o_ptr->pval)) == SKILL_MAGIC))
{
return TRUE;
}
diff --git a/src/types.h b/src/types.h
index 825e25ab..c921d028 100644
--- a/src/types.h
+++ b/src/types.h
@@ -2569,72 +2569,6 @@ struct skill_type
u32b flags1; /* Skill flags */
};
-
-/*
- * School index list.
- */
-typedef struct school_idx school_idx;
-struct school_idx {
- s32b i; /* School index */
- school_idx *next; /* for list */
-};
-
-
-/*
- * Casting type
- */
-typedef enum { USE_SPELL_POINTS, USE_PIETY } casting_type;
-
-
-/*
- * Spell effect function result
- */
-typedef enum {
- NO_CAST, /* Spell not cast; user aborted */
- CAST_OBVIOUS, /* Cast; caster discovers effect (devices) */
- CAST_HIDDEN /* Cast; caster does NOT discover effect (devices) */
-} casting_result;
-
-/*
- * The spell function must provide the desc
- */
-typedef struct spell_type spell_type;
-struct spell_type
-{
- cptr name; /* Name */
- byte skill_level; /* Required level (to learn) */
- string_list *description; /* List of strings */
-
- casting_result (*effect_func)(int o_idx); /* Spell effect function */
- char* (*info_func)(); /* Information function */
- int (*lasting_func)(); /* Lasting effect function */
- bool_ (*depend_func)(); /* Check dependencies */
-
- s16b minimum_pval; /* Minimum required pval for item-based spells */
-
- casting_type casting_type; /* Type of casting required */
- s16b casting_stat; /* Stat used for casting */
-
- bool_ castable_while_blind;
- bool_ castable_while_confused;
-
- dice_type device_charges; /* Number of charges for devices */
- device_allocation *device_allocation; /* Allocation table for devices */
-
- s16b random_type; /* Type of random items in which skill may appear */
-
- s32b failure_rate; /* Failure rate */
-
- s32b inertia_difficulty; /* Mana cost when used in Inertia Control */
- s32b inertia_delay; /* Delay between castings */
-
- range_type mana_range;
-
- dice_type activation_duration; /* Duration for activation (if any) */
-
- school_idx *schools;
-};
-
typedef struct school_provider school_provider;
struct school_provider
{
diff --git a/src/variable.c b/src/variable.c
index 2ec4f7bc..84ca93ee 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -1383,7 +1383,7 @@ bool_ player_char_health;
* The spell list of schools
*/
s16b school_spells_count = 0;
-spell_type school_spells[SCHOOL_SPELLS_MAX];
+spell_type *school_spells[SCHOOL_SPELLS_MAX];
s16b schools_count = 0;
school_type schools[SCHOOLS_MAX];