From d98a999477698bb0a304c4995df44f2b7ef5389d Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Tue, 29 May 2012 06:25:07 +0200 Subject: Lua: Convert all the spell metadata to C code (Yay automated translation!) --- src/CMakeLists.txt | 2 +- src/cmd5.c | 70 +- src/cmd6.c | 80 +- src/defines.h | 5 + src/dungeon.c | 26 +- src/externs.h | 297 +++--- src/init2.c | 9 - src/lua_bind.c | 37 +- src/object1.c | 3 +- src/object2.c | 125 ++- src/script.c | 8 - src/spells.pkg | 583 +----------- src/spells3.c | 332 ++++--- src/spells4.c | 58 +- src/spells5.c | 2605 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/types.h | 32 +- src/variable.c | 4 +- 17 files changed, 3210 insertions(+), 1066 deletions(-) create mode 100644 src/spells5.c (limited to 'src') 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]; @@ -2146,10 +2146,32 @@ bool_ get_item_hook_find_spell(int *item) return FALSE; } +/* + * 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 @@ -3649,6 +3649,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- * @@ -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 @@ -865,6 +865,11 @@ #define MAX_BETWEEN_EXITS 3 +/* + * Maximum number of school spells + */ +#define SCHOOL_SPELLS_MAX 200 + /* * Number of effects */ 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); } /* @@ -3225,6 +3226,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" * @@ -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 @@ -2357,528 +2310,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 */ @@ -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 +#include + +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(®ENERATION, "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; -- cgit v1.2.3