summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/cmd5.c70
-rw-r--r--src/cmd6.c80
-rw-r--r--src/defines.h5
-rw-r--r--src/dungeon.c26
-rw-r--r--src/externs.h297
-rw-r--r--src/init2.c9
-rw-r--r--src/lua_bind.c37
-rw-r--r--src/object1.c3
-rw-r--r--src/object2.c125
-rw-r--r--src/script.c8
-rw-r--r--src/spells.pkg583
-rw-r--r--src/spells3.c332
-rw-r--r--src/spells4.c58
-rw-r--r--src/spells5.c2605
-rw-r--r--src/types.h32
-rw-r--r--src/variable.c4
17 files changed, 3210 insertions, 1066 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 219ceb7c..d1648754 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,7 +10,7 @@ SET(SRCS
object1.c object2.c randart.c squeltch.c traps.c
monster1.c monster2.c monster3.c
xtra1.c xtra2.c skills.c powers.c gods.c
- spells1.c spells2.c spells3.c spells4.c corrupt.c mimic.c
+ spells1.c spells2.c spells3.c spells4.c spells5.c corrupt.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
help.c range.c
diff --git a/src/cmd5.c b/src/cmd5.c
index d0c60042..e322186b 100644
--- a/src/cmd5.c
+++ b/src/cmd5.c
@@ -2101,14 +2101,14 @@ bool_ get_item_hook_find_spell(int *item)
{
int i, spell;
char buf[80];
- char buf2[100];
strcpy(buf, "Manathrust");
if (!get_string("Spell name? ", buf, 79))
return FALSE;
- sprintf(buf2, "return find_spell(\"%s\")", buf);
- spell = exec_lua(buf2);
+
+ spell = find_spell(buf);
if (spell == -1) return FALSE;
+
for (i = 0; i < INVEN_TOTAL; i++)
{
object_type *o_ptr = &p_ptr->inventory[i];
@@ -2147,9 +2147,31 @@ bool_ get_item_hook_find_spell(int *item)
}
/*
+ * Is the spell castable?
+ */
+bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr)
+{
+ spell_type *spell = spell_at(spell_idx);
+ assert(o_ptr != NULL);
+
+ if (get_level(spell_idx, 50, 0) == 0)
+ {
+ return FALSE;
+ }
+
+ if (o_ptr->pval < spell->minimum_pval)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
* Get a spell from a book
*/
-s32b get_school_spell(cptr do_what, cptr check_fct, s16b force_book)
+s32b get_school_spell(cptr do_what, s16b force_book)
{
int i, item;
s32b spell = -1;
@@ -2320,13 +2342,13 @@ s32b get_school_spell(cptr do_what, cptr check_fct, s16b force_book)
}
else
{
- s32b ok;
+ bool_ ok;
/* Save the spell index */
spell = spell_x(sval, pval, i);
/* Do we need to do some pre test */
- call_lua(check_fct, "(d,O)", "d", spell, o_ptr, &ok);
+ ok = is_ok_spell(spell, o_ptr);
/* Require "okay" spells */
if (!ok)
@@ -2344,10 +2366,10 @@ s32b get_school_spell(cptr do_what, cptr check_fct, s16b force_book)
}
else
{
- s32b ok;
+ bool_ ok;
/* Require "okay" spells */
- call_lua(check_fct, "(d, O)", "d", hack_force_spell, hack_force_spell_obj, &ok);
+ ok = is_ok_spell(hack_force_spell, hack_force_spell_obj);
if (ok)
{
flag = TRUE;
@@ -2404,7 +2426,7 @@ void cast_school_spell()
return;
}
- spell = get_school_spell("cast", "is_ok_spell", 0);
+ spell = get_school_spell("cast", 0);
/* Actualy cast the choice */
if (spell != -1)
@@ -2502,14 +2524,14 @@ static bool_ hook_school_can_spellable(object_type *o_ptr)
*/
void do_cmd_copy_spell()
{
- int spell = get_school_spell("copy", "is_ok_spell", 0);
+ int spell = get_school_spell("copy", 0);
int item;
object_type *o_ptr;
if (spell == -1) return;
/* Spells that cannot be randomly created cannot be copied */
- if (exec_lua(format("return can_spell_random(%d)", spell)) == FALSE)
+ if (can_spell_random(spell) <= 0)
{
msg_print("This spell cannot be copied.");
return;
@@ -2523,29 +2545,3 @@ void do_cmd_copy_spell()
o_ptr->pval2 = spell;
inven_item_describe(item);
}
-
-/*
- * Finds a spell by name, optimized for speed
- */
-int find_spell(const char *name)
-{
- int oldtop, spell;
- oldtop = lua_gettop(L);
-
- lua_getglobal(L, "find_spell");
- tolua_pushstring(L, name);
-
- /* Call the function */
- if (lua_call(L, 1, 1))
- {
- cmsg_format(TERM_VIOLET, "ERROR in lua_call while calling 'find_spell'.");
- lua_settop(L, oldtop);
- return -1;
- }
-
- spell = tolua_getnumber(L, -(lua_gettop(L) - oldtop), -1);
-
- lua_settop(L, oldtop);
-
- return spell;
-}
diff --git a/src/cmd6.c b/src/cmd6.c
index 39483bbd..7bd6c80a 100644
--- a/src/cmd6.c
+++ b/src/cmd6.c
@@ -3650,6 +3650,33 @@ void unset_stick_mode()
/*
+ * Activate a device
+ */
+static void activate_stick(s16b s, bool_ *obvious, bool_ *use_charge)
+{
+ spell_type *spell = spell_at(s);
+ bool_ *ret;
+
+ assert(obvious != NULL);
+ assert(use_charge != NULL);
+ assert(spell->effect_func != NULL);
+
+ ret = spell->effect_func(-1);
+
+ if (ret == NULL)
+ {
+ *use_charge = FALSE;
+ *obvious = FALSE;
+ }
+ else
+ {
+ *use_charge = TRUE;
+ *obvious = *ret;
+ }
+}
+
+
+/*
* Use a staff. -RAK-
*
* One charge of one staff disappears.
@@ -3660,7 +3687,7 @@ void do_cmd_use_staff(void)
{
int item, ident, chance;
- s32b obvious, use_charge;
+ bool_ obvious, use_charge;
object_type *o_ptr;
@@ -3754,7 +3781,7 @@ void do_cmd_use_staff(void)
/* Analyze the staff */
- call_lua("activate_stick", "(d)", "dd", o_ptr->pval2, &obvious, &use_charge);
+ activate_stick(o_ptr->pval2, &obvious, &use_charge);
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
@@ -3850,7 +3877,7 @@ void do_cmd_use_staff(void)
*/
void do_cmd_aim_wand(void)
{
- s32b obvious, use_charge;
+ bool_ obvious, use_charge;
int item, ident, chance, sval;
@@ -3945,7 +3972,7 @@ void do_cmd_aim_wand(void)
sval = o_ptr->sval;
/* Analyze the wand */
- call_lua("activate_stick", "(d)", "dd", o_ptr->pval2, &obvious, &use_charge);
+ activate_stick(o_ptr->pval2, &obvious, &use_charge);
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
@@ -4989,42 +5016,16 @@ void do_cmd_activate(void)
}
-static void get_activation_duration(int spl, int *base, int *sides)
-{
- assert(base != NULL);
- assert(sides != NULL);
-
- *base = get_lua_int(format("__tmp_spells[%d].activate[1]", spl));
- if (*base <= 0)
- {
- base = 0;
- }
-
- *sides = get_lua_int(format("__tmp_spells[%d].activate[2]", spl));
- if (*sides <= 0)
- {
- sides = 0;
- }
-}
-
static void get_activation_desc(char *buf, int spl)
{
- spell_type *spell = &school_spells[spl];
+ spell_type *spell = spell_at(spl);
char turns[32];
- int base, sides;
-
- get_activation_duration(spl, &base, &sides);
- sprintf(turns, "%d", base);
- if (sides > 0)
- {
- char buf[32];
- sprintf(buf, "+d%d", sides);
- strcat(turns, buf);
- }
+ 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);
@@ -5032,11 +5033,16 @@ static void get_activation_desc(char *buf, int spl)
static int get_activation_timeout(int spl)
{
- int base, sides;
- get_activation_duration(spl, &base, &sides);
- return base + randint(sides);
+ 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)
{
@@ -5082,7 +5088,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
if (doit)
{
- call_lua("activate_activation", "(d,d)", "", -spell, item);
+ activate_activation(-spell, item);
o_ptr->timeout = get_activation_timeout(-spell);
}
else
diff --git a/src/defines.h b/src/defines.h
index 7457134a..099d3fe1 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -866,6 +866,11 @@
#define MAX_BETWEEN_EXITS 3
/*
+ * Maximum number of school spells
+ */
+#define SCHOOL_SPELLS_MAX 200
+
+/*
* Number of effects
*/
#define MAX_EFFECTS 128
diff --git a/src/dungeon.c b/src/dungeon.c
index e60f1ef0..342779b2 100644
--- a/src/dungeon.c
+++ b/src/dungeon.c
@@ -801,30 +801,10 @@ bool_ decays(object_type *o_ptr)
static int process_lasting_spell(s16b music)
{
- int oldtop, use_mana;
+ spell_type *spell = spell_at(-music);
- if (music > 0) return FALSE;
-
- oldtop = lua_gettop(L);
-
- music = -music;
-
- /* Push the function */
- lua_getglobal(L, "exec_lasting_spell");
-
- /* Push the spell */
- tolua_pushnumber(L, music);
-
- /* Call the function */
- if (lua_call(L, 1, 1))
- {
- cmsg_format(TERM_VIOLET, "ERROR in lua_call while calling lasting spell");
- return 0;
- }
-
- use_mana = tolua_getnumber(L, -(lua_gettop(L) - oldtop), 0);
- lua_settop(L, oldtop);
- return use_mana;
+ assert(spell->lasting_func != NULL);
+ return spell->lasting_func();
}
static void gere_class_special()
diff --git a/src/externs.h b/src/externs.h
index 0ebe0f04..897cc074 100644
--- a/src/externs.h
+++ b/src/externs.h
@@ -564,8 +564,8 @@ extern hist_type *bg;
extern int max_bg_idx;
extern s32b extra_savefile_parts;
extern bool_ player_char_health;
-extern s16b max_spells;
-extern spell_type *school_spells;
+extern s16b school_spells_count;
+extern spell_type school_spells[SCHOOL_SPELLS_MAX];
extern s16b max_schools;
extern school_type *schools;
extern int project_time;
@@ -801,7 +801,8 @@ extern void do_poly_self(void);
extern void brand_weapon(int brand_type);
extern cptr symbiote_name(bool_ capitalize);
extern int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost);
-extern s32b get_school_spell(cptr do_what, cptr check_fct, s16b force_book);
+extern bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr);
+extern s32b get_school_spell(cptr do_what, s16b force_book);
extern void do_cmd_copy_spell(void);
extern void cast_school_spell(void);
extern void browse_school_spell(int book, int pval, object_type *o_ptr);
@@ -969,7 +970,6 @@ extern errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int
/* init2.c */
extern void init_corruptions();
-extern void init_spells(s16b new_size);
extern void init_schools(s16b new_size);
extern void reinit_gods(s16b new_size);
extern void reinit_quests(s16b new_size);
@@ -1411,17 +1411,17 @@ extern s32b POISONBLOOD;
extern s32b THUNDERSTORM;
extern s32b STERILIZE;
-bool_ *air_noxious_cloud();
+bool_ *air_noxious_cloud(int);
char *air_noxious_cloud_info();
-bool_ *air_wings_of_winds();
+bool_ *air_wings_of_winds(int);
char *air_wings_of_winds_info();
-bool_ *air_invisibility();
+bool_ *air_invisibility(int);
char *air_invisibility_info();
-bool_ *air_poison_blood();
+bool_ *air_poison_blood(int);
char *air_poison_blood_info();
-bool_ *air_thunderstorm();
+bool_ *air_thunderstorm(int);
char *air_thunderstorm_info();
-bool_ *air_sterilize();
+bool_ *air_sterilize(int);
char *air_sterilize_info();
extern s32b BLINK;
@@ -1431,17 +1431,17 @@ extern s32b TELEAWAY;
extern s32b RECALL;
extern s32b PROBABILITY_TRAVEL;
-bool_ *convey_blink();
+bool_ *convey_blink(int);
char *convey_blink_info();
-bool_ *convey_disarm();
+bool_ *convey_disarm(int);
char *convey_disarm_info();
-bool_ *convey_teleport();
+bool_ *convey_teleport(int);
char *convey_teleport_info();
-bool_ *convey_teleport_away();
+bool_ *convey_teleport_away(int);
char *convey_teleport_away_info();
-bool_ *convey_recall();
+bool_ *convey_recall(int);
char *convey_recall_info();
-bool_ *convey_probability_travel();
+bool_ *convey_probability_travel(int);
char *convey_probability_travel_info();
extern s32b DEMON_BLADE;
@@ -1454,23 +1454,23 @@ extern s32b DEMON_SUMMON;
extern s32b DISCHARGE_MINION;
extern s32b CONTROL_DEMON;
-bool_ *demonology_demon_blade();
+bool_ *demonology_demon_blade(int);
char *demonology_demon_blade_info();
-bool_ *demonology_demon_madness();
+bool_ *demonology_demon_madness(int);
char *demonology_demon_madness_info();
-bool_ *demonology_demon_field();
+bool_ *demonology_demon_field(int);
char *demonology_demon_field_info();
-bool_ *demonology_doom_shield();
+bool_ *demonology_doom_shield(int);
char *demonology_doom_shield_info();
-bool_ *demonology_unholy_word();
+bool_ *demonology_unholy_word(int);
char *demonology_unholy_word_info();
-bool_ *demonology_demon_cloak();
+bool_ *demonology_demon_cloak(int);
char *demonology_demon_cloak_info();
-bool_ *demonology_summon_demon();
+bool_ *demonology_summon_demon(int);
char *demonology_summon_demon_info();
-bool_ *demonology_discharge_minion();
+bool_ *demonology_discharge_minion(int);
char *demonology_discharge_minion_info();
-bool_ *demonology_control_demon();
+bool_ *demonology_control_demon(int);
char *demonology_control_demon_info();
extern s32b STARIDENTIFY;
@@ -1480,17 +1480,17 @@ extern s32b SENSEHIDDEN;
extern s32b REVEALWAYS;
extern s32b SENSEMONSTERS;
-bool_ *divination_greater_identify();
+bool_ *divination_greater_identify(int);
char *divination_greater_identify_info();
-bool_ *divination_identify();
+bool_ *divination_identify(int);
char *divination_identify_info();
-bool_ *divination_vision();
+bool_ *divination_vision(int);
char *divination_vision_info();
-bool_ *divination_sense_hidden();
+bool_ *divination_sense_hidden(int);
char *divination_sense_hidden_info();
-bool_ *divination_reveal_ways();
+bool_ *divination_reveal_ways(int);
char *divination_reveal_ways_info();
-bool_ *divination_sense_monsters();
+bool_ *divination_sense_monsters(int);
char *divination_sense_monsters_info();
extern s32b STONESKIN;
@@ -1499,15 +1499,15 @@ extern s32b STONEPRISON;
extern s32b STRIKE;
extern s32b SHAKE;
-bool_ *earth_stone_skin();
+bool_ *earth_stone_skin(int);
char *earth_stone_skin_info();
-bool_ *earth_dig();
+bool_ *earth_dig(int);
char *earth_dig_info();
-bool_ *earth_stone_prison();
+bool_ *earth_stone_prison(int);
char *earth_stone_prison_info();
-bool_ *earth_strike();
+bool_ *earth_strike(int);
char *earth_strike_info();
-bool_ *earth_shake();
+bool_ *earth_shake(int);
char *earth_shake_info();
extern s32b ERU_SEE;
@@ -1515,13 +1515,13 @@ extern s32b ERU_LISTEN;
extern s32b ERU_UNDERSTAND;
extern s32b ERU_PROT;
-bool_ *eru_see_the_music();
+bool_ *eru_see_the_music(int);
char *eru_see_the_music_info();
-bool_ *eru_listen_to_the_music();
+bool_ *eru_listen_to_the_music(int);
char *eru_listen_to_the_music_info();
-bool_ *eru_know_the_music();
+bool_ *eru_know_the_music(int);
char *eru_know_the_music_info();
-bool_ *eru_lay_of_protection();
+bool_ *eru_lay_of_protection(int);
char *eru_lay_of_protection_info();
extern s32b GLOBELIGHT;
@@ -1530,15 +1530,15 @@ extern s32b FIERYAURA;
extern s32b FIREWALL;
extern s32b FIREGOLEM;
-bool_ *fire_globe_of_light();
+bool_ *fire_globe_of_light(int);
char *fire_globe_of_light_info();
-bool_ *fire_fireflash();
+bool_ *fire_fireflash(int);
char *fire_fireflash_info();
-bool_ *fire_fiery_shield();
+bool_ *fire_fiery_shield(int);
char *fire_fiery_shield_info();
-bool_ *fire_firewall();
+bool_ *fire_firewall(int);
char *fire_firewall_info();
-bool_ *fire_golem();
+bool_ *fire_golem(int);
char *fire_golem_info();
extern s32b CALL_THE_ELEMENTS;
@@ -1550,25 +1550,25 @@ extern s32b DRIPPING_TREAD;
extern s32b GROW_BARRIER;
extern s32b ELEMENTAL_MINION;
-bool_ *geomancy_call_the_elements();
+bool_ *geomancy_call_the_elements(int);
char *geomancy_call_the_elements_info();
-bool_ *geomancy_channel_elements();
+bool_ *geomancy_channel_elements(int);
char *geomancy_channel_elements_info();
-bool_ *geomancy_elemental_wave();
+bool_ *geomancy_elemental_wave(int);
char *geomancy_elemental_wave_info();
-bool_ *geomancy_vaporize();
+bool_ *geomancy_vaporize(int);
char *geomancy_vaporize_info();
bool_ geomancy_vaporize_depends();
-bool_ *geomancy_geolysis();
+bool_ *geomancy_geolysis(int);
char *geomancy_geolysis_info();
bool_ geomancy_geolysis_depends();
-bool_ *geomancy_dripping_tread();
+bool_ *geomancy_dripping_tread(int);
char *geomancy_dripping_tread_info();
bool_ geomancy_dripping_tread_depends();
-bool_ *geomancy_grow_barrier();
+bool_ *geomancy_grow_barrier(int);
char *geomancy_grow_barrier_info();
bool_ geomancy_grow_barrier_depends();
-bool_ *geomancy_elemental_minion();
+bool_ *geomancy_elemental_minion(int);
char *geomancy_elemental_minion_info();
extern s32b MANATHRUST;
@@ -1576,13 +1576,13 @@ extern s32b DELCURSES;
extern s32b RESISTS;
extern s32b MANASHIELD;
-bool_ *mana_manathrust();
+bool_ *mana_manathrust(int);
char *mana_manathrust_info();
-bool_ *mana_remove_curses();
+bool_ *mana_remove_curses(int);
char *mana_remove_curses_info();
-bool_ *mana_elemental_shield();
+bool_ *mana_elemental_shield(int);
char *mana_elemental_shield_info();
-bool_ *mana_disruption_shield();
+bool_ *mana_disruption_shield(int);
char *mana_disruption_shield_info();
extern s32b MANWE_SHIELD;
@@ -1590,13 +1590,13 @@ extern s32b MANWE_AVATAR;
extern s32b MANWE_BLESS;
extern s32b MANWE_CALL;
-bool_ *manwe_wind_shield();
+bool_ *manwe_wind_shield(int);
char *manwe_wind_shield_info();
-bool_ *manwe_avatar();
+bool_ *manwe_avatar(int);
char *manwe_avatar_info();
-bool_ *manwe_blessing();
+bool_ *manwe_blessing(int);
char *manwe_blessing_info();
-bool_ *manwe_call();
+bool_ *manwe_call(int);
char *manwe_call_info();
extern s32b MELKOR_CURSE;
@@ -1605,11 +1605,11 @@ extern s32b MELKOR_MIND_STEAL;
void do_melkor_curse(int m_idx);
-bool_ *melkor_curse();
+bool_ *melkor_curse(int);
char *melkor_curse_info();
-bool_ *melkor_corpse_explosion();
+bool_ *melkor_corpse_explosion(int);
char *melkor_corpse_explosion_info();
-bool_ *melkor_mind_steal();
+bool_ *melkor_mind_steal(int);
char *melkor_mind_steal_info();
extern s32b RECHARGE;
@@ -1619,15 +1619,15 @@ extern s32b TRACKER;
extern s32b INERTIA_CONTROL;
extern timer_type *TIMER_INERTIA_CONTROL;
-bool_ *meta_recharge();
+bool_ *meta_recharge(int);
char *meta_recharge_info();
-bool_ *meta_spellbinder();
+bool_ *meta_spellbinder(int);
char *meta_spellbinder_info();
-bool_ *meta_disperse_magic();
+bool_ *meta_disperse_magic(int);
char *meta_disperse_magic_info();
-bool_ *meta_tracker();
+bool_ *meta_tracker(int);
char *meta_tracker_info();
-bool_ *meta_inertia_control();
+bool_ *meta_inertia_control(int);
char *meta_inertia_control_info();
void meta_inertia_control_timer_callback();
@@ -1639,13 +1639,13 @@ extern s32b CONFUSE;
extern s32b ARMOROFFEAR;
extern s32b STUN;
-bool_ *mind_charm();
+bool_ *mind_charm(int);
char *mind_charm_info();
-bool_ *mind_confuse();
+bool_ *mind_confuse(int);
char *mind_confuse_info();
-bool_ *mind_armor_of_fear();
+bool_ *mind_armor_of_fear(int);
char *mind_armor_of_fear_info();
-bool_ *mind_stun();
+bool_ *mind_stun(int);
char *mind_stun_info();
extern s32b MAGELOCK;
@@ -1653,24 +1653,24 @@ extern s32b SLOWMONSTER;
extern s32b ESSENCESPEED;
extern s32b BANISHMENT;
-bool_ *tempo_magelock();
+bool_ *tempo_magelock(int);
char *tempo_magelock_info();
-bool_ *tempo_slow_monster();
+bool_ *tempo_slow_monster(int);
char *tempo_slow_monster_info();
-bool_ *tempo_essence_of_speed();
+bool_ *tempo_essence_of_speed(int);
char *tempo_essence_of_speed_info();
-bool_ *tempo_banishment();
+bool_ *tempo_banishment(int);
char *tempo_banishment_info();
extern s32b TULKAS_AIM;
extern s32b TULKAS_WAVE;
extern s32b TULKAS_SPIN;
-bool_ *tulkas_divine_aim();
+bool_ *tulkas_divine_aim(int);
char *tulkas_divine_aim_info();
-bool_ *tulkas_wave_of_power();
+bool_ *tulkas_wave_of_power(int);
char *tulkas_wave_of_power_info();
-bool_ *tulkas_whirlwind();
+bool_ *tulkas_whirlwind(int);
char *tulkas_whirlwind_info();
extern s32b DRAIN;
@@ -1681,13 +1681,13 @@ extern s32b FLAMEOFUDUN;
int udun_in_book(s32b sval, s32b pval);
int levels_in_book(s32b sval, s32b pval);
-bool_ *udun_drain();
+bool_ *udun_drain(int);
char *udun_drain_info();
-bool_ *udun_genocide();
+bool_ *udun_genocide(int);
char *udun_genocide_info();
-bool_ *udun_wraithform();
+bool_ *udun_wraithform(int);
char *udun_wraithform_info();
-bool_ *udun_flame_of_udun();
+bool_ *udun_flame_of_udun(int);
char *udun_flame_of_udun_info();
extern s32b TIDALWAVE;
@@ -1696,15 +1696,15 @@ extern s32b ENTPOTION;
extern s32b VAPOR;
extern s32b GEYSER;
-bool_ *water_tidal_wave();
+bool_ *water_tidal_wave(int);
char *water_tidal_wave_info();
-bool_ *water_ice_storm();
+bool_ *water_ice_storm(int);
char *water_ice_storm_info();
-bool_ *water_ent_potion();
+bool_ *water_ent_potion(int);
char *water_ent_potion_info();
-bool_ *water_vapor();
+bool_ *water_vapor(int);
char *water_vapor_info();
-bool_ *water_geyser();
+bool_ *water_geyser(int);
char *water_geyser_info();
extern s32b YAVANNA_CHARM_ANIMAL;
@@ -1713,15 +1713,15 @@ extern s32b YAVANNA_TREE_ROOTS;
extern s32b YAVANNA_WATER_BITE;
extern s32b YAVANNA_UPROOT;
-bool_ *yavanna_charm_animal();
+bool_ *yavanna_charm_animal(int);
char *yavanna_charm_animal_info();
-bool_ *yavanna_grow_grass();
+bool_ *yavanna_grow_grass(int);
char *yavanna_grow_grass_info();
-bool_ *yavanna_tree_roots();
+bool_ *yavanna_tree_roots(int);
char *yavanna_tree_roots_info();
-bool_ *yavanna_water_bite();
+bool_ *yavanna_water_bite(int);
char *yavanna_water_bite_info();
-bool_ *yavanna_uproot();
+bool_ *yavanna_uproot(int);
char *yavanna_uproot_info();
extern s32b GROWTREE;
@@ -1731,17 +1731,17 @@ extern s32b REGENERATION;
extern s32b SUMMONANNIMAL;
extern s32b GROW_ATHELAS;
-bool_ *nature_grow_trees();
+bool_ *nature_grow_trees(int);
char *nature_grow_trees_info();
-bool_ *nature_healing();
+bool_ *nature_healing(int);
char *nature_healing_info();
-bool_ *nature_recovery();
+bool_ *nature_recovery(int);
char *nature_recovery_info();
-bool_ *nature_regeneration();
+bool_ *nature_regeneration(int);
char *nature_regeneration_info();
-bool_ *nature_summon_animal();
+bool_ *nature_summon_animal(int);
char *nature_summon_animal_info();
-bool_ *nature_grow_athelas();
+bool_ *nature_grow_athelas(int);
char *nature_grow_athelas_info();
extern s32b DEVICE_HEAL_MONSTER;
@@ -1759,33 +1759,33 @@ extern s32b DEVICE_THUNDERLORDS;
extern s32b DEVICE_RADAGAST;
extern s32b DEVICE_VALAROMA;
-bool_ *device_heal_monster();
+bool_ *device_heal_monster(int);
char *device_heal_monster_info();
-bool_ *device_haste_monster();
+bool_ *device_haste_monster(int);
char *device_haste_monster_info();
-bool_ *device_wish();
+bool_ *device_wish(int);
char *device_wish_info();
-bool_ *device_summon_monster();
+bool_ *device_summon_monster(int);
char *device_summon_monster_info();
-bool_ *device_mana();
+bool_ *device_mana(int);
char *device_mana_info();
-bool_ *device_nothing();
+bool_ *device_nothing(int);
char *device_nothing_info();
-bool_ *device_lebohaum();
+bool_ *device_lebohaum(int);
char *device_lebohaum_info();
-bool_ *device_maggot();
+bool_ *device_maggot(int);
char *device_maggot_info();
-bool_ *device_holy_fire();
+bool_ *device_holy_fire(int);
char *device_holy_fire_info();
-bool_ *device_eternal_flame();
+bool_ *device_eternal_flame(int);
char *device_eternal_flame_info();
-bool_ *device_durandil();
+bool_ *device_durandil(int);
char *device_durandil_info();
-bool_ *device_thunderlords();
+bool_ *device_thunderlords(int);
char *device_thunderlords_info();
-bool_ *device_radagast();
+bool_ *device_radagast(int);
char *device_radagast_info();
-bool_ *device_valaroma();
+bool_ *device_valaroma(int);
char *device_valaroma_info();
extern s32b MUSIC_STOP;
@@ -1802,51 +1802,51 @@ extern s32b MUSIC_WIND;
extern s32b MUSIC_YLMIR;
extern s32b MUSIC_AMBARKANTA;
-bool_ *music_stop_singing_spell();
+bool_ *music_stop_singing_spell(int);
char *music_stop_singing_info();
int music_holding_pattern_lasting();
-bool_ *music_holding_pattern_spell();
+bool_ *music_holding_pattern_spell(int);
char *music_holding_pattern_info();
int music_illusion_pattern_lasting();
-bool_ *music_illusion_pattern_spell();
+bool_ *music_illusion_pattern_spell(int);
char *music_illusion_pattern_info();
int music_stun_pattern_lasting();
-bool_ *music_stun_pattern_spell();
+bool_ *music_stun_pattern_spell(int);
char *music_stun_pattern_info();
int music_song_of_the_sun_lasting();
-bool_ *music_song_of_the_sun_spell();
+bool_ *music_song_of_the_sun_spell(int);
char *music_song_of_the_sun_info();
int music_flow_of_life_lasting();
-bool_ *music_flow_of_life_spell();
+bool_ *music_flow_of_life_spell(int);
char *music_flow_of_life_info();
int music_heroic_ballad_lasting();
-bool_ *music_heroic_ballad_spell();
+bool_ *music_heroic_ballad_spell(int);
char *music_heroic_ballad_info();
int music_hobbit_melodies_lasting();
-bool_ *music_hobbit_melodies_spell();
+bool_ *music_hobbit_melodies_spell(int);
char *music_hobbit_melodies_info();
int music_clairaudience_lasting();
-bool_ *music_clairaudience_spell();
+bool_ *music_clairaudience_spell(int);
char *music_clairaudience_info();
-bool_ *music_blow_spell();
+bool_ *music_blow_spell(int);
char *music_blow_info();
-bool_ *music_gush_of_wind_spell();
+bool_ *music_gush_of_wind_spell(int);
char *music_gush_of_wind_info();
-bool_ *music_horns_of_ylmir_spell();
+bool_ *music_horns_of_ylmir_spell(int);
char *music_horns_of_ylmir_info();
-bool_ *music_ambarkanta_spell();
+bool_ *music_ambarkanta_spell(int);
char *music_ambarkanta_info();
extern s32b AULE_FIREBRAND;
@@ -1854,13 +1854,13 @@ extern s32b AULE_ENCHANT_WEAPON;
extern s32b AULE_ENCHANT_ARMOUR;
extern s32b AULE_CHILD;
-bool_ *aule_firebrand_spell();
+bool_ *aule_firebrand_spell(int);
char *aule_firebrand_info();
-bool_ *aule_enchant_weapon_spell();
+bool_ *aule_enchant_weapon_spell(int);
char *aule_enchant_weapon_info();
-bool_ *aule_enchant_armour_spell();
+bool_ *aule_enchant_armour_spell(int);
char *aule_enchant_armour_info();
-bool_ *aule_child_spell();
+bool_ *aule_child_spell(int);
char *aule_child_info();
extern s32b MANDOS_TEARS_LUTHIEN;
@@ -1868,13 +1868,13 @@ extern s32b MANDOS_SPIRIT_FEANTURI;
extern s32b MANDOS_TALE_DOOM;
extern s32b MANDOS_CALL_HALLS;
-bool_ *mandos_tears_of_luthien_spell();
+bool_ *mandos_tears_of_luthien_spell(int);
char *mandos_tears_of_luthien_info();
-bool_ *mandos_spirit_of_the_feanturi_spell();
+bool_ *mandos_spirit_of_the_feanturi_spell(int);
char *mandos_spirit_of_the_feanturi_info();
-bool_ *mandos_tale_of_doom_spell();
+bool_ *mandos_tale_of_doom_spell(int);
char *mandos_tale_of_doom_info();
-bool_ *mandos_call_to_the_halls_spell();
+bool_ *mandos_call_to_the_halls_spell(int);
char *mandos_call_to_the_halls_info();
extern s32b ULMO_BELEGAER;
@@ -1882,13 +1882,13 @@ extern s32b ULMO_DRAUGHT_ULMONAN;
extern s32b ULMO_CALL_ULUMURI;
extern s32b ULMO_WRATH;
-bool_ *ulmo_song_of_belegaer_spell();
+bool_ *ulmo_song_of_belegaer_spell(int);
char *ulmo_song_of_belegaer_info();
-bool_ *ulmo_draught_of_ulmonan_spell();
+bool_ *ulmo_draught_of_ulmonan_spell(int);
char *ulmo_draught_of_ulmonan_info();
-bool_ *ulmo_call_of_the_ulumuri_spell();
+bool_ *ulmo_call_of_the_ulumuri_spell(int);
char *ulmo_call_of_the_ulumuri_info();
-bool_ *ulmo_wrath_of_ulmo_spell();
+bool_ *ulmo_wrath_of_ulmo_spell(int);
char *ulmo_wrath_of_ulmo_info();
extern s32b VARDA_LIGHT_VALINOR;
@@ -1896,13 +1896,13 @@ extern s32b VARDA_CALL_ALMAREN;
extern s32b VARDA_EVENSTAR;
extern s32b VARDA_STARKINDLER;
-bool_ *varda_light_of_valinor_spell();
+bool_ *varda_light_of_valinor_spell(int);
char *varda_light_of_valinor_info();
-bool_ *varda_call_of_almaren_spell();
+bool_ *varda_call_of_almaren_spell(int);
char *varda_call_of_almaren_info();
-bool_ *varda_evenstar_spell();
+bool_ *varda_evenstar_spell(int);
char *varda_evenstar_info();
-bool_ *varda_star_kindler_spell();
+bool_ *varda_star_kindler_spell(int);
char *varda_star_kindler_info();
/* spells4.c */
@@ -1954,6 +1954,7 @@ 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);
void dice_init(dice_type *dice, long base, long num, long sides);
bool_ dice_parse(dice_type *dice, cptr s);
@@ -1961,6 +1962,13 @@ void dice_parse_checked(dice_type *dice, cptr s);
long dice_roll(dice_type *dice);
void dice_print(dice_type *dice, char *buf);
+/* spells5.c */
+void school_spells_init();
+spell_type *spell_at(s32b index);
+s16b get_random_spell(s16b random_type, int lev);
+bool_ check_spell_depends(s16b spell_idx);
+int spell_get_school_idx(s16b spell_idx, int i);
+
/* range.c */
extern void range_init(range_type *range, s32b min, s32b max);
@@ -2341,6 +2349,7 @@ extern void theme_intro();
/* lua_bind.c */
+extern s16b can_spell_random(s16b spell_idx);
extern magic_power *grab_magic_power(magic_power *m_ptr, int num);
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 bool_ lua_spell_success(magic_power *spell, int stat, char *oups_fct);
@@ -2363,8 +2372,6 @@ extern int get_lua_list_size(cptr list_name);
extern bool_ get_com_lua(cptr promtp, int *com);
extern s16b new_school(int i, cptr name, s16b skill);
-extern s16b new_spell(int i, cptr name);
-extern spell_type *grab_spell_type(s16b num);
extern school_type *grab_school_type(s16b num);
extern s32b lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus);
extern s32b get_level_device(s32b s, s32b max, s32b min);
diff --git a/src/init2.c b/src/init2.c
index 9e9911f8..f195c469 100644
--- a/src/init2.c
+++ b/src/init2.c
@@ -1960,10 +1960,8 @@ static errr init_misc(void)
message__tail = MESSAGE_BUF;
/* Prepare schools */
- max_spells = 0;
max_schools = 0;
schools = NULL;
- school_spells = NULL;
process_hooks(HOOK_INIT_GAME, "(s)", "begin");
@@ -2067,13 +2065,6 @@ static errr init_wilderness(void)
return 0;
}
-void init_spells(s16b new_size)
-{
- /* allocate the extra memory */
- C_MAKE(school_spells, new_size, spell_type);
- max_spells = new_size;
-}
-
void init_schools(s16b new_size)
{
/* allocate the extra memory */
diff --git a/src/lua_bind.c b/src/lua_bind.c
index 456e653d..0c099c00 100644
--- a/src/lua_bind.c
+++ b/src/lua_bind.c
@@ -17,6 +17,11 @@
#include "tolua.h"
extern lua_State *L;
+s16b can_spell_random(s16b spell_idx)
+{
+ return spell_at(spell_idx)->random_type;
+}
+
magic_power *grab_magic_power(magic_power *m_ptr, int num)
{
return (&m_ptr[num]);
@@ -171,19 +176,6 @@ s16b new_school(int i, cptr name, s16b skill)
return (i);
}
-s16b new_spell(int i, cptr name)
-{
- school_spells[i].name = string_make(name);
- school_spells[i].level = 0;
- school_spells[i].level = 0;
- return (i);
-}
-
-spell_type *grab_spell_type(s16b num)
-{
- return (&school_spells[num]);
-}
-
school_type *grab_school_type(s16b num)
{
return (&schools[num]);
@@ -245,12 +237,10 @@ s32b get_level_device(s32b s, s32b max, s32b min)
return lvl;
}
-int get_mana(s32b s) {
- return exec_lua(format("return get_mana(%d)", s));
-}
-
-static int get_spell_stat(s32b s) {
- return exec_lua(format("return get_spell_stat(%d)", s));
+int get_mana(s32b s)
+{
+ spell_type *spell = spell_at(s);
+ return get_level(s, spell->mana_range.max, spell->mana_range.min);
}
/** Returns spell chance of failure for spell */
@@ -261,9 +251,9 @@ s32b spell_chance(s32b s)
/* Extract the base spell failure rate */
if (get_level_use_stick > -1) {
- return lua_spell_device_chance(s_ptr->fail, level, s_ptr->skill_level);
+ return lua_spell_device_chance(s_ptr->failure_rate, level, s_ptr->skill_level);
} else {
- return lua_spell_chance(s_ptr->fail, level, s_ptr->skill_level, get_mana(s), get_power(s), get_spell_stat(s));
+ return lua_spell_chance(s_ptr->failure_rate, level, s_ptr->skill_level, get_mana(s), get_power(s), s_ptr->casting_stat);
}
}
@@ -582,5 +572,8 @@ void timer_aggravate_evil_callback()
cptr get_spell_info(s32b s)
{
- return string_exec_lua(format("return __spell_info[" FMTs32b "]()", 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 dac3085e..a4676744 100644
--- a/src/object1.c
+++ b/src/object1.c
@@ -2857,7 +2857,8 @@ void describe_device(object_type *o_ptr)
print_device_desc(o_ptr->pval2);
text_out("\nSpell level: ");
- text_out_c(TERM_L_BLUE, string_exec_lua(format("return tostring(get_level(%d, 50, 0))", o_ptr->pval2)));
+ 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));
diff --git a/src/object2.c b/src/object2.c
index 75fc7fa8..cf413c4c 100644
--- a/src/object2.c
+++ b/src/object2.c
@@ -2535,7 +2535,8 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
*/
void charge_stick(object_type *o_ptr)
{
- o_ptr->pval = exec_lua(format("return get_stick_charges(%d)", o_ptr->pval2));
+ spell_type *spell = spell_at(o_ptr->pval2);
+ o_ptr->pval = dice_roll(&spell->device_charges);
}
/*
@@ -3226,6 +3227,94 @@ 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)
+ */
+long get_random_stick(byte tval, int level)
+{
+ int tries;
+
+ for (tries = 0; tries < 1000; tries++)
+ {
+ long spell_idx = rand_int(school_spells_count);
+ spell_type *spell = spell_at(spell_idx);
+ device_allocation *device_allocation = get_device_allocation(spell, tval);
+
+ if ((device_allocation != NULL) &&
+ (rand_int(spell->skill_level * 3) < level) &&
+ (magik(100 - device_allocation->rarity)))
+ {
+ return spell_idx;
+ }
+ }
+
+ return -1;
+}
+
+
+/*
+ * Randomized level
+ */
+static int randomized_level_in_range(range_type *range, int level)
+{
+ s32b r = range->max - range->min;
+
+ /* The basic idea is to have a max possible level of half the dungeon level */
+ if (r * 2 > level)
+ {
+ r = level / 2;
+ }
+
+ /* Randomize a bit */
+ r = m_bonus(r, dun_level);
+
+ /* get the result */
+ return range->min + r;
+}
+
+
+/*
+ * Get a random base 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);
+ return randomized_level_in_range(&device_allocation->base_level, level);
+}
+
+/*
+ * Get a random max level
+ */
+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);
+ return randomized_level_in_range(&device_allocation->max_level, level);
+}
+
+
+/*
* Apply magic to an item known to be "boring"
*
* Hack -- note the special code for various items
@@ -3263,9 +3352,13 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
/* Only random ones */
if (magik(75))
- i = exec_lua(format("return get_random_spell(SKILL_MAGIC, %d)", level));
+ {
+ i = get_random_spell(SKILL_MAGIC, level);
+ }
else
- i = exec_lua(format("return get_random_spell(SKILL_SPIRITUALITY, %d)", level));
+ {
+ i = get_random_spell(SKILL_SPIRITUALITY, level);
+ }
/* Use globe of light(or the first one) */
if (i == -1)
@@ -3359,9 +3452,12 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
/* Decide the spell, pval == -1 means to bypass spell selection */
if (o_ptr->pval != -1)
{
- int spl = exec_lua("return get_random_stick(TV_WAND, dun_level)");
+ int spl = get_random_stick(TV_WAND, dun_level);
- if (spl == -1) spl = exec_lua("return find_spell('Manathrust')");
+ if (spl == -1)
+ {
+ spl = MANATHRUST;
+ }
o_ptr->pval2 = spl;
}
@@ -3372,8 +3468,8 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
}
/* Ok now get a base level */
- call_lua("get_stick_base_level", "(d,d,d)", "d", TV_WAND, dun_level, o_ptr->pval2, &bonus_lvl);
- call_lua("get_stick_max_level", "(d,d,d)", "d", TV_WAND, dun_level, o_ptr->pval2, &max_lvl);
+ bonus_lvl = get_stick_base_level(TV_WAND, dun_level, o_ptr->pval2);
+ max_lvl = get_stick_max_level(TV_WAND, dun_level, o_ptr->pval2);
o_ptr->pval3 = (max_lvl << 16) + (bonus_lvl & 0xFFFF);
/* Hack -- charge wands */
@@ -3387,9 +3483,12 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
/* Decide the spell, pval == -1 means to bypass spell selection */
if (o_ptr->pval != -1)
{
- int spl = exec_lua("return get_random_stick(TV_STAFF, dun_level)");
+ int spl = get_random_stick(TV_STAFF, dun_level);
- if (spl == -1) spl = exec_lua("return find_spell('Globe of Light')");
+ if (spl == -1)
+ {
+ spl = GLOBELIGHT;
+ }
o_ptr->pval2 = spl;
}
@@ -3400,8 +3499,8 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
}
/* Ok now get a base level */
- call_lua("get_stick_base_level", "(d,d,d)", "d", TV_STAFF, dun_level, o_ptr->pval2, &bonus_lvl);
- call_lua("get_stick_max_level", "(d,d,d)", "d", TV_STAFF, dun_level, o_ptr->pval2, &max_lvl);
+ bonus_lvl = get_stick_base_level(TV_STAFF, dun_level, o_ptr->pval2);
+ max_lvl = get_stick_max_level(TV_STAFF, dun_level, o_ptr->pval2);
o_ptr->pval3 = (max_lvl << 16) + (bonus_lvl & 0xFFFF);
/* Hack -- charge staffs */
@@ -3975,8 +4074,8 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
}
/* Determine a base and a max level */
- call_lua("get_stick_base_level", "(d,d,d)", "d", o_ptr->tval, dun_level, o_ptr->pval2, &base_lvl);
- call_lua("get_stick_max_level", "(d,d,d)", "d", o_ptr->tval, dun_level, o_ptr->pval2, &max_lvl);
+ base_lvl = get_stick_base_level(o_ptr->tval, dun_level, o_ptr->pval2);
+ max_lvl = get_stick_max_level(o_ptr->tval, dun_level, o_ptr->pval2);
o_ptr->pval3 = (max_lvl << 16) + (base_lvl & 0xFFFF);
/* Hack -- charge wands */
diff --git a/src/script.c b/src/script.c
index c9979c17..51484d3a 100644
--- a/src/script.c
+++ b/src/script.c
@@ -234,14 +234,6 @@ void init_lua_init()
exec_lua(format("finish_school(%d)", i));
}
- /* Finish up the spells */
- max = exec_lua("return __tmp_spells_num");
- init_spells(max);
- for (i = 0; i < max; i++)
- {
- exec_lua(format("finish_spell(%d)", i));
- }
-
/* Finish up the corruptions */
init_corruptions();
}
diff --git a/src/spells.pkg b/src/spells.pkg
index 0ea452bf..6360e7d3 100644
--- a/src/spells.pkg
+++ b/src/spells.pkg
@@ -2147,6 +2147,8 @@ extern magic_power *grab_magic_power @ get_magic_power(magic_power *m_ptr, int n
*/
extern bool lua_spell_success @ magic_power_sucess(magic_power *spell, int stat, char *oups_fct=NULL);
+extern s16b can_spell_random(s16b spell_idx);
+
/* Schools */
/** @struct school_spell_type
@@ -2166,24 +2168,6 @@ struct spell_type@school_spell_type
*/
byte skill_level;
- /** @structvar mana
- * @brief Number
- * @note Required mana at lvl 1
- */
- byte mana;
-
- /** @structvar mana_max
- * @brief Number
- * @note Required mana at max lvl
- */
- byte mana_max;
-
- /** @structvar fail
- * @brief Number
- * @note Minimum chance of failure
- */
- s16b fail;
-
/** @structvar level
* @brief Number
* @note Spell level(0 = not learnt)
@@ -2227,37 +2211,6 @@ struct school_type
*/
extern s16b new_school(int i, cptr name, s16b skill);
-/** @fn new_spell(int i, cptr name)
- * @dgonly
- * @brief Add spell to array of spells for a school.\n
- * @param i Number \n i is index of school spell array where spell is added.
- * There is no range checking.
- * @brief Index
- * @param name String \n name is the name of the spell.
- * @brief Name
- * @return Number \ The index parameter.
- * @note
- * Spell level is set to zero.\n\n
- * Note: do not call this function directly.\n
- * By order of DG.
- * @note (see file lua_bind.c)
- */
-extern s16b new_spell(int i, cptr name);
-
-/** @fn spell(s16b num);
- * @dgonly
- * @brief Get spell "num" from array of spells for a school.\n
- * @param num Number \n num is the index of the spell.
- * There is no range checking.
- * @brief Index
- * @return spell_type \n The spell.
- * @note
- * Note: do not call this function directly.\n
- * By order of DG.
- * @note (see file lua_bind.c)
- */
-extern spell_type *grab_spell_type @ spell(s16b num);
-
/** @fn school(s16b num);
* @dgonly
* @brief Get school "num" from array of schools.\n
@@ -2338,7 +2291,7 @@ extern s32b lua_spell_device_chance(s32b chance, int level, int base_level);
* If no spell is chosen, -1 is returned.
* @note (see file cmd5.c)
*/
-extern s32b get_school_spell(cptr do_what, cptr check_fct, s16b force_book);
+extern s32b get_school_spell(cptr do_what, s16b force_book);
/** @fn get_pos_player(int dis, int *ny=0, int *nx=0)
* @brief Get a grid near the player.\n
@@ -2358,528 +2311,6 @@ extern s32b get_school_spell(cptr do_what, cptr check_fct, s16b force_book);
extern void get_pos_player(int dis, int *ny=0, int *nx=0);
/**
- * Geomancy
- */
-extern void geomancy_random_floor(int y, int x, bool kill_wall);
-extern void geomancy_dig(int y, int x, int dir, int length);
-extern void channel_the_elements(int y, int x, int level);
-
-/*
- * Air
- */
-extern s32b NOXIOUSCLOUD;
-extern s32b AIRWINGS;
-extern s32b INVISIBILITY;
-extern s32b POISONBLOOD;
-extern s32b THUNDERSTORM;
-extern s32b STERILIZE;
-
-bool_ *air_noxious_cloud();
-char *air_noxious_cloud_info();
-bool_ *air_wings_of_winds();
-char *air_wings_of_winds_info();
-bool_ *air_invisibility();
-char *air_invisibility_info();
-bool_ *air_poison_blood();
-char *air_poison_blood_info();
-bool_ *air_thunderstorm();
-char *air_thunderstorm_info();
-bool_ *air_sterilize();
-char *air_sterilize_info();
-
-/*
- * Conveyance
- */
-extern s32b BLINK;
-extern s32b DISARM;
-extern s32b TELEPORT;
-extern s32b TELEAWAY;
-extern s32b RECALL;
-extern s32b PROBABILITY_TRAVEL;
-
-bool_ *convey_blink();
-char *convey_blink_info();
-bool_ *convey_disarm();
-char *convey_disarm_info();
-bool_ *convey_teleport();
-char *convey_teleport_info();
-bool_ *convey_teleport_away();
-char *convey_teleport_away_info();
-bool_ *convey_recall();
-char *convey_recall_info();
-bool_ *convey_probability_travel();
-char *convey_probability_travel_info();
-
-/*
- * Demonology
- */
-extern s32b DEMON_BLADE;
-extern s32b DEMON_MADNESS;
-extern s32b DEMON_FIELD;
-extern s32b DOOM_SHIELD;
-extern s32b UNHOLY_WORD;
-extern s32b DEMON_CLOAK;
-extern s32b DEMON_SUMMON;
-extern s32b DISCHARGE_MINION;
-extern s32b CONTROL_DEMON;
-
-bool_ *demonology_demon_blade();
-char *demonology_demon_blade_info();
-bool_ *demonology_demon_madness();
-char *demonology_demon_madness_info();
-bool_ *demonology_demon_field();
-char *demonology_demon_field_info();
-bool_ *demonology_doom_shield();
-char *demonology_doom_shield_info();
-bool_ *demonology_unholy_word();
-char *demonology_unholy_word_info();
-bool_ *demonology_demon_cloak();
-char *demonology_demon_cloak_info();
-bool_ *demonology_summon_demon();
-char *demonology_summon_demon_info();
-bool_ *demonology_discharge_minion();
-char *demonology_discharge_minion_info();
-bool_ *demonology_control_demon();
-char *demonology_control_demon_info();
-
-/*
- * Divination
- */
-extern s32b STARIDENTIFY;
-extern s32b IDENTIFY;
-extern s32b VISION;
-extern s32b SENSEHIDDEN;
-extern s32b REVEALWAYS;
-extern s32b SENSEMONSTERS;
-
-bool_ *divination_greater_identify();
-char *divination_greater_identify_info();
-bool_ *divination_identify();
-char *divination_identify_info();
-bool_ *divination_vision();
-char *divination_vision_info();
-bool_ *divination_sense_hidden();
-char *divination_sense_hidden_info();
-bool_ *divination_reveal_ways();
-char *divination_reveal_ways_info();
-bool_ *divination_sense_monsters();
-char *divination_sense_monsters_info();
-
-/*
- * Earth
- */
-extern s32b STONESKIN;
-extern s32b DIG;
-extern s32b STONEPRISON;
-extern s32b STRIKE;
-extern s32b SHAKE;
-
-bool_ *earth_stone_skin();
-char *earth_stone_skin_info();
-bool_ *earth_dig();
-char *earth_dig_info();
-bool_ *earth_stone_prison();
-char *earth_stone_prison_info();
-bool_ *earth_strike();
-char *earth_strike_info();
-bool_ *earth_shake();
-char *earth_shake_info();
-
-/*
- * Eru
- */
-extern s32b ERU_SEE;
-extern s32b ERU_LISTEN;
-extern s32b ERU_UNDERSTAND;
-extern s32b ERU_PROT;
-
-bool_ *eru_see_the_music();
-char *eru_see_the_music_info();
-bool_ *eru_listen_to_the_music();
-char *eru_listen_to_the_music_info();
-bool_ *eru_know_the_music();
-char *eru_know_the_music_info();
-bool_ *eru_lay_of_protection();
-char *eru_lay_of_protection_info();
-
-/*
- * Fire
- */
-extern s32b GLOBELIGHT;
-extern s32b FIREFLASH;
-extern s32b FIERYAURA;
-extern s32b FIREWALL;
-extern s32b FIREGOLEM;
-
-bool_ *fire_globe_of_light();
-char *fire_globe_of_light_info();
-bool_ *fire_fireflash();
-char *fire_fireflash_info();
-bool_ *fire_fiery_shield();
-char *fire_fiery_shield_info();
-bool_ *fire_firewall();
-char *fire_firewall_info();
-bool_ *fire_golem();
-char *fire_golem_info();
-
-/*
- * Geomancy
- */
-extern s32b CALL_THE_ELEMENTS;
-extern s32b CHANNEL_ELEMENTS;
-extern s32b ELEMENTAL_WAVE;
-extern s32b VAPORIZE;
-extern s32b GEOLYSIS;
-extern s32b DRIPPING_TREAD;
-extern s32b GROW_BARRIER;
-extern s32b ELEMENTAL_MINION;
-
-bool_ *geomancy_call_the_elements();
-char *geomancy_call_the_elements_info();
-bool_ *geomancy_channel_elements();
-char *geomancy_channel_elements_info();
-bool_ *geomancy_elemental_wave();
-char *geomancy_elemental_wave_info();
-bool_ *geomancy_vaporize();
-char *geomancy_vaporize_info();
-bool_ geomancy_vaporize_depends();
-bool_ *geomancy_geolysis();
-char *geomancy_geolysis_info();
-bool_ geomancy_geolysis_depends();
-bool_ *geomancy_dripping_tread();
-char *geomancy_dripping_tread_info();
-bool_ geomancy_dripping_tread_depends();
-bool_ *geomancy_grow_barrier();
-char *geomancy_grow_barrier_info();
-bool_ geomancy_grow_barrier_depends();
-bool_ *geomancy_elemental_minion();
-char *geomancy_elemental_minion_info();
-
-extern s32b MANATHRUST;
-extern s32b DELCURSES;
-extern s32b RESISTS;
-extern s32b MANASHIELD;
-
-bool_ *mana_manathrust();
-char *mana_manathrust_info();
-bool_ *mana_remove_curses();
-char *mana_remove_curses_info();
-bool_ *mana_elemental_shield();
-char *mana_elemental_shield_info();
-bool_ *mana_disruption_shield();
-char *mana_disruption_shield_info();
-
-extern s32b MANWE_SHIELD;
-extern s32b MANWE_AVATAR;
-extern s32b MANWE_BLESS;
-extern s32b MANWE_CALL;
-
-bool_ *manwe_wind_shield();
-char *manwe_wind_shield_info();
-bool_ *manwe_avatar();
-char *manwe_avatar_info();
-bool_ *manwe_blessing();
-char *manwe_blessing_info();
-bool_ *manwe_call();
-char *manwe_call_info();
-
-extern s32b MELKOR_CURSE;
-extern s32b MELKOR_CORPSE_EXPLOSION;
-extern s32b MELKOR_MIND_STEAL;
-
-bool_ *melkor_curse();
-char *melkor_curse_info();
-bool_ *melkor_corpse_explosion();
-char *melkor_corpse_explosion_info();
-bool_ *melkor_mind_steal();
-char *melkor_mind_steal_info();
-
-extern s32b RECHARGE;
-extern s32b SPELLBINDER;
-extern s32b DISPERSEMAGIC;
-extern s32b TRACKER;
-extern s32b INERTIA_CONTROL;
-
-bool_ *meta_recharge();
-char *meta_recharge_info();
-bool_ *meta_spellbinder();
-char *meta_spellbinder_info();
-bool_ *meta_disperse_magic();
-char *meta_disperse_magic_info();
-bool_ *meta_tracker();
-char *meta_tracker_info();
-bool_ *meta_inertia_control();
-char *meta_inertia_control_info();
-
-extern s32b CHARM;
-extern s32b CONFUSE;
-extern s32b ARMOROFFEAR;
-extern s32b STUN;
-
-bool_ *mind_charm();
-char *mind_charm_info();
-bool_ *mind_confuse();
-char *mind_confuse_info();
-bool_ *mind_armor_of_fear();
-char *mind_armor_of_fear_info();
-bool_ *mind_stun();
-char *mind_stun_info();
-
-extern s32b MAGELOCK;
-extern s32b SLOWMONSTER;
-extern s32b ESSENCESPEED;
-extern s32b BANISHMENT;
-
-bool_ *tempo_magelock();
-char *tempo_magelock_info();
-bool_ *tempo_slow_monster();
-char *tempo_slow_monster_info();
-bool_ *tempo_essence_of_speed();
-char *tempo_essence_of_speed_info();
-bool_ *tempo_banishment();
-char *tempo_banishment_info();
-
-extern s32b TULKAS_AIM;
-extern s32b TULKAS_WAVE;
-extern s32b TULKAS_SPIN;
-
-bool_ *tulkas_divine_aim();
-char *tulkas_divine_aim_info();
-bool_ *tulkas_wave_of_power();
-char *tulkas_wave_of_power_info();
-bool_ *tulkas_whirlwind();
-char *tulkas_whirlwind_info();
-
-extern s32b DRAIN;
-extern s32b GENOCIDE;
-extern s32b WRAITHFORM;
-extern s32b FLAMEOFUDUN;
-
-bool_ *udun_drain();
-char *udun_drain_info();
-bool_ *udun_genocide();
-char *udun_genocide_info();
-bool_ *udun_wraithform();
-char *udun_wraithform_info();
-bool_ *udun_flame_of_udun();
-char *udun_flame_of_udun_info();
-
-extern s32b TIDALWAVE;
-extern s32b ICESTORM;
-extern s32b ENTPOTION;
-extern s32b VAPOR;
-extern s32b GEYSER;
-
-bool_ *water_tidal_wave();
-char *water_tidal_wave_info();
-bool_ *water_ice_storm();
-char *water_ice_storm_info();
-bool_ *water_ent_potion();
-char *water_ent_potion_info();
-bool_ *water_vapor();
-char *water_vapor_info();
-bool_ *water_geyser();
-char *water_geyser_info();
-
-extern s32b YAVANNA_CHARM_ANIMAL;
-extern s32b YAVANNA_GROW_GRASS;
-extern s32b YAVANNA_TREE_ROOTS;
-extern s32b YAVANNA_WATER_BITE;
-extern s32b YAVANNA_UPROOT;
-
-bool_ *yavanna_charm_animal();
-char *yavanna_charm_animal_info();
-bool_ *yavanna_grow_grass();
-char *yavanna_grow_grass_info();
-bool_ *yavanna_tree_roots();
-char *yavanna_tree_roots_info();
-bool_ *yavanna_water_bite();
-char *yavanna_water_bite_info();
-bool_ *yavanna_uproot();
-char *yavanna_uproot_info();
-
-extern s32b GROWTREE;
-extern s32b HEALING;
-extern s32b RECOVERY;
-extern s32b REGENERATION;
-extern s32b SUMMONANNIMAL;
-extern s32b GROW_ATHELAS;
-
-bool_ *nature_grow_trees();
-char *nature_grow_trees_info();
-bool_ *nature_healing();
-char *nature_healing_info();
-bool_ *nature_recovery();
-char *nature_recovery_info();
-bool_ *nature_regeneration();
-char *nature_regeneration_info();
-bool_ *nature_summon_animal();
-char *nature_summon_animal_info();
-bool_ *nature_grow_athelas();
-char *nature_grow_athelas_info();
-
-extern s32b DEVICE_HEAL_MONSTER;
-extern s32b DEVICE_SPEED_MONSTER;
-extern s32b DEVICE_WISH;
-extern s32b DEVICE_SUMMON;
-extern s32b DEVICE_MANA;
-extern s32b DEVICE_NOTHING;
-extern s32b DEVICE_LEBOHAUM;
-extern s32b DEVICE_MAGGOT;
-extern s32b DEVICE_HOLY_FIRE;
-extern s32b DEVICE_ETERNAL_FLAME;
-extern s32b DEVICE_DURANDIL;
-extern s32b DEVICE_THUNDERLORDS;
-extern s32b DEVICE_RADAGAST;
-extern s32b DEVICE_VALAROMA;
-
-bool_ *device_heal_monster();
-char *device_heal_monster_info();
-bool_ *device_haste_monster();
-char *device_haste_monster_info();
-bool_ *device_wish();
-char *device_wish_info();
-bool_ *device_summon_monster();
-char *device_summon_monster_info();
-bool_ *device_mana();
-char *device_mana_info();
-bool_ *device_nothing();
-char *device_nothing_info();
-bool_ *device_lebohaum();
-char *device_lebohaum_info();
-bool_ *device_maggot();
-char *device_maggot_info();
-bool_ *device_holy_fire();
-char *device_holy_fire_info();
-bool_ *device_eternal_flame();
-char *device_eternal_flame_info();
-bool_ *device_durandil();
-char *device_durandil_info();
-bool_ *device_thunderlords();
-char *device_thunderlords_info();
-bool_ *device_radagast();
-char *device_radagast_info();
-bool_ *device_valaroma();
-char *device_valaroma_info();
-
-extern s32b MUSIC_STOP;
-extern s32b MUSIC_HOLD;
-extern s32b MUSIC_CONF;
-extern s32b MUSIC_STUN;
-extern s32b MUSIC_LITE;
-extern s32b MUSIC_HEAL;
-extern s32b MUSIC_HERO;
-extern s32b MUSIC_TIME;
-extern s32b MUSIC_MIND;
-extern s32b MUSIC_BLOW;
-extern s32b MUSIC_WIND;
-extern s32b MUSIC_YLMIR;
-extern s32b MUSIC_AMBARKANTA;
-
-bool_ *music_stop_singing_spell();
-char *music_stop_singing_info();
-
-int music_holding_pattern_lasting();
-bool_ *music_holding_pattern_spell();
-char *music_holding_pattern_info();
-
-int music_illusion_pattern_lasting();
-bool_ *music_illusion_pattern_spell();
-char *music_illusion_pattern_info();
-
-int music_stun_pattern_lasting();
-bool_ *music_stun_pattern_spell();
-char *music_stun_pattern_info();
-
-int music_song_of_the_sun_lasting();
-bool_ *music_song_of_the_sun_spell();
-char *music_song_of_the_sun_info();
-
-int music_flow_of_life_lasting();
-bool_ *music_flow_of_life_spell();
-char *music_flow_of_life_info();
-
-int music_heroic_ballad_lasting();
-bool_ *music_heroic_ballad_spell();
-char *music_heroic_ballad_info();
-
-int music_hobbit_melodies_lasting();
-bool_ *music_hobbit_melodies_spell();
-char *music_hobbit_melodies_info();
-
-int music_clairaudience_lasting();
-bool_ *music_clairaudience_spell();
-char *music_clairaudience_info();
-
-bool_ *music_blow_spell();
-char *music_blow_info();
-
-bool_ *music_gush_of_wind_spell();
-char *music_gush_of_wind_info();
-
-bool_ *music_horns_of_ylmir_spell();
-char *music_horns_of_ylmir_info();
-
-bool_ *music_ambarkanta_spell();
-char *music_ambarkanta_info();
-
-extern s32b AULE_FIREBRAND;
-extern s32b AULE_ENCHANT_WEAPON;
-extern s32b AULE_ENCHANT_ARMOUR;
-extern s32b AULE_CHILD;
-
-bool_ *aule_firebrand_spell();
-char *aule_firebrand_info();
-bool_ *aule_enchant_weapon_spell();
-char *aule_enchant_weapon_info();
-bool_ *aule_enchant_armour_spell();
-char *aule_enchant_armour_info();
-bool_ *aule_child_spell();
-char *aule_child_info();
-
-extern s32b MANDOS_TEARS_LUTHIEN;
-extern s32b MANDOS_SPIRIT_FEANTURI;
-extern s32b MANDOS_TALE_DOOM;
-extern s32b MANDOS_CALL_HALLS;
-
-bool_ *mandos_tears_of_luthien_spell();
-char *mandos_tears_of_luthien_info();
-bool_ *mandos_spirit_of_the_feanturi_spell();
-char *mandos_spirit_of_the_feanturi_info();
-bool_ *mandos_tale_of_doom_spell();
-char *mandos_tale_of_doom_info();
-bool_ *mandos_call_to_the_halls_spell();
-char *mandos_call_to_the_halls_info();
-
-extern s32b ULMO_BELEGAER;
-extern s32b ULMO_DRAUGHT_ULMONAN;
-extern s32b ULMO_CALL_ULUMURI;
-extern s32b ULMO_WRATH;
-
-bool_ *ulmo_song_of_belegaer_spell();
-char *ulmo_song_of_belegaer_info();
-bool_ *ulmo_draught_of_ulmonan_spell();
-char *ulmo_draught_of_ulmonan_info();
-bool_ *ulmo_call_of_the_ulumuri_spell();
-char *ulmo_call_of_the_ulumuri_info();
-bool_ *ulmo_wrath_of_ulmo_spell();
-char *ulmo_wrath_of_ulmo_info();
-
-extern s32b VARDA_LIGHT_VALINOR;
-extern s32b VARDA_CALL_ALMAREN;
-extern s32b VARDA_EVENSTAR;
-extern s32b VARDA_STARKINDLER;
-
-bool_ *varda_light_of_valinor_spell();
-char *varda_light_of_valinor_info();
-bool_ *varda_call_of_almaren_spell();
-char *varda_call_of_almaren_info();
-bool_ *varda_evenstar_spell();
-char *varda_evenstar_info();
-bool_ *varda_star_kindler_spell();
-char *varda_star_kindler_info();
-
-/**
* spells4.c
*/
void init_school_books();
@@ -2912,3 +2343,11 @@ extern s32b SCHOOL_YAVANNA;
void lua_cast_school_spell @ cast_school_spell(s32b spell_idx, bool no_cost = FALSE);
void spell_description_add_line(s32b spell_idx, cptr line);
+
+/**
+ * spells5.c
+ */
+void school_spells_init();
+s16b get_random_spell(s16b random_type, int lev);
+bool check_spell_depends(s16b spell_idx);
+int spell_get_school_idx(s16b spell_idx, int i);
diff --git a/src/spells3.c b/src/spells3.c
index b8632bf9..07a2527b 100644
--- a/src/spells3.c
+++ b/src/spells3.c
@@ -179,7 +179,7 @@ s32b get_level_s(int sp, int max)
return get_level(sp, max, 1);
}
-bool_ *air_noxious_cloud()
+bool_ *air_noxious_cloud(int item)
{
int dir, type;
@@ -211,7 +211,7 @@ char *air_noxious_cloud_info()
return buf;
}
-bool_ *air_wings_of_winds()
+bool_ *air_wings_of_winds(int item)
{
if (get_level_s(AIRWINGS, 50) >= 16)
{
@@ -237,7 +237,7 @@ char *air_wings_of_winds_info()
return buf;
}
-bool_ *air_invisibility()
+bool_ *air_invisibility(int item)
{
if (p_ptr->tim_invisible == 0)
{
@@ -257,7 +257,7 @@ char *air_invisibility_info()
return buf;
}
-bool_ *air_poison_blood()
+bool_ *air_poison_blood(int item)
{
bool_ *cast = NO_CAST;
@@ -286,7 +286,7 @@ char *air_poison_blood_info()
return buf;
}
-bool_ *air_thunderstorm()
+bool_ *air_thunderstorm(int item)
{
if (p_ptr->tim_thunder == 0)
{
@@ -308,7 +308,7 @@ char *air_thunderstorm_info()
return buf;
}
-bool_ *air_sterilize()
+bool_ *air_sterilize(int item)
{
set_no_breeders((30) + 20 + get_level_s(STERILIZE, 70));
return CAST;
@@ -323,7 +323,7 @@ char *air_sterilize_info()
return buf;
}
-bool_ *convey_blink()
+bool_ *convey_blink(int item)
{
if (get_level_s(BLINK, 50) >= 30)
{
@@ -350,7 +350,7 @@ char *convey_blink_info()
return buf;
}
-bool_ *convey_disarm()
+bool_ *convey_disarm(int item)
{
destroy_doors_touch();
if (get_level_s(DISARM, 50) >= 10)
@@ -366,7 +366,7 @@ char *convey_disarm_info()
return "";
}
-bool_ *convey_teleport()
+bool_ *convey_teleport(int item)
{
p_ptr->energy -= (25 - get_level_s(TELEPORT, 50));
teleport_player(100 + get_level_s(TELEPORT, 100));
@@ -382,7 +382,7 @@ char *convey_teleport_info()
return buf;
}
-bool_ *convey_teleport_away()
+bool_ *convey_teleport_away(int item)
{
if (get_level_s(TELEAWAY, 50) >= 20)
{
@@ -437,7 +437,7 @@ static int recall_get_f()
return f;
}
-bool_ *convey_recall()
+bool_ *convey_recall(int item)
{
int x,y;
cave_type *c_ptr;
@@ -493,7 +493,7 @@ char *convey_recall_info()
return buf;
}
-bool_ *convey_probability_travel()
+bool_ *convey_probability_travel(int item)
{
set_prob_travel(randint(20) + get_level_s(PROBABILITY_TRAVEL, 60));
return CAST;
@@ -508,7 +508,7 @@ char *convey_probability_travel_info()
return buf;
}
-bool_ *demonology_demon_blade()
+bool_ *demonology_demon_blade(int item)
{
int rad, type;
@@ -542,7 +542,7 @@ char *demonology_demon_blade_info()
return buf;
}
-bool_ *demonology_demon_madness()
+bool_ *demonology_demon_madness(int item)
{
int dir, type, y1, x1, y2, x2;
@@ -590,7 +590,7 @@ char *demonology_demon_madness_info()
return buf;
}
-bool_ *demonology_demon_field()
+bool_ *demonology_demon_field(int item)
{
int dir;
@@ -617,7 +617,7 @@ char *demonology_demon_field_info()
return buf;
}
-bool_ *demonology_doom_shield()
+bool_ *demonology_doom_shield(int item)
{
set_shield(randint(10) + 20 + get_level_s(DOOM_SHIELD, 100),
-300 + get_level_s(DOOM_SHIELD, 100),
@@ -638,7 +638,7 @@ char *demonology_doom_shield_info()
return buf;
}
-bool_ *demonology_unholy_word()
+bool_ *demonology_unholy_word(int item)
{
int x, y;
cave_type *c_ptr = NULL;
@@ -704,7 +704,7 @@ char *demonology_unholy_word_info()
return buf;
}
-bool_ *demonology_demon_cloak()
+bool_ *demonology_demon_cloak(int item)
{
set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15, 0));
return CAST;
@@ -719,7 +719,7 @@ char *demonology_demon_cloak_info()
return buf;
}
-bool_ *demonology_summon_demon()
+bool_ *demonology_summon_demon(int item)
{
int type, level, minlevel;
@@ -756,7 +756,7 @@ char *demonology_summon_demon_info()
return buf;
}
-bool_ *demonology_discharge_minion()
+bool_ *demonology_discharge_minion(int item)
{
cave_type *c_ptr;
int x, y;
@@ -809,7 +809,7 @@ char *demonology_discharge_minion_info()
return buf;
}
-bool_ *demonology_control_demon()
+bool_ *demonology_control_demon(int item)
{
int dir;
if (!get_aim_dir(&dir))
@@ -830,7 +830,7 @@ char *demonology_control_demon_info()
return buf;
}
-bool_ *divination_greater_identify()
+bool_ *divination_greater_identify(int item)
{
if (get_check("Cast on yourself?"))
{
@@ -848,7 +848,7 @@ char *divination_greater_identify_info()
return "";
}
-bool_ *divination_identify()
+bool_ *divination_identify(int item)
{
if (get_level_s(IDENTIFY, 50) >= 27)
{
@@ -889,7 +889,7 @@ char *divination_identify_info()
}
}
-bool_ *divination_vision()
+bool_ *divination_vision(int item)
{
if (get_level_s(VISION, 50) >= 25)
{
@@ -908,7 +908,7 @@ char *divination_vision_info()
return "";
}
-bool_ *divination_sense_hidden()
+bool_ *divination_sense_hidden(int item)
{
detect_traps(15 + get_level(SENSEHIDDEN, 40, 0));
if (get_level_s(SENSEHIDDEN, 50) >= 15)
@@ -939,7 +939,7 @@ char *divination_sense_hidden_info()
return buf;
}
-bool_ *divination_reveal_ways()
+bool_ *divination_reveal_ways(int item)
{
detect_doors(10 + get_level(REVEALWAYS, 40, 0));
detect_stairs(10 + get_level(REVEALWAYS, 40, 0));
@@ -955,7 +955,7 @@ char *divination_reveal_ways_info()
return buf;
}
-bool_ *divination_sense_monsters()
+bool_ *divination_sense_monsters(int item)
{
detect_monsters_normal(10 + get_level(SENSEMONSTERS, 40, 0));
if (get_level_s(SENSEMONSTERS, 50) >= 30)
@@ -986,7 +986,7 @@ char *divination_sense_monsters_info()
return buf;
}
-bool_ *earth_stone_skin()
+bool_ *earth_stone_skin(int item)
{
int type;
@@ -1028,7 +1028,7 @@ char *earth_stone_skin_info()
return buf;
}
-bool_ *earth_dig()
+bool_ *earth_dig(int item)
{
int dir;
if (!get_aim_dir(&dir))
@@ -1045,7 +1045,7 @@ char *earth_dig_info()
return "";
}
-bool_ *earth_stone_prison()
+bool_ *earth_stone_prison(int item)
{
int x,y;
@@ -1071,7 +1071,7 @@ char *earth_stone_prison_info()
return "";
}
-bool_ *earth_strike()
+bool_ *earth_strike(int item)
{
int dir, dmg;
@@ -1110,7 +1110,7 @@ char *earth_strike_info()
return buf;
}
-bool_ *earth_shake()
+bool_ *earth_shake(int item)
{
int x,y;
@@ -1137,7 +1137,7 @@ char *earth_shake_info()
return buf;
}
-bool_ *eru_see_the_music()
+bool_ *eru_see_the_music(int item)
{
set_tim_invis(randint(20) + 10 + get_level_s(ERU_SEE, 100));
@@ -1167,7 +1167,7 @@ char *eru_see_the_music_info()
return buf;
}
-bool_ *eru_listen_to_the_music()
+bool_ *eru_listen_to_the_music(int item)
{
if (get_level_s(ERU_LISTEN, 50) >= 30)
{
@@ -1190,7 +1190,7 @@ char *eru_listen_to_the_music_info()
return "";
}
-bool_ *eru_know_the_music()
+bool_ *eru_know_the_music(int item)
{
if (get_level_s(ERU_UNDERSTAND, 50) >= 10)
{
@@ -1208,7 +1208,7 @@ char *eru_know_the_music_info()
return "";
}
-bool_ *eru_lay_of_protection()
+bool_ *eru_lay_of_protection(int item)
{
fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2, 0));
return CAST;
@@ -1223,7 +1223,7 @@ char *eru_lay_of_protection_info()
return buf;
}
-bool_ *fire_globe_of_light()
+bool_ *fire_globe_of_light(int item)
{
if (get_level_s(GLOBELIGHT, 50) >= 3)
{
@@ -1263,7 +1263,7 @@ char *fire_globe_of_light_info()
return buf;
}
-bool_ *fire_fireflash()
+bool_ *fire_fireflash(int item)
{
int dir;
int type = GF_FIRE;
@@ -1294,7 +1294,7 @@ char *fire_fireflash_info()
return buf;
}
-bool_ *fire_fiery_shield()
+bool_ *fire_fiery_shield(int item)
{
int type = SHIELD_FIRE;
if (get_level_s(FIERYAURA, 50) >= 8)
@@ -1321,7 +1321,7 @@ char *fire_fiery_shield_info()
return buf;
}
-bool_ *fire_firewall()
+bool_ *fire_firewall(int item)
{
int dir;
int type = GF_FIRE;
@@ -1358,7 +1358,7 @@ bool_ item_tester_hook_fire_golem(object_type *o_ptr)
(o_ptr->sval == SV_LITE_LANTERN)));
}
-bool_ *fire_golem()
+bool_ *fire_golem(int ignored)
{
int item, x, y, m_idx;
@@ -1407,7 +1407,7 @@ char *fire_golem_info()
return buf;
}
-bool_ *geomancy_call_the_elements()
+bool_ *geomancy_call_the_elements(int item)
{
int dir = 0;
@@ -1436,7 +1436,7 @@ char *geomancy_call_the_elements_info()
return buf;
}
-bool_ *geomancy_channel_elements()
+bool_ *geomancy_channel_elements(int item)
{
channel_the_elements(p_ptr->py, p_ptr->px, get_level_s(CHANNEL_ELEMENTS, 50));
return CAST;
@@ -1469,7 +1469,7 @@ static eff_type *geomancy_find_effect(eff_type effs[], int feat)
return NULL;
}
-bool_ *geomancy_elemental_wave()
+bool_ *geomancy_elemental_wave(int item)
{
int dir = 0, y = 0, x = 0;
eff_type *eff_ptr = NULL;
@@ -1538,7 +1538,7 @@ char *geomancy_elemental_wave_info()
return "";
}
-bool_ *geomancy_vaporize()
+bool_ *geomancy_vaporize(int item)
{
eff_type *eff_ptr = NULL;
eff_type t[] = {
@@ -1599,7 +1599,7 @@ bool_ geomancy_vaporize_depends()
return get_skill(SKILL_AIR) >= 4;
}
-bool_ *geomancy_geolysis()
+bool_ *geomancy_geolysis(int item)
{
int dir = 0;
@@ -1628,7 +1628,7 @@ bool_ geomancy_geolysis_depends()
return get_skill(SKILL_EARTH) >= 7;
}
-bool_ *geomancy_dripping_tread()
+bool_ *geomancy_dripping_tread(int item)
{
if (p_ptr->dripping_tread == 0)
{
@@ -1658,7 +1658,7 @@ bool_ geomancy_dripping_tread_depends()
return get_skill(SKILL_WATER) >= 10;
}
-bool_ *geomancy_grow_barrier()
+bool_ *geomancy_grow_barrier(int item)
{
int dir = 0;
@@ -1714,7 +1714,7 @@ int geomancy_count_elements(cptr *elements)
return i;
}
-bool_ *geomancy_elemental_minion()
+bool_ *geomancy_elemental_minion(int item)
{
int dir = 0;
int x = 0, y = 0;
@@ -1824,7 +1824,7 @@ static void get_manathrust_dam(s16b *num, s16b *sides)
*sides = 1 + get_level_s(MANATHRUST, 20);
}
-bool_ *mana_manathrust()
+bool_ *mana_manathrust(int item)
{
int dir;
s16b num = 0;
@@ -1854,7 +1854,7 @@ char *mana_manathrust_info()
return buf;
}
-bool_ *mana_remove_curses()
+bool_ *mana_remove_curses(int item)
{
bool_ done = FALSE;
@@ -1880,7 +1880,7 @@ char *mana_remove_curses_info()
return "";
}
-bool_ *mana_elemental_shield()
+bool_ *mana_elemental_shield(int item)
{
bool_ *res = NO_CAST;
@@ -1920,7 +1920,7 @@ char *mana_elemental_shield_info()
return buf;
}
-bool_ *mana_disruption_shield()
+bool_ *mana_disruption_shield(int item)
{
if (get_level_s(MANASHIELD, 50) >= 5)
{
@@ -1948,7 +1948,7 @@ char *mana_disruption_shield_info()
return buf;
}
-bool_ *manwe_wind_shield()
+bool_ *manwe_wind_shield(int item)
{
s32b dur = get_level_s(MANWE_SHIELD, 50) + 10 + randint(20);
@@ -1998,7 +1998,7 @@ char *manwe_wind_shield_info()
return buf;
}
-bool_ *manwe_avatar()
+bool_ *manwe_avatar(int item)
{
s16b mimic_idx = resolve_mimic_name("Maia");
assert(mimic_idx >= 0);
@@ -2018,7 +2018,7 @@ char *manwe_avatar_info()
return buf;
}
-bool_ *manwe_blessing()
+bool_ *manwe_blessing(int item)
{
s32b dur = get_level_s(MANWE_BLESS, 70) + 30 + randint(40);
@@ -2051,7 +2051,7 @@ char *manwe_blessing_info()
return buf;
}
-bool_ *manwe_call()
+bool_ *manwe_call(int item)
{
int y = 0, x = 0, m_idx = -1, r_idx = -1;
@@ -2170,7 +2170,7 @@ void do_melkor_curse(int m_idx)
m_ptr->csleep = 0;
}
-bool_ *melkor_curse()
+bool_ *melkor_curse(int item)
{
int dir = 0;
@@ -2196,7 +2196,7 @@ char *melkor_curse_info()
return "";
}
-bool_ *melkor_corpse_explosion()
+bool_ *melkor_corpse_explosion(int item)
{
fire_ball(GF_CORPSE_EXPL,
0,
@@ -2214,7 +2214,7 @@ char *melkor_corpse_explosion_info()
return buf;
}
-bool_ *melkor_mind_steal()
+bool_ *melkor_mind_steal(int item)
{
int dir = 0;
@@ -2264,7 +2264,7 @@ char *melkor_mind_steal_info()
return buf;
}
-bool_ *meta_recharge()
+bool_ *meta_recharge(int item)
{
recharge(60 + get_level_s(RECHARGE, 140));
return CAST;
@@ -2289,7 +2289,7 @@ static int get_spellbinder_max()
return i;
}
-bool_ *meta_spellbinder()
+bool_ *meta_spellbinder(int item)
{
if (p_ptr->spellbinder_num != 0)
{
@@ -2358,7 +2358,7 @@ bool_ *meta_spellbinder()
i = p_ptr->spellbinder_num;
while (i > 0)
{
- s32b s = get_school_spell("bind", "is_ok_spell", 0);
+ s32b s = get_school_spell("bind", 0);
if (s == -1)
{
p_ptr->spellbinder_trigger = 0;
@@ -2392,7 +2392,7 @@ char *meta_spellbinder_info()
return buf;
}
-bool_ *meta_disperse_magic()
+bool_ *meta_disperse_magic(int item)
{
set_blind(0);
set_lite(0);
@@ -2431,7 +2431,7 @@ char *meta_disperse_magic_info()
return "";
}
-bool_ *meta_tracker()
+bool_ *meta_tracker(int item)
{
if ((last_teleportation_y < 0) ||
(last_teleportation_x < 0))
@@ -2464,21 +2464,10 @@ void meta_inertia_control_hook_birth_objects()
stop_inertia_controlled_spell();
}
-static bool_ lua_var_is_nil(cptr var)
-{
- char buf[128];
- sprintf(buf, "return (%s == nil)", var);
- return exec_lua(buf);
-}
-
-bool_ *meta_inertia_control()
+bool_ *meta_inertia_control(int item)
{
s32b s;
- char prefix[128];
- char inertia_0_var[128];
- char inertia_1_var[128];
- int inertia_0;
- int inertia_1;
+ spell_type *spell;
if (p_ptr->inertia_controlled_spell != -1)
{
@@ -2487,37 +2476,33 @@ bool_ *meta_inertia_control()
return NO_CAST;
}
- s = get_school_spell("control", "is_ok_spell", 0);
+ s = get_school_spell("control", 0);
if (s == -1)
{
stop_inertia_controlled_spell();
return NO_CAST;
}
- sprintf(prefix, "__tmp_spells[" FMTs32b "].inertia", s);
- sprintf(inertia_0_var, "__tmp_spells[" FMTs32b "].inertia[1]", s);
- sprintf(inertia_1_var, "__tmp_spells[" FMTs32b "].inertia[2]", s);
+ spell = spell_at(s);
- if (lua_var_is_nil(prefix))
+ if ((spell->inertia_difficulty < 0) ||
+ (spell->inertia_delay < 0))
{
msg_print("This spell inertia flow can not be controlled.");
stop_inertia_controlled_spell();
return NO_CAST;
}
- inertia_0 = get_lua_int(inertia_0_var);
- if (inertia_0 > get_level_s(INERTIA_CONTROL, 10))
+ if (spell->inertia_difficulty > get_level_s(INERTIA_CONTROL, 10))
{
- msg_format("This spell inertia flow(%d) is too strong to be controlled by your current spell.", inertia_0);
+ msg_format("This spell inertia flow(%d) is too strong to be controlled by your current spell.", spell->inertia_difficulty);
stop_inertia_controlled_spell();
return NO_CAST;
}
- inertia_1 = get_lua_int(inertia_1_var);
-
p_ptr->inertia_controlled_spell = s;
TIMER_INERTIA_CONTROL->enabled = TRUE;
- TIMER_INERTIA_CONTROL->delay = inertia_1;
+ TIMER_INERTIA_CONTROL->delay = spell->inertia_delay;
TIMER_INERTIA_CONTROL->countdown = TIMER_INERTIA_CONTROL->delay;
p_ptr->update |= PU_MANA;
msg_format("Inertia flow controlling spell %s.", school_spells[s].name);
@@ -2568,7 +2553,7 @@ static int mind_charm_power()
return 10 + get_level_s(CHARM, 150);
}
-bool_ *mind_charm()
+bool_ *mind_charm(int item)
{
int pwr = mind_charm_power();
int level = get_level_s(CHARM, 50);
@@ -2612,7 +2597,7 @@ static int mind_confuse_power()
return 10 + get_level_s(CONFUSE, 150);
}
-bool_ *mind_confuse()
+bool_ *mind_confuse(int item)
{
int pwr = mind_confuse_power();
int level = get_level_s(CONFUSE, 50);
@@ -2666,7 +2651,7 @@ static int mind_armor_of_fear_power_dice()
return 5 + get_level_s(ARMOROFFEAR, 20);
}
-bool_ *mind_armor_of_fear()
+bool_ *mind_armor_of_fear(int item)
{
set_shield(randint(10) + mind_armor_of_fear_base_duration(),
10,
@@ -2692,7 +2677,7 @@ static int mind_stun_power()
return 10 + get_level_s(STUN, 150);
}
-bool_ *mind_stun()
+bool_ *mind_stun(int item)
{
int dir;
@@ -2722,7 +2707,7 @@ char *mind_stun_info()
return buf;
}
-bool_ *tempo_magelock()
+bool_ *tempo_magelock(int item)
{
if (get_level_s(MAGELOCK, 50) >= 30)
{
@@ -2773,7 +2758,7 @@ static s32b tempo_slow_monster_power()
return 40 + get_level_s(SLOWMONSTER, 160);
}
-bool_ *tempo_slow_monster()
+bool_ *tempo_slow_monster(int item)
{
int dir;
s32b pwr;
@@ -2822,7 +2807,7 @@ static s32b tempo_essence_of_speed_bonus()
return 5 + get_level_s(ESSENCESPEED, 20);
}
-bool_ *tempo_essence_of_speed()
+bool_ *tempo_essence_of_speed(int item)
{
if (p_ptr->fast == 0)
{
@@ -2847,7 +2832,7 @@ static s32b tempo_banishment_power()
return 40 + get_level_s(BANISHMENT, 160);
}
-bool_ *tempo_banishment()
+bool_ *tempo_banishment(int item)
{
s32b pwr = tempo_banishment_power();
@@ -2869,7 +2854,7 @@ char *tempo_banishment_info()
return buf;
}
-bool_ *tulkas_divine_aim()
+bool_ *tulkas_divine_aim(int item)
{
s32b dur = get_level_s(TULKAS_AIM, 50) + randint(10);
@@ -2891,7 +2876,7 @@ char *tulkas_divine_aim_info()
return buf;
}
-bool_ *tulkas_wave_of_power()
+bool_ *tulkas_wave_of_power(int item)
{
int dir;
@@ -2913,7 +2898,7 @@ char *tulkas_wave_of_power_info()
return buf;
}
-bool_ *tulkas_whirlwind()
+bool_ *tulkas_whirlwind(int item)
{
fire_ball(GF_ATTACK, 0, 1, 1);
return CAST;
@@ -2942,19 +2927,15 @@ int udun_in_book(s32b sval, s32b pval)
spell_idx != NULL;
spell_idx = sglib_spell_idx_list_it_next(&it))
{
- int j;
- int n;
- char buf[128];
-
- sprintf(buf, "__spell_school[" FMTs32b "+1]", spell_idx->i);
- n = get_lua_list_size(buf);
+ spell_type *spell = spell_at(spell_idx->i);
+ school_idx *school_idx = NULL;
+ struct sglib_school_idx_iterator sit;
- for (j = 0; j < n; j++)
+ for (school_idx = sglib_school_idx_it_init(&sit, spell->schools);
+ school_idx != NULL;
+ school_idx = sglib_school_idx_it_next(&sit))
{
- int sch;
- sprintf(buf, "__spell_school[" FMTs32b "][%d+1]", spell_idx->i, j);
- sch = get_lua_int(buf);
-
+ int sch = school_idx->i;
if ((sch == SCHOOL_UDUN) ||
(sch == SCHOOL_MELKOR))
{
@@ -2983,11 +2964,10 @@ int levels_in_book(s32b sval, s32b pval)
spell_idx != NULL;
spell_idx = sglib_spell_idx_list_it_next(&it))
{
- char buf[128];
s32b s = spell_idx->i;
+ spell_type *spell = spell_at(s);
- sprintf(buf, "__tmp_spells[" FMTs32b "].level", s);
- levels += get_lua_int(buf);
+ levels += spell->skill_level;
}
return levels;
@@ -3000,7 +2980,7 @@ static bool_ udun_object_is_drainable(object_type *o_ptr)
(o_ptr->tval == TV_STAFF));
}
-bool_ *udun_drain()
+bool_ *udun_drain(int ignored)
{
int item;
object_type *o_ptr = NULL;
@@ -3062,7 +3042,7 @@ char *udun_drain_info()
return "";
}
-bool_ *udun_genocide()
+bool_ *udun_genocide(int item)
{
if (get_level_s(GENOCIDE, 50) < 10)
{
@@ -3093,7 +3073,7 @@ static int udun_wraithform_base_duration()
return 20 + get_level_s(WRAITHFORM, 40);
}
-bool_ *udun_wraithform()
+bool_ *udun_wraithform(int item)
{
set_shadow(randint(30) + udun_wraithform_base_duration());
return CAST;
@@ -3113,7 +3093,7 @@ static int udun_flame_of_udun_base_duration()
return 5 + get_level_s(FLAMEOFUDUN, 30);
}
-bool_ *udun_flame_of_udun()
+bool_ *udun_flame_of_udun(int item)
{
set_mimic(randint(15) + udun_flame_of_udun_base_duration(),
resolve_mimic_name("Balrog"),
@@ -3140,7 +3120,7 @@ static int tidal_wave_duration()
return 6 + get_level_s(TIDALWAVE, 10);
}
-bool_ *water_tidal_wave()
+bool_ *water_tidal_wave(int item)
{
fire_wave(GF_WAVE,
0,
@@ -3176,7 +3156,7 @@ static int water_ice_storm_duration()
return 20 + get_level_s(ICESTORM, 70);
}
-bool_ *water_ice_storm()
+bool_ *water_ice_storm(int item)
{
int type = GF_COLD;
@@ -3211,7 +3191,7 @@ static int water_ent_potion_base_duration()
return 25 + get_level_s(ENTPOTION, 40);;
}
-bool_ *water_ent_potion()
+bool_ *water_ent_potion(int item)
{
set_food(PY_FOOD_MAX - 1);
msg_print("The Ent's Potion fills your stomach.");
@@ -3259,7 +3239,7 @@ static int water_vapor_duration()
return 5;
}
-bool_ *water_vapor()
+bool_ *water_vapor(int item)
{
fire_cloud(GF_WATER,
0,
@@ -3289,7 +3269,7 @@ static void get_geyser_damage(int *dice, int *sides)
*sides = 3 + get_level_s(GEYSER, 35);
}
-bool_ *water_geyser()
+bool_ *water_geyser(int item)
{
int dir, dice, sides;
@@ -3330,7 +3310,7 @@ static int charm_animal_radius()
return get_level_s(YAVANNA_CHARM_ANIMAL, 2);
}
-bool_ *yavanna_charm_animal()
+bool_ *yavanna_charm_animal(int item)
{
int dir;
@@ -3361,7 +3341,7 @@ static int yavanna_grow_grass_radius()
return get_level_s(YAVANNA_GROW_GRASS, 4);
}
-bool_ *yavanna_grow_grass()
+bool_ *yavanna_grow_grass(int item)
{
grow_grass(yavanna_grow_grass_radius());
return CAST;
@@ -3391,7 +3371,7 @@ static int tree_roots_damage()
return 10 + get_level_s(YAVANNA_TREE_ROOTS, 20);
}
-bool_ *yavanna_tree_roots()
+bool_ *yavanna_tree_roots(int item)
{
set_roots(tree_roots_duration(),
tree_roots_ac(),
@@ -3420,7 +3400,7 @@ static int water_bite_damage()
return 10 + get_level_s(YAVANNA_WATER_BITE, 50);
}
-bool_ *yavanna_water_bite()
+bool_ *yavanna_water_bite(int item)
{
int rad = 0;
@@ -3452,7 +3432,7 @@ static int uproot_mlevel()
return 30 + get_level_s(YAVANNA_UPROOT, 70);
}
-bool_ *yavanna_uproot()
+bool_ *yavanna_uproot(int item)
{
int dir, x, y;
cave_type *c_ptr;
@@ -3510,7 +3490,7 @@ static int nature_grow_trees_radius()
return 2 + get_level_s(GROWTREE, 7);
}
-bool_ *nature_grow_trees()
+bool_ *nature_grow_trees(int item)
{
grow_trees(nature_grow_trees_radius());
return CAST;
@@ -3535,7 +3515,7 @@ static int nature_healing_hp()
return p_ptr->mhp * nature_healing_percentage() / 100;
}
-bool_ *nature_healing()
+bool_ *nature_healing(int item)
{
hp_player(nature_healing_hp());
return CAST;
@@ -3551,7 +3531,7 @@ char *nature_healing_info()
return buf;
}
-bool_ *nature_recovery()
+bool_ *nature_recovery(int item)
{
set_poisoned(p_ptr->poisoned / 2);
if (get_level_s(RECOVERY, 50) >= 5)
@@ -3590,7 +3570,7 @@ static int regeneration_power()
return 300 + get_level_s(REGENERATION, 700);
}
-bool_ *nature_regeneration()
+bool_ *nature_regeneration(int item)
{
if (p_ptr->tim_regen == 0)
{
@@ -3616,7 +3596,7 @@ static int summon_animal_level()
return 25 + get_level_s(SUMMONANNIMAL, 50);
}
-bool_ *nature_summon_animal()
+bool_ *nature_summon_animal(int item)
{
summon_specific_level = summon_animal_level();
summon_specific_friendly(p_ptr->py,
@@ -3636,7 +3616,7 @@ char *nature_summon_animal_info()
return buf;
}
-bool_ *nature_grow_athelas()
+bool_ *nature_grow_athelas(int item)
{
if (p_ptr->black_breath)
{
@@ -3657,7 +3637,7 @@ static int device_heal_monster_hp()
return 20 + get_level_s(DEVICE_HEAL_MONSTER, 380);
}
-bool_ *device_heal_monster()
+bool_ *device_heal_monster(int item)
{
int dir;
@@ -3679,7 +3659,7 @@ char *device_heal_monster_info()
return buf;
}
-bool_ *device_haste_monster()
+bool_ *device_haste_monster(int item)
{
int dir;
@@ -3697,7 +3677,7 @@ char *device_haste_monster_info()
return "speed +10";
}
-bool_ *device_wish()
+bool_ *device_wish(int item)
{
make_wish();
return CAST;
@@ -3708,7 +3688,7 @@ char *device_wish_info()
return "";
}
-bool_ *device_summon_monster()
+bool_ *device_summon_monster(int item)
{
int i;
for (i = 0; i < 4 + get_level_s(DEVICE_SUMMON, 30); i++)
@@ -3728,7 +3708,7 @@ static int device_mana_pct()
return 20 + get_level_s(DEVICE_MANA, 50);
}
-bool_ *device_mana()
+bool_ *device_mana(int item)
{
increase_mana((p_ptr->msp * device_mana_pct()) / 100);
return CAST;
@@ -3743,7 +3723,7 @@ char *device_mana_info()
return buf;
}
-bool_ *device_nothing()
+bool_ *device_nothing(int item)
{
return CAST;
}
@@ -3753,7 +3733,7 @@ char *device_nothing_info()
return "";
}
-bool_ *device_lebohaum()
+bool_ *device_lebohaum(int item)
{
msg_print("You hear a little song in your head in some unknown tongue:");
msg_print("'Avec le casque Lebohaum y a jamais d'anicroches, je parcours les dongeons,");
@@ -3767,7 +3747,7 @@ char *device_lebohaum_info()
return "";
}
-bool_ *device_maggot()
+bool_ *device_maggot(int item)
{
int dir;
@@ -3790,7 +3770,7 @@ static int holy_fire_damage()
return 50 + get_level_s(DEVICE_HOLY_FIRE, 300);
}
-bool_ *device_holy_fire()
+bool_ *device_holy_fire(int item)
{
project_hack(GF_HOLY_FIRE, holy_fire_damage());
return CAST;
@@ -3892,7 +3872,7 @@ char *device_eternal_flame_info()
return "";
}
-bool_ *device_durandil()
+bool_ *device_durandil(int item)
{
msg_print("You hear a little song in your head in some unknown tongue:");
msg_print("'Les epees Durandils sont forgees dans les mines par des nains.");
@@ -3914,7 +3894,7 @@ char *device_durandil_info()
return "";
}
-bool_ *device_thunderlords()
+bool_ *device_thunderlords(int item)
{
switch (game_module_idx)
{
@@ -3957,7 +3937,7 @@ char *device_thunderlords_info()
return "";
}
-bool_ *device_radagast()
+bool_ *device_radagast(int item)
{
cmsg_print(TERM_GREEN, "The staff's power cleanses you completely!");
remove_all_curse();
@@ -3996,7 +3976,7 @@ char *device_radagast_info()
return "";
}
-bool_ *device_valaroma()
+bool_ *device_valaroma(int item)
{
int power = 5 * p_ptr->lev;
banish_evil(power);
@@ -4013,7 +3993,7 @@ void static start_lasting_spell(int spl)
p_ptr->music_extra = -spl;
}
-bool_ *music_stop_singing_spell()
+bool_ *music_stop_singing_spell(int item)
{
start_lasting_spell(0);
return CAST;
@@ -4035,7 +4015,7 @@ int music_holding_pattern_lasting()
return get_mana(MUSIC_HOLD);
}
-bool_ *music_holding_pattern_spell()
+bool_ *music_holding_pattern_spell(int item)
{
start_lasting_spell(MUSIC_HOLD);
return CAST;
@@ -4061,7 +4041,7 @@ int music_illusion_pattern_lasting()
return get_mana(MUSIC_CONF);
}
-bool_ *music_illusion_pattern_spell()
+bool_ *music_illusion_pattern_spell(int item)
{
start_lasting_spell(MUSIC_CONF);
return CAST;
@@ -4087,7 +4067,7 @@ int music_stun_pattern_lasting()
return get_mana(MUSIC_STUN);
}
-bool_ *music_stun_pattern_spell()
+bool_ *music_stun_pattern_spell(int item)
{
start_lasting_spell(MUSIC_STUN);
return CAST;
@@ -4108,7 +4088,7 @@ int music_song_of_the_sun_lasting()
return 1;
}
-bool_ *music_song_of_the_sun_spell()
+bool_ *music_song_of_the_sun_spell(int item)
{
start_lasting_spell(MUSIC_LITE);
return CAST;
@@ -4130,7 +4110,7 @@ int music_flow_of_life_lasting()
return get_mana(MUSIC_HEAL);
}
-bool_ *music_flow_of_life_spell()
+bool_ *music_flow_of_life_spell(int item)
{
start_lasting_spell(MUSIC_HEAL);
return CAST;
@@ -4163,7 +4143,7 @@ int music_heroic_ballad_lasting()
return get_mana(MUSIC_HERO);
}
-bool_ *music_heroic_ballad_spell()
+bool_ *music_heroic_ballad_spell(int item)
{
start_lasting_spell(MUSIC_HERO);
return CAST;
@@ -4184,7 +4164,7 @@ int music_hobbit_melodies_lasting()
return get_mana(MUSIC_TIME);
}
-bool_ *music_hobbit_melodies_spell()
+bool_ *music_hobbit_melodies_spell(int item)
{
start_lasting_spell(MUSIC_TIME);
return CAST;
@@ -4217,7 +4197,7 @@ int music_clairaudience_lasting()
return get_mana(MUSIC_MIND);
}
-bool_ *music_clairaudience_spell()
+bool_ *music_clairaudience_spell(int item)
{
start_lasting_spell(MUSIC_MIND);
return CAST;
@@ -4239,7 +4219,7 @@ char *music_clairaudience_info()
}
}
-bool_ *music_blow_spell()
+bool_ *music_blow_spell(int item)
{
fire_ball(GF_SOUND,
0,
@@ -4259,7 +4239,7 @@ char *music_blow_info()
return buf;
}
-bool_ *music_gush_of_wind_spell()
+bool_ *music_gush_of_wind_spell(int item)
{
fire_ball(GF_AWAY_ALL,
0,
@@ -4278,7 +4258,7 @@ char *music_gush_of_wind_info()
return buf;
}
-bool_ *music_horns_of_ylmir_spell()
+bool_ *music_horns_of_ylmir_spell(int item)
{
earthquake(p_ptr->py, p_ptr->px, 2 + get_level_s(SHAKE, 10));
return CAST;
@@ -4293,7 +4273,7 @@ char *music_horns_of_ylmir_info()
return buf;
}
-bool_ *music_ambarkanta_spell()
+bool_ *music_ambarkanta_spell(int item)
{
alter_reality();
return CAST;
@@ -4304,7 +4284,7 @@ char *music_ambarkanta_info()
return "";
}
-bool_ *aule_firebrand_spell()
+bool_ *aule_firebrand_spell(int item)
{
int rad = 0;
int type = GF_FIRE;
@@ -4362,7 +4342,7 @@ static bool_ aule_enchant_weapon_item_tester(object_type *o_ptr)
}
}
-bool_ *aule_enchant_weapon_spell()
+bool_ *aule_enchant_weapon_spell(int ignored)
{
s32b level = get_level_s(AULE_ENCHANT_WEAPON, 50);
s16b num_h, num_d, num_p;
@@ -4434,7 +4414,7 @@ bool_ aule_enchant_armor_item_tester(object_type *o_ptr)
}
}
-bool_ *aule_enchant_armour_spell()
+bool_ *aule_enchant_armour_spell(int ignored)
{
s32b level = get_level_s(AULE_ENCHANT_ARMOUR, 50);
s16b num_h, num_d, num_a, num_p;
@@ -4483,7 +4463,7 @@ char *aule_enchant_armour_info()
return buf;
}
-bool_ *aule_child_spell()
+bool_ *aule_child_spell(int item)
{
int y, x;
s16b m_idx;
@@ -4517,7 +4497,7 @@ static int tears_of_luthien_hp()
return 10 * get_level_s(MANDOS_TEARS_LUTHIEN, 30);
}
-bool_ *mandos_tears_of_luthien_spell()
+bool_ *mandos_tears_of_luthien_spell(int item)
{
hp_player(tears_of_luthien_hp());
set_stun(0);
@@ -4535,7 +4515,7 @@ char *mandos_tears_of_luthien_info()
return buf;
}
-bool_ *mandos_spirit_of_the_feanturi_spell()
+bool_ *mandos_spirit_of_the_feanturi_spell(int item)
{
s32b level = get_level_s(MANDOS_SPIRIT_FEANTURI, 50);
@@ -4577,7 +4557,7 @@ static int tale_of_doom_duration()
return 5 + get_level_s(MANDOS_TALE_DOOM,10);
}
-bool_ *mandos_tale_of_doom_spell()
+bool_ *mandos_tale_of_doom_spell(int item)
{
set_tim_precognition(tale_of_doom_duration());
return CAST;
@@ -4597,7 +4577,7 @@ int call_to_the_halls_mlev()
return 20 + get_level(MANDOS_CALL_HALLS, 70, 0);
}
-bool_ *mandos_call_to_the_halls_spell()
+bool_ *mandos_call_to_the_halls_spell(int item)
{
#define N_SUMMONS 2
int y, x;
@@ -4636,7 +4616,7 @@ static void get_belegaer_damage(int *dice, int *sides)
*sides = 3 + get_level_s(ULMO_BELEGAER, 35);
}
-bool_ *ulmo_song_of_belegaer_spell()
+bool_ *ulmo_song_of_belegaer_spell(int item)
{
int dir, dice, sides;
@@ -4671,7 +4651,7 @@ int draught_of_ulmonan_hp()
return 5 * get_level_s(ULMO_DRAUGHT_ULMONAN, 50);
}
-bool_ *ulmo_draught_of_ulmonan_spell()
+bool_ *ulmo_draught_of_ulmonan_spell(int item)
{
s32b level = get_level_s(ULMO_DRAUGHT_ULMONAN, 50);
@@ -4712,7 +4692,7 @@ static int call_of_the_ulumuri_mlev()
return 30 + get_level(ULMO_CALL_ULUMURI, 70, 0);
}
-bool_ *ulmo_call_of_the_ulumuri_spell()
+bool_ *ulmo_call_of_the_ulumuri_spell(int item)
{
#define N_SUMMONS 2
int x,y;
@@ -4757,7 +4737,7 @@ static int wrath_of_ulmo_duration()
return 10 + get_level_s(ULMO_WRATH, 14);
}
-bool_ *ulmo_wrath_of_ulmo_spell()
+bool_ *ulmo_wrath_of_ulmo_spell(int item)
{
int dir, type = GF_WATER;
@@ -4798,7 +4778,7 @@ static int light_of_valinor_radius()
return 5 + get_level_s(VARDA_LIGHT_VALINOR, 6);
}
-bool_ *varda_light_of_valinor_spell()
+bool_ *varda_light_of_valinor_spell(int item)
{
if (get_level_s(VARDA_LIGHT_VALINOR, 50) >= 3)
{
@@ -4837,7 +4817,7 @@ char *varda_light_of_valinor_info()
}
}
-bool_ *varda_call_of_almaren_spell()
+bool_ *varda_call_of_almaren_spell(int item)
{
int power = 5 * p_ptr->lev;
if (get_level_s(VARDA_CALL_ALMAREN, 50) >= 20)
@@ -4856,7 +4836,7 @@ char *varda_call_of_almaren_info()
return "";
}
-bool_ *varda_evenstar_spell()
+bool_ *varda_evenstar_spell(int item)
{
wiz_lite_extra();
if (get_level_s(VARDA_EVENSTAR, 50) >= 40)
@@ -4883,7 +4863,7 @@ static int star_kindler_damage()
return 20 + get_level_s(VARDA_STARKINDLER, 100);
}
-bool_ *varda_star_kindler_spell()
+bool_ *varda_star_kindler_spell(int item)
{
int dir, i, n = star_kindler_bursts();
diff --git a/src/spells4.c b/src/spells4.c
index 900121fc..8bd63bb3 100644
--- a/src/spells4.c
+++ b/src/spells4.c
@@ -72,23 +72,17 @@ void school_idx_add_new(school_idx **list, s32b i)
static bool_ uses_piety_to_cast(int s)
{
- char buf[128];
- sprintf(buf, "return check_affect(%d, \"piety\", FALSE)", s);
- return exec_lua(buf);
+ return spell_at(s)->casting_type == USE_PIETY;
}
static bool_ castable_while_blind(int s)
{
- char buf[128];
- sprintf(buf, "return not check_affect(%d, \"blind\")", s);
- return exec_lua(buf);
+ return spell_at(s)->castable_while_blind;
}
static bool_ castable_while_confused(int s)
{
- char buf[128];
- sprintf(buf, "return not check_affect(%d, \"confusion\")", s);
- return exec_lua(buf);
+ return spell_at(s)->castable_while_confused;
}
/** Describe what type of energy the spell uses for casting */
@@ -484,22 +478,45 @@ void random_book_setup(s16b sval, s32b spell_idx)
}
}
-static cptr spell_school_name(s32b s)
+static void spell_school_name(char *buf, spell_type *spell)
{
- return string_exec_lua(format("return spell_school_name(%d)", s));
+ school_idx *school_idx = NULL;
+ struct sglib_school_idx_iterator sit;
+ bool_ first = TRUE;
+
+ buf[0] = '\0';
+
+ 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;
+ school_type *school = grab_school_type(sch);
+ /* Add separator? */
+ if (!first)
+ {
+ strcat(buf, "/");
+ }
+ first = FALSE;
+
+ /* Add school name */
+ strcat(buf, school->name);
+ }
}
int print_spell(cptr label_, byte color, int y, s32b s)
{
s32b level;
bool_ na;
- cptr sch_str = spell_school_name(s);
+ spell_type *spell = spell_at(s);
+ char sch_str[128];
cptr spell_info = get_spell_info(s);
cptr label = (label_ == NULL) ? "" : label_;
char level_str[8] = "n/a";
char buf[128];
get_level_school(s, 50, -50, &level, &na);
+ spell_school_name(sch_str, spell);
if (!na)
{
@@ -539,10 +556,10 @@ int print_book(s16b sval, s32b pval, object_type *obj)
{
s32b s = spell_idx->i;
byte color = TERM_L_DARK;
- int is_ok;
+ bool_ is_ok;
char label[8];
- call_lua("is_ok_spell", "(d,O)", "d", s, obj, &is_ok);
+ is_ok = is_ok_spell(s, obj);
if (is_ok)
{
color = (get_mana(s) > get_power(s)) ? TERM_ORANGE : TERM_L_GREEN;
@@ -560,9 +577,9 @@ int print_book(s16b sval, s32b pval, object_type *obj)
static bool_ call_spell_function(s32b s)
{
- char buf[128];
- sprintf(buf, "return (__spell_spell[" FMTs32b "]() ~= nil)", s);
- return exec_lua(buf);
+ spell_type *spell = spell_at(s);
+ assert(spell->effect_func != NULL);
+ return (spell->effect_func(-1) != NULL);
}
void lua_cast_school_spell(s32b s, bool_ no_cost)
@@ -669,6 +686,13 @@ void device_allocation_init(device_allocation *device_allocation, byte tval)
device_allocation->next = NULL;
}
+device_allocation *device_allocation_new(byte tval)
+{
+ device_allocation *d = malloc(sizeof(device_allocation));
+ device_allocation_init(d, tval);
+ return d;
+}
+
int compare_device_allocation(device_allocation *a, device_allocation *b)
{
return SGLIB_NUMERIC_COMPARATOR(a->tval, b->tval);
diff --git a/src/spells5.c b/src/spells5.c
new file mode 100644
index 00000000..821d4151
--- /dev/null
+++ b/src/spells5.c
@@ -0,0 +1,2605 @@
+#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);
+
+ spell->castable_while_blind = FALSE;
+ spell->castable_while_confused = FALSE;
+}
+
+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;
+
+ *index = school_spells_count;
+ school_spells_count++;
+
+ return spell;
+}
+
+spell_type *spell_at(s32b index)
+{
+ assert(index >= 0);
+ assert(index < school_spells_count);
+
+ return &school_spells[index];
+}
+
+int find_spell(cptr name)
+{
+ int i;
+
+ for (i = 0; i < school_spells_count; i++)
+ {
+ spell_type *spell = spell_at(i);
+ if (streq(spell->name, name))
+ {
+ return i;
+ }
+ }
+
+ /* Not found */
+ return -1;
+}
+
+s16b get_random_spell(s16b random_type, int level)
+{
+ int tries;
+
+ for (tries = 0; tries < 1000; tries++)
+ {
+ 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))
+ {
+ return spl;
+ }
+ }
+
+ return -1;
+}
+
+bool_ check_spell_depends(s16b spell_idx)
+{
+ spell_type *spell = spell_at(spell_idx);
+ if (spell->depend_func != NULL) {
+ return spell->depend_func();
+ } else {
+ return TRUE;
+ }
+}
+
+int spell_get_school_idx(s16b spell_idx, int idx)
+{
+ spell_type *spell = spell_at(spell_idx);
+ school_idx *school_idx = NULL;
+ struct sglib_school_idx_iterator sit;
+
+ if (idx < 0)
+ {
+ return -1;
+ }
+
+ for (school_idx = sglib_school_idx_it_init(&sit, spell->schools);
+ school_idx != NULL && idx > 0;
+ school_idx = sglib_school_idx_it_next(&sit))
+ {
+ /* Just counting down */
+ }
+
+ if (school_idx == NULL)
+ {
+ return -1;
+ }
+ else
+ {
+ return school_idx->i;
+ }
+}
+
+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 *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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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);
+ }
+ }
+}
+
+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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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 *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);
+ }
+}
+
+void school_spells_init()
+{
+ {
+ 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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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");
+
+ {
+ 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 *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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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");
+
+ {
+ 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 *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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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 *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");
+
+ {
+ 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 *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 *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 *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");
+
+ {
+ 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 *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");
+
+ {
+ 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 *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 *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 *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 *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");
+
+ {
+ 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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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");
+
+ {
+ 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 *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 *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 *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 *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 *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 *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 *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 *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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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 *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);
+
+ dice_parse_checked(&spell->device_charges, "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);
+ }
+
+ {
+ device_allocation *device_allocation = device_allocation_new(TV_WAND);
+ 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 *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 *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");
+
+ {
+ 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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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);
+ }
+
+ /* Module-specific spells */
+ switch (game_module_idx)
+ {
+ case MODULE_TOME:
+ spells_init_tome();
+ break;
+ case MODULE_THEME:
+ spells_init_theme();
+ break;
+ default:
+ assert(FALSE);
+ }
+
+}
diff --git a/src/types.h b/src/types.h
index fbf049ae..b00ade5c 100644
--- a/src/types.h
+++ b/src/types.h
@@ -2527,11 +2527,37 @@ struct spell_type
{
cptr name; /* Name */
byte skill_level; /* Required level (to learn) */
- byte mana; /* Required mana at lvl 1 */
- byte mana_max; /* Required mana at max lvl */
- s16b fail; /* Minimum chance of failure */
s16b level; /* Spell level(0 = not learnt) */
string_list *description; /* List of strings */
+
+ bool_ *(*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_type school_type;
diff --git a/src/variable.c b/src/variable.c
index 105bbc7f..71fb5dd8 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -1498,8 +1498,8 @@ bool_ player_char_health;
/*
* The spell list of schools
*/
-s16b max_spells;
-spell_type *school_spells;
+s16b school_spells_count = 0;
+spell_type school_spells[SCHOOL_SPELLS_MAX];
s16b max_schools;
school_type *schools;