summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
13 files changed, 446 insertions, 162 deletions
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 */