summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/birth.cc3
-rw-r--r--src/cmd7.cc44
-rw-r--r--src/loadsave.cc12
-rw-r--r--src/player_type.hpp6
-rw-r--r--src/random_spell.hpp22
-rw-r--r--src/skills.cc9
-rw-r--r--src/spells1.cc139
-rw-r--r--src/variable.cc6
-rw-r--r--src/variable.hpp3
9 files changed, 110 insertions, 134 deletions
diff --git a/src/birth.cc b/src/birth.cc
index 25b1beff..9081ec06 100644
--- a/src/birth.cc
+++ b/src/birth.cc
@@ -845,9 +845,6 @@ static void player_wipe(void)
noscore = 0;
wizard = 0;
- /* Assume no innate spells */
- spell_num = 0;
-
/* Clear the fate */
for (i = 0; i < MAX_FATES; i++)
{
diff --git a/src/cmd7.cc b/src/cmd7.cc
index 4c485c2f..ff98d28d 100644
--- a/src/cmd7.cc
+++ b/src/cmd7.cc
@@ -16,6 +16,7 @@
#include "dungeon_flag.hpp"
#include "ego_item_type.hpp"
#include "files.hpp"
+#include "game.hpp"
#include "hooks.hpp"
#include "mimic.hpp"
#include "monster2.hpp"
@@ -1222,7 +1223,7 @@ void do_cmd_pray(void)
/*
* Return percentage chance of spell failure.
*/
-int spell_chance_random(random_spell* rspell)
+int spell_chance_random(random_spell const *rspell)
{
int chance, minfail;
@@ -1257,18 +1258,16 @@ int spell_chance_random(random_spell* rspell)
*/
static void print_spell_batch(int batch, int max)
{
- char buff[80];
-
- random_spell* rspell;
-
- int i;
-
+ auto const &random_spells = p_ptr->random_spells;
prt(format(" %-30s Lev Fail Mana Damage ", "Name"), 1, 20);
+ int i;
for (i = 0; i < max; i++)
{
- rspell = &random_spells[batch * 10 + i];
+ auto rspell = &random_spells[batch * 10 + i];
+
+ char buff[80];
if (rspell->untried)
{
@@ -1295,18 +1294,14 @@ static void print_spell_batch(int batch, int max)
/*
* List ten random spells and ask to pick one.
*/
-static random_spell* select_spell_from_batch(int batch)
+static random_spell* select_spell_from_batch(std::size_t batch)
{
- char tmp[160];
+ auto &random_spells = p_ptr->random_spells;
+ char tmp[160];
char out_val[30];
-
char which;
-
- int mut_max = 10;
-
- random_spell* ret;
-
+ random_spell* ret = nullptr;
/* Enter "icky" mode */
character_icky = TRUE;
@@ -1314,10 +1309,9 @@ static random_spell* select_spell_from_batch(int batch)
/* Save the screen */
Term_save();
- if (spell_num < (batch + 1) * 10)
- {
- mut_max = spell_num - batch * 10;
- }
+ int const mut_max = (random_spells.size() < (batch + 1) * 10)
+ ? random_spells.size() - batch * 10
+ : 10;
strnfmt(tmp, 160, "(a-%c, A-%c to browse, / to rename, - to comment) Select a power: ",
I2A(mut_max - 1), I2A(mut_max - 1) - 'a' + 'A');
@@ -1447,12 +1441,11 @@ static random_spell* select_spell_from_batch(int batch)
*/
static random_spell* select_spell()
{
- char tmp[160];
+ auto const &random_spells = p_ptr->random_spells;
+ char tmp[160];
char which;
- int batch_max = (spell_num - 1) / 10;
-
random_spell *ret;
@@ -1464,12 +1457,15 @@ static random_spell* select_spell()
}
/* No spells available */
- if (spell_num == 0)
+ if (random_spells.empty())
{
msg_print("There are no spells you can cast.");
return NULL;
}
+ /* How many spells in the last batch? */
+ int batch_max = (random_spells.size() - 1) / 10;
+
/* Enter "icky" mode */
character_icky = TRUE;
diff --git a/src/loadsave.cc b/src/loadsave.cc
index bbcc8784..06e53d02 100644
--- a/src/loadsave.cc
+++ b/src/loadsave.cc
@@ -480,10 +480,8 @@ static void do_subrace(ls_flag_t flag)
}
-/* Load/Save the random spells info */
-static void do_spells(int i, ls_flag_t flag)
+static void do_random_spell(random_spell *s_ptr, ls_flag_t flag)
{
- random_spell *s_ptr = &random_spells[i];
do_string(s_ptr->name, 30, flag);
do_string(s_ptr->desc, 30, flag);
do_s16b(&s_ptr->mana, flag);
@@ -891,15 +889,11 @@ static bool_ do_extra(ls_flag_t flag)
/* The fate */
do_bool(&p_ptr->no_mortal, flag);
+ /* Random spells */
+ do_vector(flag, p_ptr->random_spells, do_random_spell);
/* Spells */
{
- do_s16b(&spell_num, flag);
- for (std::size_t i = 0; i < MAX_SPELLS; i++)
- {
- do_spells(i, flag);
- }
-
do_s16b(&rune_num, flag);
for (std::size_t i = 0; i < MAX_RUNES; i++)
diff --git a/src/player_type.hpp b/src/player_type.hpp
index 20fa81a4..c9c7538b 100644
--- a/src/player_type.hpp
+++ b/src/player_type.hpp
@@ -7,6 +7,7 @@
#include "inventory.hpp"
#include "object_type.hpp"
#include "powers.hpp"
+#include "random_spell.hpp"
#include "spellbinder.hpp"
#include <array>
@@ -409,6 +410,11 @@ struct player_type
bool_ leaving = FALSE; /* True if player is leaving */
/**
+ * Random spells.
+ */
+ std::vector<random_spell> random_spells;
+
+ /**
* Does the player have the given ability?
*/
bool has_ability(u16b ability_idx) const;
diff --git a/src/random_spell.hpp b/src/random_spell.hpp
index 2c814c9f..2ed71096 100644
--- a/src/random_spell.hpp
+++ b/src/random_spell.hpp
@@ -7,15 +7,15 @@
*/
struct random_spell
{
- char desc[30]; /* Desc of the spell */
- char name[30]; /* Name of the spell */
- s16b mana; /* Mana cost */
- s16b fail; /* Failure rate */
- u32b proj_flags; /* Project function flags */
- byte GF; /* Type of the projection */
- byte radius;
- byte dam_sides;
- byte dam_dice;
- byte level; /* Level needed */
- bool untried; /* Is the spell was tried? */
+ char desc[30] = { }; /* Desc of the spell */
+ char name[30] = { }; /* Name of the spell */
+ s16b mana = 0; /* Mana cost */
+ s16b fail = 0; /* Failure rate */
+ u32b proj_flags = 0; /* Project function flags */
+ byte GF = 0; /* Type of the projection */
+ byte radius = 0;
+ byte dam_sides = 0;
+ byte dam_dice = 0;
+ byte level = 0; /* Level needed */
+ bool untried = true; /* Is the spell was tried? */
};
diff --git a/src/skills.cc b/src/skills.cc
index df252683..b97e80a8 100644
--- a/src/skills.cc
+++ b/src/skills.cc
@@ -385,16 +385,19 @@ void recalc_skills(bool_ init)
}
else
{
+ auto const &random_spells = p_ptr->random_spells;
+
int thaum_gain = 0;
- /* Gain thaum spells */
- while (thaum_level < get_skill_scale(SKILL_THAUMATURGY, 100))
+ /* Gain thaum spells while there's more to be gained */
+ while ((thaum_level < get_skill_scale(SKILL_THAUMATURGY, 100)) &&
+ (random_spells.size() < MAX_SPELLS))
{
- if (spell_num == MAX_SPELLS) break;
thaum_level++;
generate_spell((thaum_level + 1) / 2);
thaum_gain++;
}
+
if (thaum_gain)
{
if (thaum_gain == 1)
diff --git a/src/spells1.cc b/src/spells1.cc
index 3f09e592..eb3664cc 100644
--- a/src/spells1.cc
+++ b/src/spells1.cc
@@ -8923,136 +8923,125 @@ static void name_spell(random_spell* s_ptr)
void generate_spell(int plev)
{
- random_spell* rspell;
- int dice, sides, chance, mana, power;
- bool_ destruc_gen = FALSE;
- bool_ simple_gen = TRUE;
- bool_ ball_desc = FALSE;
+ auto &random_spells = p_ptr->random_spells;
- if (spell_num == MAX_SPELLS) return;
+ assert(random_spells.size() < MAX_SPELLS);
- rspell = &random_spells[spell_num];
+ bool destruc_gen = false;
+ bool simple_gen = true;
+ bool ball_desc = false;
- power = rand_int(5);
+ // Calculate power, dice, etc.
+ int const power = rand_int(5);
+ int const dice = std::max(1, (plev / 2) + power);
+ int const sides = std::max(5, plev + power);
+ int const mana = std::max(1, plev + (plev * power) / 15);
- dice = plev / 2;
- sides = plev;
- mana = plev;
+ // Create spell
+ random_spell rspell;
+ rspell.level = plev;
+ rspell.mana = mana;
+ rspell.untried = true;
- /* Make the spell more or less powerful. */
- dice += power;
- sides += power;
- mana += (plev * power) / 15;
+ // Spells are always maximally destructive
+ rspell.proj_flags = PROJECT_KILL | PROJECT_ITEM | PROJECT_GRID;
- /* Stay within reasonable bounds. */
- if (dice < 1) dice = 1;
+ // Roll the dice as to the "type" of spell
+ int chance = randint(100);
- if (sides < 5) sides = 5;
-
- if (mana < 1) mana = 1;
-
- rspell->level = plev;
- rspell->mana = mana;
- rspell->untried = true;
-
- /* Spells are always maximally destructive. */
- rspell->proj_flags = PROJECT_KILL | PROJECT_ITEM | PROJECT_GRID;
-
- chance = randint(100);
-
- /* Hack -- Always start with Magic Missile or derivative at lev. 1 */
+ // We always start with Magic Missile or derivative at level 1
if (plev == 1 || chance < 25)
{
- rspell->proj_flags |= PROJECT_STOP;
- /* Swap dice and sides for better damage */
- rspell->dam_dice = sides;
- rspell->dam_sides = dice;
- rspell->radius = 0;
+ // Swap dice and sides for better damage
+ rspell.proj_flags |= PROJECT_STOP;
+ rspell.dam_dice = sides;
+ rspell.dam_sides = dice;
+ rspell.radius = 0;
}
else if (chance < 50)
{
- rspell->proj_flags |= PROJECT_BEAM;
- rspell->dam_dice = dice;
- rspell->dam_sides = sides;
- rspell->radius = 0;
+ rspell.proj_flags |= PROJECT_BEAM;
+ rspell.dam_dice = dice;
+ rspell.dam_sides = sides;
+ rspell.radius = 0;
}
else if (chance < 76)
{
- rspell->proj_flags |= PROJECT_STOP;
- rspell->radius = dice / 3;
- rspell->dam_dice = dice;
- rspell->dam_sides = sides;
- ball_desc = TRUE;
+ rspell.proj_flags |= PROJECT_STOP;
+ rspell.radius = dice / 3;
+ rspell.dam_dice = dice;
+ rspell.dam_sides = sides;
+ ball_desc = true;
}
else if (chance < 83)
{
- rspell->proj_flags |= PROJECT_BLAST;
- rspell->radius = sides / 3;
- rspell->dam_dice = dice;
- rspell->dam_sides = sides;
+ rspell.proj_flags |= PROJECT_BLAST;
+ rspell.radius = sides / 3;
+ rspell.dam_dice = dice;
+ rspell.dam_sides = sides;
- destruc_gen = TRUE;
- simple_gen = FALSE;
+ destruc_gen = true;
+ simple_gen = false;
}
else if (chance < 90)
{
- rspell->proj_flags |= PROJECT_METEOR_SHOWER;
- /* Area effect spells do way less damage "per shot" */
- rspell->dam_dice = dice / 5;
- rspell->dam_sides = sides / 5;
- rspell->radius = sides / 3;
- if (rspell->radius < 4) rspell->radius = 4;
+ // Area effect spells do way less damage "per shot"
+ rspell.proj_flags |= PROJECT_METEOR_SHOWER;
+ rspell.dam_dice = dice / 5;
+ rspell.dam_sides = sides / 5;
+ rspell.radius = std::max(4, sides / 3);
- destruc_gen = TRUE;
+ destruc_gen = true;
}
else
{
- rspell->proj_flags |= PROJECT_VIEWABLE;
- /* View spells do less damage */
- rspell->dam_dice = dice;
- rspell->dam_sides = sides / 2;
+ // View spells do less damage
+ rspell.proj_flags |= PROJECT_VIEWABLE;
+ rspell.dam_dice = dice;
+ rspell.dam_sides = sides / 2;
}
- /* Both a destructive and a simple spell requested --
- * pick one or the other. */
+ // Both a destructive and a simple spell requested; pick one or the other
if (destruc_gen && simple_gen)
{
if (magik(25))
{
- simple_gen = FALSE;
+ simple_gen = false;
}
else
{
- destruc_gen = FALSE;
+ destruc_gen = false;
}
}
- /* Pick a simple spell */
+ // Choose the appropriate GF
if (simple_gen)
{
- rspell->GF = attack_types[rand_int(25)];
+ rspell.GF = attack_types[rand_int(25)];
}
- /* Pick a destructive spell */
else
{
- rspell->GF = destructive_attack_types[rand_int(10)];
+ rspell.GF = destructive_attack_types[rand_int(10)];
}
- /* Give the spell a name. */
- name_spell(rspell);
+ // Give the spell a name
+ name_spell(&rspell);
+
+ // Give the spell a description
if (ball_desc)
{
/* 30 character limit on the string! */
- sprintf(rspell->desc, "Dam: %d, Rad: %d, Pow: %d",
+ sprintf(rspell.desc, "Dam: %d, Rad: %d, Pow: %d",
sides, dice, power);
}
else
{
- sprintf(rspell->desc, "Damage: %dd%d, Power: %d",
+ sprintf(rspell.desc, "Damage: %dd%d, Power: %d",
dice, sides, power);
}
- spell_num++;
+ // Add
+ random_spells.emplace_back(rspell);
}
/*
diff --git a/src/variable.cc b/src/variable.cc
index 3813614e..84fcdfba 100644
--- a/src/variable.cc
+++ b/src/variable.cc
@@ -790,12 +790,6 @@ s32b RANDART_ARMOR;
s32b RANDART_JEWEL;
/*
- * Random spells.
- */
-random_spell random_spells[MAX_SPELLS];
-s16b spell_num;
-
-/*
* Runecrafter's selfmade spells.
*/
rune_spell rune_spells[MAX_RUNES];
diff --git a/src/variable.hpp b/src/variable.hpp
index b8fb91ea..ef480af9 100644
--- a/src/variable.hpp
+++ b/src/variable.hpp
@@ -32,7 +32,6 @@
#include "randart_part_type_fwd.hpp"
#include "random_artifact.hpp"
#include "random_quest.hpp"
-#include "random_spell.hpp"
#include "rune_spell.hpp"
#include "school_type.hpp"
#include "set_type_fwd.hpp"
@@ -236,8 +235,6 @@ extern random_artifact random_artifacts[MAX_RANDARTS];
extern s32b RANDART_WEAPON;
extern s32b RANDART_ARMOR;
extern s32b RANDART_JEWEL;
-extern random_spell random_spells[MAX_SPELLS];
-extern s16b spell_num;
extern rune_spell rune_spells[MAX_RUNES];
extern s16b rune_num;
extern fate fates[MAX_FATES];