summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2012-05-30 05:33:44 +0200
committerBardur Arantsson <bardur@scientician.net>2012-05-30 20:08:05 +0200
commit1b9ce2b53e26ed2d983efb9da10eb2be89d6d705 (patch)
tree1e1a6071fdf11515bf9f3e98fc83b7117045a241
parentfbc40366c8a50a695fcb913c5f25d717330e9672 (diff)
Lua: Migrate spell schools to C
-rw-r--r--lib/core/init.lua1
-rw-r--r--lib/core/s_aux.lua147
-rw-r--r--lib/mods/theme/core/init.lua1
-rw-r--r--lib/mods/theme/core/s_aux.lua146
-rw-r--r--lib/mods/theme/scpt/init.lua4
-rw-r--r--lib/mods/theme/scpt/spells.lua385
-rw-r--r--lib/scpt/init.lua4
-rw-r--r--lib/scpt/spells.lua293
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/defines.h5
-rw-r--r--src/externs.h21
-rw-r--r--src/init2.c12
-rw-r--r--src/lua_bind.c35
-rw-r--r--src/script.c8
-rw-r--r--src/spells.pkg79
-rw-r--r--src/spells4.c2
-rw-r--r--src/spells5.c33
-rw-r--r--src/spells6.c380
-rw-r--r--src/types.h25
-rw-r--r--src/variable.c4
-rw-r--r--src/xtra1.c1
21 files changed, 452 insertions, 1137 deletions
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
@@ -871,6 +871,11 @@
#define SCHOOL_SPELLS_MAX 200
/*
+ * Maximum number of spell schools
+ */
+#define SCHOOLS_MAX 50
+
+/*
* Number of effects
*/
#define MAX_EFFECTS 128
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, &notused);
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 <angband.h>
+
+#include <assert.h>
+
+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 */