From 1b9ce2b53e26ed2d983efb9da10eb2be89d6d705 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Wed, 30 May 2012 05:33:44 +0200 Subject: Lua: Migrate spell schools to C --- lib/core/init.lua | 1 - lib/core/s_aux.lua | 147 ---------------- lib/mods/theme/core/init.lua | 1 - lib/mods/theme/core/s_aux.lua | 146 ---------------- lib/mods/theme/scpt/init.lua | 4 +- lib/mods/theme/scpt/spells.lua | 385 ----------------------------------------- lib/scpt/init.lua | 4 +- lib/scpt/spells.lua | 293 ------------------------------- src/CMakeLists.txt | 3 +- src/defines.h | 5 + src/externs.h | 21 ++- src/init2.c | 12 +- src/lua_bind.c | 35 +--- src/script.c | 8 - src/spells.pkg | 79 +-------- src/spells4.c | 2 +- src/spells5.c | 33 +--- src/spells6.c | 380 ++++++++++++++++++++++++++++++++++++++++ src/types.h | 25 +++ src/variable.c | 4 +- src/xtra1.c | 1 + 21 files changed, 452 insertions(+), 1137 deletions(-) delete mode 100644 lib/core/s_aux.lua delete mode 100644 lib/mods/theme/core/s_aux.lua delete mode 100644 lib/mods/theme/scpt/spells.lua delete mode 100644 lib/scpt/spells.lua create mode 100644 src/spells6.c diff --git a/lib/core/init.lua b/lib/core/init.lua index 35f820d3..23c76461 100644 --- a/lib/core/init.lua +++ b/lib/core/init.lua @@ -16,7 +16,6 @@ tome_dofile_anywhere(ANGBAND_DIR_CORE, "objects.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "monsters.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "building.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "dungeon.lua") -tome_dofile_anywhere(ANGBAND_DIR_CORE, "s_aux.lua") -- Load the ingame contextual help tome_dofile_anywhere(ANGBAND_DIR_CORE, "help.lua") diff --git a/lib/core/s_aux.lua b/lib/core/s_aux.lua deleted file mode 100644 index 860892ae..00000000 --- a/lib/core/s_aux.lua +++ /dev/null @@ -1,147 +0,0 @@ --- Functions to help with spells, do not touch - -__schools = {} -__schools_num = 0 - -function add_school(s) - __schools[__schools_num] = s - - __schools_num = __schools_num + 1 - return (__schools_num - 1) -end - -function finish_school(i) - local s - - s = __schools[i] - assert(s.name, "No school name!") - assert(s.skill, "No school skill!") - - -- Need hooks? - if s.hooks then - add_hooks(s.hooks) - end - - new_school(i, s.name, s.skill) -end - --- Creates the school books array -__spell_school = {} - --- Find if the school is under the influence of a god, returns nil or the level -function get_god_level(sch) - if __schools[sch].gods[player.pgod] then - return (s_info[__schools[sch].gods[player.pgod].skill + 1].value * __schools[sch].gods[player.pgod].mul) / __schools[sch].gods[player.pgod].div - else - return nil - end -end - --- Change this fct if I want to switch to learnable spells -function get_level_school(s, max, min) - local lvl, sch, num, bonus - local allow_spell_power = TRUE - - lvl = 0 - num = 0 - bonus = 0 - - -- No max specified ? assume 50 - if not max then - max = 50 - end - if not min then - min = 1 - end - - -- Do we pass tests? - if check_spell_depends(s) ~= TRUE then - return min, "n/a" - end - - local index = 0 - while 1 do - sch = spell_get_school_idx(s, index) - if sch == -1 then - break - end - index = index + 1 - - local r, s, p, ok = 0, 0, 0, 0 - - -- Does it require we worship a specific god? - if __schools[sch].god then - if __schools[sch].god ~= player.pgod then - if min then return min, "n/a" - else return 1, "n/a" end - end - end - - -- Take the basic skill value - r = s_info[(school(sch).skill) + 1].value - - -- Do we pass tests? - if __schools[sch].depend then - if __schools[sch].depend() ~= TRUE then - return min, "n/a" - end - end - - -- Are we under sorcery effect ? - if __schools[sch].sorcery then - s = s_info[SKILL_SORCERY + 1].value - end - - -- Are we affected by spell power ? - -- All teh schools must allow it for it to work - if not __schools[sch].spell_power then - allow_spell_power = nil - end - - -- Are we under a god effect ? - if __schools[sch].gods then - p = get_god_level(sch) - if not p then p = 0 end - end - - -- Find the higher - ok = r - if ok < s then ok = s end - if ok < p then ok = p end - - -- Do we need to add a special bonus ? - if __schools[sch].bonus_level then - bonus = bonus + (__schools[sch].bonus_level() * (SKILL_STEP / 10)) - end - - -- All schools must be non zero to be able to use it - if ok == 0 then return min, "n/a" end - - -- Apply it - lvl = lvl + ok - num = num + 1 - end - - -- Add the Spellpower skill as a bonus - if allow_spell_power then - bonus = bonus + (get_skill_scale(SKILL_SPELL, 20) * (SKILL_STEP / 10)) - end - - -- Add bonus from objects - bonus = bonus + (player.to_s * (SKILL_STEP / 10)) - - -- / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative - -- The loss of information should be negligible since 1 skill = 1000 internally - lvl = (lvl / num) / 10 - lvl = lua_get_level(s, lvl, max, min, bonus) - - return lvl, nil -end - --- The real get_level, works for schooled magic and for innate powers -function get_level(s, max, min) - if not max then max = 50 end - if not min then min = 1 end - return %get_level(s, max, min) -end - diff --git a/lib/mods/theme/core/init.lua b/lib/mods/theme/core/init.lua index 35f820d3..23c76461 100644 --- a/lib/mods/theme/core/init.lua +++ b/lib/mods/theme/core/init.lua @@ -16,7 +16,6 @@ tome_dofile_anywhere(ANGBAND_DIR_CORE, "objects.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "monsters.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "building.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "dungeon.lua") -tome_dofile_anywhere(ANGBAND_DIR_CORE, "s_aux.lua") -- Load the ingame contextual help tome_dofile_anywhere(ANGBAND_DIR_CORE, "help.lua") diff --git a/lib/mods/theme/core/s_aux.lua b/lib/mods/theme/core/s_aux.lua deleted file mode 100644 index 3e98ec94..00000000 --- a/lib/mods/theme/core/s_aux.lua +++ /dev/null @@ -1,146 +0,0 @@ --- Functions to help with spells, do not touch - -__schools = {} -__schools_num = 0 - -function add_school(s) - __schools[__schools_num] = s - - __schools_num = __schools_num + 1 - return (__schools_num - 1) -end - -function finish_school(i) - local s - - s = __schools[i] - assert(s.name, "No school name!") - assert(s.skill, "No school skill!") - - -- Need hooks? - if s.hooks then - add_hooks(s.hooks) - end - - new_school(i, s.name, s.skill) -end - --- Creates the school books array -__spell_school = {} - --- Find if the school is under the influence of a god, returns nil or the level -function get_god_level(sch) - if __schools[sch].gods[player.pgod] then - return (s_info[__schools[sch].gods[player.pgod].skill + 1].value * __schools[sch].gods[player.pgod].mul) / __schools[sch].gods[player.pgod].div - else - return nil - end -end - --- Change this fct if I want to switch to learnable spells -function get_level_school(s, max, min) - local lvl, sch, num, bonus - local allow_spell_power = TRUE - - lvl = 0 - num = 0 - bonus = 0 - - -- No max specified ? assume 50 - if not max then - max = 50 - end - if not min then - min = 1 - end - - -- Do we pass tests? - if check_spell_depends(s) ~= TRUE then - return min, "n/a" - end - - local index = 0 - while 1 do - sch = spell_get_school_idx(s, index) - if sch == -1 then - break - end - index = index + 1 - - local r, s, p, ok = 0, 0, 0, 0 - - -- Does it require we worship a specific god? - if __schools[sch].god then - if __schools[sch].god ~= player.pgod then - if min then return min, "n/a" - else return 1, "n/a" end - end - end - - -- Take the basic skill value - r = s_info[(school(sch).skill) + 1].value - - -- Do we pass tests? - if __schools[sch].depend then - if __schools[sch].depend() ~= TRUE then - return min, "n/a" - end - end - - -- Are we under sorcery effect ? - if __schools[sch].sorcery then - s = s_info[SKILL_SORCERY + 1].value - end - - -- Are we affected by spell power ? - -- All teh schools must allow it for it to work - if not __schools[sch].spell_power then - allow_spell_power = nil - end - - -- Are we under a god effect ? - if __schools[sch].gods then - p = get_god_level(sch) - if not p then p = 0 end - end - - -- Find the higher - ok = r - if ok < s then ok = s end - if ok < p then ok = p end - - -- Do we need to add a special bonus ? - if __schools[sch].bonus_level then - bonus = bonus + (__schools[sch].bonus_level() * (SKILL_STEP / 10)) - end - - -- All schools must be non zero to be able to use it - if ok == 0 then return min, "n/a" end - - -- Apply it - lvl = lvl + ok - num = num + 1 - end - - -- Add the Spellpower skill as a bonus - if allow_spell_power then - bonus = bonus + (get_skill_scale(SKILL_SPELL, 20) * (SKILL_STEP / 10)) - end - - -- Add bonus from objects - bonus = bonus + (player.to_s * (SKILL_STEP / 10)) - - -- / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative - -- The loss of information should be negligible since 1 skill = 1000 internally - lvl = (lvl / num) / 10 - lvl = lua_get_level(s, lvl, max, min, bonus) - - return lvl, nil -end - --- The real get_level, works for schooled magic and for innate powers -function get_level(s, max, min) - if not max then max = 50 end - if not min then min = 1 end - return %get_level(s, max, min) -end diff --git a/lib/mods/theme/scpt/init.lua b/lib/mods/theme/scpt/init.lua index a65db8ac..af4ba3d9 100644 --- a/lib/mods/theme/scpt/init.lua +++ b/lib/mods/theme/scpt/init.lua @@ -15,7 +15,9 @@ tome_dofile("stores.lua") tome_dofile("mkeys.lua") -- Add the schools of magic -tome_dofile("spells.lua") +schools_init() +school_spells_init() +init_school_books() -- Post-spell creation initialization initialize_bookable_spells() diff --git a/lib/mods/theme/scpt/spells.lua b/lib/mods/theme/scpt/spells.lua deleted file mode 100644 index e37d922f..00000000 --- a/lib/mods/theme/scpt/spells.lua +++ /dev/null @@ -1,385 +0,0 @@ --- --- This file takes care of the schools of magic --- - --- Create the schools -SCHOOL_MANA = add_school -{ - ["name"] = "Mana", - ["skill"] = SKILL_MANA, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Varda provides the Mana school at 1/4 the prayer skill - [GOD_VARDA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 4, - }, - -- Eru Iluvatar provides the Mana school at half the prayer skill - [GOD_ERU] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, - ["hooks"] = - { - [HOOK_CALC_MANA] = function(msp) - if get_skill(SKILL_MANA) >= 35 then - msp = msp + (msp * ((get_skill(SKILL_MANA) - 34)) / 100) - return TRUE, msp - end - end - }, -} -SCHOOL_FIRE = add_school -{ - ["name"] = "Fire", - ["skill"] = SKILL_FIRE, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Aule provides the Fire school at 3/5 the prayer skill - [GOD_AULE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 3, - ["div"] = 5, - }, - }, -} -SCHOOL_AIR = add_school -{ - ["name"] = "Air", - ["skill"] = SKILL_AIR, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Manwe Sulimo provides the Air school at 2/3 the prayer skill - [GOD_MANWE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 2, - ["div"] = 3, - }, - }, -} -SCHOOL_WATER = add_school -{ - ["name"] = "Water", - ["skill"] = SKILL_WATER, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Yavanna Kementari provides the Water school at 1/2 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - -- Ulmo provides the Water school at 3/5 the prayer skill - [GOD_ULMO] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 3, - ["div"] = 5, - }, - }, -} -SCHOOL_EARTH = add_school -{ - ["name"] = "Earth", - ["skill"] = SKILL_EARTH, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Tulkas provides the Earth school at 4/5 the prayer skill - [GOD_TULKAS] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 4, - ["div"] = 5, - }, - -- Yavanna Kementari provides the Earth school at 1/2 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - - -- Aule provides the Earth school at 1/3 the prayer skill - [GOD_AULE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - }, -} -SCHOOL_CONVEYANCE = add_school -{ - ["name"] = "Conveyance", - ["skill"] = SKILL_CONVEYANCE, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Manwe Sulimo provides the Conveyance school at 1/2 the prayer skill - [GOD_MANWE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_GEOMANCY = add_school -{ - ["name"] = "Geomancy", - ["skill"] = SKILL_GEOMANCY, - ["spell_power"] = TRUE, - -- Require to wield a Mage Staff, as the spells requries the caster to stomp the floor with it - ["depend"] = function() - -- Require at least one point in each school - if get_skill(SKILL_FIRE) == 0 then return end - if get_skill(SKILL_AIR) == 0 then return end - if get_skill(SKILL_EARTH) == 0 then return end - if get_skill(SKILL_WATER) == 0 then return end - - local obj = get_object(INVEN_WIELD) - if (obj.k_idx > 0) and (obj.tval == TV_MSTAFF) then return TRUE end - end, -} -SCHOOL_DIVINATION = add_school -{ - ["name"] = "Divination", - ["skill"] = SKILL_DIVINATION, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Eru Iluvatar provides the Divination school at 2/3 the prayer skill - [GOD_ERU] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 2, - ["div"] = 3, - }, - -- Mandos the Divination school at 1/3 the prayer skill - [GOD_MANDOS] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - }, -} -SCHOOL_TEMPORAL = add_school -{ - ["name"] = "Temporal", - ["skill"] = SKILL_TEMPORAL, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Yavanna Kementari provides the Temporal school at 1/6 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 6, - }, - -- Mandos provides the Temporal school at 1/4 the prayer skill - [GOD_MANDOS] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 4, - }, - }, -} -SCHOOL_NATURE = add_school -{ - ["name"] = "Nature", - ["skill"] = SKILL_NATURE, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Yavanna Kementari provides the Nature school at 1/2 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - -- Ulmo provides the Nature school at 1/2 the prayer skill - [GOD_ULMO] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_META = add_school -{ - ["name"] = "Meta", - ["skill"] = SKILL_META, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Manwe Sulimo provides the Meta school at 1/3 the prayer skill - [GOD_MANWE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - -- Varda provides the Meta school at 1/2 the prayer skill - [GOD_VARDA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_MIND = add_school -{ - ["name"] = "Mind", - ["skill"] = SKILL_MIND, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Eru Iluvatar provides the Mind school at 1/3 the prayer skill - [GOD_ERU] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - -- Melkor Bauglir provides the Mind school at 1/3 the prayer skill - [GOD_MELKOR] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - }, -} -SCHOOL_UDUN = add_school -{ - ["name"] = "Udun", - ["skill"] = SKILL_UDUN, - ["bonus_level"] = function() - return ((player.lev * 2) / 3) - end, -} -SCHOOL_DEMON = add_school -{ - ["name"] = "Demon", - ["skill"] = SKILL_DAEMON, - ["no_random"] = TRUE, -} - --- The God specific schools, all tied to the prayer skill -SCHOOL_ERU = add_school -{ - ["name"] = "Eru Iluvatar", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_ERU, -} -SCHOOL_MANWE = add_school -{ - ["name"] = "Manwe Sulimo", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_MANWE, -} -SCHOOL_TULKAS = add_school -{ - ["name"] = "Tulkas", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_TULKAS, -} -SCHOOL_MELKOR = add_school -{ - ["name"] = "Melkor Bauglir", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_MELKOR, -} -SCHOOL_YAVANNA = add_school -{ - ["name"] = "Yavanna Kementari", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_YAVANNA, -} - --- New schools -SCHOOL_AULE = add_school -{ - ["name"] = "Aule the Smith", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_AULE, -} -SCHOOL_VARDA = add_school -{ - ["name"] = "Varda Elentari", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_VARDA, -} - -SCHOOL_ULMO = add_school -{ - ["name"] = "Ulmo", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_ULMO, -} - -SCHOOL_MANDOS = add_school -{ - ["name"] = "Mandos", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_MANDOS, -} - --- Not a real school, rather a palcehodler for stick only spells -SCHOOL_DEVICE = add_school -{ - ["name"] = "Device", - ["skill"] = SKILL_DEVICE, -} - --- Music "spells" -SCHOOL_MUSIC = add_school -{ - ["name"] = "Music", - ["skill"] = SKILL_MUSIC, -} - --- Initialize school spells. -school_spells_init() - --- Initialize spellbooks -init_school_books() diff --git a/lib/scpt/init.lua b/lib/scpt/init.lua index 55a6ce63..69fca70d 100644 --- a/lib/scpt/init.lua +++ b/lib/scpt/init.lua @@ -15,7 +15,9 @@ tome_dofile("stores.lua") tome_dofile("mkeys.lua") -- Add the schools of magic -tome_dofile("spells.lua") +schools_init() +school_spells_init() +init_school_books() -- Post-spell creation initialization initialize_bookable_spells() diff --git a/lib/scpt/spells.lua b/lib/scpt/spells.lua deleted file mode 100644 index 2ce7d1f3..00000000 --- a/lib/scpt/spells.lua +++ /dev/null @@ -1,293 +0,0 @@ --- --- This file takes care of the schools of magic --- - --- Create the schools -SCHOOL_MANA = add_school -{ - ["name"] = "Mana", - ["skill"] = SKILL_MANA, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Eru Iluvatar provides the Mana school at half the prayer skill - [GOD_ERU] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, - ["hooks"] = - { - [HOOK_CALC_MANA] = function(msp) - if get_skill(SKILL_MANA) >= 35 then - msp = msp + (msp * ((get_skill(SKILL_MANA) - 34)) / 100) - return TRUE, msp - end - end - }, -} -SCHOOL_FIRE = add_school -{ - ["name"] = "Fire", - ["skill"] = SKILL_FIRE, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, -} -SCHOOL_AIR = add_school -{ - ["name"] = "Air", - ["skill"] = SKILL_AIR, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Manwe Sulimo provides the Air school at 2/3 the prayer skill - [GOD_MANWE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 2, - ["div"] = 3, - }, - }, -} -SCHOOL_WATER = add_school -{ - ["name"] = "Water", - ["skill"] = SKILL_WATER, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Yavanna Kementari provides the Water school at 1/2 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_EARTH = add_school -{ - ["name"] = "Earth", - ["skill"] = SKILL_EARTH, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Tulkas provides the Earth school at 4/5 the prayer skill - [GOD_TULKAS] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 4, - ["div"] = 5, - }, - -- Yavanna Kementari provides the Earth school at 1/2 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_CONVEYANCE = add_school -{ - ["name"] = "Conveyance", - ["skill"] = SKILL_CONVEYANCE, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Manwe Sulimo provides the Conveyance school at 1/2 the prayer skill - [GOD_MANWE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_GEOMANCY = add_school -{ - ["name"] = "Geomancy", - ["skill"] = SKILL_GEOMANCY, - ["spell_power"] = TRUE, - -- Require to wield a Mage Staff, as the spells requries the caster to stomp the floor with it - ["depend"] = function() - -- Require at least one point in each school - if get_skill(SKILL_FIRE) == 0 then return end - if get_skill(SKILL_AIR) == 0 then return end - if get_skill(SKILL_EARTH) == 0 then return end - if get_skill(SKILL_WATER) == 0 then return end - - local obj = get_object(INVEN_WIELD) - if (obj.k_idx > 0) and (obj.tval == TV_MSTAFF) then return TRUE end - end, -} -SCHOOL_DIVINATION = add_school -{ - ["name"] = "Divination", - ["skill"] = SKILL_DIVINATION, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Eru Iluvatar provides the Divination school at 2/3 the prayer skill - [GOD_ERU] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 2, - ["div"] = 3, - }, - }, -} -SCHOOL_TEMPORAL = add_school -{ - ["name"] = "Temporal", - ["skill"] = SKILL_TEMPORAL, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Yavanna Kementari provides the Temporal school at 1/6 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 6, - }, - }, -} -SCHOOL_NATURE = add_school -{ - ["name"] = "Nature", - ["skill"] = SKILL_NATURE, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Yavanna Kementari provides the Nature school at 1/2 the prayer skill - [GOD_YAVANNA] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 2, - }, - }, -} -SCHOOL_META = add_school -{ - ["name"] = "Meta", - ["skill"] = SKILL_META, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Manwe Sulimo provides the Meta school at 1/3 the prayer skill - [GOD_MANWE] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - }, -} -SCHOOL_MIND = add_school -{ - ["name"] = "Mind", - ["skill"] = SKILL_MIND, - ["spell_power"] = TRUE, - ["sorcery"] = TRUE, - ["gods"] = - { - -- Eru Iluvatar provides the Mind school at 1/3 the prayer skill - [GOD_ERU] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - -- Melkor Bauglir provides the Mind school at 1/3 the prayer skill - [GOD_MELKOR] = - { - ["skill"] = SKILL_PRAY, - ["mul"] = 1, - ["div"] = 3, - }, - }, -} -SCHOOL_UDUN = add_school -{ - ["name"] = "Udun", - ["skill"] = SKILL_UDUN, - ["bonus_level"] = function() - return ((player.lev * 2) / 3) - end, -} -SCHOOL_DEMON = add_school -{ - ["name"] = "Demon", - ["skill"] = SKILL_DAEMON, - ["no_random"] = TRUE, -} - --- The God specific schools, all tied to the prayer skill -SCHOOL_ERU = add_school -{ - ["name"] = "Eru Iluvatar", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_ERU, -} -SCHOOL_MANWE = add_school -{ - ["name"] = "Manwe Sulimo", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_MANWE, -} -SCHOOL_TULKAS = add_school -{ - ["name"] = "Tulkas", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_TULKAS, -} -SCHOOL_MELKOR = add_school -{ - ["name"] = "Melkor Bauglir", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_MELKOR, -} -SCHOOL_YAVANNA = add_school -{ - ["name"] = "Yavanna Kementari", - ["skill"] = SKILL_PRAY, - ["spell_power"] = TRUE, - ["god"] = GOD_YAVANNA, -} - --- Not a real school, rather a palcehodler for stick only spells -SCHOOL_DEVICE = add_school -{ - ["name"] = "Device", - ["skill"] = SKILL_DEVICE, -} - --- Music "spells" -SCHOOL_MUSIC = add_school -{ - ["name"] = "Music", - ["skill"] = SKILL_MUSIC, -} - --- Initialize school spells. -school_spells_init() - --- Initialize spellbooks -init_school_books() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d1648754..d84f94ba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,8 @@ 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 spells5.c corrupt.c mimic.c + spells1.c spells2.c spells3.c spells4.c spells5.c spells6.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/defines.h b/src/defines.h index 099d3fe1..9b0a512a 100644 --- a/src/defines.h +++ b/src/defines.h @@ -870,6 +870,11 @@ */ #define SCHOOL_SPELLS_MAX 200 +/* + * Maximum number of spell schools + */ +#define SCHOOLS_MAX 50 + /* * Number of effects */ diff --git a/src/externs.h b/src/externs.h index 8f55d3d8..95a91f05 100644 --- a/src/externs.h +++ b/src/externs.h @@ -566,8 +566,8 @@ extern s32b extra_savefile_parts; extern bool_ player_char_health; extern s16b school_spells_count; extern spell_type school_spells[SCHOOL_SPELLS_MAX]; -extern s16b max_schools; -extern school_type *schools; +extern s16b schools_count; +extern school_type schools[SCHOOLS_MAX]; extern int project_time; extern s32b project_time_effect; extern effect_type effects[MAX_EFFECTS]; @@ -970,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_schools(s16b new_size); extern void reinit_gods(s16b new_size); extern void reinit_quests(s16b new_size); extern void create_stores_stock(int t); @@ -1966,8 +1965,16 @@ void dice_print(dice_type *dice, char *buf); void school_spells_init(); spell_type *spell_at(s32b index); s16b get_random_spell(s16b random_type, int lev); -bool_ check_spell_depends(s16b spell_idx); -int spell_get_school_idx(s16b spell_idx, int i); +bool_ check_spell_depends(spell_type *spell); + +/* spells6.c */ + +SGLIB_DEFINE_LIST_PROTOTYPES(school_provider, compare_school_provider, next); + +void schools_init(); +school_type *school_at(int index); + +void mana_school_calc_mana(int *msp); /* range.c */ extern void range_init(range_type *range, s32b min, s32b max); @@ -2371,9 +2378,7 @@ 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 school_type *grab_school_type(s16b num); -extern s32b lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus); +extern s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus); extern s32b get_level_device(s32b s, s32b max, s32b min); extern int get_mana(s32b s); extern int get_power(s32b s); diff --git a/src/init2.c b/src/init2.c index f195c469..0ce8c1a0 100644 --- a/src/init2.c +++ b/src/init2.c @@ -1959,10 +1959,7 @@ static errr init_misc(void) /* Hack -- No messages yet */ message__tail = MESSAGE_BUF; - /* Prepare schools */ - max_schools = 0; - schools = NULL; - + /* Initialize game */ process_hooks(HOOK_INIT_GAME, "(s)", "begin"); /* Initialise the values */ @@ -2065,13 +2062,6 @@ static errr init_wilderness(void) return 0; } -void init_schools(s16b new_size) -{ - /* allocate the extra memory */ - C_MAKE(schools, new_size, school_type); - max_schools = new_size; -} - /* * Initialise some other arrays */ diff --git a/src/lua_bind.c b/src/lua_bind.c index 0c099c00..34a89613 100644 --- a/src/lua_bind.c +++ b/src/lua_bind.c @@ -168,25 +168,17 @@ bool_ get_com_lua(cptr prompt, int *com) return (TRUE); } -/* Spell schools */ -s16b new_school(int i, cptr name, s16b skill) -{ - schools[i].name = string_make(name); - schools[i].skill = skill; - return (i); -} - school_type *grab_school_type(s16b num) { return (&schools[num]); } /* Change this fct if I want to switch to learnable spells */ -s32b lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus) +s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus) { s32b tmp; - tmp = lvl - ((school_spells[s].skill_level - 1) * (SKILL_STEP / 10)); + tmp = lvl - ((spell->skill_level - 1) * (SKILL_STEP / 10)); if (tmp >= (SKILL_STEP / 10)) /* We require at least one spell level */ tmp += bonus; @@ -209,6 +201,7 @@ s32b lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus) s32b get_level_device(s32b s, s32b max, s32b min) { int lvl; + spell_type *spell = spell_at(s); /* No max specified ? assume 50 */ if (max <= 0) { @@ -223,16 +216,16 @@ s32b get_level_device(s32b s, s32b max, s32b min) lvl = lvl + (get_level_use_stick * SKILL_STEP); /* Sticks are limited */ - if (lvl - ((school_spells[s].skill_level + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP) + if (lvl - ((spell->skill_level + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP) { - lvl = (get_level_max_stick + school_spells[s].skill_level - 1) * SKILL_STEP; + lvl = (get_level_max_stick + spell->skill_level - 1) * SKILL_STEP; } /* / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative -- The loss of information should be negligible since 1 skill = 1000 internally */ lvl = lvl / 10; - lvl = lua_get_level(s, lvl, max, min, 0); + lvl = lua_get_level(spell, lvl, max, min, 0); return lvl; } @@ -257,19 +250,6 @@ s32b spell_chance(s32b s) } } -void get_level_school(s32b s, s32b max, s32b min, s32b *level, bool_ *na) -{ - if (level != NULL) - { - *level = exec_lua(format("local lvl, na = get_level_school(%d, %d, %d); return lvl", s, max, min)); - } - - if (na != NULL) - { - *na = exec_lua(format("local lvl, na = get_level_school(%d, %d, %d); return (na == \"n/a\")", s, max, min)); - } -} - s32b get_level(s32b s, s32b max, s32b min) { /** Ahah shall we use Magic device instead ? */ @@ -277,7 +257,8 @@ s32b get_level(s32b s, s32b max, s32b min) return get_level_device(s, max, min); } else { s32b level; - get_level_school(s, max, min, &level, NULL); + bool_ notused; + get_level_school(s, max, min, &level, ¬used); return level; } } diff --git a/src/script.c b/src/script.c index 51484d3a..4d066a58 100644 --- a/src/script.c +++ b/src/script.c @@ -226,14 +226,6 @@ void init_lua_init() /* Load the first lua file */ tome_dofile_anywhere(ANGBAND_DIR_CORE, "init.lua", TRUE); - /* Finish up schools */ - max = exec_lua("return __schools_num"); - init_schools(max); - for (i = 0; i < max; i++) - { - exec_lua(format("finish_school(%d)", i)); - } - /* Finish up the corruptions */ init_corruptions(); } diff --git a/src/spells.pkg b/src/spells.pkg index d7564618..7385accc 100644 --- a/src/spells.pkg +++ b/src/spells.pkg @@ -2170,78 +2170,6 @@ struct spell_type@school_spell_type }; -/** @struct school_type - * @brief Spell school - */ -struct school_type -{ - /** @structvar name - * @brief String - * @note Name - */ - cptr name; - /** @structvar skill - * @brief Number - * @note Skil used for that school - */ - s16b skill; -}; - -/** @fn new_school(int i, cptr name, s16b skill) - * @dgonly - * @brief Add school to array of schools.\n - * @param i Number \n i is index of school array where school is added. - * There is no range checking. - * @brief Index - * @param name String \n name is the name of the school. - * @brief Name - * @param skill Number \n skill is the skill of the school. - * @brief Skill - * @return Number \ The index parameter. - * @note - * Note: do not call this function directly.\n - * Please use add_school() in s_aux.lua instead.\n - * By order of DG. - * @note (see file lua_bind.c) - */ -extern s16b new_school(int i, cptr name, s16b skill); - -/** @fn school(s16b num); - * @dgonly - * @brief Get school "num" from array of schools.\n - * @param num Number \n num is the index of the school. - * There is no range checking. - * @brief Index - * @return school_type \n The school. - * @note - * Note: do not call this function directly.\n - * By order of DG. - * @note (see file lua_bind.c) - */ -extern school_type *grab_school_type @ school(s16b num); - -/** @fn lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus) - * @dgonly - * @brief Get the casting level of school spell "s".\n - * @param s Number \n s is the index of the spell in array of school spells. - * There is no range checking. - * @brief Spell index - * @param lvl Number \n lvl represents the level of player skill. - * @brief Player skill level - * @param max Number \n max is the maximum level for the spell. - * @brief Maximum spell level - * @param min Number \n min is the minimum level for the spell. - * @brief Minimum spell level - * @param bonus Number \n bonus is any bonus to final level. - * @brief Bonus - * @return Number \n Casting level. - * @note - * Note: do not call this function directly.\n - * By order of DG. - * @note (see file lua_bind.c) - */ -extern s32b lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus); - /** Get level of device */ extern s32b get_level_device(s32b s, s32b max, s32b min); @@ -2344,5 +2272,8 @@ void spell_description_add_line(s32b spell_idx, cptr line); */ 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); + +/** + * spells6.c + */ +void schools_init(); diff --git a/src/spells4.c b/src/spells4.c index 4fd51cbe..e58ac4ea 100644 --- a/src/spells4.c +++ b/src/spells4.c @@ -491,7 +491,7 @@ static void spell_school_name(char *buf, spell_type *spell) school_idx = sglib_school_idx_it_next(&sit)) { int sch = school_idx->i; - school_type *school = grab_school_type(sch); + school_type *school = school_at(sch); /* Add separator? */ if (!first) { diff --git a/src/spells5.c b/src/spells5.c index 821d4151..d2d9eda2 100644 --- a/src/spells5.c +++ b/src/spells5.c @@ -90,9 +90,10 @@ s16b get_random_spell(s16b random_type, int level) return -1; } -bool_ check_spell_depends(s16b spell_idx) +bool_ check_spell_depends(spell_type *spell) { - spell_type *spell = spell_at(spell_idx); + assert(spell != NULL); + if (spell->depend_func != NULL) { return spell->depend_func(); } else { @@ -100,34 +101,6 @@ bool_ check_spell_depends(s16b spell_idx) } } -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); diff --git a/src/spells6.c b/src/spells6.c new file mode 100644 index 00000000..37e4c42c --- /dev/null +++ b/src/spells6.c @@ -0,0 +1,380 @@ +#include + +#include + +static int compare_school_provider(school_provider *a, school_provider *b) +{ + return SGLIB_NUMERIC_COMPARATOR(a->deity_idx, b->deity_idx); +} + +static void school_provider_init(school_provider *p, byte deity_idx, long mul, long div) +{ + assert(p != NULL); + + p->deity_idx = deity_idx; + p->skill_idx = SKILL_PRAY; + p->mul = mul; + p->div = div; + p->next = NULL; +} + +static school_provider *school_provider_new(byte deity_idx, long mul, long div) +{ + school_provider *p = malloc(sizeof(school_provider)); + school_provider_init(p, deity_idx, mul, div); + return p; +} + +SGLIB_DEFINE_LIST_FUNCTIONS(school_provider, compare_school_provider, next); + +school_type *school_at(int index) +{ + assert(index >= 0); + assert(index < schools_count); + + return &schools[index]; +} + +static void school_init(school_type *school, cptr name, s16b skill) +{ + assert(school != NULL); + + memset(school, 0, sizeof(school_type)); + + school->name = name; + school->skill = skill; + + school->deity_idx = -1; +} + +static school_type *school_new(s32b *school_idx, cptr name, s16b skill) +{ + assert(schools_count < SCHOOLS_MAX); + + *school_idx = schools_count; + schools_count++; + + school_type *school = &schools[*school_idx]; + school_init(school, name, skill); + + return school; +} + +static school_type *sorcery_school_new(s32b *school_idx, cptr name, s16b skill) +{ + school_type *school = school_new(school_idx, name, skill); + school->spell_power = TRUE; + school->sorcery = TRUE; + return school; +} + +static school_type *god_school_new(s32b *school_idx, byte god) +{ + school_type *school = NULL; + deity_type *deity = NULL; + + /* Get the god */ + deity = god_at(god); + assert(deity != NULL); + + /* Ignore gods which aren't enabled for this module. */ + if (god_enabled(deity)) + { + school = school_new(school_idx, deity->name, SKILL_PRAY); + school->spell_power = TRUE; + school->deity_idx = god; + school->deity = deity; + return school; + } + else + { + return NULL; + } +} + +static void school_god(school_type *school, byte god, int mul, int div) +{ + deity_type *deity = god_at(god); + assert(deity != NULL); + + /* Ignore gods which aren't enabled for this module. */ + if (god_enabled(deity)) + { + school_provider *school_provider = school_provider_new(god, mul, div); + sglib_school_provider_add(&school->providers, school_provider); + } +} + +static int udun_bonus_levels() +{ + return (p_ptr->lev * 2) / 3; +} + +static bool_ geomancy_depends_satisfied() +{ + object_type *o_ptr = NULL; + + /* Require at least one point in each school */ + if ((get_skill(SKILL_FIRE) <= 0) || + (get_skill(SKILL_AIR) <= 0) || + (get_skill(SKILL_EARTH) <= 0) || + (get_skill(SKILL_WATER) <= 0)) + { + return FALSE; + } + + /* Require to wield a Mage Staff, as the spells requries the + * caster to stomp the floor with it. */ + o_ptr = get_object(INVEN_WIELD); + + return ((o_ptr != NULL) && + (o_ptr->k_idx > 0) && + (o_ptr->tval == TV_MSTAFF)); +} + +long get_provided_levels(school_type *school) +{ + school_provider *school_provider = NULL; + struct sglib_school_provider_iterator school_provider_it; + + for (school_provider = sglib_school_provider_it_init(&school_provider_it, school->providers); + school_provider != NULL; + school_provider = sglib_school_provider_it_next(&school_provider_it)) + { + if (school_provider->deity_idx == p_ptr->pgod) + { + return (s_info[school_provider->skill_idx].value * school_provider->mul) / school_provider->div; + } + } + + return 0; +} + +void get_level_school(s32b spell_idx, s32b max, s32b min, s32b *level, bool_ *na) +{ + spell_type *spell = spell_at(spell_idx); + school_idx *school_idx = NULL; + struct sglib_school_idx_iterator sit; + bool_ allow_spell_power = TRUE; + long lvl, num, bonus; + + assert(level != NULL); + assert(na != NULL); + + lvl = 0; + num = 0; + bonus = 0; + + /* Do we pass tests? */ + if (!check_spell_depends(spell)) + { + *level = min; + *na = TRUE; + return; + } + + /* Go through all the spell's schools. */ + for (school_idx = sglib_school_idx_it_init(&sit, spell->schools); + school_idx != NULL; + school_idx = sglib_school_idx_it_next(&sit)) + { + school_type *school = school_at(school_idx->i); + long r = 0, s = 0, p = 0, ok = 0; + + /* Does it require we worship a specific god? */ + if ((school->deity_idx > 0) && + (school->deity_idx != p_ptr->pgod)) + { + *level = min; + *na = TRUE; + return; + } + + /* Take the basic skill value */ + r = s_info[school->skill].value; + + /* Do we pass tests? */ + if ((school->depends_satisfied != NULL) && + (!school->depends_satisfied())) + { + *level = min; + *na = TRUE; + return; + } + + /* Include effects of Sorcery (if applicable) */ + if (school->sorcery) + { + s = s_info[SKILL_SORCERY].value; + } + + /* Include effects of Spell Power? Every school must + * allow use of Spell Power for it to apply. */ + if (!school->spell_power) + { + allow_spell_power = FALSE; + } + + /* Calculate effects of provided levels */ + p = get_provided_levels(school); + + /* Find the highest of Skill, Sorcery and Provided levels. */ + ok = r; + if (ok < s) + { + ok = s; + } + if (ok < p) + { + ok = p; + } + + /* Do we need to add a special bonus? */ + if (school->bonus_levels != NULL) + { + bonus += (school->bonus_levels() * (SKILL_STEP / 10)); + } + + /* All schools must be non-zero to be able to use it. */ + if (ok <= 0) + { + *level = min; + *na = TRUE; + return; + } + + /* Apply it */ + lvl = lvl + ok; + num = num + 1; + } + + /* Add the Spellpower skill as a bonus on top */ + if (allow_spell_power) + { + bonus += (get_skill_scale(SKILL_SPELL, 20) * (SKILL_STEP / 10)); + } + + /* Add bonus from objects */ + bonus += (p_ptr->to_s * (SKILL_STEP / 10)); + + /* We divide by 10 because otherwise we can overflow a s32b + * and we can use a u32b because the value can be negative. + * The loss of information should be negligible since 1 skill + * point is 1000 internally. */ + lvl = (lvl / num) / 10; + lvl = lua_get_level(spell, lvl, max, min, bonus); + + /* Result */ + *level = lvl; + *na = FALSE; +} + +void schools_init() +{ + { + school_type *school = sorcery_school_new(&SCHOOL_MANA, "Mana", SKILL_MANA); + school_god(school, GOD_ERU, 1, 2); + school_god(school, GOD_VARDA, 1, 4); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_FIRE, "Fire", SKILL_FIRE); + school_god(school, GOD_AULE, 3, 5); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_AIR, "Air", SKILL_AIR); + school_god(school, GOD_MANWE, 2, 3); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_WATER, "Water", SKILL_WATER); + school_god(school, GOD_YAVANNA, 1, 2); + school_god(school, GOD_ULMO, 3, 5); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_EARTH, "Earth", SKILL_EARTH); + school_god(school, GOD_TULKAS, 4, 5); + school_god(school, GOD_YAVANNA, 1, 2); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_CONVEYANCE, "Conveyance", SKILL_CONVEYANCE); + school_god(school, GOD_MANWE, 1, 2); + } + + { + school_type *school = school_new(&SCHOOL_GEOMANCY, "Geomancy", SKILL_GEOMANCY); + school->spell_power = TRUE; + school->depends_satisfied = geomancy_depends_satisfied; + } + + { + school_type *school = sorcery_school_new(&SCHOOL_DIVINATION, "Divination", SKILL_DIVINATION); + school_god(school, GOD_ERU, 2, 3); + school_god(school, GOD_MANDOS, 1, 3); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_TEMPORAL, "Temporal", SKILL_TEMPORAL); + school_god(school, GOD_YAVANNA, 1, 6); + school_god(school, GOD_MANDOS, 1, 4); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_NATURE, "Nature", SKILL_NATURE); + school_god(school, GOD_YAVANNA, 1, 2); + school_god(school, GOD_ULMO, 1, 2); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_META, "Meta", SKILL_META); + school_god(school, GOD_MANWE, 1, 3); + school_god(school, GOD_VARDA, 1, 2); + } + + { + school_type *school = sorcery_school_new(&SCHOOL_MIND, "Mind", SKILL_MIND); + school_god(school, GOD_ERU, 1, 3); + school_god(school, GOD_MELKOR, 1, 3); + } + + { + school_type *school = school_new(&SCHOOL_UDUN, "Udun", SKILL_UDUN); + school->bonus_levels = udun_bonus_levels; + } + + { + school_new(&SCHOOL_DEMON, "Demon", SKILL_DAEMON); + } + + /* God-specific schools; all with a standard setup */ + { + god_school_new(&SCHOOL_ERU, GOD_ERU); + god_school_new(&SCHOOL_MANWE, GOD_MANWE); + god_school_new(&SCHOOL_TULKAS, GOD_TULKAS); + god_school_new(&SCHOOL_MELKOR, GOD_MELKOR); + god_school_new(&SCHOOL_YAVANNA, GOD_YAVANNA); + + god_school_new(&SCHOOL_AULE, GOD_AULE); + god_school_new(&SCHOOL_VARDA, GOD_VARDA); + god_school_new(&SCHOOL_ULMO, GOD_ULMO); + god_school_new(&SCHOOL_MANDOS, GOD_MANDOS); + } + + /* Placeholder schools */ + { + school_new(&SCHOOL_DEVICE, "Device", SKILL_DEVICE); + school_new(&SCHOOL_DEVICE, "Music", SKILL_MUSIC); + } + +} + +void mana_school_calc_mana(int *msp) +{ + if (get_skill(SKILL_MANA) >= 35) + { + *msp = *msp + (*msp * ((get_skill(SKILL_MANA) - 34)) / 100); + } +} diff --git a/src/types.h b/src/types.h index ed86a4af..5173a89c 100644 --- a/src/types.h +++ b/src/types.h @@ -2568,11 +2568,36 @@ struct spell_type school_idx *schools; }; +typedef struct school_provider school_provider; +struct school_provider +{ + byte deity_idx; /* Deity which provides school levels */ + + s16b skill_idx; /* Skill used for determining the boost */ + + long mul; /* Multiplier */ + + long div; /* Divisor */ + + school_provider *next; /* Next provider in list */ +}; + typedef struct school_type school_type; struct school_type { cptr name; /* Name */ s16b skill; /* Skill used for that school */ + bool_ spell_power; /* Does spell power affect spells in this school? */ + bool_ sorcery; /* Does Sorcery affect this school? */ + + int deity_idx; /* Deity; if <=0, no deity required */ + deity_type *deity; /* Direct pointer to deity */ + + int (*bonus_levels)(); /* Calculate number of bonus levels */ + + bool_ (*depends_satisfied)(); /* Are dependendies satisfied? */ + + school_provider *providers; /* List of secondary providers of this school */ }; /* diff --git a/src/variable.c b/src/variable.c index 71fb5dd8..417fb975 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1500,8 +1500,8 @@ bool_ player_char_health; */ s16b school_spells_count = 0; spell_type school_spells[SCHOOL_SPELLS_MAX]; -s16b max_schools; -school_type *schools; +s16b schools_count = 0; +school_type schools[SCHOOLS_MAX]; /* * Lasting spell effects diff --git a/src/xtra1.c b/src/xtra1.c index f393635f..4ccdf08e 100644 --- a/src/xtra1.c +++ b/src/xtra1.c @@ -1793,6 +1793,7 @@ static void calc_mana(void) msp = process_hooks_return[0].num; } + mana_school_calc_mana(&msp); meta_inertia_control_calc_mana(&msp); /* Mana can never be negative */ -- cgit v1.2.3