summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/cave.cc113
-rw-r--r--src/cmd1.cc5
-rw-r--r--src/cmd5.cc361
-rw-r--r--src/cmd5.hpp3
-rw-r--r--src/cmd6.cc63
-rw-r--r--src/defines.h159
-rw-r--r--src/flag_set.hpp9
-rw-r--r--src/generate.cc98
-rw-r--r--src/init1.cc188
-rw-r--r--src/melee2.cc1135
-rw-r--r--src/monster1.cc200
-rw-r--r--src/monster2.cc40
-rw-r--r--src/monster3.cc19
-rw-r--r--src/monster_ego.hpp13
-rw-r--r--src/monster_power.hpp4
-rw-r--r--src/monster_power_fwd.hpp3
-rw-r--r--src/monster_race.hpp6
-rw-r--r--src/monster_spell.cc36
-rw-r--r--src/monster_spell.hpp91
-rw-r--r--src/monster_spell_flag.hpp20
-rw-r--r--src/monster_spell_flag_list.hpp102
-rw-r--r--src/monster_spell_flag_set.hpp7
-rw-r--r--src/q_bounty.cc3
-rw-r--r--src/q_god.cc9
-rw-r--r--src/q_poison.cc3
-rw-r--r--src/q_rand.cc5
-rw-r--r--src/rule_type.hpp6
-rw-r--r--src/spells1.cc39
-rw-r--r--src/spells2.cc184
-rw-r--r--src/tables.cc192
-rw-r--r--src/wizard1.cc207
32 files changed, 1432 insertions, 1892 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a68e056b..5a4b326f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -45,6 +45,7 @@ SET(SRCS_COMMON
messages.cc
mimic.cc
modules.cc
+ monster_spell.cc
monster_type.cc
monster1.cc
monster2.cc
diff --git a/src/cave.cc b/src/cave.cc
index 09f5d843..9d5daede 100644
--- a/src/cave.cc
+++ b/src/cave.cc
@@ -6,6 +6,7 @@
#include "hook_enter_dungeon_in.hpp"
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object1.hpp"
#include "object_kind.hpp"
@@ -500,50 +501,60 @@ static char get_shimmer_color()
/*
- * Table of breath colors. Must match listings in a single set of
- * monster spell flags.
- *
- * The value "255" is special. Monsters with that kind of breath
- * may be any color.
+ * Breath color
*/
-static byte breath_to_attr[32][2] =
-{
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { TERM_SLATE, TERM_L_DARK }, /* RF4_BRTH_ACID */
- { TERM_BLUE, TERM_L_BLUE }, /* RF4_BRTH_ELEC */
- { TERM_RED, TERM_L_RED }, /* RF4_BRTH_FIRE */
- { TERM_WHITE, TERM_L_WHITE }, /* RF4_BRTH_COLD */
- { TERM_GREEN, TERM_L_GREEN }, /* RF4_BRTH_POIS */
- { TERM_L_GREEN, TERM_GREEN }, /* RF4_BRTH_NETHR */
- { TERM_YELLOW, TERM_ORANGE }, /* RF4_BRTH_LITE */
- { TERM_L_DARK, TERM_SLATE }, /* RF4_BRTH_DARK */
- { TERM_L_UMBER, TERM_UMBER }, /* RF4_BRTH_CONFU */
- { TERM_YELLOW, TERM_L_UMBER }, /* RF4_BRTH_SOUND */
- { 255, 255 }, /* (any color) */ /* RF4_BRTH_CHAOS */
- { TERM_VIOLET, TERM_VIOLET }, /* RF4_BRTH_DISEN */
- { TERM_L_RED, TERM_VIOLET }, /* RF4_BRTH_NEXUS */
- { TERM_L_BLUE, TERM_L_BLUE }, /* RF4_BRTH_TIME */
- { TERM_L_WHITE, TERM_SLATE }, /* RF4_BRTH_INER */
- { TERM_L_WHITE, TERM_SLATE }, /* RF4_BRTH_GRAV */
- { TERM_UMBER, TERM_L_UMBER }, /* RF4_BRTH_SHARD */
- { TERM_ORANGE, TERM_RED }, /* RF4_BRTH_PLAS */
- { TERM_UMBER, TERM_L_UMBER }, /* RF4_BRTH_FORCE */
- { TERM_L_BLUE, TERM_WHITE }, /* RF4_BRTH_MANA */
- { 0, 0 }, /* */
- { TERM_GREEN, TERM_L_GREEN }, /* RF4_BRTH_NUKE */
- { 0, 0 }, /* */
- { TERM_WHITE, TERM_L_RED }, /* RF4_BRTH_DISINT */
+struct breath_color {
+ std::size_t breath_idx;
+ byte first_color;
+ byte second_color;
};
/*
+ * Breath colors. The value "255" is special. Monsters with
+ * that kind of breath may be any color.
+ */
+static breath_color const *lookup_breath_color(std::size_t i)
+{
+ static breath_color breath_to_attr[] =
+ {
+ { SF_BR_ACID_IDX, TERM_SLATE, TERM_L_DARK },
+ { SF_BR_ELEC_IDX, TERM_BLUE, TERM_L_BLUE },
+ { SF_BR_FIRE_IDX, TERM_RED, TERM_L_RED },
+ { SF_BR_COLD_IDX, TERM_WHITE, TERM_L_WHITE },
+ { SF_BR_POIS_IDX, TERM_GREEN, TERM_L_GREEN },
+ { SF_BR_NETH_IDX, TERM_L_GREEN, TERM_GREEN },
+ { SF_BR_LITE_IDX, TERM_YELLOW, TERM_ORANGE },
+ { SF_BR_DARK_IDX, TERM_L_DARK, TERM_SLATE },
+ { SF_BR_CONF_IDX, TERM_L_UMBER, TERM_UMBER },
+ { SF_BR_SOUN_IDX, TERM_YELLOW, TERM_L_UMBER },
+ { SF_BR_CHAO_IDX, 255, 255 },
+ { SF_BR_DISE_IDX, TERM_VIOLET, TERM_VIOLET },
+ { SF_BR_NEXU_IDX, TERM_L_RED, TERM_VIOLET },
+ { SF_BR_TIME_IDX, TERM_L_BLUE, TERM_L_BLUE },
+ { SF_BR_INER_IDX, TERM_L_WHITE, TERM_SLATE },
+ { SF_BR_GRAV_IDX, TERM_L_WHITE, TERM_SLATE },
+ { SF_BR_SHAR_IDX, TERM_UMBER, TERM_L_UMBER },
+ { SF_BR_PLAS_IDX, TERM_ORANGE, TERM_RED },
+ { SF_BR_WALL_IDX, TERM_UMBER, TERM_L_UMBER },
+ { SF_BR_MANA_IDX, TERM_L_BLUE, TERM_WHITE },
+ { SF_BR_NUKE_IDX, TERM_GREEN, TERM_L_GREEN },
+ { SF_BR_DISI_IDX, TERM_WHITE, TERM_L_RED },
+ };
+
+ for (auto const &breath_color: breath_to_attr)
+ {
+ if (breath_color.breath_idx == i)
+ {
+ return &breath_color;
+ }
+ }
+
+ return nullptr;
+}
+
+
+/*
* Multi-hued monsters shimmer acording to their breaths.
*
* If a monster has only one kind of breath, it uses both colors
@@ -556,9 +567,7 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr)
{
byte allowed_attrs[15];
- int i, j;
-
- int stored_colors = 0;
+ std::size_t stored_colors = 0;
int breaths = 0;
@@ -571,18 +580,22 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr)
if (!r_ptr->freq_inate) return (get_shimmer_color());
/* Check breaths */
- for (i = 0; i < 32; i++)
+ for (std::size_t i = 0; i < monster_spell_flag_set::nbits; i++)
{
bool_ stored = FALSE;
/* Don't have that breath */
- if (!(r_ptr->flags4 & (1L << i))) continue;
+ if (!(r_ptr->spells.bit(i))) continue;
- /* Get the first color of this breath */
- first_color = breath_to_attr[i][0];
+ /* Find the breath in our list */
+ auto breath_color = lookup_breath_color(i);
+ if (!breath_color)
+ {
+ continue;
+ }
- /* Breath has no color associated with it */
- if (first_color == 0) continue;
+ /* Get the first color of this breath */
+ first_color = breath_color->first_color;
/* Monster can be of any color */
if (first_color == 255) return (randint(15));
@@ -596,7 +609,7 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr)
/* Always store the first color */
- for (j = 0; j < stored_colors; j++)
+ for (std::size_t j = 0; j < stored_colors; j++)
{
/* Already stored */
if (allowed_attrs[j] == first_color) stored = TRUE;
@@ -613,7 +626,7 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr)
*/
if (breaths == 1)
{
- second_color = breath_to_attr[i][1];
+ second_color = breath_color->second_color;
}
}
diff --git a/src/cmd1.cc b/src/cmd1.cc
index 69592b71..dddcbcef 100644
--- a/src/cmd1.cc
+++ b/src/cmd1.cc
@@ -25,6 +25,7 @@
#include "monster2.hpp"
#include "monster3.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
@@ -2228,7 +2229,7 @@ void py_attack(int y, int x, int max_blow)
/* Stunning blow */
if (magik(get_skill(SKILL_STUN)) && (o_ptr->tval == TV_HAFTED) && (o_ptr->weight > 50) && done_crit)
{
- if (!(r_ptr->flags4 & RF4_BR_SOUN) && !(r_ptr->flags4 & RF4_BR_WALL) && k)
+ if (!(r_ptr->spells & SF_BR_SOUN) && !(r_ptr->spells & SF_BR_WALL) && k)
{
int tmp;
@@ -2476,7 +2477,7 @@ void py_attack(int y, int x, int max_blow)
(randint(90) > m_ptr->level))
{
if (!((r_ptr->flags1 & RF1_UNIQUE) ||
- (r_ptr->flags4 & RF4_BR_CHAO) ||
+ (r_ptr->spells & SF_BR_CHAO) ||
(m_ptr->mflag & MFLAG_QUEST)))
{
/* Handle polymorph */
diff --git a/src/cmd5.cc b/src/cmd5.cc
index a3a70b01..2c9798de 100644
--- a/src/cmd5.cc
+++ b/src/cmd5.cc
@@ -16,6 +16,7 @@
#include "lua_bind.hpp"
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "object1.hpp"
#include "object2.hpp"
#include "object_type.hpp"
@@ -616,44 +617,43 @@ cptr symbiote_name(bool_ capitalize)
return buf;
}
+
/*
- * Extract powers
+ * Find monster power
*/
-std::vector<int> extract_monster_powers(monster_race const *r_ptr, bool great)
+monster_power const *lookup_monster_power(std::size_t idx)
{
- std::vector<int> powers;
- powers.reserve(MONSTER_POWERS_MAX);
-
- /* List the monster powers -- RF4_* */
- for (std::size_t i = 0; i < 32; i++)
+ for (auto const &p: monster_powers)
{
- if (r_ptr->flags4 & BIT(i))
+ if (p.monster_spell_index == idx)
{
- if (monster_powers[i].great && (!great)) continue;
- if (!monster_powers[i].power) continue;
- powers.push_back(i);
+ return &p;
}
}
+ return nullptr;
+}
- /* List the monster powers -- RF5_* */
- for (std::size_t i = 0; i < 32; i++)
- {
- if (r_ptr->flags5 & BIT(i))
- {
- if (monster_powers[i + 32].great && (!great)) continue;
- if (!monster_powers[i + 32].power) continue;
- powers.push_back(i + 32);
- }
- }
- /* List the monster powers -- RF6_* */
- for (std::size_t i = 0; i < 32; i++)
+/*
+ * Extract powers
+ */
+std::vector<monster_power const *> extract_monster_powers(monster_race const *r_ptr, bool great)
+{
+ std::vector<monster_power const *> powers;
+ powers.reserve(MONSTER_POWERS_MAX);
+
+ for (std::size_t i = 0; i < monster_spell_flag_set::nbits; i++)
{
- if (r_ptr->flags6 & BIT(i))
+ if (r_ptr->spells.bit(i))
{
- if (monster_powers[i + 64].great && (!great)) continue;
- if (!monster_powers[i + 64].power) continue;
- powers.push_back(i + 64);
+ if (auto power = lookup_monster_power(i))
+ {
+ if (power->great && (!great))
+ {
+ continue;
+ }
+ powers.push_back(power);
+ }
}
}
@@ -677,7 +677,7 @@ static int calc_monster_spell_mana(monster_power const *mp_ptr)
static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool great, bool symbiosis)
{
/* Extract available monster powers */
- std::vector<int> powers = extract_monster_powers(r_ptr, great);
+ auto powers = extract_monster_powers(r_ptr, great);
int const num = powers.size(); // Avoid signed/unsigned warnings
if (!num)
@@ -701,7 +701,7 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
Term_save();
/* Get a spell from the user */
- int power = -1; // Selected power
+ monster_power const *power = nullptr;
bool_ flag = FALSE; // Nothing chosen yet
while (!flag)
{
@@ -716,7 +716,7 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
while (ctr < num)
{
- monster_power *mp_ptr = &monster_powers[powers[ctr]];
+ monster_power const *mp_ptr = powers[ctr];
label = (ctr < 26) ? I2A(ctr) : I2D(ctr - 26);
@@ -799,12 +799,13 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
continue;
}
- /* Save the spell index */
+ /* Save the spell */
power = powers[i];
/* Make sure it's actually possible for the player to cast */
- if (!symbiosis) {
- if (p_ptr->csp < calc_monster_spell_mana(&monster_powers[power]))
+ if (!symbiosis)
+ {
+ if (p_ptr->csp < calc_monster_spell_mana(power))
{
bell();
continue;
@@ -817,7 +818,7 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
char tmp_val[160];
/* Prompt */
- strnfmt(tmp_val, 78, "Use %s? ", monster_powers[power].name);
+ strnfmt(tmp_val, 78, "Use %s? ", power->name);
/* Belay that order */
if (!get_check(tmp_val)) continue;
@@ -832,22 +833,22 @@ static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool
character_icky = FALSE;
/* Abort if needed */
- if (!flag)
+ if (!flag || (power == nullptr))
{
return std::make_tuple(-1, num);
}
- return std::make_tuple(power, num);
+ return std::make_tuple(power->monster_spell_index, num);
}
/*
* Apply the effect of a monster power
*/
-static void apply_monster_power(monster_race const *r_ptr, int power)
+static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_spell_idx)
{
- assert(power >= 0);
- assert(power < MONSTER_POWERS_MAX);
+ assert(monster_spell_idx >= 0);
+ assert(monster_spell_idx < monster_spell_flag_set::nbits);
/* Shorthand */
int const x = p_ptr->px;
@@ -861,36 +862,30 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
: 1 + (p_ptr->lev / 20);
/* Analyse power */
- switch (power)
+ switch (monster_spell_idx)
{
- /**** RF4 (bit position) ****/
-
- /* SHRIEK */
- case 0:
+ case SF_SHRIEK_IDX:
{
aggravate_monsters( -1);
break;
}
- /* MULTIPLY */
- case 1:
+ case SF_MULTIPLY_IDX:
{
do_cmd_wiz_named_friendly(p_ptr->body_monster, FALSE);
break;
}
- /* S_ANIMAL */
- case 2:
+ case SF_S_ANIMAL_IDX:
{
summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE);
break;
}
- /* ROCKET */
- case 3:
+ case SF_ROCKET_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -900,8 +895,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* ARROW_1 */
- case 4:
+ case SF_ARROW_1_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -911,8 +905,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* ARROW_2 */
- case 5:
+ case SF_ARROW_2_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -922,8 +915,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* ARROW_3 */
- case 6:
+ case SF_ARROW_3_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -933,8 +925,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* ARROW_4 */
- case 7:
+ case SF_ARROW_4_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -944,8 +935,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_ACID */
- case 8:
+ case SF_BR_ACID_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -955,8 +945,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_ELEC */
- case 9:
+ case SF_BR_ELEC_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -966,8 +955,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_FIRE */
- case 10:
+ case SF_BR_FIRE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -977,8 +965,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_COLD */
- case 11:
+ case SF_BR_COLD_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -988,8 +975,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_POIS */
- case 12:
+ case SF_BR_POIS_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -999,8 +985,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_NETH */
- case 13:
+ case SF_BR_NETH_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1010,8 +995,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_LITE */
- case 14:
+ case SF_BR_LITE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1021,8 +1005,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_DARK */
- case 15:
+ case SF_BR_DARK_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1032,8 +1015,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_CONF */
- case 16:
+ case SF_BR_CONF_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1043,8 +1025,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_SOUN */
- case 17:
+ case SF_BR_SOUN_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1054,8 +1035,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_CHAO */
- case 18:
+ case SF_BR_CHAO_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1065,8 +1045,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_DISE */
- case 19:
+ case SF_BR_DISE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1076,8 +1055,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_NEXU */
- case 20:
+ case SF_BR_NEXU_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1087,8 +1065,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_TIME */
- case 21:
+ case SF_BR_TIME_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1098,8 +1075,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_INER */
- case 22:
+ case SF_BR_INER_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1109,8 +1085,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_GRAV */
- case 23:
+ case SF_BR_GRAV_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1120,8 +1095,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_SHAR */
- case 24:
+ case SF_BR_SHAR_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1131,8 +1105,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_PLAS */
- case 25:
+ case SF_BR_PLAS_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1142,8 +1115,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_WALL */
- case 26:
+ case SF_BR_WALL_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1153,8 +1125,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_MANA */
- case 27:
+ case SF_BR_MANA_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1164,8 +1135,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_NUKE */
- case 28:
+ case SF_BA_NUKE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1175,8 +1145,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_NUKE */
- case 29:
+ case SF_BR_NUKE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1186,8 +1155,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_CHAO */
- case 30:
+ case SF_BA_CHAO_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1197,8 +1165,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BR_DISI */
- case 31:
+ case SF_BR_DISI_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1208,11 +1175,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
-
- /**** RF5 (bit position + 32) ****/
-
- /* BA_ACID */
- case 32:
+ case SF_BA_ACID_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1222,8 +1185,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_ELEC */
- case 33:
+ case SF_BA_ELEC_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1233,8 +1195,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_FIRE */
- case 34:
+ case SF_BA_FIRE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1244,8 +1205,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_COLD */
- case 35:
+ case SF_BA_COLD_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1255,8 +1215,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_POIS */
- case 36:
+ case SF_BA_POIS_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1266,8 +1225,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_NETH */
- case 37:
+ case SF_BA_NETH_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1277,8 +1235,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_WATE */
- case 38:
+ case SF_BA_WATE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1288,8 +1245,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_MANA */
- case 39:
+ case SF_BA_MANA_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1299,8 +1255,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BA_DARK */
- case 40:
+ case SF_BA_DARK_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1310,14 +1265,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* 41 DRAIN_MANA -- Not available */
-
- /* 42 MIND_BLAST -- Not available */
-
- /* 43 BRAIN_SMASH -- Not available */
-
- /* CAUSE_1 */
- case 44:
+ case SF_CAUSE_1_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1327,8 +1275,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* CAUSE_2 */
- case 45:
+ case SF_CAUSE_2_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1338,8 +1285,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* CAUSE_3 */
- case 46:
+ case SF_CAUSE_3_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1349,8 +1295,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* CAUSE_4 */
- case 47:
+ case SF_CAUSE_4_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1360,8 +1305,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_ACID */
- case 48:
+ case SF_BO_ACID_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1371,8 +1315,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_ELEC */
- case 49:
+ case SF_BO_ELEC_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1382,8 +1325,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_FIRE */
- case 50:
+ case SF_BO_FIRE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1393,8 +1335,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_COLD */
- case 51:
+ case SF_BO_COLD_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1404,8 +1345,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_POIS */
- case 52:
+ case SF_BO_POIS_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1415,8 +1355,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_NETH */
- case 53:
+ case SF_BO_NETH_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1426,8 +1365,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_WATE */
- case 54:
+ case SF_BO_WATE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1437,8 +1375,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_MANA */
- case 55:
+ case SF_BO_MANA_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1448,8 +1385,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_PLAS */
- case 56:
+ case SF_BO_PLAS_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1459,8 +1395,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BO_ICEE */
- case 57:
+ case SF_BO_ICEE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1470,8 +1405,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* MISSILE */
- case 58:
+ case SF_MISSILE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1481,8 +1415,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* SCARE */
- case 59:
+ case SF_SCARE_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1492,8 +1425,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BLIND */
- case 60:
+ case SF_BLIND_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1503,8 +1435,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* CONF */
- case 61:
+ case SF_CONF_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1514,8 +1445,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* SLOW */
- case 62:
+ case SF_SLOW_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1525,8 +1455,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* HOLD */
- case 63:
+ case SF_HOLD_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1536,11 +1465,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
-
- /**** RF6 (bit position + 64) ****/
-
- /* HASTE */
- case 64:
+ case SF_HASTE_IDX:
{
if (!p_ptr->fast)
{
@@ -1554,8 +1479,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* HAND_DOOM */
- case 65:
+ case SF_HAND_DOOM_IDX:
{
int dir;
if (!get_aim_dir(&dir)) break;
@@ -1565,16 +1489,14 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* HEAL */
- case 66:
+ case SF_HEAL_IDX:
{
hp_player(damroll(8, 5));
break;
}
- /* S_ANIMALS */
- case 67:
+ case SF_S_ANIMALS_IDX:
{
for (int k = 0; k < 4; k++)
{
@@ -1584,8 +1506,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* BLINK */
- case 68:
+ case SF_BLINK_IDX:
{
if (dungeon_flags & DF_NO_TELEPORT)
{
@@ -1598,8 +1519,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* TPORT */
- case 69:
+ case SF_TPORT_IDX:
{
if (dungeon_flags & DF_NO_TELEPORT)
{
@@ -1612,8 +1532,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* TELE_TO */
- case 70:
+ case SF_TELE_TO_IDX:
{
int ii, ij;
@@ -1642,8 +1561,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* TELE_AWAY */
- case 71:
+ case SF_TELE_AWAY_IDX:
{
if (dungeon_flags & DF_NO_TELEPORT)
{
@@ -1659,8 +1577,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* TELE_LEVEL */
- case 72:
+ case SF_TELE_LEVEL_IDX:
{
if (dungeon_flags & DF_NO_TELEPORT)
{
@@ -1673,8 +1590,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* DARKNESS */
- case 73:
+ case SF_DARKNESS_IDX:
{
(void)project( -1, 3, p_ptr->py, p_ptr->px, 0, GF_DARK_WEAK,
PROJECT_GRID | PROJECT_KILL);
@@ -1685,16 +1601,14 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* TRAPS */
- case 74:
+ case SF_TRAPS_IDX:
{
trap_creation();
break;
}
- /* S_THUNDERLORD */
- case 79:
+ case SF_S_THUNDERLORD_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1704,8 +1618,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_KIN -- Summon Kin, because we code bugs :) */
- case 80:
+ case SF_S_KIN_IDX:
{
/* Big hack */
summon_kin_type = r_ptr->d_char;
@@ -1718,8 +1631,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_HI_DEMON */
- case 81:
+ case SF_S_HI_DEMON_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1729,8 +1641,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_MONSTER */
- case 82:
+ case SF_S_MONSTER_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1740,8 +1651,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_MONSTERS */
- case 83:
+ case SF_S_MONSTERS_IDX:
{
for (int k = 0; k < 6; k++)
{
@@ -1751,8 +1661,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_ANT */
- case 84:
+ case SF_S_ANT_IDX:
{
for (int k = 0; k < 6; k++)
{
@@ -1762,8 +1671,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_SPIDER */
- case 85:
+ case SF_S_SPIDER_IDX:
{
for (int k = 0; k < 6; k++)
{
@@ -1773,8 +1681,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_HOUND */
- case 86:
+ case SF_S_HOUND_IDX:
{
for (int k = 0; k < 6; k++)
{
@@ -1784,8 +1691,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_HYDRA */
- case 87:
+ case SF_S_HYDRA_IDX:
{
for (int k = 0; k < 6; k++)
{
@@ -1795,8 +1701,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_ANGEL */
- case 88:
+ case SF_S_ANGEL_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1806,8 +1711,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_DEMON */
- case 89:
+ case SF_S_DEMON_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1817,8 +1721,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_UNDEAD */
- case 90:
+ case SF_S_UNDEAD_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1828,8 +1731,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_DRAGON */
- case 91:
+ case SF_S_DRAGON_IDX:
{
for (int k = 0; k < 1; k++)
{
@@ -1839,8 +1741,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_HI_UNDEAD */
- case 92:
+ case SF_S_HI_UNDEAD_IDX:
{
for (int k = 0; k < 8; k++)
{
@@ -1850,8 +1751,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_HI_DRAGON */
- case 93:
+ case SF_S_HI_DRAGON_IDX:
{
for (int k = 0; k < 8; k++)
{
@@ -1861,8 +1761,7 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
- /* S_WRAITH */
- case 94:
+ case SF_S_WRAITH_IDX:
{
for (int k = 0; k < 8; k++)
{
@@ -1871,8 +1770,6 @@ static void apply_monster_power(monster_race const *r_ptr, int power)
break;
}
-
- /* 95 S_UNIQUE -- Not available */
}
}
diff --git a/src/cmd5.hpp b/src/cmd5.hpp
index 4b116596..7a0cd27a 100644
--- a/src/cmd5.hpp
+++ b/src/cmd5.hpp
@@ -3,6 +3,7 @@
#include "h-basic.h"
#include "object_type_fwd.hpp"
#include "monster_race_fwd.hpp"
+#include "monster_power_fwd.hpp"
#include <vector>
extern bool_ is_magestaff(void);
@@ -17,4 +18,4 @@ extern bool_ is_ok_spell(s32b spell_idx, s32b pval);
extern s32b get_school_spell(cptr do_what, s16b force_book);
extern void do_cmd_copy_spell(void);
extern void cast_school_spell(void);
-extern std::vector<int> extract_monster_powers(monster_race const *r_ptr, bool great);
+extern std::vector<monster_power const *> extract_monster_powers(monster_race const *r_ptr, bool great);
diff --git a/src/cmd6.cc b/src/cmd6.cc
index 387a236e..b1022bd1 100644
--- a/src/cmd6.cc
+++ b/src/cmd6.cc
@@ -25,6 +25,7 @@
#include "mimic.hpp"
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
@@ -539,7 +540,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
*/
/* Acid */
- if (r_ptr->flags4 & RF4_BR_ACID && brpow > 0)
+ if ((r_ptr->spells & SF_BR_ACID) && brpow > 0)
{
brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3));
@@ -554,13 +555,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
o_ptr->pval = 1;
}
- else if (r_ptr->flags4 & RF4_BR_ACID)
+ else if (r_ptr->spells & SF_BR_ACID)
{
set_oppose_acid(p_ptr->oppose_acid + rand_int(10) + 10);
}
/* Electricity */
- if (r_ptr->flags4 & RF4_BR_ELEC && brpow > 0)
+ if ((r_ptr->spells & SF_BR_ELEC) && brpow > 0)
{
brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3));
@@ -576,13 +577,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
o_ptr->weight = o_ptr->weight - brpow;
o_ptr->pval = o_ptr->weight;
}
- else if (r_ptr->flags4 & RF4_BR_ELEC)
+ else if (r_ptr->spells & SF_BR_ELEC)
{
set_oppose_elec(p_ptr->oppose_elec + rand_int(10) + 10);
}
/* Fire */
- if (r_ptr->flags4 & RF4_BR_FIRE && brpow > 0)
+ if ((r_ptr->spells & SF_BR_FIRE) && brpow > 0)
{
brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3));
@@ -597,13 +598,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
o_ptr->pval = 1;
}
- else if (r_ptr->flags4 & RF4_BR_FIRE)
+ else if (r_ptr->spells & SF_BR_FIRE)
{
set_oppose_fire(p_ptr->oppose_fire + rand_int(10) + 10);
}
/* Cold */
- if (r_ptr->flags4 & RF4_BR_COLD && brpow > 0)
+ if ((r_ptr->spells & SF_BR_COLD) && brpow > 0)
{
brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3));
@@ -619,13 +620,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
o_ptr->weight = o_ptr->weight - brpow;
o_ptr->pval = o_ptr->weight;
}
- else if (r_ptr->flags4 & RF4_BR_COLD)
+ else if (r_ptr->spells & SF_BR_COLD)
{
set_oppose_cold(p_ptr->oppose_cold + rand_int(10) + 10);
}
/* Poison */
- if (r_ptr->flags4 & RF4_BR_POIS && brpow > 0)
+ if ((r_ptr->spells & SF_BR_POIS) && brpow > 0)
{
brdam = ((brpow / 3) > 800 ? 800 : (brpow / 3));
@@ -648,7 +649,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
/* Nether */
- if (r_ptr->flags4 & RF4_BR_NETH && brpow > 0)
+ if ((r_ptr->spells & SF_BR_NETH) && brpow > 0)
{
brdam = ((brpow / 6) > 550 ? 550 : (brpow / 6));
@@ -685,7 +686,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
/* Confusion */
- if (r_ptr->flags4 & RF4_BR_CONF && brpow > 0)
+ if ((r_ptr->spells & SF_BR_CONF) && brpow > 0)
{
msg_print("A strange liquid splashes on you!");
@@ -698,7 +699,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
/* Chaos */
- if (r_ptr->flags4 & RF4_BR_CHAO && brpow > 0)
+ if ((r_ptr->spells & SF_BR_CHAO) && brpow > 0)
{
brdam = ((brpow / 6) > 600 ? 600 : (brpow / 6));
@@ -744,7 +745,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
/* Disenchantment */
- if (r_ptr->flags4 & RF4_BR_DISE && brpow > 0)
+ if ((r_ptr->spells & SF_BR_DISE) && brpow > 0)
{
brdam = ((brpow / 6) > 500 ? 500 : (brpow / 6));
@@ -766,7 +767,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
}
/* Plasma */
- if (r_ptr->flags4 & RF4_BR_PLAS && brpow > 0)
+ if ((r_ptr->spells & SF_BR_PLAS) && brpow > 0)
{
brdam = ((brpow / 6) > 150 ? 150 : (brpow / 6));
@@ -880,27 +881,27 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
{
(void)set_confused(0);
}
- if (r_ptr->flags6 & RF6_S_THUNDERLORD)
+ if (r_ptr->spells & SF_S_THUNDERLORD)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_THUNDERLORD, FALSE);
}
- if (r_ptr->flags6 & RF6_S_DEMON)
+ if (r_ptr->spells & SF_S_DEMON)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, FALSE);
}
- if (r_ptr->flags6 & RF6_S_KIN)
+ if (r_ptr->spells & SF_S_KIN)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_KIN, FALSE);
}
- if (r_ptr->flags6 & RF6_S_HI_DEMON)
+ if (r_ptr->spells & SF_S_HI_DEMON)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DEMON, FALSE);
}
- if (r_ptr->flags6 & RF6_S_MONSTER)
+ if (r_ptr->spells & SF_S_MONSTER)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE);
}
- if (r_ptr->flags6 & RF6_S_MONSTERS)
+ if (r_ptr->spells & SF_S_MONSTERS)
{
int k;
for (k = 0; k < 8; k++)
@@ -908,47 +909,47 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE);
}
}
- if (r_ptr->flags6 & RF6_S_UNDEAD)
+ if (r_ptr->spells & SF_S_UNDEAD)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, FALSE);
}
- if (r_ptr->flags6 & RF6_S_DRAGON)
+ if (r_ptr->spells & SF_S_DRAGON)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON, FALSE);
}
- if (r_ptr->flags6 & RF6_S_ANT)
+ if (r_ptr->spells & SF_S_ANT)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT, FALSE);
}
- if (r_ptr->flags6 & RF6_S_SPIDER)
+ if (r_ptr->spells & SF_S_SPIDER)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER, FALSE);
}
- if (r_ptr->flags6 & RF6_S_HOUND)
+ if (r_ptr->spells & SF_S_HOUND)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND, FALSE);
}
- if (r_ptr->flags6 & RF6_S_HYDRA)
+ if (r_ptr->spells & SF_S_HYDRA)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA, FALSE);
}
- if (r_ptr->flags6 & RF6_S_ANGEL)
+ if (r_ptr->spells & SF_S_ANGEL)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL, FALSE);
}
- if (r_ptr->flags6 & RF6_S_HI_DRAGON)
+ if (r_ptr->spells & SF_S_HI_DRAGON)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON, FALSE);
}
- if (r_ptr->flags6 & RF6_S_HI_UNDEAD)
+ if (r_ptr->spells & SF_S_HI_UNDEAD)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD, FALSE);
}
- if (r_ptr->flags6 & RF6_S_WRAITH)
+ if (r_ptr->spells & SF_S_WRAITH)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH, FALSE);
}
- if (r_ptr->flags6 & RF6_S_UNIQUE)
+ if (r_ptr->spells & SF_S_UNIQUE)
{
summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE, FALSE);
}
diff --git a/src/defines.h b/src/defines.h
index a809f8d3..942675b5 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -2739,114 +2739,6 @@
/*
* New monster race bit flags
*/
-#define RF4_SHRIEK 0x00000001 /* Shriek for help */
-#define RF4_MULTIPLY 0x00000002 /* Monster reproduces */
-#define RF4_S_ANIMAL 0x00000004 /* Summon animals */
-#define RF4_ROCKET 0x00000008 /* TY: Rocket */
-#define RF4_ARROW_1 0x00000010 /* Fire an arrow (light) */
-#define RF4_ARROW_2 0x00000020 /* Fire an arrow (heavy) */
-#define RF4_ARROW_3 0x00000040 /* Fire missiles (light) */
-#define RF4_ARROW_4 0x00000080 /* Fire missiles (heavy) */
-#define RF4_BR_ACID 0x00000100 /* Breathe Acid */
-#define RF4_BR_ELEC 0x00000200 /* Breathe Elec */
-#define RF4_BR_FIRE 0x00000400 /* Breathe Fire */
-#define RF4_BR_COLD 0x00000800 /* Breathe Cold */
-#define RF4_BR_POIS 0x00001000 /* Breathe Poison */
-#define RF4_BR_NETH 0x00002000 /* Breathe Nether */
-#define RF4_BR_LITE 0x00004000 /* Breathe Lite */
-#define RF4_BR_DARK 0x00008000 /* Breathe Dark */
-#define RF4_BR_CONF 0x00010000 /* Breathe Confusion */
-#define RF4_BR_SOUN 0x00020000 /* Breathe Sound */
-#define RF4_BR_CHAO 0x00040000 /* Breathe Chaos */
-#define RF4_BR_DISE 0x00080000 /* Breathe Disenchant */
-#define RF4_BR_NEXU 0x00100000 /* Breathe Nexus */
-#define RF4_BR_TIME 0x00200000 /* Breathe Time */
-#define RF4_BR_INER 0x00400000 /* Breathe Inertia */
-#define RF4_BR_GRAV 0x00800000 /* Breathe Gravity */
-#define RF4_BR_SHAR 0x01000000 /* Breathe Shards */
-#define RF4_BR_PLAS 0x02000000 /* Breathe Plasma */
-#define RF4_BR_WALL 0x04000000 /* Breathe Force */
-#define RF4_BR_MANA 0x08000000 /* Breathe Mana */
-#define RF4_BA_NUKE 0x10000000 /* TY: Nuke Ball */
-#define RF4_BR_NUKE 0x20000000 /* TY: Toxic Breath */
-#define RF4_BA_CHAO 0x40000000 /* Chaos Ball */
-#define RF4_BR_DISI 0x80000000 /* Breathe Disintegration */
-
-/*
- * New monster race bit flags
- */
-#define RF5_BA_ACID 0x00000001 /* Acid Ball */
-#define RF5_BA_ELEC 0x00000002 /* Elec Ball */
-#define RF5_BA_FIRE 0x00000004 /* Fire Ball */
-#define RF5_BA_COLD 0x00000008 /* Cold Ball */
-#define RF5_BA_POIS 0x00000010 /* Poison Ball */
-#define RF5_BA_NETH 0x00000020 /* Nether Ball */
-#define RF5_BA_WATE 0x00000040 /* Water Ball */
-#define RF5_BA_MANA 0x00000080 /* Mana Storm */
-#define RF5_BA_DARK 0x00000100 /* Darkness Storm */
-#define RF5_DRAIN_MANA 0x00000200 /* Drain Mana */
-#define RF5_MIND_BLAST 0x00000400 /* Blast Mind */
-#define RF5_BRAIN_SMASH 0x00000800 /* Smash Brain */
-#define RF5_CAUSE_1 0x00001000 /* Cause Light Wound */
-#define RF5_CAUSE_2 0x00002000 /* Cause Serious Wound */
-#define RF5_CAUSE_3 0x00004000 /* Cause Critical Wound */
-#define RF5_CAUSE_4 0x00008000 /* Cause Mortal Wound */
-#define RF5_BO_ACID 0x00010000 /* Acid Bolt */
-#define RF5_BO_ELEC 0x00020000 /* Elec Bolt (unused) */
-#define RF5_BO_FIRE 0x00040000 /* Fire Bolt */
-#define RF5_BO_COLD 0x00080000 /* Cold Bolt */
-#define RF5_BO_POIS 0x00100000 /* Poison Bolt (unused) */
-#define RF5_BO_NETH 0x00200000 /* Nether Bolt */
-#define RF5_BO_WATE 0x00400000 /* Water Bolt */
-#define RF5_BO_MANA 0x00800000 /* Mana Bolt */
-#define RF5_BO_PLAS 0x01000000 /* Plasma Bolt */
-#define RF5_BO_ICEE 0x02000000 /* Ice Bolt */
-#define RF5_MISSILE 0x04000000 /* Magic Missile */
-#define RF5_SCARE 0x08000000 /* Frighten Player */
-#define RF5_BLIND 0x10000000 /* Blind Player */
-#define RF5_CONF 0x20000000 /* Confuse Player */
-#define RF5_SLOW 0x40000000 /* Slow Player */
-#define RF5_HOLD 0x80000000 /* Paralyze Player */
-
-/*
- * New monster race bit flags
- */
-#define RF6_HASTE 0x00000001 /* Speed self */
-#define RF6_HAND_DOOM 0x00000002 /* Hand of Doom */
-#define RF6_HEAL 0x00000004 /* Heal self */
-#define RF6_S_ANIMALS 0x00000008 /* Summon animals */
-#define RF6_BLINK 0x00000010 /* Teleport Short */
-#define RF6_TPORT 0x00000020 /* Teleport Long */
-#define RF6_TELE_TO 0x00000040 /* Move player to monster */
-#define RF6_TELE_AWAY 0x00000080 /* Move player far away */
-#define RF6_TELE_LEVEL 0x00000100 /* Move player vertically */
-#define RF6_DARKNESS 0x00000200 /* Create Darkness */
-#define RF6_TRAPS 0x00000400 /* Create Traps */
-#define RF6_FORGET 0x00000800 /* Cause amnesia */
-#define RF6_RAISE_DEAD 0x00001000 /* Raise Dead */
-#define RF6_S_BUG 0x00002000 /* Summon Software bug */
-#define RF6_S_RNG 0x00004000 /* Summon RNG */
-#define RF6_S_THUNDERLORD 0x00008000 /* Summon Thunderlords */
-#define RF6_S_KIN 0x00010000 /* Summon "kin" */
-#define RF6_S_HI_DEMON 0x00020000 /* Summon greater demons! */
-#define RF6_S_MONSTER 0x00040000 /* Summon Monster */
-#define RF6_S_MONSTERS 0x00080000 /* Summon Monsters */
-#define RF6_S_ANT 0x00100000 /* Summon Ants */
-#define RF6_S_SPIDER 0x00200000 /* Summon Spiders */
-#define RF6_S_HOUND 0x00400000 /* Summon Hounds */
-#define RF6_S_HYDRA 0x00800000 /* Summon Hydras */
-#define RF6_S_ANGEL 0x01000000 /* Summon Angel */
-#define RF6_S_DEMON 0x02000000 /* Summon Demon */
-#define RF6_S_UNDEAD 0x04000000 /* Summon Undead */
-#define RF6_S_DRAGON 0x08000000 /* Summon Dragon */
-#define RF6_S_HI_UNDEAD 0x10000000 /* Summon Greater Undead */
-#define RF6_S_HI_DRAGON 0x20000000 /* Summon Ancient Dragon */
-#define RF6_S_WRAITH 0x40000000 /* Summon Unique Wraith */
-#define RF6_S_UNIQUE 0x80000000 /* Summon Unique Monster */
-
-/*
- * New monster race bit flags
- */
#define RF7_AQUATIC 0x00000001 /* Aquatic monster */
#define RF7_CAN_SWIM 0x00000002 /* Monster can swim */
#define RF7_CAN_FLY 0x00000004 /* Monster can fly */
@@ -2913,57 +2805,6 @@
#define RF9_NEVER_GENE 0x00004000 /* The monster cannot be normaly generated */
-/*
- * Hack -- choose "intelligent" spells when desperate
- */
-
-#define RF4_INT_MASK \
- (RF4_S_ANIMAL)
-
-#define RF5_INT_MASK \
- (RF5_HOLD | RF5_SLOW | RF5_CONF | RF5_BLIND | RF5_SCARE)
-
-#define RF6_INT_MASK \
- (RF6_BLINK | RF6_TPORT | RF6_TELE_LEVEL | RF6_TELE_AWAY | \
- RF6_HEAL | RF6_HASTE | RF6_TRAPS | \
- RF6_S_KIN | RF6_S_HI_DEMON | RF6_S_MONSTER | RF6_S_MONSTERS | \
- RF6_S_ANT | RF6_S_SPIDER | RF6_S_HOUND | RF6_S_HYDRA | \
- RF6_S_ANGEL | RF6_S_DRAGON | RF6_S_UNDEAD | RF6_S_DEMON | \
- RF6_S_HI_DRAGON | RF6_S_HI_UNDEAD | RF6_S_WRAITH | RF6_S_UNIQUE | \
- RF6_S_THUNDERLORD | RF6_S_BUG | RF6_S_RNG | RF6_S_ANIMALS)
-
-
-/*
- * Hack -- "bolt" spells that may hurt fellow monsters
- */
-#define RF4_BOLT_MASK \
- (RF4_ARROW_1 | RF4_ARROW_2 | RF4_ARROW_3 | RF4_ARROW_4)
-
-#define RF5_BOLT_MASK \
- (RF5_BO_ACID | RF5_BO_ELEC | RF5_BO_FIRE | RF5_BO_COLD | \
- RF5_BO_POIS | RF5_BO_NETH | RF5_BO_WATE | RF5_BO_MANA | \
- RF5_BO_PLAS | RF5_BO_ICEE | RF5_MISSILE)
-
-#define RF6_BOLT_MASK \
- 0L
-
-
-/* Hack -- summon spells */
-
-#define RF4_SUMMON_MASK \
- (RF4_S_ANIMAL)
-
-#define RF5_SUMMON_MASK \
- 0L
-
-#define RF6_SUMMON_MASK \
- (RF6_S_KIN | RF6_S_HI_DEMON | RF6_S_MONSTER | RF6_S_MONSTERS | RF6_S_ANT | \
- RF6_S_SPIDER | RF6_S_HOUND | RF6_S_HYDRA | RF6_S_ANGEL | RF6_S_DEMON | \
- RF6_S_UNDEAD | RF6_S_DRAGON | RF6_S_HI_UNDEAD | RF6_S_HI_DRAGON | \
- RF6_S_WRAITH | RF6_S_UNIQUE | RF6_S_THUNDERLORD | RF6_S_BUG | RF6_S_RNG | \
- RF6_S_ANIMALS)
-
-
/*** Macro Definitions ***/
diff --git a/src/flag_set.hpp b/src/flag_set.hpp
index 2e5d46ea..b4bdc92f 100644
--- a/src/flag_set.hpp
+++ b/src/flag_set.hpp
@@ -16,6 +16,9 @@ private:
std::uint32_t m_data[tiers];
public:
+ static constexpr const std::size_t nbits = tiers * 32;
+
+public:
constexpr flag_set()
: m_data { 0 }
@@ -81,6 +84,12 @@ public:
return !empty();
}
+ constexpr bool bit(std::size_t i) const
+ {
+ assert(i < nbits);
+ return (m_data[i / 32] & (1UL << (i % 32)));
+ }
+
flag_set &operator |= (flag_set const &other)
{
for (std::size_t i = 0; i < tiers; i++)
diff --git a/src/generate.cc b/src/generate.cc
index dc5005d0..ed35035c 100644
--- a/src/generate.cc
+++ b/src/generate.cc
@@ -21,6 +21,7 @@
#include "loadsave.hpp"
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object2.hpp"
#include "object_kind.hpp"
@@ -2857,33 +2858,6 @@ static bool_ vault_aux_giant(int r_idx)
/*
- * Hack -- breath type for "vault_aux_dragon()"
- */
-static u32b vault_aux_dragon_mask4;
-
-
-/*
- * Helper function for "monster pit (dragon)"
- */
-static bool_ vault_aux_dragon(int r_idx)
-{
- monster_race *r_ptr = &r_info[r_idx];
-
- /* Decline unique monsters */
- if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
-
- /* Hack -- Require "d" or "D" monsters */
- if (!strchr("Dd", r_ptr->d_char)) return (FALSE);
-
- /* Hack -- Require correct "breath attack" */
- if (r_ptr->flags4 != vault_aux_dragon_mask4) return (FALSE);
-
- /* Okay */
- return (TRUE);
-}
-
-
-/*
* Helper function for "monster pit (demon)"
*/
static bool_ vault_aux_demon(int r_idx)
@@ -3283,93 +3257,71 @@ static void build_type6(int by0, int bx0)
/* Dragon pit */
else if (tmp < 80)
{
+ /* Hack - get_mon_num_hook needs a plain function */
+ static monster_spell_flag_set mask;
+
/* Pick dragon type */
switch (rand_int(6))
{
- /* Black */
case 0:
{
- /* Message */
name = "acid dragon";
-
- /* Restrict dragon breath type */
- vault_aux_dragon_mask4 = RF4_BR_ACID;
-
- /* Done */
+ mask = SF_BR_ACID;
break;
}
-
- /* Blue */
case 1:
{
- /* Message */
name = "electric dragon";
-
- /* Restrict dragon breath type */
- vault_aux_dragon_mask4 = RF4_BR_ELEC;
-
- /* Done */
+ mask = SF_BR_ELEC;
break;
}
- /* Red */
case 2:
{
- /* Message */
name = "fire dragon";
-
- /* Restrict dragon breath type */
- vault_aux_dragon_mask4 = RF4_BR_FIRE;
-
- /* Done */
+ mask = SF_BR_FIRE;
break;
}
- /* White */
case 3:
{
- /* Message */
name = "cold dragon";
-
- /* Restrict dragon breath type */
- vault_aux_dragon_mask4 = RF4_BR_COLD;
-
- /* Done */
+ mask = SF_BR_COLD;
break;
}
- /* Green */
case 4:
{
- /* Message */
name = "poison dragon";
-
- /* Restrict dragon breath type */
- vault_aux_dragon_mask4 = RF4_BR_POIS;
-
- /* Done */
+ mask = SF_BR_POIS;
break;
}
- /* Multi-hued */
default:
{
- /* Message */
name = "multi-hued dragon";
-
- /* Restrict dragon breath type */
- vault_aux_dragon_mask4 = (RF4_BR_ACID | RF4_BR_ELEC |
- RF4_BR_FIRE | RF4_BR_COLD |
- RF4_BR_POIS);
-
- /* Done */
+ mask = SF_BR_ACID | SF_BR_ELEC | SF_BR_FIRE | SF_BR_COLD | SF_BR_POIS;
break;
}
}
/* Restrict monster selection */
- get_mon_num_hook = vault_aux_dragon;
+ get_mon_num_hook = [](int r_idx) -> bool_ {
+ monster_race *r_ptr = &r_info[r_idx];
+
+ /* Decline unique monsters */
+ if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
+
+ /* Hack -- Require "d" or "D" monsters */
+ if (!strchr("Dd", r_ptr->d_char)) return (FALSE);
+
+ /* Hack -- Require correct "breath attack" */
+ if ((r_ptr->spells & mask) != mask) return (FALSE);
+
+ /* Okay */
+ return (TRUE);
+ };
}
/* Demon pit */
diff --git a/src/init1.cc b/src/init1.cc
index cfd767f8..3b94adb5 100644
--- a/src/init1.cc
+++ b/src/init1.cc
@@ -16,6 +16,7 @@
#include "monster2.hpp"
#include "monster_ego.hpp"
#include "monster_race.hpp"
+#include "monster_spell.hpp"
#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
@@ -271,124 +272,6 @@ static cptr r_info_flags3[] =
/*
* Monster race flags
*/
-static cptr r_info_flags4[] =
-{
- "SHRIEK",
- "MULTIPLY",
- "S_ANIMAL",
- "ROCKET",
- "ARROW_1",
- "ARROW_2",
- "ARROW_3",
- "ARROW_4",
- "BR_ACID",
- "BR_ELEC",
- "BR_FIRE",
- "BR_COLD",
- "BR_POIS",
- "BR_NETH",
- "BR_LITE",
- "BR_DARK",
- "BR_CONF",
- "BR_SOUN",
- "BR_CHAO",
- "BR_DISE",
- "BR_NEXU",
- "BR_TIME",
- "BR_INER",
- "BR_GRAV",
- "BR_SHAR",
- "BR_PLAS",
- "BR_WALL",
- "BR_MANA",
- "BA_NUKE",
- "BR_NUKE",
- "BA_CHAO",
- "BR_DISI",
-};
-
-/*
- * Monster race flags
- */
-static cptr r_info_flags5[] =
-{
- "BA_ACID",
- "BA_ELEC",
- "BA_FIRE",
- "BA_COLD",
- "BA_POIS",
- "BA_NETH",
- "BA_WATE",
- "BA_MANA",
- "BA_DARK",
- "DRAIN_MANA",
- "MIND_BLAST",
- "BRAIN_SMASH",
- "CAUSE_1",
- "CAUSE_2",
- "CAUSE_3",
- "CAUSE_4",
- "BO_ACID",
- "BO_ELEC",
- "BO_FIRE",
- "BO_COLD",
- "BO_POIS",
- "BO_NETH",
- "BO_WATE",
- "BO_MANA",
- "BO_PLAS",
- "BO_ICEE",
- "MISSILE",
- "SCARE",
- "BLIND",
- "CONF",
- "SLOW",
- "HOLD"
-};
-
-/*
- * Monster race flags
- */
-static cptr r_info_flags6[] =
-{
- "HASTE",
- "HAND_DOOM",
- "HEAL",
- "S_ANIMALS",
- "BLINK",
- "TPORT",
- "TELE_TO",
- "TELE_AWAY",
- "TELE_LEVEL",
- "DARKNESS",
- "TRAPS",
- "FORGET",
- "ANIM_DEAD", /* ToDo: Implement ANIM_DEAD */
- "S_BUG",
- "S_RNG",
- "S_THUNDERLORD", /* DG : Summon Thunderlord */
- "S_KIN",
- "S_HI_DEMON",
- "S_MONSTER",
- "S_MONSTERS",
- "S_ANT",
- "S_SPIDER",
- "S_HOUND",
- "S_HYDRA",
- "S_ANGEL",
- "S_DEMON",
- "S_UNDEAD",
- "S_DRAGON",
- "S_HI_UNDEAD",
- "S_HI_DRAGON",
- "S_WRAITH",
- "S_UNIQUE"
-};
-
-
-/*
- * Monster race flags
- */
static cptr r_info_flags7[] =
{
"AQUATIC",
@@ -5488,14 +5371,15 @@ static errr grab_one_basic_flag(monster_race *r_ptr, cptr what)
/*
* Grab one (spell) flag in a monster_race from a textual string
*/
-static errr grab_one_spell_flag(monster_race *r_ptr, cptr what)
+static errr grab_one_monster_spell_flag(monster_spell_flag_set *flags, cptr what)
{
- if (lookup_flags(what,
- flag_tie(&r_ptr->flags4, r_info_flags4),
- flag_tie(&r_ptr->flags5, r_info_flags5),
- flag_tie(&r_ptr->flags6, r_info_flags6)))
+ for (auto const &monster_spell: monster_spells())
{
- return (0);
+ if (streq(what, monster_spell->name))
+ {
+ *flags |= monster_spell->flag_set;
+ return 0;
+ }
}
/* Oops */
@@ -5823,7 +5707,7 @@ errr init_r_info_txt(FILE *fp)
/* Parse this entry */
else
{
- if (0 != grab_one_spell_flag(r_ptr, s))
+ if (0 != grab_one_monster_spell_flag(&r_ptr->spells, s))
{
return (5);
}
@@ -5887,32 +5771,6 @@ static errr grab_one_basic_ego_flag(monster_ego *re_ptr, cptr what, bool_ add)
/*
- * Grab one (spell) flag in a monster_race from a textual string
- */
-static errr grab_one_spell_ego_flag(monster_ego *re_ptr, cptr what, bool_ add)
-{
- /* Dispatch to correct set of flags */
- u32b *f4 = add ? &re_ptr->mflags4 : &re_ptr->nflags4;
- u32b *f5 = add ? &re_ptr->mflags5 : &re_ptr->nflags5;
- u32b *f6 = add ? &re_ptr->mflags6 : &re_ptr->nflags6;
-
- /* Lookup */
- if (lookup_flags(what,
- flag_tie(f4, r_info_flags4),
- flag_tie(f5, r_info_flags5),
- flag_tie(f6, r_info_flags6)))
- {
- return (0);
- }
-
- /* Oops */
- msg_format("Unknown monster flag '%s'.", what);
-
- /* Failure */
- return (1);
-}
-
-/*
* Grab one (basic) flag in a monster_race from a textual string
*/
static errr grab_one_ego_flag(monster_ego *re_ptr, cptr what, bool_ must)
@@ -6278,7 +6136,7 @@ errr init_re_info_txt(FILE *fp)
/* Parse this entry */
else {
- if (0 != grab_one_spell_ego_flag(re_ptr, s, TRUE))
+ if (0 != grab_one_monster_spell_flag(&re_ptr->mspells, s))
{
return (5);
}
@@ -6308,7 +6166,7 @@ errr init_re_info_txt(FILE *fp)
if (!strcmp(s, "MF_ALL"))
{
/* No flags */
- re_ptr->nflags4 = re_ptr->nflags5 = re_ptr->nflags6 = 0xFFFFFFFF;
+ re_ptr->nspells = ~monster_spell_flag_set();
/* Start at next entry */
s = t;
@@ -6318,7 +6176,7 @@ errr init_re_info_txt(FILE *fp)
}
/* Parse this entry */
- if (0 != grab_one_spell_ego_flag(re_ptr, s, FALSE)) return (5);
+ if (0 != grab_one_monster_spell_flag(&re_ptr->nspells, s)) return (5);
/* Start the next entry */
s = t;
@@ -6549,26 +6407,6 @@ static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what, byt
/*
- * Grab one (spell) flag in a monster_race from a textual string
- */
-static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what, byte rule)
-{
- if (lookup_flags(what,
- flag_tie(&d_ptr->rules[rule].mflags4, r_info_flags4),
- flag_tie(&d_ptr->rules[rule].mflags5, r_info_flags5),
- flag_tie(&d_ptr->rules[rule].mflags6, r_info_flags6)))
- {
- return 0;
- }
-
- /* Oops */
- msg_format("Unknown monster flag '%s'.", what);
-
- /* Failure */
- return (1);
-}
-
-/*
* Initialize the "d_info" array, by parsing an ascii "template" file
*/
errr init_d_info_txt(FILE *fp)
@@ -7009,7 +6847,7 @@ errr init_d_info_txt(FILE *fp)
s = buf + 2;
/* Parse this entry */
- if (0 != grab_one_spell_monster_flag(d_ptr, s, rule_num))
+ if (0 != grab_one_monster_spell_flag(&d_ptr->rules[rule_num].mspells, s))
{
return (5);
}
diff --git a/src/melee2.cc b/src/melee2.cc
index 83827dcf..3e03c8f6 100644
--- a/src/melee2.cc
+++ b/src/melee2.cc
@@ -28,6 +28,8 @@
#include "monster2.hpp"
#include "monster3.hpp"
#include "monster_race.hpp"
+#include "monster_spell.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
@@ -301,16 +303,13 @@ static bool_ int_outof(std::shared_ptr<monster_race> r_ptr, int prob)
/*
* Remove the "bad" spells from a spell list
*/
-static void remove_bad_spells(int m_idx, u32b *f4p, u32b *f5p, u32b *f6p)
+static void remove_bad_spells(int m_idx, monster_spell_flag_set *spells_p)
{
monster_type *m_ptr = &m_list[m_idx];
-
- u32b f4 = (*f4p);
- u32b f5 = (*f5p);
- u32b f6 = (*f6p);
-
u32b smart = 0L;
+ // Shorthand
+ auto spells(*spells_p);
/* Too stupid to know anything? */
auto const r_ptr = m_ptr->race();
@@ -338,201 +337,199 @@ static void remove_bad_spells(int m_idx, u32b *f4p, u32b *f5p, u32b *f6p)
if (smart & (SM_IMM_ACID))
{
- if (int_outof(r_ptr, 100)) f4 &= ~RF4_BR_ACID;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BA_ACID;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_ACID;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BR_ACID;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BA_ACID;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ACID;
}
else if ((smart & (SM_OPP_ACID)) && (smart & (SM_RES_ACID)))
{
- if (int_outof(r_ptr, 80)) f4 &= ~RF4_BR_ACID;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BA_ACID;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BO_ACID;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BR_ACID;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BA_ACID;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BO_ACID;
}
else if ((smart & (SM_OPP_ACID)) || (smart & (SM_RES_ACID)))
{
- if (int_outof(r_ptr, 30)) f4 &= ~RF4_BR_ACID;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BA_ACID;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BO_ACID;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BR_ACID;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BA_ACID;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BO_ACID;
}
if (smart & (SM_IMM_ELEC))
{
- if (int_outof(r_ptr, 100)) f4 &= ~RF4_BR_ELEC;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BA_ELEC;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_ELEC;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BR_ELEC;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BA_ELEC;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ELEC;
}
else if ((smart & (SM_OPP_ELEC)) && (smart & (SM_RES_ELEC)))
{
- if (int_outof(r_ptr, 80)) f4 &= ~RF4_BR_ELEC;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BA_ELEC;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BO_ELEC;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BR_ELEC;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BA_ELEC;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BO_ELEC;
}
else if ((smart & (SM_OPP_ELEC)) || (smart & (SM_RES_ELEC)))
{
- if (int_outof(r_ptr, 30)) f4 &= ~RF4_BR_ELEC;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BA_ELEC;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BO_ELEC;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BR_ELEC;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BA_ELEC;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BO_ELEC;
}
if (smart & (SM_IMM_FIRE))
{
- if (int_outof(r_ptr, 100)) f4 &= ~RF4_BR_FIRE;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BA_FIRE;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_FIRE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BR_FIRE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BA_FIRE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_FIRE;
}
else if ((smart & (SM_OPP_FIRE)) && (smart & (SM_RES_FIRE)))
{
- if (int_outof(r_ptr, 80)) f4 &= ~RF4_BR_FIRE;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BA_FIRE;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BO_FIRE;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BR_FIRE;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BA_FIRE;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BO_FIRE;
}
else if ((smart & (SM_OPP_FIRE)) || (smart & (SM_RES_FIRE)))
{
- if (int_outof(r_ptr, 30)) f4 &= ~RF4_BR_FIRE;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BA_FIRE;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BO_FIRE;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BR_FIRE;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BA_FIRE;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BO_FIRE;
}
if (smart & (SM_IMM_COLD))
{
- if (int_outof(r_ptr, 100)) f4 &= ~RF4_BR_COLD;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BA_COLD;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_COLD;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_ICEE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BR_COLD;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BA_COLD;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_COLD;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ICEE;
}
else if ((smart & (SM_OPP_COLD)) && (smart & (SM_RES_COLD)))
{
- if (int_outof(r_ptr, 80)) f4 &= ~RF4_BR_COLD;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BA_COLD;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BO_COLD;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BO_ICEE;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BR_COLD;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BA_COLD;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BO_COLD;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BO_ICEE;
}
else if ((smart & (SM_OPP_COLD)) || (smart & (SM_RES_COLD)))
{
- if (int_outof(r_ptr, 30)) f4 &= ~RF4_BR_COLD;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BA_COLD;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BO_COLD;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BO_ICEE;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BR_COLD;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BA_COLD;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BO_COLD;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BO_ICEE;
}
if ((smart & (SM_OPP_POIS)) && (smart & (SM_RES_POIS)))
{
- if (int_outof(r_ptr, 80)) f4 &= ~RF4_BR_POIS;
- if (int_outof(r_ptr, 80)) f5 &= ~RF5_BA_POIS;
- if (int_outof(r_ptr, 40)) f4 &= ~RF4_BA_NUKE;
- if (int_outof(r_ptr, 40)) f4 &= ~RF4_BR_NUKE;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BR_POIS;
+ if (int_outof(r_ptr, 80)) spells &= ~SF_BA_POIS;
+ if (int_outof(r_ptr, 40)) spells &= ~SF_BA_NUKE;
+ if (int_outof(r_ptr, 40)) spells &= ~SF_BR_NUKE;
}
else if ((smart & (SM_OPP_POIS)) || (smart & (SM_RES_POIS)))
{
- if (int_outof(r_ptr, 30)) f4 &= ~RF4_BR_POIS;
- if (int_outof(r_ptr, 30)) f5 &= ~RF5_BA_POIS;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BR_POIS;
+ if (int_outof(r_ptr, 30)) spells &= ~SF_BA_POIS;
}
if (smart & (SM_RES_NETH))
{
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_NETH;
- if (int_outof(r_ptr, 50)) f5 &= ~RF5_BA_NETH;
- if (int_outof(r_ptr, 50)) f5 &= ~RF5_BO_NETH;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_NETH;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BA_NETH;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BO_NETH;
}
if (smart & (SM_RES_LITE))
{
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_LITE;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_LITE;
}
if (smart & (SM_RES_DARK))
{
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_DARK;
- if (int_outof(r_ptr, 50)) f5 &= ~RF5_BA_DARK;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_DARK;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BA_DARK;
}
if (smart & (SM_RES_FEAR))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_SCARE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_SCARE;
}
if (smart & (SM_RES_CONF))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_CONF;
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_CONF;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_CONF;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_CONF;
}
if (smart & (SM_RES_CHAOS))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_CONF;
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_CONF;
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_CHAO;
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BA_CHAO;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_CONF;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_CONF;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_CHAO;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BA_CHAO;
}
if (smart & (SM_RES_DISEN))
{
- if (int_outof(r_ptr, 100)) f4 &= ~RF4_BR_DISE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BR_DISE;
}
if (smart & (SM_RES_BLIND))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BLIND;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BLIND;
}
if (smart & (SM_RES_NEXUS))
{
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_NEXU;
- if (int_outof(r_ptr, 50)) f6 &= ~RF6_TELE_LEVEL;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_NEXU;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_TELE_LEVEL;
}
if (smart & (SM_RES_SOUND))
{
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_SOUN;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_SOUN;
}
if (smart & (SM_RES_SHARD))
{
- if (int_outof(r_ptr, 50)) f4 &= ~RF4_BR_SHAR;
- if (int_outof(r_ptr, 20)) f4 &= ~RF4_ROCKET;
+ if (int_outof(r_ptr, 50)) spells &= ~SF_BR_SHAR;
+ if (int_outof(r_ptr, 20)) spells &= ~SF_ROCKET;
}
if (smart & (SM_IMM_REFLECT))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_COLD;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_FIRE;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_ACID;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_ELEC;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_POIS;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_NETH;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_WATE;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_MANA;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_PLAS;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_BO_ICEE;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_MISSILE;
- if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_1);
- if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_2);
- if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_3);
- if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_4);
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_COLD;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_FIRE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ACID;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ELEC;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_POIS;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_NETH;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_WATE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_MANA;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_PLAS;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ICEE;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_MISSILE;
+ if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_1);
+ if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_2);
+ if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_3);
+ if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_4);
}
if (smart & (SM_IMM_FREE))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_HOLD;
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_SLOW;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_HOLD;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_SLOW;
}
if (smart & (SM_IMM_MANA))
{
- if (int_outof(r_ptr, 100)) f5 &= ~RF5_DRAIN_MANA;
+ if (int_outof(r_ptr, 100)) spells &= ~SF_DRAIN_MANA;
}
/* XXX XXX XXX No spells left? */
/* if (!f4 && !f5 && !f6) ... */
- (*f4p) = f4;
- (*f5p) = f5;
- (*f6p) = f6;
+ *spells_p = spells;
}
@@ -628,117 +625,70 @@ static void bolt(int m_idx, int typ, int dam_hp)
/*
- * Return TRUE if a spell is good for hurting the player (directly).
- */
-static bool_ spell_attack(byte spell)
-{
- /* All RF4 spells hurt (except for shriek, multiply, summon animal) */
- if (spell >= 96 + 3 && spell <= 96 + 31) return (TRUE);
-
- /* Various "ball" spells */
- if (spell >= 128 && spell <= 128 + 8) return (TRUE);
-
- /* "Cause wounds" and "bolt" spells */
- if (spell >= 128 + 12 && spell <= 128 + 26) return (TRUE);
-
- /* Hand of Doom */
- if (spell == 160 + 1) return (TRUE);
-
- /* Doesn't hurt */
- return (FALSE);
-}
-
-
-/*
- * Return TRUE if a spell is good for escaping.
- */
-static bool_ spell_escape(byte spell)
-{
- /* Blink or Teleport */
- if (spell == 160 + 4 || spell == 160 + 5) return (TRUE);
-
- /* Teleport the player away */
- if (spell == 160 + 7 || spell == 160 + 8) return (TRUE);
-
- /* Isn't good for escaping */
- return (FALSE);
-}
-
-/*
- * Return TRUE if a spell is good for annoying the player.
- */
-static bool_ spell_annoy(byte spell)
-{
- /* Shriek */
- if (spell == 96 + 0) return (TRUE);
-
- /* Brain smash, et al (added curses) */
- if (spell >= 128 + 9 && spell <= 128 + 14) return (TRUE);
-
- /* Scare, confuse, blind, slow, paralyze */
- if (spell >= 128 + 27 && spell <= 128 + 31) return (TRUE);
-
- /* Teleport to */
- if (spell == 160 + 6) return (TRUE);
-
- /* Darkness, make traps, cause amnesia */
- if (spell >= 160 + 9 && spell <= 160 + 11) return (TRUE);
-
- /* Doesn't annoy */
- return (FALSE);
-}
-
-/*
- * Return TRUE if a spell summons help.
+ * Calculate the mask for "bolt" spells
*/
-static bool_ spell_summon(byte spell)
+static monster_spell_flag_set compute_bolt_mask()
{
- /* RF4_S_ANIMAL, RF6_S_ANIMALS */
- if (spell == 96 + 2 || spell == 160 + 3) return (TRUE);
- /* All other summon spells */
- if (spell >= 160 + 13 && spell <= 160 + 31) return (TRUE);
-
- /* Doesn't summon */
- return (FALSE);
+ monster_spell_flag_set flags;
+ for (auto const &monster_spell: monster_spells())
+ {
+ if (monster_spell->is_bolt)
+ {
+ flags |= monster_spell->flag_set;
+ }
+ }
+ return flags;
}
/*
- * Return TRUE if a spell is good in a tactical situation.
+ * Calculate mask for summoning spells
*/
-static bool_ spell_tactic(byte spell)
+static monster_spell_flag_set compute_summoning_mask()
{
- /* Blink */
- if (spell == 160 + 4) return (TRUE);
-
- /* Not good */
- return (FALSE);
+ monster_spell_flag_set flags;
+ for (auto const &monster_spell: monster_spells())
+ {
+ if (monster_spell->is_summon)
+ {
+ flags |= monster_spell->flag_set;
+ }
+ }
+ return flags;
}
/*
- * Return TRUE if a spell hastes.
+ * Calculate mask for spells requiring SMART flag
*/
-static bool_ spell_haste(byte spell)
+static monster_spell_flag_set compute_smart_mask()
{
- /* Haste self */
- if (spell == 160 + 0) return (TRUE);
-
- /* Not a haste spell */
- return (FALSE);
+ monster_spell_flag_set flags;
+ for (auto const &monster_spell: monster_spells())
+ {
+ if (monster_spell->is_smart)
+ {
+ flags |= monster_spell->flag_set;
+ }
+ }
+ return flags;
}
/*
- * Return TRUE if a spell is good for healing.
+ * Calculate mask for spells requiring SMART flag
*/
-static bool_ spell_heal(byte spell)
+static monster_spell_flag_set compute_innate_mask()
{
- /* Heal */
- if (spell == 160 + 2) return (TRUE);
-
- /* No healing */
- return (FALSE);
+ monster_spell_flag_set flags;
+ for (auto const &monster_spell: monster_spells())
+ {
+ if (monster_spell->is_innate)
+ {
+ flags |= monster_spell->flag_set;
+ }
+ }
+ return flags;
}
@@ -756,49 +706,71 @@ static bool_ spell_heal(byte spell)
*
* This function may well be an efficiency bottleneck.
*/
-static int choose_attack_spell(int m_idx, byte spells[], byte num)
+static monster_spell const *choose_attack_spell(int m_idx, std::vector<monster_spell const *> const &spells)
{
monster_type *m_ptr = &m_list[m_idx];
- byte escape[96], escape_num = 0;
- byte attack[96], attack_num = 0;
- byte summon[96], summon_num = 0;
- byte tactic[96], tactic_num = 0;
- byte annoy[96], annoy_num = 0;
- byte haste[96], haste_num = 0;
- byte heal[96], heal_num = 0;
-
/* Stupid monsters choose randomly */
auto const r_ptr = m_ptr->race();
if (r_ptr->flags2 & RF2_STUPID)
{
/* Pick at random */
- return (spells[rand_int(num)]);
+ return spells[rand_int(spells.size())];
}
+ /* Spells by category */
+ std::vector<monster_spell const *> escape; escape.reserve(spells.size());
+ std::vector<monster_spell const *> attack; attack.reserve(spells.size());
+ std::vector<monster_spell const *> summon; summon.reserve(spells.size());
+ std::vector<monster_spell const *> tactic; tactic.reserve(spells.size());
+ std::vector<monster_spell const *> annoy ; annoy.reserve(spells.size());
+ std::vector<monster_spell const *> haste ; haste.reserve(spells.size());
+ std::vector<monster_spell const *> heal ; heal.reserve(spells.size());
+
/* Categorize spells */
- for (int i = 0; i < num; i++)
+ for (std::size_t i = 0; i < spells.size(); i++)
{
/* Escape spell? */
- if (spell_escape(spells[i])) escape[escape_num++] = spells[i];
+ if (spells[i]->is_escape)
+ {
+ escape.push_back(spells[i]);
+ }
/* Attack spell? */
- if (spell_attack(spells[i])) attack[attack_num++] = spells[i];
+ if (spells[i]->is_damage)
+ {
+ attack.push_back(spells[i]);
+ }
/* Summon spell? */
- if (spell_summon(spells[i])) summon[summon_num++] = spells[i];
+ if (spells[i]->is_summon)
+ {
+ summon.push_back(spells[i]);
+ }
/* Tactical spell? */
- if (spell_tactic(spells[i])) tactic[tactic_num++] = spells[i];
+ if (spells[i]->is_tactic)
+ {
+ tactic.push_back(spells[i]);
+ }
/* Annoyance spell? */
- if (spell_annoy(spells[i])) annoy[annoy_num++] = spells[i];
+ if (spells[i]->is_annoy)
+ {
+ annoy.push_back(spells[i]);
+ }
/* Haste spell? */
- if (spell_haste(spells[i])) haste[haste_num++] = spells[i];
+ if (spells[i]->is_haste)
+ {
+ haste.push_back(spells[i]);
+ }
/* Heal spell? */
- if (spell_heal(spells[i])) heal[heal_num++] = spells[i];
+ if (spells[i]->is_heal)
+ {
+ heal.push_back(spells[i]);
+ }
}
/*** Try to pick an appropriate spell type ***/
@@ -806,68 +778,59 @@ static int choose_attack_spell(int m_idx, byte spells[], byte num)
/* Hurt badly or afraid, attempt to flee */
if ((m_ptr->hp < m_ptr->maxhp / 3) || m_ptr->monfear)
{
- /* Choose escape spell if possible */
- if (escape_num) return (escape[rand_int(escape_num)]);
+ if (!escape.empty()) return escape[rand_int(escape.size())];
}
/* Still hurt badly, couldn't flee, attempt to heal */
if (m_ptr->hp < m_ptr->maxhp / 3)
{
- /* Choose heal spell if possible */
- if (heal_num) return (heal[rand_int(heal_num)]);
+ if (!heal.empty()) return heal[rand_int(heal.size())];
}
/* Player is close and we have attack spells, blink away */
- if ((distance(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx) < 4) && attack_num && (rand_int(100) < 75))
+ if ((distance(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx) < 4) && !attack.empty() && (rand_int(100) < 75))
{
- /* Choose tactical spell */
- if (tactic_num) return (tactic[rand_int(tactic_num)]);
+ if (!tactic.empty()) return tactic[rand_int(tactic.size())];
}
/* We're hurt (not badly), try to heal */
if ((m_ptr->hp < m_ptr->maxhp * 3 / 4) && (rand_int(100) < 75))
{
- /* Choose heal spell if possible */
- if (heal_num) return (heal[rand_int(heal_num)]);
+ if (!heal.empty()) return heal[rand_int(heal.size())];
}
/* Summon if possible (sometimes) */
- if (summon_num && (rand_int(100) < 50))
+ if (!summon.empty() && (rand_int(100) < 50))
{
- /* Choose summon spell */
- return (summon[rand_int(summon_num)]);
+ return summon[rand_int(summon.size())];
}
/* Attack spell (most of the time) */
- if (attack_num && (rand_int(100) < 85))
+ if (!attack.empty() && (rand_int(100) < 85))
{
- /* Choose attack spell */
- return (attack[rand_int(attack_num)]);
+ return attack[rand_int(attack.size())];
}
/* Try another tactical spell (sometimes) */
- if (tactic_num && (rand_int(100) < 50))
+ if (!tactic.empty() && (rand_int(100) < 50))
{
- /* Choose tactic spell */
- return (tactic[rand_int(tactic_num)]);
+ return tactic[rand_int(tactic.size())];
}
/* Haste self if we aren't already somewhat hasted (rarely) */
- if (haste_num && (rand_int(100) < (20 + m_ptr->speed - m_ptr->mspeed)))
+ if (!haste.empty() && (rand_int(100) < (20 + m_ptr->speed - m_ptr->mspeed)))
{
- /* Choose haste spell */
- return (haste[rand_int(haste_num)]);
+ return haste[rand_int(haste.size())];
}
/* Annoy player (most of the time) */
- if (annoy_num && (rand_int(100) < 85))
+ if (!annoy.empty() && (rand_int(100) < 85))
{
- /* Choose annoyance spell */
- return (annoy[rand_int(annoy_num)]);
+ return annoy[rand_int(annoy.size())];
}
/* Choose no spell */
- return (0);
+ return nullptr;
}
@@ -981,6 +944,24 @@ void cmonster_msg(char a, cptr fmt, ...)
}
}
+/**
+ * Extract list of spell indexes from a flag set.
+ */
+static std::vector<monster_spell const *> extract_spells(monster_spell_flag_set const &spell_flag_set)
+{
+ auto result = std::vector<monster_spell const *>();
+ result.reserve(spell_flag_set.nbits);
+
+ for (std::size_t k = 0; k < monster_spell_flag_set::nbits; k++)
+ {
+ if (spell_flag_set.bit(k))
+ {
+ result.push_back(monster_spells()[k]);
+ }
+ }
+
+ return result;
+}
/*
* Monster tries to 'cast a spell' (or breath, etc)
@@ -989,15 +970,14 @@ void cmonster_msg(char a, cptr fmt, ...)
int monst_spell_monst_spell = -1;
static bool_ monst_spell_monst(int m_idx)
{
+ static const monster_spell_flag_set SF_INT_MASK = compute_smart_mask();
+
int y = 0, x = 0;
int i = 1;
- int thrown_spell;
- byte spell[96], num = 0;
char m_name[80], t_name[80];
char m_poss[80];
char ddesc[80];
monster_type *m_ptr = &m_list[m_idx]; /* Attacker */
- u32b f4, f5, f6; /* racial spell flags */
bool_ direct = TRUE;
bool_ wake_up = FALSE;
@@ -1059,10 +1039,8 @@ static bool_ monst_spell_monst(int m_idx)
/* Extract the monster level */
const int rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1);
- /* Extract the racial spell flags */
- f4 = r_ptr->flags4;
- f5 = r_ptr->flags5;
- f6 = r_ptr->flags6;
+ /* Which spells are allowed? */
+ monster_spell_flag_set allowed_spells = r_ptr->spells;
/* Hack -- allow "desperate" spells */
if ((r_ptr->flags2 & RF2_SMART) &&
@@ -1070,34 +1048,17 @@ static bool_ monst_spell_monst(int m_idx)
(rand_int(100) < 50))
{
/* Require intelligent spells */
- f4 &= RF4_INT_MASK;
- f5 &= RF5_INT_MASK;
- f6 &= RF6_INT_MASK;
-
- /* No spells left */
- if ((!f4 && !f5 && !f6) && (monst_spell_monst_spell == -1)) return (FALSE);
- }
+ allowed_spells &= SF_INT_MASK;
- /* Extract the "inate" spells */
- for (int k = 0; k < 32; k++)
- {
- if (f4 & (1L << k)) spell[num++] = k + 32 * 3;
- }
-
- /* Extract the "normal" spells */
- for (int k = 0; k < 32; k++)
- {
- if (f5 & (1L << k)) spell[num++] = k + 32 * 4;
+ /* No spells left? */
+ if ((!allowed_spells) && (monst_spell_monst_spell == -1)) return (FALSE);
}
- /* Extract the "bizarre" spells */
- for (int k = 0; k < 32; k++)
- {
- if (f6 & (1L << k)) spell[num++] = k + 32 * 5;
- }
+ /* Extract spells */
+ auto spell = extract_spells(allowed_spells);
- /* No spells left */
- if (!num) return (FALSE);
+ /* No spells left? */
+ if (spell.empty()) return (FALSE);
/* Stop if player is dead or gone */
if (!alive || death) return (FALSE);
@@ -1118,12 +1079,12 @@ static bool_ monst_spell_monst(int m_idx)
monster_desc(ddesc, m_ptr, 0x88);
/* Choose a spell to cast */
- thrown_spell = spell[rand_int(num)];
+ auto thrown_spell = spell[rand_int(spell.size())];
/* Force a spell ? */
if (monst_spell_monst_spell > -1)
{
- thrown_spell = monst_spell_monst_spell;
+ thrown_spell = spell[monst_spell_monst_spell];
monst_spell_monst_spell = -1;
}
@@ -1133,10 +1094,9 @@ static bool_ monst_spell_monst(int m_idx)
see_both = (see_m && see_t);
int count = 0;
- switch (thrown_spell)
+ switch (thrown_spell->spell_idx)
{
- /* RF4_SHRIEK */
- case 96 + 0:
+ case SF_SHRIEK_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1146,14 +1106,12 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_MULTIPLY */
- case 96 + 1:
+ case SF_MULTIPLY_IDX:
{
break;
}
- /* RF4_S_ANIMAL */
- case 96 + 2:
+ case SF_S_ANIMAL_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1169,8 +1127,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_ROCKET */
- case 96 + 3:
+ case SF_ROCKET_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear an explosion!");
@@ -1181,8 +1138,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_ARROW_1 */
- case 96 + 4:
+ case SF_ARROW_1_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear a strange noise.");
@@ -1193,8 +1149,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_ARROW_2 */
- case 96 + 5:
+ case SF_ARROW_2_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear a strange noise.");
@@ -1205,8 +1160,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_ARROW_3 */
- case 96 + 6:
+ case SF_ARROW_3_IDX:
{
if (disturb_other) disturb(1);
@@ -1218,8 +1172,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_ARROW_4 */
- case 96 + 7:
+ case SF_ARROW_4_IDX:
{
if (!see_either) monster_msg("You hear a strange noise.");
else if (disturb_other) disturb(1);
@@ -1230,8 +1183,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_ACID */
- case 96 + 8:
+ case SF_BR_ACID_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1243,8 +1195,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_ELEC */
- case 96 + 9:
+ case SF_BR_ELEC_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1256,8 +1207,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_FIRE */
- case 96 + 10:
+ case SF_BR_FIRE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1269,8 +1219,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_COLD */
- case 96 + 11:
+ case SF_BR_COLD_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1282,8 +1231,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_POIS */
- case 96 + 12:
+ case SF_BR_POIS_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1295,8 +1243,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_NETH */
- case 96 + 13:
+ case SF_BR_NETH_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1308,8 +1255,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_LITE */
- case 96 + 14:
+ case SF_BR_LITE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1321,8 +1267,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_DARK */
- case 96 + 15:
+ case SF_BR_DARK_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1334,8 +1279,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_CONF */
- case 96 + 16:
+ case SF_BR_CONF_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1347,8 +1291,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_SOUN */
- case 96 + 17:
+ case SF_BR_SOUN_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1360,8 +1303,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_CHAO */
- case 96 + 18:
+ case SF_BR_CHAO_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1373,8 +1315,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_DISE */
- case 96 + 19:
+ case SF_BR_DISE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1386,8 +1327,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_NEXU */
- case 96 + 20:
+ case SF_BR_NEXU_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1399,8 +1339,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_TIME */
- case 96 + 21:
+ case SF_BR_TIME_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1412,8 +1351,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_INER */
- case 96 + 22:
+ case SF_BR_INER_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1425,8 +1363,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_GRAV */
- case 96 + 23:
+ case SF_BR_GRAV_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1438,8 +1375,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_SHAR */
- case 96 + 24:
+ case SF_BR_SHAR_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1451,8 +1387,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_PLAS */
- case 96 + 25:
+ case SF_BR_PLAS_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1464,8 +1399,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_WALL */
- case 96 + 26:
+ case SF_BR_WALL_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1477,8 +1411,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_MANA */
- case 96 + 27:
+ case SF_BR_MANA_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1490,8 +1423,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BA_NUKE */
- case 96 + 28:
+ case SF_BA_NUKE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear someone mumble.");
@@ -1503,8 +1435,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_NUKE */
- case 96 + 29:
+ case SF_BR_NUKE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1516,8 +1447,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BA_CHAO */
- case 96 + 30:
+ case SF_BA_CHAO_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear someone mumble frighteningly.");
@@ -1529,8 +1459,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF4_BR_DISI -> Breathe Disintegration */
- case 96 + 31:
+ case SF_BR_DISI_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
@@ -1542,8 +1471,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_ACID */
- case 128 + 0:
+ case SF_BA_ACID_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1553,8 +1481,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_ELEC */
- case 128 + 1:
+ case SF_BA_ELEC_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1565,8 +1492,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_FIRE */
- case 128 + 2:
+ case SF_BA_FIRE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1577,8 +1503,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_COLD */
- case 128 + 3:
+ case SF_BA_COLD_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1589,8 +1514,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_POIS */
- case 128 + 4:
+ case SF_BA_POIS_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1601,8 +1525,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_NETH */
- case 128 + 5:
+ case SF_BA_NETH_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1613,8 +1536,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_WATE */
- case 128 + 6:
+ case SF_BA_WATE_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
@@ -1626,8 +1548,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_MANA */
- case 128 + 7:
+ case SF_BA_MANA_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble powerfully.");
@@ -1638,8 +1559,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BA_DARK */
- case 128 + 8:
+ case SF_BA_DARK_IDX:
{
if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble powerfully.");
@@ -1650,8 +1570,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_DRAIN_MANA */
- case 128 + 9:
+ case SF_DRAIN_MANA_IDX:
{
/* Attack power */
int r1 = (randint(rlev) / 2) + 1;
@@ -1665,7 +1584,7 @@ static bool_ monst_spell_monst(int m_idx)
/* Heal the monster */
if (m_ptr->hp < m_ptr->maxhp)
{
- if (!(tr_ptr->flags4 || tr_ptr->flags5 || tr_ptr->flags6))
+ if (!tr_ptr->spells)
{
if (see_both)
monster_msg("%^s is unaffected!", t_name);
@@ -1691,8 +1610,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_MIND_BLAST */
- case 128 + 10:
+ case SF_MIND_BLAST_IDX:
{
if (!direct) break;
@@ -1731,8 +1649,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BRAIN_SMASH */
- case 128 + 11:
+ case SF_BRAIN_SMASH_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1772,8 +1689,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_CAUSE_1 */
- case 128 + 12:
+ case SF_CAUSE_1_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1793,8 +1709,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_CAUSE_2 */
- case 128 + 13:
+ case SF_CAUSE_2_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1813,8 +1728,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_CAUSE_3 */
- case 128 + 14:
+ case SF_CAUSE_3_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1833,8 +1747,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_CAUSE_4 */
- case 128 + 15:
+ case SF_CAUSE_4_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1853,8 +1766,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_ACID */
- case 128 + 16:
+ case SF_BO_ACID_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1864,8 +1776,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_ELEC */
- case 128 + 17:
+ case SF_BO_ELEC_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1875,8 +1786,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_FIRE */
- case 128 + 18:
+ case SF_BO_FIRE_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1886,8 +1796,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_COLD */
- case 128 + 19:
+ case SF_BO_COLD_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1897,15 +1806,13 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_POIS */
- case 128 + 20:
+ case SF_BO_POIS_IDX:
{
/* XXX XXX XXX */
break;
}
- /* RF5_BO_NETH */
- case 128 + 21:
+ case SF_BO_NETH_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1915,8 +1822,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_WATE */
- case 128 + 22:
+ case SF_BO_WATE_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1926,8 +1832,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_MANA */
- case 128 + 23:
+ case SF_BO_MANA_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1937,8 +1842,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_PLAS */
- case 128 + 24:
+ case SF_BO_PLAS_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1948,8 +1852,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BO_ICEE */
- case 128 + 25:
+ case SF_BO_ICEE_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1959,8 +1862,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_MISSILE */
- case 128 + 26:
+ case SF_MISSILE_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -1970,8 +1872,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_SCARE */
- case 128 + 27:
+ case SF_SCARE_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -1994,8 +1895,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_BLIND */
- case 128 + 28:
+ case SF_BLIND_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -2020,8 +1920,7 @@ static bool_ monst_spell_monst(int m_idx)
}
- /* RF5_CONF */
- case 128 + 29:
+ case SF_CONF_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -2044,8 +1943,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_SLOW */
- case 128 + 30:
+ case SF_SLOW_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -2068,8 +1966,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF5_HOLD */
- case 128 + 31:
+ case SF_HOLD_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -2092,9 +1989,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
-
- /* RF6_HASTE */
- case 160 + 0:
+ case SF_HASTE_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m)
@@ -2123,8 +2018,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_HAND_DOOM */
- case 160 + 1:
+ case SF_HAND_DOOM_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -2155,8 +2049,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_HEAL */
- case 160 + 2:
+ case SF_HEAL_IDX:
{
if (disturb_other) disturb(1);
@@ -2220,8 +2113,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_ANIMALS */
- case 160 + 3:
+ case SF_S_ANIMALS_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2237,8 +2129,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_BLINK */
- case 160 + 4:
+ case SF_BLINK_IDX:
{
if (disturb_other) disturb(1);
if (see_m) monster_msg("%^s blinks away.", m_name);
@@ -2246,8 +2137,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_TPORT */
- case 160 + 5:
+ case SF_TPORT_IDX:
{
if (dungeon_flags & DF_NO_TELEPORT) break; /* No teleport on special levels */
else
@@ -2259,15 +2149,13 @@ static bool_ monst_spell_monst(int m_idx)
}
}
- /* RF6_TELE_TO */
- case 160 + 6:
+ case SF_TELE_TO_IDX:
{
/* Not implemented */
break;
}
- /* RF6_TELE_AWAY */
- case 160 + 7:
+ case SF_TELE_AWAY_IDX:
{
if (dungeon_flags & DF_NO_TELEPORT) break;
@@ -2308,15 +2196,13 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_TELE_LEVEL */
- case 160 + 8:
+ case SF_TELE_LEVEL_IDX:
{
/* Not implemented */
break;
}
- /* RF6_DARKNESS */
- case 160 + 9:
+ case SF_DARKNESS_IDX:
{
if (!direct) break;
if (disturb_other) disturb(1);
@@ -2330,22 +2216,19 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_TRAPS */
- case 160 + 10:
+ case SF_TRAPS_IDX:
{
/* Not implemented */
break;
}
- /* RF6_FORGET */
- case 160 + 11:
+ case SF_FORGET_IDX:
{
/* Not implemented */
break;
}
- /* RF6_S_BUG */
- case 160 + 13:
+ case SF_S_BUG_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2361,8 +2244,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_RNG */
- case 160 + 14:
+ case SF_S_RNG_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2378,9 +2260,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
-
- /* RF6_S_THUNDERLORD */
- case 160 + 15:
+ case SF_S_THUNDERLORD_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2396,8 +2276,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_SUMMON_KIN */
- case 160 + 16:
+ case SF_S_KIN_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2419,8 +2298,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_HI_DEMON */
- case 160 + 17:
+ case SF_S_HI_DEMON_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2433,8 +2311,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_MONSTER */
- case 160 + 18:
+ case SF_S_MONSTER_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2450,8 +2327,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_MONSTERS */
- case 160 + 19:
+ case SF_S_MONSTERS_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2467,8 +2343,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_ANT */
- case 160 + 20:
+ case SF_S_ANT_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2484,8 +2359,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_SPIDER */
- case 160 + 21:
+ case SF_S_SPIDER_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2501,8 +2375,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_HOUND */
- case 160 + 22:
+ case SF_S_HOUND_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2518,8 +2391,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_HYDRA */
- case 160 + 23:
+ case SF_S_HYDRA_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2535,8 +2407,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_ANGEL */
- case 160 + 24:
+ case SF_S_ANGEL_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2552,8 +2423,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_DEMON */
- case 160 + 25:
+ case SF_S_DEMON_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2569,8 +2439,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_UNDEAD */
- case 160 + 26:
+ case SF_S_UNDEAD_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2586,8 +2455,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_DRAGON */
- case 160 + 27:
+ case SF_S_DRAGON_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2603,8 +2471,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_HI_UNDEAD */
- case 160 + 28:
+ case SF_S_HI_UNDEAD_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2623,8 +2490,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_HI_DRAGON */
- case 160 + 29:
+ case SF_S_HI_DRAGON_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2643,8 +2509,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_WRAITH */
- case 160 + 30:
+ case SF_S_WRAITH_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2663,8 +2528,7 @@ static bool_ monst_spell_monst(int m_idx)
break;
}
- /* RF6_S_UNIQUE */
- case 160 + 31:
+ case SF_S_UNIQUE_IDX:
{
if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
@@ -2860,9 +2724,12 @@ void curse_equipment_dg(int chance, int heavy_chance)
*/
static bool_ make_attack_spell(int m_idx)
{
- int k, chance, thrown_spell, rlev, failrate;
- byte spell[96], num = 0;
- u32b f4, f5, f6;
+ static const auto SF_BOLT_MASK = compute_bolt_mask();
+ static const auto SF_SUMMON_MASK = compute_summoning_mask();
+ static const auto SF_INT_MASK = compute_smart_mask();
+ static const auto SF_INNATE_MASK = compute_innate_mask();
+
+ int k, chance, rlev, failrate;
char m_name[80];
bool_ no_inate = FALSE;
int x, y;
@@ -2934,12 +2801,13 @@ static bool_ make_attack_spell(int m_idx)
rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1);
/* Extract the racial spell flags */
- f4 = r_ptr->flags4;
- f5 = r_ptr->flags5;
- f6 = r_ptr->flags6;
+ monster_spell_flag_set allowed_spells = r_ptr->spells;
/* Forbid inate attacks sometimes */
- if (no_inate) f4 = 0L;
+ if (no_inate)
+ {
+ allowed_spells &= ~SF_INNATE_MASK;
+ }
/* Hack -- allow "desperate" spells */
if ((r_ptr->flags2 & RF2_SMART) &&
@@ -2947,67 +2815,44 @@ static bool_ make_attack_spell(int m_idx)
(rand_int(100) < 50))
{
/* Require intelligent spells */
- f4 &= RF4_INT_MASK;
- f5 &= RF5_INT_MASK;
- f6 &= RF6_INT_MASK;
+ allowed_spells &= SF_INT_MASK;
- /* No spells left */
- if (!f4 && !f5 && !f6) return (FALSE);
+ /* No spells left? */
+ if (!allowed_spells) return (FALSE);
}
/* Remove the "ineffective" spells */
- remove_bad_spells(m_idx, &f4, &f5, &f6);
+ remove_bad_spells(m_idx, &allowed_spells);
/* No spells left */
- if (!f4 && !f5 && !f6) return (FALSE);
+ if (!allowed_spells) return (FALSE);
/* Check for a clean bolt shot */
- if ((f4&RF4_BOLT_MASK || f5 & RF5_BOLT_MASK ||
- f6&RF6_BOLT_MASK) &&
+ if ((allowed_spells & SF_BOLT_MASK) &&
!(r_ptr->flags2 & RF2_STUPID) &&
!clean_shot(m_ptr->fy, m_ptr->fx, y, x))
{
/* Remove spells that will only hurt friends */
- f4 &= ~RF4_BOLT_MASK;
- f5 &= ~RF5_BOLT_MASK;
- f6 &= ~RF6_BOLT_MASK;
+ allowed_spells &= ~SF_BOLT_MASK;
}
/* Check for a possible summon */
- if ((f4 & RF4_SUMMON_MASK || f5 & RF5_SUMMON_MASK ||
- f6 & RF6_SUMMON_MASK) &&
+ if ((allowed_spells & SF_SUMMON_MASK) &&
!(r_ptr->flags2 & RF2_STUPID) &&
!(summon_possible(y, x)))
{
/* Remove summoning spells */
- f4 &= ~RF4_SUMMON_MASK;
- f5 &= ~RF5_SUMMON_MASK;
- f6 &= ~RF6_SUMMON_MASK;
+ allowed_spells &= ~SF_SUMMON_MASK;
}
/* No spells left */
- if (!f4 && !f5 && !f6) return (FALSE);
+ if (!allowed_spells) return (FALSE);
/* Extract the "inate" spells */
- for (k = 0; k < 32; k++)
- {
- if (f4 & (1L << k)) spell[num++] = k + 32 * 3;
- }
-
- /* Extract the "normal" spells */
- for (k = 0; k < 32; k++)
- {
- if (f5 & (1L << k)) spell[num++] = k + 32 * 4;
- }
-
- /* Extract the "bizarre" spells */
- for (k = 0; k < 32; k++)
- {
- if (f6 & (1L << k)) spell[num++] = k + 32 * 5;
- }
+ auto spell = extract_spells(allowed_spells);
/* No spells left */
- if (!num) return (FALSE);
+ if (spell.empty()) return (FALSE);
/* Stop if player is dead or gone */
if (!alive || death) return (FALSE);
@@ -3019,7 +2864,7 @@ static bool_ make_attack_spell(int m_idx)
monster_desc(m_name, m_ptr, 0x00);
/* Choose a spell to cast */
- thrown_spell = choose_attack_spell(m_idx, spell, num);
+ auto thrown_spell = choose_attack_spell(m_idx, spell);
/* Abort if no spell was chosen */
if (!thrown_spell) return (FALSE);
@@ -3031,7 +2876,7 @@ static bool_ make_attack_spell(int m_idx)
if (r_ptr->flags2 & RF2_STUPID) failrate = 0;
/* Check for spell failure (inate attacks never fail) */
- if ((thrown_spell >= 128) && (rand_int(100) < failrate))
+ if ((!thrown_spell->is_innate) && (rand_int(100) < failrate))
{
/* Message */
msg_format("%^s tries to cast a spell, but fails.", m_name);
@@ -3040,7 +2885,7 @@ static bool_ make_attack_spell(int m_idx)
}
/* Can the player disrupt its puny attempts? */
- if ((p_ptr->antimagic_dis >= m_ptr->cdis) && (magik(p_ptr->antimagic)) && (thrown_spell >= 128))
+ if ((p_ptr->antimagic_dis >= m_ptr->cdis) && magik(p_ptr->antimagic) && thrown_spell->is_magic)
{
char m_poss[80];
@@ -3061,10 +2906,9 @@ static bool_ make_attack_spell(int m_idx)
monster_desc(ddesc, m_ptr, 0x88);
/* Cast the spell. */
- switch (thrown_spell)
+ switch (thrown_spell->spell_idx)
{
- /* RF4_SHRIEK */
- case 96 + 0:
+ case SF_SHRIEK_IDX:
{
disturb(1);
msg_format("%^s makes a high pitched shriek.", m_name);
@@ -3072,14 +2916,12 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_MULTIPLY */
- case 96 + 1:
+ case SF_MULTIPLY_IDX:
{
break;
}
- /* RF4_S_ANIMAL */
- case 96 + 2:
+ case SF_S_ANIMAL_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3092,8 +2934,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_ROCKET */
- case 96 + 3:
+ case SF_ROCKET_IDX:
{
disturb(1);
if (blind) msg_format("%^s shoots something.", m_name);
@@ -3104,8 +2945,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_ARROW_1 */
- case 96 + 4:
+ case SF_ARROW_1_IDX:
{
disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
@@ -3115,8 +2955,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_ARROW_2 */
- case 96 + 5:
+ case SF_ARROW_2_IDX:
{
disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
@@ -3126,8 +2965,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_ARROW_3 */
- case 96 + 6:
+ case SF_ARROW_3_IDX:
{
disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
@@ -3137,8 +2975,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_ARROW_4 */
- case 96 + 7:
+ case SF_ARROW_4_IDX:
{
disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
@@ -3148,8 +2985,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_ACID */
- case 96 + 8:
+ case SF_BR_ACID_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3160,8 +2996,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_ELEC */
- case 96 + 9:
+ case SF_BR_ELEC_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3172,8 +3007,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_FIRE */
- case 96 + 10:
+ case SF_BR_FIRE_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3184,8 +3018,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_COLD */
- case 96 + 11:
+ case SF_BR_COLD_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3196,8 +3029,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_POIS */
- case 96 + 12:
+ case SF_BR_POIS_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3208,9 +3040,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
-
- /* RF4_BR_NETH */
- case 96 + 13:
+ case SF_BR_NETH_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3221,8 +3051,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_LITE */
- case 96 + 14:
+ case SF_BR_LITE_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3233,8 +3062,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_DARK */
- case 96 + 15:
+ case SF_BR_DARK_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3245,8 +3073,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_CONF */
- case 96 + 16:
+ case SF_BR_CONF_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3257,8 +3084,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_SOUN */
- case 96 + 17:
+ case SF_BR_SOUN_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3269,8 +3095,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_CHAO */
- case 96 + 18:
+ case SF_BR_CHAO_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3281,8 +3106,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_DISE */
- case 96 + 19:
+ case SF_BR_DISE_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3293,8 +3117,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_NEXU */
- case 96 + 20:
+ case SF_BR_NEXU_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3305,8 +3128,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_TIME */
- case 96 + 21:
+ case SF_BR_TIME_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3316,8 +3138,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_INER */
- case 96 + 22:
+ case SF_BR_INER_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3327,8 +3148,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_GRAV */
- case 96 + 23:
+ case SF_BR_GRAV_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3338,8 +3158,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_SHAR */
- case 96 + 24:
+ case SF_BR_SHAR_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3350,8 +3169,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_PLAS */
- case 96 + 25:
+ case SF_BR_PLAS_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3361,8 +3179,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_WALL */
- case 96 + 26:
+ case SF_BR_WALL_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3372,8 +3189,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_MANA */
- case 96 + 27:
+ case SF_BR_MANA_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3383,8 +3199,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BA_NUKE */
- case 96 + 28:
+ case SF_BA_NUKE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3394,8 +3209,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_NUKE */
- case 96 + 29:
+ case SF_BR_NUKE_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3406,8 +3220,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BA_CHAO */
- case 96 + 30:
+ case SF_BA_CHAO_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles frighteningly.", m_name);
@@ -3417,8 +3230,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF4_BR_DISI -> Disintegration breath! */
- case 96 + 31:
+ case SF_BR_DISI_IDX:
{
disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
@@ -3428,10 +3240,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
-
-
- /* RF5_BA_ACID */
- case 128 + 0:
+ case SF_BA_ACID_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3442,8 +3251,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_ELEC */
- case 128 + 1:
+ case SF_BA_ELEC_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3454,8 +3262,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_FIRE */
- case 128 + 2:
+ case SF_BA_FIRE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3466,8 +3273,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_COLD */
- case 128 + 3:
+ case SF_BA_COLD_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3478,8 +3284,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_POIS */
- case 128 + 4:
+ case SF_BA_POIS_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3490,8 +3295,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_NETH */
- case 128 + 5:
+ case SF_BA_NETH_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3502,8 +3306,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_WATE */
- case 128 + 6:
+ case SF_BA_WATE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3514,8 +3317,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_MANA */
- case 128 + 7:
+ case SF_BA_MANA_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles powerfully.", m_name);
@@ -3525,8 +3327,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BA_DARK */
- case 128 + 8:
+ case SF_BA_DARK_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles powerfully.", m_name);
@@ -3537,8 +3338,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_DRAIN_MANA */
- case 128 + 9:
+ case SF_DRAIN_MANA_IDX:
{
if (p_ptr->csp)
{
@@ -3594,8 +3394,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_MIND_BLAST */
- case 128 + 10:
+ case SF_MIND_BLAST_IDX:
{
disturb(1);
if (!seen)
@@ -3630,8 +3429,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BRAIN_SMASH */
- case 128 + 11:
+ case SF_BRAIN_SMASH_IDX:
{
disturb(1);
if (!seen)
@@ -3678,8 +3476,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_CAUSE_1 */
- case 128 + 12:
+ case SF_CAUSE_1_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3696,8 +3493,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_CAUSE_2 */
- case 128 + 13:
+ case SF_CAUSE_2_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3714,8 +3510,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_CAUSE_3 */
- case 128 + 14:
+ case SF_CAUSE_3_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles loudly.", m_name);
@@ -3732,8 +3527,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_CAUSE_4 */
- case 128 + 15:
+ case SF_CAUSE_4_IDX:
{
disturb(1);
if (blind) msg_format("%^s screams the word 'DIE!'", m_name);
@@ -3750,8 +3544,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_ACID */
- case 128 + 16:
+ case SF_BO_ACID_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3762,8 +3555,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_ELEC */
- case 128 + 17:
+ case SF_BO_ELEC_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3774,8 +3566,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_FIRE */
- case 128 + 18:
+ case SF_BO_FIRE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3786,8 +3577,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_COLD */
- case 128 + 19:
+ case SF_BO_COLD_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3798,15 +3588,13 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_POIS */
- case 128 + 20:
+ case SF_BO_POIS_IDX:
{
/* XXX XXX XXX */
break;
}
- /* RF5_BO_NETH */
- case 128 + 21:
+ case SF_BO_NETH_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3817,8 +3605,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_WATE */
- case 128 + 22:
+ case SF_BO_WATE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3828,8 +3615,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_MANA */
- case 128 + 23:
+ case SF_BO_MANA_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3839,8 +3625,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_PLAS */
- case 128 + 24:
+ case SF_BO_PLAS_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3850,8 +3635,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BO_ICEE */
- case 128 + 25:
+ case SF_BO_ICEE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3862,8 +3646,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_MISSILE */
- case 128 + 26:
+ case SF_MISSILE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3873,8 +3656,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_SCARE */
- case 128 + 27:
+ case SF_SCARE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles, and you hear scary noises.", m_name);
@@ -3895,8 +3677,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_BLIND */
- case 128 + 28:
+ case SF_BLIND_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3917,8 +3698,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_CONF */
- case 128 + 29:
+ case SF_CONF_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles, and you hear puzzling noises.", m_name);
@@ -3939,8 +3719,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_SLOW */
- case 128 + 30:
+ case SF_SLOW_IDX:
{
disturb(1);
msg_format("%^s drains power from your muscles!", m_name);
@@ -3960,8 +3739,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF5_HOLD */
- case 128 + 31:
+ case SF_HOLD_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -3982,10 +3760,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
-
-
- /* RF6_HASTE */
- case 160 + 0:
+ case SF_HASTE_IDX:
{
disturb(1);
if (blind)
@@ -4014,8 +3789,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_HAND_DOOM */
- case 160 + 1:
+ case SF_HAND_DOOM_IDX:
{
disturb(1);
msg_format("%^s invokes the Hand of Doom!", m_name);
@@ -4035,8 +3809,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_HEAL */
- case 160 + 2:
+ case SF_HEAL_IDX:
{
disturb(1);
@@ -4099,8 +3872,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_ANIMALS */
- case 160 + 3:
+ case SF_S_ANIMALS_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4113,8 +3885,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_BLINK */
- case 160 + 4:
+ case SF_BLINK_IDX:
{
disturb(1);
msg_format("%^s blinks away.", m_name);
@@ -4122,8 +3893,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_TPORT */
- case 160 + 5:
+ case SF_TPORT_IDX:
{
disturb(1);
msg_format("%^s teleports away.", m_name);
@@ -4131,8 +3901,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_TELE_TO */
- case 160 + 6:
+ case SF_TELE_TO_IDX:
{
disturb(1);
msg_format("%^s commands you to return.", m_name);
@@ -4140,8 +3909,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_TELE_AWAY */
- case 160 + 7:
+ case SF_TELE_AWAY_IDX:
{
disturb(1);
msg_format("%^s teleports you away.", m_name);
@@ -4149,8 +3917,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_TELE_LEVEL */
- case 160 + 8:
+ case SF_TELE_LEVEL_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles strangely.", m_name);
@@ -4171,8 +3938,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_DARKNESS */
- case 160 + 9:
+ case SF_DARKNESS_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4181,8 +3947,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_TRAPS */
- case 160 + 10:
+ case SF_TRAPS_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles, and then cackles evilly.", m_name);
@@ -4191,8 +3956,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_FORGET */
- case 160 + 11:
+ case SF_FORGET_IDX:
{
disturb(1);
msg_format("%^s tries to blank your mind.", m_name);
@@ -4208,8 +3972,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_BUG */
- case 160 + 13:
+ case SF_S_BUG_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4222,8 +3985,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_RNG */
- case 160 + 14:
+ case SF_S_RNG_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4236,8 +3998,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_THUNDERLORD */
- case 160 + 15:
+ case SF_S_THUNDERLORD_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4250,8 +4011,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_SUMMON_KIN */
- case 160 + 16:
+ case SF_S_KIN_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4270,8 +4030,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_HI_DEMON */
- case 160 + 17:
+ case SF_S_HI_DEMON_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4281,8 +4040,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_MONSTER */
- case 160 + 18:
+ case SF_S_MONSTER_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4295,8 +4053,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_MONSTERS */
- case 160 + 19:
+ case SF_S_MONSTERS_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4309,8 +4066,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_ANT */
- case 160 + 20:
+ case SF_S_ANT_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4323,8 +4079,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_SPIDER */
- case 160 + 21:
+ case SF_S_SPIDER_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4337,8 +4092,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_HOUND */
- case 160 + 22:
+ case SF_S_HOUND_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4351,8 +4105,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_HYDRA */
- case 160 + 23:
+ case SF_S_HYDRA_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4365,8 +4118,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_ANGEL */
- case 160 + 24:
+ case SF_S_ANGEL_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4379,8 +4131,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_DEMON */
- case 160 + 25:
+ case SF_S_DEMON_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4393,8 +4144,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_UNDEAD */
- case 160 + 26:
+ case SF_S_UNDEAD_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4407,8 +4157,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_DRAGON */
- case 160 + 27:
+ case SF_S_DRAGON_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4421,8 +4170,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_HI_UNDEAD */
- case 160 + 28:
+ case SF_S_HI_UNDEAD_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4438,8 +4186,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_HI_DRAGON */
- case 160 + 29:
+ case SF_S_HI_DRAGON_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4455,8 +4202,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_WRAITH */
- case 160 + 30:
+ case SF_S_WRAITH_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -4475,8 +4221,7 @@ static bool_ make_attack_spell(int m_idx)
break;
}
- /* RF6_S_UNIQUE */
- case 160 + 31:
+ case SF_S_UNIQUE_IDX:
{
disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
@@ -6188,7 +5933,7 @@ static void process_monster(int m_idx, bool_ is_frien)
ox = m_ptr->fx;
/* Attempt to "multiply" if able and allowed */
- if ((r_ptr->flags4 & RF4_MULTIPLY) && (num_repro < MAX_REPRO))
+ if ((r_ptr->spells & SF_MULTIPLY) && (num_repro < MAX_REPRO))
{
if (ai_multiply(m_idx)) return;
}
diff --git a/src/monster1.cc b/src/monster1.cc
index 0c94fb5a..e7c1a35f 100644
--- a/src/monster1.cc
+++ b/src/monster1.cc
@@ -12,6 +12,7 @@
#include "monster2.hpp"
#include "monster_ego.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "player_type.hpp"
#include "util.hpp"
#include "variable.hpp"
@@ -65,11 +66,9 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
u32b const flags1 = r_ptr->flags1;
u32b const flags2 = r_ptr->flags2;
u32b const flags3 = r_ptr->flags3;
- u32b const flags4 = r_ptr->flags4;
- u32b const flags5 = r_ptr->flags5;
- u32b const flags6 = r_ptr->flags6;
u32b const flags7 = r_ptr->flags7;
u32b const flags9 = r_ptr->flags9;
+ monster_spell_flag_set spells = r_ptr->spells;
/* Extract a gender (if applicable) */
int msex = 0;
@@ -355,12 +354,12 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
/* Collect inate attacks */
vn = 0;
- if (flags4 & RF4_SHRIEK) vp[vn++] = "shriek for help";
- if (flags4 & RF4_ROCKET) vp[vn++] = "shoot a rocket";
- if (flags4 & (RF4_ARROW_1)) vp[vn++] = "fire an arrow";
- if (flags4 & (RF4_ARROW_2)) vp[vn++] = "fire arrows";
- if (flags4 & (RF4_ARROW_3)) vp[vn++] = "fire a missile";
- if (flags4 & (RF4_ARROW_4)) vp[vn++] = "fire missiles";
+ if (spells & SF_SHRIEK) vp[vn++] = "shriek for help";
+ if (spells & SF_ROCKET) vp[vn++] = "shoot a rocket";
+ if (spells & SF_ARROW_1) vp[vn++] = "fire an arrow";
+ if (spells & SF_ARROW_2) vp[vn++] = "fire arrows";
+ if (spells & SF_ARROW_3) vp[vn++] = "fire a missile";
+ if (spells & SF_ARROW_4) vp[vn++] = "fire missiles";
/* Describe inate attacks */
if (vn)
@@ -387,28 +386,28 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
/* Collect breaths */
vn = 0;
- if (flags4 & RF4_BR_ACID) vp[vn++] = "acid";
- if (flags4 & RF4_BR_ELEC) vp[vn++] = "lightning";
- if (flags4 & RF4_BR_FIRE) vp[vn++] = "fire";
- if (flags4 & RF4_BR_COLD) vp[vn++] = "frost";
- if (flags4 & RF4_BR_POIS) vp[vn++] = "poison";
- if (flags4 & RF4_BR_NETH) vp[vn++] = "nether";
- if (flags4 & RF4_BR_LITE) vp[vn++] = "light";
- if (flags4 & RF4_BR_DARK) vp[vn++] = "darkness";
- if (flags4 & RF4_BR_CONF) vp[vn++] = "confusion";
- if (flags4 & RF4_BR_SOUN) vp[vn++] = "sound";
- if (flags4 & RF4_BR_CHAO) vp[vn++] = "chaos";
- if (flags4 & RF4_BR_DISE) vp[vn++] = "disenchantment";
- if (flags4 & RF4_BR_NEXU) vp[vn++] = "nexus";
- if (flags4 & RF4_BR_TIME) vp[vn++] = "time";
- if (flags4 & RF4_BR_INER) vp[vn++] = "inertia";
- if (flags4 & RF4_BR_GRAV) vp[vn++] = "gravity";
- if (flags4 & RF4_BR_SHAR) vp[vn++] = "shards";
- if (flags4 & RF4_BR_PLAS) vp[vn++] = "plasma";
- if (flags4 & RF4_BR_WALL) vp[vn++] = "force";
- if (flags4 & RF4_BR_MANA) vp[vn++] = "mana";
- if (flags4 & RF4_BR_NUKE) vp[vn++] = "toxic waste";
- if (flags4 & RF4_BR_DISI) vp[vn++] = "disintegration";
+ if (spells & SF_BR_ACID) vp[vn++] = "acid";
+ if (spells & SF_BR_ELEC) vp[vn++] = "lightning";
+ if (spells & SF_BR_FIRE) vp[vn++] = "fire";
+ if (spells & SF_BR_COLD) vp[vn++] = "frost";
+ if (spells & SF_BR_POIS) vp[vn++] = "poison";
+ if (spells & SF_BR_NETH) vp[vn++] = "nether";
+ if (spells & SF_BR_LITE) vp[vn++] = "light";
+ if (spells & SF_BR_DARK) vp[vn++] = "darkness";
+ if (spells & SF_BR_CONF) vp[vn++] = "confusion";
+ if (spells & SF_BR_SOUN) vp[vn++] = "sound";
+ if (spells & SF_BR_CHAO) vp[vn++] = "chaos";
+ if (spells & SF_BR_DISE) vp[vn++] = "disenchantment";
+ if (spells & SF_BR_NEXU) vp[vn++] = "nexus";
+ if (spells & SF_BR_TIME) vp[vn++] = "time";
+ if (spells & SF_BR_INER) vp[vn++] = "inertia";
+ if (spells & SF_BR_GRAV) vp[vn++] = "gravity";
+ if (spells & SF_BR_SHAR) vp[vn++] = "shards";
+ if (spells & SF_BR_PLAS) vp[vn++] = "plasma";
+ if (spells & SF_BR_WALL) vp[vn++] = "force";
+ if (spells & SF_BR_MANA) vp[vn++] = "mana";
+ if (spells & SF_BR_NUKE) vp[vn++] = "toxic waste";
+ if (spells & SF_BR_DISI) vp[vn++] = "disintegration";
/* Describe breaths */
if (vn)
@@ -435,73 +434,73 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
/* Collect spells */
vn = 0;
- if (flags5 & RF5_BA_ACID) vp[vn++] = "produce acid balls";
- if (flags5 & RF5_BA_ELEC) vp[vn++] = "produce lightning balls";
- if (flags5 & RF5_BA_FIRE) vp[vn++] = "produce fire balls";
- if (flags5 & RF5_BA_COLD) vp[vn++] = "produce frost balls";
- if (flags5 & RF5_BA_POIS) vp[vn++] = "produce poison balls";
- if (flags5 & RF5_BA_NETH) vp[vn++] = "produce nether balls";
- if (flags5 & RF5_BA_WATE) vp[vn++] = "produce water balls";
- if (flags4 & RF4_BA_NUKE) vp[vn++] = "produce balls of radiation";
- if (flags5 & RF5_BA_MANA) vp[vn++] = "invoke mana storms";
- if (flags5 & RF5_BA_DARK) vp[vn++] = "invoke darkness storms";
- if (flags4 & RF4_BA_CHAO) vp[vn++] = "invoke raw chaos";
- if (flags6 & RF6_HAND_DOOM) vp[vn++] = "invoke the Hand of Doom";
- if (flags5 & RF5_DRAIN_MANA) vp[vn++] = "drain mana";
- if (flags5 & RF5_MIND_BLAST) vp[vn++] = "cause mind blasting";
- if (flags5 & RF5_BRAIN_SMASH) vp[vn++] = "cause brain smashing";
- if (flags5 & (RF5_CAUSE_1)) vp[vn++] = "cause light wounds and cursing";
- if (flags5 & (RF5_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing";
- if (flags5 & (RF5_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing";
- if (flags5 & (RF5_CAUSE_4)) vp[vn++] = "cause mortal wounds";
- if (flags5 & RF5_BO_ACID) vp[vn++] = "produce acid bolts";
- if (flags5 & RF5_BO_ELEC) vp[vn++] = "produce lightning bolts";
- if (flags5 & RF5_BO_FIRE) vp[vn++] = "produce fire bolts";
- if (flags5 & RF5_BO_COLD) vp[vn++] = "produce frost bolts";
- if (flags5 & RF5_BO_POIS) vp[vn++] = "produce poison bolts";
- if (flags5 & RF5_BO_NETH) vp[vn++] = "produce nether bolts";
- if (flags5 & RF5_BO_WATE) vp[vn++] = "produce water bolts";
- if (flags5 & RF5_BO_MANA) vp[vn++] = "produce mana bolts";
- if (flags5 & RF5_BO_PLAS) vp[vn++] = "produce plasma bolts";
- if (flags5 & RF5_BO_ICEE) vp[vn++] = "produce ice bolts";
- if (flags5 & RF5_MISSILE) vp[vn++] = "produce magic missiles";
- if (flags5 & RF5_SCARE) vp[vn++] = "terrify";
- if (flags5 & RF5_BLIND) vp[vn++] = "blind";
- if (flags5 & RF5_CONF) vp[vn++] = "confuse";
- if (flags5 & RF5_SLOW) vp[vn++] = "slow";
- if (flags5 & RF5_HOLD) vp[vn++] = "paralyze";
- if (flags6 & RF6_HASTE) vp[vn++] = "haste-self";
- if (flags6 & RF6_HEAL) vp[vn++] = "heal-self";
- if (flags6 & RF6_BLINK) vp[vn++] = "blink-self";
- if (flags6 & RF6_TPORT) vp[vn++] = "teleport-self";
- if (flags6 & RF6_S_BUG) vp[vn++] = "summon software bugs";
- if (flags6 & RF6_S_RNG) vp[vn++] = "summon RNG";
- if (flags6 & RF6_TELE_TO) vp[vn++] = "teleport to";
- if (flags6 & RF6_TELE_AWAY) vp[vn++] = "teleport away";
- if (flags6 & RF6_TELE_LEVEL) vp[vn++] = "teleport level";
- if (flags6 & RF6_S_THUNDERLORD) vp[vn++] = "summon a Thunderlord";
- if (flags6 & RF6_DARKNESS) vp[vn++] = "create darkness";
- if (flags6 & RF6_TRAPS) vp[vn++] = "create traps";
- if (flags6 & RF6_FORGET) vp[vn++] = "cause amnesia";
- if (flags6 & RF6_RAISE_DEAD) vp[vn++] = "raise dead";
- if (flags6 & RF6_S_MONSTER) vp[vn++] = "summon a monster";
- if (flags6 & RF6_S_MONSTERS) vp[vn++] = "summon monsters";
- if (flags6 & RF6_S_KIN) vp[vn++] = "summon aid";
- if (flags6 & RF6_S_ANT) vp[vn++] = "summon ants";
- if (flags6 & RF6_S_SPIDER) vp[vn++] = "summon spiders";
- if (flags6 & RF6_S_HOUND) vp[vn++] = "summon hounds";
- if (flags6 & RF6_S_HYDRA) vp[vn++] = "summon hydras";
- if (flags6 & RF6_S_ANGEL) vp[vn++] = "summon an angel";
- if (flags6 & RF6_S_DEMON) vp[vn++] = "summon a demon";
- if (flags6 & RF6_S_UNDEAD) vp[vn++] = "summon an undead";
- if (flags6 & RF6_S_DRAGON) vp[vn++] = "summon a dragon";
- if (flags4 & RF4_S_ANIMAL) vp[vn++] = "summon animal";
- if (flags6 & RF6_S_ANIMALS) vp[vn++] = "summon animals";
- if (flags6 & RF6_S_HI_UNDEAD) vp[vn++] = "summon Greater Undead";
- if (flags6 & RF6_S_HI_DRAGON) vp[vn++] = "summon Ancient Dragons";
- if (flags6 & RF6_S_HI_DEMON) vp[vn++] = "summon Greater Demons";
- if (flags6 & RF6_S_WRAITH) vp[vn++] = "summon Ringwraith";
- if (flags6 & RF6_S_UNIQUE) vp[vn++] = "summon Unique Monsters";
+ if (spells & SF_BA_ACID) vp[vn++] = "produce acid balls";
+ if (spells & SF_BA_ELEC) vp[vn++] = "produce lightning balls";
+ if (spells & SF_BA_FIRE) vp[vn++] = "produce fire balls";
+ if (spells & SF_BA_COLD) vp[vn++] = "produce frost balls";
+ if (spells & SF_BA_POIS) vp[vn++] = "produce poison balls";
+ if (spells & SF_BA_NETH) vp[vn++] = "produce nether balls";
+ if (spells & SF_BA_WATE) vp[vn++] = "produce water balls";
+ if (spells & SF_BA_NUKE) vp[vn++] = "produce balls of radiation";
+ if (spells & SF_BA_MANA) vp[vn++] = "invoke mana storms";
+ if (spells & SF_BA_DARK) vp[vn++] = "invoke darkness storms";
+ if (spells & SF_BA_CHAO) vp[vn++] = "invoke raw chaos";
+ if (spells & SF_HAND_DOOM) vp[vn++] = "invoke the Hand of Doom";
+ if (spells & SF_DRAIN_MANA) vp[vn++] = "drain mana";
+ if (spells & SF_MIND_BLAST) vp[vn++] = "cause mind blasting";
+ if (spells & SF_BRAIN_SMASH) vp[vn++] = "cause brain smashing";
+ if (spells & (SF_CAUSE_1)) vp[vn++] = "cause light wounds and cursing";
+ if (spells & (SF_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing";
+ if (spells & (SF_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing";
+ if (spells & (SF_CAUSE_4)) vp[vn++] = "cause mortal wounds";
+ if (spells & SF_BO_ACID) vp[vn++] = "produce acid bolts";
+ if (spells & SF_BO_ELEC) vp[vn++] = "produce lightning bolts";
+ if (spells & SF_BO_FIRE) vp[vn++] = "produce fire bolts";
+ if (spells & SF_BO_COLD) vp[vn++] = "produce frost bolts";
+ if (spells & SF_BO_POIS) vp[vn++] = "produce poison bolts";
+ if (spells & SF_BO_NETH) vp[vn++] = "produce nether bolts";
+ if (spells & SF_BO_WATE) vp[vn++] = "produce water bolts";
+ if (spells & SF_BO_MANA) vp[vn++] = "produce mana bolts";
+ if (spells & SF_BO_PLAS) vp[vn++] = "produce plasma bolts";
+ if (spells & SF_BO_ICEE) vp[vn++] = "produce ice bolts";
+ if (spells & SF_MISSILE) vp[vn++] = "produce magic missiles";
+ if (spells & SF_SCARE) vp[vn++] = "terrify";
+ if (spells & SF_BLIND) vp[vn++] = "blind";
+ if (spells & SF_CONF) vp[vn++] = "confuse";
+ if (spells & SF_SLOW) vp[vn++] = "slow";
+ if (spells & SF_HOLD) vp[vn++] = "paralyze";
+ if (spells & SF_HASTE) vp[vn++] = "haste-self";
+ if (spells & SF_HEAL) vp[vn++] = "heal-self";
+ if (spells & SF_BLINK) vp[vn++] = "blink-self";
+ if (spells & SF_TPORT) vp[vn++] = "teleport-self";
+ if (spells & SF_S_BUG) vp[vn++] = "summon software bugs";
+ if (spells & SF_S_RNG) vp[vn++] = "summon RNG";
+ if (spells & SF_TELE_TO) vp[vn++] = "teleport to";
+ if (spells & SF_TELE_AWAY) vp[vn++] = "teleport away";
+ if (spells & SF_TELE_LEVEL) vp[vn++] = "teleport level";
+ if (spells & SF_S_THUNDERLORD) vp[vn++] = "summon a Thunderlord";
+ if (spells & SF_DARKNESS) vp[vn++] = "create darkness";
+ if (spells & SF_TRAPS) vp[vn++] = "create traps";
+ if (spells & SF_FORGET) vp[vn++] = "cause amnesia";
+ if (spells & SF_RAISE_DEAD) vp[vn++] = "raise dead";
+ if (spells & SF_S_MONSTER) vp[vn++] = "summon a monster";
+ if (spells & SF_S_MONSTERS) vp[vn++] = "summon monsters";
+ if (spells & SF_S_KIN) vp[vn++] = "summon aid";
+ if (spells & SF_S_ANT) vp[vn++] = "summon ants";
+ if (spells & SF_S_SPIDER) vp[vn++] = "summon spiders";
+ if (spells & SF_S_HOUND) vp[vn++] = "summon hounds";
+ if (spells & SF_S_HYDRA) vp[vn++] = "summon hydras";
+ if (spells & SF_S_ANGEL) vp[vn++] = "summon an angel";
+ if (spells & SF_S_DEMON) vp[vn++] = "summon a demon";
+ if (spells & SF_S_UNDEAD) vp[vn++] = "summon an undead";
+ if (spells & SF_S_DRAGON) vp[vn++] = "summon a dragon";
+ if (spells & SF_S_ANIMAL) vp[vn++] = "summon animal";
+ if (spells & SF_S_ANIMALS) vp[vn++] = "summon animals";
+ if (spells & SF_S_HI_UNDEAD) vp[vn++] = "summon Greater Undead";
+ if (spells & SF_S_HI_DRAGON) vp[vn++] = "summon Ancient Dragons";
+ if (spells & SF_S_HI_DEMON) vp[vn++] = "summon Greater Demons";
+ if (spells & SF_S_WRAITH) vp[vn++] = "summon Ringwraith";
+ if (spells & SF_S_UNIQUE) vp[vn++] = "summon Unique Monsters";
/* Describe spells */
if (vn)
@@ -633,7 +632,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
{
text_out(format("%^s is rarely detected by telepathy. ", wd_he[msex]));
}
- if (flags4 & RF4_MULTIPLY)
+ if (spells & SF_MULTIPLY)
{
text_out_c(TERM_L_UMBER, format("%^s breeds explosively. ", wd_he[msex]));
}
@@ -641,6 +640,7 @@ static void roff_aux(std::shared_ptr<monster_race const> r_ptr)
{
text_out_c(TERM_L_WHITE, format("%^s regenerates quickly. ", wd_he[msex]));
}
+
if (r_ptr->flags7 & RF7_MORTAL)
{
text_out_c(TERM_RED, format("%^s is a mortal being. ", wd_he[msex]));
@@ -1388,7 +1388,7 @@ bool_ monster_quest(int r_idx)
if (r_ptr->flags7 & RF7_AQUATIC) return FALSE;
/* No random quests for multiplying monsters */
- if (r_ptr->flags4 & RF4_MULTIPLY) return FALSE;
+ if (r_ptr->spells & SF_MULTIPLY) return FALSE;
return TRUE;
}
diff --git a/src/monster2.cc b/src/monster2.cc
index 1adc9e7b..b387b495 100644
--- a/src/monster2.cc
+++ b/src/monster2.cc
@@ -22,6 +22,7 @@
#include "monster3.hpp"
#include "monster_ego.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
@@ -333,23 +334,19 @@ std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego)
nr_ptr->flags1 &= ~(re_ptr->nflags1);
nr_ptr->flags2 &= ~(re_ptr->nflags2);
nr_ptr->flags3 &= ~(re_ptr->nflags3);
- nr_ptr->flags4 &= ~(re_ptr->nflags4);
- nr_ptr->flags5 &= ~(re_ptr->nflags5);
- nr_ptr->flags6 &= ~(re_ptr->nflags6);
nr_ptr->flags7 &= ~(re_ptr->nflags7);
nr_ptr->flags8 &= ~(re_ptr->nflags8);
nr_ptr->flags9 &= ~(re_ptr->nflags9);
+ nr_ptr->spells &= ~(re_ptr->nspells);
/* Add some flags */
nr_ptr->flags1 |= re_ptr->mflags1;
nr_ptr->flags2 |= re_ptr->mflags2;
nr_ptr->flags3 |= re_ptr->mflags3;
- nr_ptr->flags4 |= re_ptr->mflags4;
- nr_ptr->flags5 |= re_ptr->mflags5;
- nr_ptr->flags6 |= re_ptr->mflags6;
nr_ptr->flags7 |= re_ptr->mflags7;
nr_ptr->flags8 |= re_ptr->mflags8;
nr_ptr->flags9 |= re_ptr->mflags9;
+ nr_ptr->spells |= re_ptr->mspells;
/* Change the char/attr is needed */
if (re_ptr->d_char != MEGO_CHAR_ANY)
@@ -452,7 +449,7 @@ void delete_monster_idx(int i)
r_ptr->on_saved = FALSE;
/* Hack -- count the number of "reproducers" */
- if (r_ptr->flags4 & RF4_MULTIPLY) num_repro--;
+ if (r_ptr->spells & SF_MULTIPLY) num_repro--;
/* XXX XXX XXX remove monster light source */
bool_ had_lite = FALSE;
@@ -884,21 +881,6 @@ bool_ apply_rule(monster_race *r_ptr, byte rule)
if ((d_ptr->rules[rule].mflags3 & r_ptr->flags3) != d_ptr->rules[rule].mflags3)
return FALSE;
}
- if (d_ptr->rules[rule].mflags4)
- {
- if ((d_ptr->rules[rule].mflags4 & r_ptr->flags4) != d_ptr->rules[rule].mflags4)
- return FALSE;
- }
- if (d_ptr->rules[rule].mflags5)
- {
- if ((d_ptr->rules[rule].mflags5 & r_ptr->flags5) != d_ptr->rules[rule].mflags5)
- return FALSE;
- }
- if (d_ptr->rules[rule].mflags6)
- {
- if ((d_ptr->rules[rule].mflags6 & r_ptr->flags6) != d_ptr->rules[rule].mflags6)
- return FALSE;
- }
if (d_ptr->rules[rule].mflags7)
{
if ((d_ptr->rules[rule].mflags7 & r_ptr->flags7) != d_ptr->rules[rule].mflags7)
@@ -914,6 +896,11 @@ bool_ apply_rule(monster_race *r_ptr, byte rule)
if ((d_ptr->rules[rule].mflags9 & r_ptr->flags9) != d_ptr->rules[rule].mflags9)
return FALSE;
}
+ if (d_ptr->rules[rule].mspells)
+ {
+ if ((d_ptr->rules[rule].mspells & r_ptr->spells) != d_ptr->rules[rule].mspells)
+ return FALSE;
+ }
for (a = 0; a < 5; a++)
{
if (d_ptr->rules[rule].r_char[a] && (d_ptr->rules[rule].r_char[a] != r_ptr->d_char)) return FALSE;
@@ -929,13 +916,12 @@ bool_ apply_rule(monster_race *r_ptr, byte rule)
if (d_ptr->rules[rule].mflags1 && (r_ptr->flags1 & d_ptr->rules[rule].mflags1)) return TRUE;
if (d_ptr->rules[rule].mflags2 && (r_ptr->flags2 & d_ptr->rules[rule].mflags2)) return TRUE;
if (d_ptr->rules[rule].mflags3 && (r_ptr->flags3 & d_ptr->rules[rule].mflags3)) return TRUE;
- if (d_ptr->rules[rule].mflags4 && (r_ptr->flags4 & d_ptr->rules[rule].mflags4)) return TRUE;
- if (d_ptr->rules[rule].mflags5 && (r_ptr->flags5 & d_ptr->rules[rule].mflags5)) return TRUE;
- if (d_ptr->rules[rule].mflags6 && (r_ptr->flags6 & d_ptr->rules[rule].mflags6)) return TRUE;
if (d_ptr->rules[rule].mflags7 && (r_ptr->flags7 & d_ptr->rules[rule].mflags7)) return TRUE;
if (d_ptr->rules[rule].mflags8 && (r_ptr->flags8 & d_ptr->rules[rule].mflags8)) return TRUE;
if (d_ptr->rules[rule].mflags9 && (r_ptr->flags9 & d_ptr->rules[rule].mflags9)) return TRUE;
+ if (d_ptr->rules[rule].mspells && (r_ptr->spells & d_ptr->rules[rule].mspells)) return TRUE;
+
for (a = 0; a < 5; a++)
if (d_ptr->rules[rule].r_char[a] == r_ptr->d_char) return TRUE;
@@ -2497,7 +2483,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/* Hack -- Count the number of "reproducers" */
- if (r_ptr->flags4 & RF4_MULTIPLY) num_repro++;
+ if (r_ptr->spells & SF_MULTIPLY) num_repro++;
/* Hack -- Notice new multi-hued monsters */
@@ -3114,7 +3100,7 @@ static bool_ summon_specific_okay(int r_idx)
!(r_ptr->flags3 & RF3_EVIL) &&
!(r_ptr->flags3 & RF3_UNDEAD) &&
!(r_ptr->flags3 & RF3_DEMON) &&
- !(r_ptr->flags4 || r_ptr->flags5 || r_ptr->flags6) &&
+ !r_ptr->spells &&
!(r_ptr->flags1 & RF1_UNIQUE));
break;
}
diff --git a/src/monster3.cc b/src/monster3.cc
index c718c880..ab002899 100644
--- a/src/monster3.cc
+++ b/src/monster3.cc
@@ -15,6 +15,7 @@
#include "melee2.hpp"
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object2.hpp"
#include "player_type.hpp"
@@ -62,8 +63,8 @@ bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr)
int s1 = is_friend(m_ptr), s2 = is_friend(t_ptr);
/* Monsters hates breeders */
- if ((m_ptr->status != MSTATUS_NEUTRAL) && (rt_ptr->flags4 & RF4_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE;
- if ((t_ptr->status != MSTATUS_NEUTRAL) && (r_ptr->flags4 & RF4_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE;
+ if ((m_ptr->status != MSTATUS_NEUTRAL) && (rt_ptr->spells & SF_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE;
+ if ((t_ptr->status != MSTATUS_NEUTRAL) && (r_ptr->spells & SF_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE;
/* No special conditions, lets test normal flags */
if (s1 && s2 && (s1 == -s2)) return TRUE;
@@ -205,7 +206,7 @@ bool_ ai_possessor(int m_idx, int o_idx)
m_ptr->energy = 0;
/* Hack -- Count the number of "reproducers" */
- if (r_ptr->flags4 & RF4_MULTIPLY) num_repro++;
+ if (r_ptr->spells & SF_MULTIPLY) num_repro++;
/* Hack -- Notice new multi-hued monsters */
if (r_ptr->flags1 & RF1_ATTR_MULTI) shimmer_monsters = TRUE;
@@ -280,7 +281,7 @@ void ai_deincarnate(int m_idx)
m_ptr->energy = 0;
/* Hack -- Count the number of "reproducers" */
- if (r_ptr->flags4 & RF4_MULTIPLY) num_repro++;
+ if (r_ptr->spells & SF_MULTIPLY) num_repro++;
/* Hack -- Notice new multi-hued monsters */
if (r_ptr->flags1 & RF1_ATTR_MULTI) shimmer_monsters = TRUE;
@@ -411,7 +412,6 @@ bool_ do_control_drop(void)
bool_ do_control_magic(void)
{
- int power = -1;
int i;
bool_ flag, redraw;
int ask;
@@ -431,7 +431,7 @@ bool_ do_control_magic(void)
}
/* Extract available monster powers */
- std::vector<int> powers = extract_monster_powers(r_ptr, true);
+ auto powers = extract_monster_powers(r_ptr, true);
int const num = powers.size(); // Avoid signed/unsigned warnings
/* Are any powers available? */
@@ -443,6 +443,7 @@ bool_ do_control_magic(void)
/* Nothing chosen yet */
flag = FALSE;
+ monster_power const *power = nullptr;
/* No redraw yet */
redraw = FALSE;
@@ -481,7 +482,7 @@ bool_ do_control_magic(void)
while (ctr < num)
{
- monster_power *mp_ptr = &monster_powers[powers[ctr]];
+ monster_power const *mp_ptr = powers[ctr];
label = (ctr < 26) ? I2A(ctr) : I2D(ctr - 26);
@@ -565,7 +566,7 @@ bool_ do_control_magic(void)
char tmp_val[160];
/* Prompt */
- strnfmt(tmp_val, 78, "Use %s? ", monster_powers[power].name);
+ strnfmt(tmp_val, 78, "Use %s? ", power->name);
/* Belay that order */
if (!get_check(tmp_val)) continue;
@@ -586,7 +587,7 @@ bool_ do_control_magic(void)
if (flag)
{
energy_use = 100;
- monst_spell_monst_spell = power + 96;
+ monst_spell_monst_spell = power->monster_spell_index;
}
return TRUE;
}
diff --git a/src/monster_ego.hpp b/src/monster_ego.hpp
index 1154c537..010ff98f 100644
--- a/src/monster_ego.hpp
+++ b/src/monster_ego.hpp
@@ -2,6 +2,7 @@
#include "h-basic.h"
#include "monster_blow.hpp"
+#include "monster_spell_flag_set.hpp"
#include <array>
@@ -55,24 +56,24 @@ struct monster_ego
u32b mflags1 = 0;
u32b mflags2 = 0;
u32b mflags3 = 0;
- u32b mflags4 = 0;
- u32b mflags5 = 0;
- u32b mflags6 = 0;
u32b mflags7 = 0;
u32b mflags8 = 0;
u32b mflags9 = 0;
+ /* Monster spells */
+ monster_spell_flag_set mspells;
+
/* Negative Flags, to be removed from the monster flags */
u32b nflags1 = 0;
u32b nflags2 = 0;
u32b nflags3 = 0;
- u32b nflags4 = 0;
- u32b nflags5 = 0;
- u32b nflags6 = 0;
u32b nflags7 = 0;
u32b nflags8 = 0;
u32b nflags9 = 0;
+ /* Negative spells; to be removed from the monster spells */
+ monster_spell_flag_set nspells;
+
s16b level = 0; /* Level of creature */
s16b rarity = 0; /* Rarity of creature */
diff --git a/src/monster_power.hpp b/src/monster_power.hpp
index 03d0f8a9..440d5ba1 100644
--- a/src/monster_power.hpp
+++ b/src/monster_power.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "monster_power_fwd.hpp"
+
#include "h-basic.h"
/**
@@ -7,7 +9,7 @@
*/
struct monster_power
{
- u32b power; /* Power RF?_xxx */
+ u32b monster_spell_index;
cptr name; /* Name of it */
int mana; /* Mana needed */
bool_ great; /* Need the use of great spells */
diff --git a/src/monster_power_fwd.hpp b/src/monster_power_fwd.hpp
new file mode 100644
index 00000000..975d2d2f
--- /dev/null
+++ b/src/monster_power_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct monster_power;
diff --git a/src/monster_race.hpp b/src/monster_race.hpp
index 94896c64..3a13e4b4 100644
--- a/src/monster_race.hpp
+++ b/src/monster_race.hpp
@@ -3,6 +3,7 @@
#include "body.hpp"
#include "h-basic.h"
#include "monster_blow.hpp"
+#include "monster_spell_flag_set.hpp"
#include "obj_theme.hpp"
#include <array>
@@ -50,13 +51,12 @@ struct monster_race
u32b flags1 = 0; /* Flags 1 (general) */
u32b flags2 = 0; /* Flags 2 (abilities) */
u32b flags3 = 0; /* Flags 3 (race/resist) */
- u32b flags4 = 0; /* Flags 4 (inate/breath) */
- u32b flags5 = 0; /* Flags 5 (normal spells) */
- u32b flags6 = 0; /* Flags 6 (special spells) */
u32b flags7 = 0; /* Flags 7 (movement related abilities) */
u32b flags8 = 0; /* Flags 8 (wilderness info) */
u32b flags9 = 0; /* Flags 9 (drops info) */
+ monster_spell_flag_set spells; /* Spells */
+
std::array<monster_blow, 4> blow { }; /* Up to four blows per round */
byte body_parts[BODY_MAX] = { 0 }; /* To help to decide what to use when body changing */
diff --git a/src/monster_spell.cc b/src/monster_spell.cc
new file mode 100644
index 00000000..08627916
--- /dev/null
+++ b/src/monster_spell.cc
@@ -0,0 +1,36 @@
+#include "monster_spell.hpp"
+
+#include "monster_spell_flag.hpp"
+
+#include <boost/preprocessor/cat.hpp>
+
+std::vector<monster_spell const *> const &monster_spells()
+{
+ // Static instance for one-time initialization.
+ static std::vector<monster_spell const *> instance;
+
+ if (instance.empty())
+ {
+#define SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) \
+ instance.emplace_back(new monster_spell { \
+ BOOST_PP_CAT(SF_, BOOST_PP_CAT(name, _IDX)), \
+ BOOST_PP_CAT(SF_, name), \
+ #name, \
+ is_summon, \
+ is_annoy, \
+ is_damage, \
+ is_bolt, \
+ is_smart, \
+ is_innate, \
+ is_escape, \
+ is_tactic, \
+ is_haste, \
+ is_heal, \
+ !is_innate, \
+ });
+#include "monster_spell_flag_list.hpp"
+#undef SF
+ };
+
+ return instance;
+}
diff --git a/src/monster_spell.hpp b/src/monster_spell.hpp
new file mode 100644
index 00000000..4dfaf974
--- /dev/null
+++ b/src/monster_spell.hpp
@@ -0,0 +1,91 @@
+#pragma once
+
+#include "monster_spell_flag_set.hpp"
+
+#include <vector>
+
+struct monster_spell {
+
+ /**
+ * The global index of the spell.
+ */
+ const std::size_t spell_idx;
+
+ /**
+ * Flag set representation of the spell.
+ */
+ const monster_spell_flag_set flag_set;
+
+ /**
+ * System name of the spell as a string.
+ */
+ const char *name;
+
+ /**
+ * Is the spell a summoning spell?
+ */
+ const bool is_summon;
+
+ /**
+ * Is the spell an "annoyance" spell?
+ */
+ const bool is_annoy;
+
+ /**
+ * Is the spell a direct damage spell?
+ */
+ const bool is_damage;
+
+ /**
+ * Is the spell a bolt spell, i.e. would it
+ * affect any creature along the trajectory from
+ * the source to its target?
+ */
+ const bool is_bolt;
+
+ /**
+ * Does the spell require an intelligent caster?
+ */
+ const bool is_smart;
+
+ /**
+ * Is the spell an innate attack? For example, breaths
+ * are innate attacks.
+ */
+ const bool is_innate;
+
+ /**
+ * Is the spell an escape spell?
+ */
+ const bool is_escape;
+
+ /**
+ * Is the spell a "tactical" spell?
+ */
+ const bool is_tactic;
+
+ /**
+ * Does the spell apply haste?
+ */
+ const bool is_haste;
+
+ /**
+ * Does the spell apply any healing?
+ */
+ const bool is_heal;
+
+ /**
+ * Is the spell "magical" in nature? Magical spells
+ * can be stopped by the anti-magic field, and non-magical
+ * ones cannot.
+ *
+ * This is the inverse of the "innate" flag.
+ */
+ const bool is_magic;
+
+};
+
+/**
+ * Get a vector of all the spells.
+ */
+std::vector<monster_spell const *> const &monster_spells();
diff --git a/src/monster_spell_flag.hpp b/src/monster_spell_flag.hpp
new file mode 100644
index 00000000..3de649ec
--- /dev/null
+++ b/src/monster_spell_flag.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "monster_spell_flag_set.hpp"
+#include <boost/preprocessor/cat.hpp>
+
+//
+// Define flag set for each flag.
+//
+#define SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) \
+ DECLARE_FLAG(monster_spell_flag_set, BOOST_PP_CAT(SF_,name), tier, index)
+#include "monster_spell_flag_list.hpp"
+#undef SF
+
+//
+// Define index for each flag.
+//
+#define SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) \
+ constexpr std::size_t BOOST_PP_CAT(BOOST_PP_CAT(SF_,name), _IDX) = (tier - 1) * 32 + index;
+#include "monster_spell_flag_list.hpp"
+#undef SF
diff --git a/src/monster_spell_flag_list.hpp b/src/monster_spell_flag_list.hpp
new file mode 100644
index 00000000..4a201db5
--- /dev/null
+++ b/src/monster_spell_flag_list.hpp
@@ -0,0 +1,102 @@
+/**
+ * X-macro list of all the monster race flags
+ */
+
+/* SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) */
+
+SF(1, 0, SHRIEK , false, true , false, false, false, true , false, false, false, false)
+SF(1, 1, MULTIPLY , false, false, false, false, false, true , false, false, false, false)
+SF(1, 2, S_ANIMAL , true , false, false, false, true , false, false, false, false, false)
+SF(1, 3, ROCKET , false, false, true , false, false, true , false, false, false, false)
+SF(1, 4, ARROW_1 , false, false, true , true , false, true , false, false, false, false)
+SF(1, 5, ARROW_2 , false, false, true , true , false, true , false, false, false, false)
+SF(1, 6, ARROW_3 , false, false, true , true , false, true , false, false, false, false)
+SF(1, 7, ARROW_4 , false, false, true , true , false, true , false, false, false, false)
+SF(1, 8, BR_ACID , false, false, true , false, false, true , false, false, false, false)
+SF(1, 9, BR_ELEC , false, false, true , false, false, true , false, false, false, false)
+SF(1, 10, BR_FIRE , false, false, true , false, false, true , false, false, false, false)
+SF(1, 11, BR_COLD , false, false, true , false, false, true , false, false, false, false)
+SF(1, 12, BR_POIS , false, false, true , false, false, true , false, false, false, false)
+SF(1, 13, BR_NETH , false, false, true , false, false, true , false, false, false, false)
+SF(1, 14, BR_LITE , false, false, true , false, false, true , false, false, false, false)
+SF(1, 15, BR_DARK , false, false, true , false, false, true , false, false, false, false)
+SF(1, 16, BR_CONF , false, false, true , false, false, true , false, false, false, false)
+SF(1, 17, BR_SOUN , false, false, true , false, false, true , false, false, false, false)
+SF(1, 18, BR_CHAO , false, false, true , false, false, true , false, false, false, false)
+SF(1, 19, BR_DISE , false, false, true , false, false, true , false, false, false, false)
+SF(1, 20, BR_NEXU , false, false, true , false, false, true , false, false, false, false)
+SF(1, 21, BR_TIME , false, false, true , false, false, true , false, false, false, false)
+SF(1, 22, BR_INER , false, false, true , false, false, true , false, false, false, false)
+SF(1, 23, BR_GRAV , false, false, true , false, false, true , false, false, false, false)
+SF(1, 24, BR_SHAR , false, false, true , false, false, true , false, false, false, false)
+SF(1, 25, BR_PLAS , false, false, true , false, false, true , false, false, false, false)
+SF(1, 26, BR_WALL , false, false, true , false, false, true , false, false, false, false)
+SF(1, 27, BR_MANA , false, false, true , false, false, true , false, false, false, false)
+SF(1, 28, BA_NUKE , false, false, true , false, false, false, false, false, false, false)
+SF(1, 29, BR_NUKE , false, false, true , false, false, true , false, false, false, false)
+SF(1, 30, BA_CHAO , false, false, true , false, false, false, false, false, false, false)
+SF(1, 31, BR_DISI , false, false, true , false, false, true , false, false, false, false)
+SF(2, 0, BA_ACID , false, false, true , false, false, false, false, false, false, false)
+SF(2, 1, BA_ELEC , false, false, true , false, false, false, false, false, false, false)
+SF(2, 2, BA_FIRE , false, false, true , false, false, false, false, false, false, false)
+SF(2, 3, BA_COLD , false, false, true , false, false, false, false, false, false, false)
+SF(2, 4, BA_POIS , false, false, true , false, false, false, false, false, false, false)
+SF(2, 5, BA_NETH , false, false, true , false, false, false, false, false, false, false)
+SF(2, 6, BA_WATE , false, false, true , false, false, false, false, false, false, false)
+SF(2, 7, BA_MANA , false, false, true , false, false, false, false, false, false, false)
+SF(2, 8, BA_DARK , false, false, true , false, false, false, false, false, false, false)
+SF(2, 9, DRAIN_MANA , false, true , false, false, false, false, false, false, false, false)
+SF(2, 10, MIND_BLAST , false, true , false, false, false, false, false, false, false, false)
+SF(2, 11, BRAIN_SMASH , false, true , false, false, false, false, false, false, false, false)
+SF(2, 12, CAUSE_1 , false, true , true , false, false, false, false, false, false, false)
+SF(2, 13, CAUSE_2 , false, true , true , false, false, false, false, false, false, false)
+SF(2, 14, CAUSE_3 , false, true , true , false, false, false, false, false, false, false)
+SF(2, 15, CAUSE_4 , false, true , true , false, false, false, false, false, false, false)
+SF(2, 16, BO_ACID , false, false, true , true , false, false, false, false, false, false)
+SF(2, 17, BO_ELEC , false, false, true , true , false, false, false, false, false, false)
+SF(2, 18, BO_FIRE , false, false, true , true , false, false, false, false, false, false)
+SF(2, 19, BO_COLD , false, false, true , true , false, false, false, false, false, false)
+SF(2, 20, BO_POIS , false, false, true , true , false, false, false, false, false, false)
+SF(2, 21, BO_NETH , false, false, true , true , false, false, false, false, false, false)
+SF(2, 22, BO_WATE , false, false, true , true , false, false, false, false, false, false)
+SF(2, 23, BO_MANA , false, false, true , true , false, false, false, false, false, false)
+SF(2, 24, BO_PLAS , false, false, true , true , false, false, false, false, false, false)
+SF(2, 25, BO_ICEE , false, false, true , true , false, false, false, false, false, false)
+SF(2, 26, MISSILE , false, false, true , true , false, false, false, false, false, false)
+SF(2, 27, SCARE , false, true , false, false, true , false, false, false, false, false)
+SF(2, 28, BLIND , false, true , false, false, true , false, false, false, false, false)
+SF(2, 29, CONF , false, true , false, false, true , false, false, false, false, false)
+SF(2, 30, SLOW , false, true , false, false, true , false, false, false, false, false)
+SF(2, 31, HOLD , false, true , false, false, true , false, false, false, false, false)
+SF(3, 0, HASTE , false, false, false, false, true , false, false, false, true , false)
+SF(3, 1, HAND_DOOM , false, false, true , false, false, false, false, false, false, false)
+SF(3, 2, HEAL , false, false, false, false, true , false, false, false, false, true )
+SF(3, 3, S_ANIMALS , true , false, false, false, true , false, false, false, false, false)
+SF(3, 4, BLINK , false, false, false, false, true , false, true , true , false, false)
+SF(3, 5, TPORT , false, false, false, false, true , false, true , false, false, false)
+SF(3, 6, TELE_TO , false, true , false, false, false, false, false, false, false, false)
+SF(3, 7, TELE_AWAY , false, false, false, false, true , false, true , false, false, false)
+SF(3, 8, TELE_LEVEL , false, false, false, false, true , false, true , false, false, false)
+SF(3, 9, DARKNESS , false, true , false, false, false, false, false, false, false, false)
+SF(3, 10, TRAPS , false, true , false, false, true , false, false, false, false, false)
+SF(3, 11, FORGET , false, true , false, false, false, false, false, false, false, false)
+SF(3, 12, RAISE_DEAD , false, false, false, false, false, false, false, false, false, false)
+SF(3, 13, S_BUG , true , false, false, false, true , false, false, false, false, false)
+SF(3, 14, S_RNG , true , false, false, false, true , false, false, false, false, false)
+SF(3, 15, S_THUNDERLORD, true , false, false, false, true , false, false, false, false, false)
+SF(3, 16, S_KIN , true , false, false, false, true , false, false, false, false, false)
+SF(3, 17, S_HI_DEMON , true , false, false, false, true , false, false, false, false, false)
+SF(3, 18, S_MONSTER , true , false, false, false, true , false, false, false, false, false)
+SF(3, 19, S_MONSTERS , true , false, false, false, true , false, false, false, false, false)
+SF(3, 20, S_ANT , true , false, false, false, true , false, false, false, false, false)
+SF(3, 21, S_SPIDER , true , false, false, false, true , false, false, false, false, false)
+SF(3, 22, S_HOUND , true , false, false, false, true , false, false, false, false, false)
+SF(3, 23, S_HYDRA , true , false, false, false, true , false, false, false, false, false)
+SF(3, 24, S_ANGEL , true , false, false, false, true , false, false, false, false, false)
+SF(3, 25, S_DEMON , true , false, false, false, true , false, false, false, false, false)
+SF(3, 26, S_UNDEAD , true , false, false, false, true , false, false, false, false, false)
+SF(3, 27, S_DRAGON , true , false, false, false, true , false, false, false, false, false)
+SF(3, 28, S_HI_UNDEAD , true , false, false, false, true , false, false, false, false, false)
+SF(3, 29, S_HI_DRAGON , true , false, false, false, true , false, false, false, false, false)
+SF(3, 30, S_WRAITH , true , false, false, false, true , false, false, false, false, false)
+SF(3, 31, S_UNIQUE , true , false, false, false, true , false, false, false, false, false)
diff --git a/src/monster_spell_flag_set.hpp b/src/monster_spell_flag_set.hpp
new file mode 100644
index 00000000..37d31665
--- /dev/null
+++ b/src/monster_spell_flag_set.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "flag_set.hpp"
+
+constexpr std::size_t SF_MAX_TIERS = 3;
+
+typedef flag_set<SF_MAX_TIERS> monster_spell_flag_set;
diff --git a/src/q_bounty.cc b/src/q_bounty.cc
index 7af282bf..dac4fef7 100644
--- a/src/q_bounty.cc
+++ b/src/q_bounty.cc
@@ -2,6 +2,7 @@
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "object1.hpp"
#include "object2.hpp"
#include "object_type.hpp"
@@ -38,7 +39,7 @@ static bool_ lua_mon_hook_bounty(int r_idx)
if (r_ptr->flags7 & RF7_FRIENDLY) return (FALSE);
/* Accept only monsters that are not breeders */
- if (r_ptr->flags4 & RF4_MULTIPLY) return (FALSE);
+ if (r_ptr->spells & SF_MULTIPLY) return (FALSE);
/* Forbid joke monsters */
if (r_ptr->flags8 & RF8_JOKEANGBAND) return (FALSE);
diff --git a/src/q_god.cc b/src/q_god.cc
index 3714e457..d9bf955c 100644
--- a/src/q_god.cc
+++ b/src/q_god.cc
@@ -9,6 +9,7 @@
#include "hook_enter_dungeon_in.hpp"
#include "hook_player_level_in.hpp"
#include "hooks.hpp"
+#include "monster_spell_flag.hpp"
#include "object2.hpp"
#include "player_type.hpp"
#include "quark.hpp"
@@ -534,8 +535,8 @@ static void quest_god_set_god_dungeon_attributes_manwe()
* too. They would have ransacked his elf-loving temple :) */
d_info[DUNGEON_GOD].rules[0].mflags2 = RF2_INVISIBLE;
d_info[DUNGEON_GOD].rules[1].mflags3 = RF3_ORC | RF3_IM_POIS;
- d_info[DUNGEON_GOD].rules[2].mflags4 = RF4_BR_POIS | RF4_BR_GRAV;
- d_info[DUNGEON_GOD].rules[3].mflags5 = RF5_BA_POIS;
+ d_info[DUNGEON_GOD].rules[2].mspells = SF_BR_POIS | SF_BR_GRAV;
+ d_info[DUNGEON_GOD].rules[3].mspells = SF_BA_POIS;
d_info[DUNGEON_GOD].rules[4].mflags7 = RF7_CAN_FLY;
}
@@ -784,8 +785,8 @@ static void quest_god_set_god_dungeon_attributes_varda()
/* M: We want air(poison-type) or flying characters. Orcs too. */
d_info[DUNGEON_GOD].rules[0].mflags2 = RF2_INVISIBLE;
d_info[DUNGEON_GOD].rules[1].mflags3 = RF3_ORC | RF3_IM_POIS;
- d_info[DUNGEON_GOD].rules[2].mflags4 = RF4_BR_POIS | RF4_BR_GRAV;
- d_info[DUNGEON_GOD].rules[3].mflags5 = RF5_BA_POIS;
+ d_info[DUNGEON_GOD].rules[2].mspells = SF_BR_POIS | SF_BR_GRAV;
+ d_info[DUNGEON_GOD].rules[3].mspells = SF_BA_POIS;
d_info[DUNGEON_GOD].rules[4].mflags7 = RF7_CAN_FLY;
}
diff --git a/src/q_poison.cc b/src/q_poison.cc
index a5b274b0..464c93ef 100644
--- a/src/q_poison.cc
+++ b/src/q_poison.cc
@@ -10,6 +10,7 @@
#include "messages.hpp"
#include "monster2.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "object2.hpp"
#include "player_type.hpp"
@@ -33,7 +34,7 @@ static bool_ create_molds_hook(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
- if (r_ptr->flags4 & RF4_MULTIPLY) return FALSE;
+ if (r_ptr->spells & SF_MULTIPLY) return FALSE;
if (r_ptr->d_char == 'm') return TRUE;
else if (r_ptr->d_char == ',') return TRUE;
diff --git a/src/q_rand.cc b/src/q_rand.cc
index bc3f2609..26903848 100644
--- a/src/q_rand.cc
+++ b/src/q_rand.cc
@@ -15,8 +15,9 @@
#include "messages.hpp"
#include "monster2.hpp"
#include "monster3.hpp"
-#include "monster_type.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
+#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
#include "object_kind.hpp"
@@ -115,7 +116,7 @@ void initialize_random_quests(int n)
if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
/* Accept only monsters that are not breeders */
- if (r_ptr->flags4 & RF4_MULTIPLY) continue;
+ if (r_ptr->spells & SF_MULTIPLY) continue;
/* Forbid joke monsters */
if (r_ptr->flags8 & RF8_JOKEANGBAND) continue;
diff --git a/src/rule_type.hpp b/src/rule_type.hpp
index d2e510a7..d6424641 100644
--- a/src/rule_type.hpp
+++ b/src/rule_type.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "h-basic.h"
+#include "monster_spell_flag_set.hpp"
/* Define monster generation rules */
struct rule_type
@@ -11,12 +12,11 @@ struct rule_type
u32b mflags1 = 0; /* The monster flags that are allowed */
u32b mflags2 = 0;
u32b mflags3 = 0;
- u32b mflags4 = 0;
- u32b mflags5 = 0;
- u32b mflags6 = 0;
u32b mflags7 = 0;
u32b mflags8 = 0;
u32b mflags9 = 0;
+ monster_spell_flag_set mspells; /* Monster spells the are allowed */
+
char r_char[5] = { 0 }; /* Monster race allowed */
};
diff --git a/src/spells1.cc b/src/spells1.cc
index cad09a92..98520b04 100644
--- a/src/spells1.cc
+++ b/src/spells1.cc
@@ -21,8 +21,9 @@
#include "melee2.hpp"
#include "monster2.hpp"
#include "monster3.hpp"
-#include "monster_type.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
+#include "monster_type.hpp"
#include "object1.hpp"
#include "object2.hpp"
#include "object_kind.hpp"
@@ -599,7 +600,7 @@ void teleport_player(int dis)
{
auto const r_ptr = m_list[cave[oy + yy][ox + xx].m_idx].race();
- if ((r_ptr->flags6 & RF6_TPORT) && !(r_ptr->flags3 & RF3_RES_TELE))
+ if ((r_ptr->spells & SF_TPORT) && !(r_ptr->flags3 & RF3_RES_TELE))
/*
* The latter limitation is to avoid
* totally unkillable suckers...
@@ -4830,7 +4831,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (seen) obvious = TRUE;
do_poly = TRUE;
do_conf = (5 + randint(11) + r) / (r + 1);
- if ((r_ptr->flags4 & RF4_BR_CHAO) ||
+ if ((r_ptr->spells & SF_BR_CHAO) ||
((r_ptr->flags3 & RF3_DEMON) && (randint(3) == 1)))
{
note = " resists.";
@@ -4846,7 +4847,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
if (seen) obvious = TRUE;
if (magik(33)) do_cut = (10 + randint(15) + r) / (r + 1);
- if (r_ptr->flags4 & RF4_BR_SHAR)
+ if (r_ptr->spells & SF_BR_SHAR)
{
note = " resists.";
dam *= 3;
@@ -4862,7 +4863,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (seen) obvious = TRUE;
if (magik(12)) do_cut = (10 + randint(15) + r) / (r + 1);
- if (r_ptr->flags4 & RF4_BR_SHAR)
+ if (r_ptr->spells & SF_BR_SHAR)
{
note = " resists somewhat.";
dam /= 2;
@@ -4883,7 +4884,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
}
else
do_stun = (10 + randint(15) + r) / (r + 1);
- if (r_ptr->flags4 & RF4_BR_SOUN)
+ if (r_ptr->spells & SF_BR_SOUN)
{
note = " resists.";
dam *= 2;
@@ -4897,7 +4898,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
if (seen) obvious = TRUE;
do_conf = (10 + randint(15) + r) / (r + 1);
- if (r_ptr->flags4 & RF4_BR_CONF)
+ if (r_ptr->spells & SF_BR_CONF)
{
note = " resists.";
dam *= 2;
@@ -5025,7 +5026,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* --hack-- Only stun if a monster fired it */
else do_stun = (randint(15) + r) / (r + 1);
- if (r_ptr->flags4 & RF4_BR_WALL)
+ if (r_ptr->spells & SF_BR_WALL)
{
note = " resists.";
dam *= 3;
@@ -5038,7 +5039,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_INERTIA:
{
if (seen) obvious = TRUE;
- if (r_ptr->flags4 & RF4_BR_INER)
+ if (r_ptr->spells & SF_BR_INER)
{
note = " resists.";
dam *= 3;
@@ -5065,7 +5066,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_TIME:
{
if (seen) obvious = TRUE;
- if (r_ptr->flags4 & RF4_BR_TIME)
+ if (r_ptr->spells & SF_BR_TIME)
{
note = " resists.";
dam *= 3;
@@ -5098,7 +5099,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (!resist_tele) do_dist = 10;
else do_dist = 0;
- if (r_ptr->flags4 & RF4_BR_GRAV)
+ if (r_ptr->spells & SF_BR_GRAV)
{
note = " resists.";
dam *= 3;
@@ -6068,7 +6069,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
case GF_LITE:
{
if (seen) obvious = TRUE;
- if (r_ptr->flags4 & RF4_BR_LITE)
+ if (r_ptr->spells & SF_BR_LITE)
{
note = " resists.";
dam *= 2;
@@ -6090,7 +6091,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (seen) obvious = TRUE;
/* Likes darkness... */
- if ((r_ptr->flags4 & RF4_BR_DARK) ||
+ if ((r_ptr->spells & SF_BR_DARK) ||
(r_ptr->flags3 & RF3_ORC) ||
(r_ptr->flags3 & RF3_HURT_LITE))
{
@@ -6620,14 +6621,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if ((who > 0) && (dam > m_ptr->hp)) dam = m_ptr->hp;
}
- if (do_pois && (!(r_ptr->flags3 & RF3_IM_POIS)) && (!(r_ptr->flags3 & RF4_BR_POIS)) && hurt_monster(m_ptr))
+ if (do_pois && (!(r_ptr->flags3 & RF3_IM_POIS)) && (!(r_ptr->flags3 & SF_BR_POIS)) && hurt_monster(m_ptr))
{
if (m_ptr->poisoned) note = " is more poisoned.";
else note = " is poisoned.";
m_ptr->poisoned += do_pois;
}
- if (do_cut && (!(r_ptr->flags4 & RF4_BR_WALL)) && hurt_monster(m_ptr))
+ if (do_cut && (!(r_ptr->spells & SF_BR_WALL)) && hurt_monster(m_ptr))
{
if (m_ptr->bleeding) note = " bleeds more strongly.";
else note = " starts bleeding.";
@@ -6760,8 +6761,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Sound and Impact breathers never stun */
else if (do_stun &&
- !(r_ptr->flags4 & RF4_BR_SOUN) &&
- !(r_ptr->flags4 & RF4_BR_WALL) && hurt_monster(m_ptr))
+ !(r_ptr->spells & SF_BR_SOUN) &&
+ !(r_ptr->spells & SF_BR_WALL) && hurt_monster(m_ptr))
{
/* Obvious */
if (seen) obvious = TRUE;
@@ -6785,8 +6786,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
/* Confusion and Chaos breathers (and sleepers) never confuse */
else if (do_conf &&
!(r_ptr->flags3 & RF3_NO_CONF) &&
- !(r_ptr->flags4 & RF4_BR_CONF) &&
- !(r_ptr->flags4 & RF4_BR_CHAO) && hurt_monster(m_ptr))
+ !(r_ptr->spells & SF_BR_CONF) &&
+ !(r_ptr->spells & SF_BR_CHAO) && hurt_monster(m_ptr))
{
/* Obvious */
if (seen) obvious = TRUE;
diff --git a/src/spells2.cc b/src/spells2.cc
index 09374ceb..08d65a4b 100644
--- a/src/spells2.cc
+++ b/src/spells2.cc
@@ -22,6 +22,7 @@
#include "monster2.hpp"
#include "monster3.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "monster_type.hpp"
#include "notes.hpp"
#include "object1.hpp"
@@ -882,7 +883,7 @@ void self_knowledge(FILE *fff)
info[i++] = "You have an empty mind.";
if (r_ptr->flags2 & RF2_WEIRD_MIND)
info[i++] = "You have a weird mind.";
- if (r_ptr->flags4 & RF4_MULTIPLY)
+ if (r_ptr->spells & SF_MULTIPLY)
info[i++] = "You can multiply.";
if (r_ptr->flags2 & RF2_POWERFUL)
info[i++] = "You have strong breath.";
@@ -974,186 +975,183 @@ void self_knowledge(FILE *fff)
if (r_ptr->flags3 & RF3_NO_SLEEP)
info[i++] = "You are immune to sleep.";
- if (r_ptr->flags4 & RF4_SHRIEK)
+ if (r_ptr->spells & SF_SHRIEK)
info[i++] = "You can aggravate monsters.";
- if (r_ptr->flags4 & RF4_ROCKET)
+ if (r_ptr->spells & SF_ROCKET)
info[i++] = "You can fire a rocket.";
- if (r_ptr->flags4 & RF4_ARROW_1)
+ if (r_ptr->spells & SF_ARROW_1)
info[i++] = "You can fire a light arrow.";
- if (r_ptr->flags4 & RF4_ARROW_2)
+ if (r_ptr->spells & SF_ARROW_2)
info[i++] = "You can fire a heavy arrow.";
- if (r_ptr->flags4 & RF4_ARROW_3)
+ if (r_ptr->spells & SF_ARROW_3)
info[i++] = "You can fire a light missile.";
- if (r_ptr->flags4 & RF4_ARROW_4)
+ if (r_ptr->spells & SF_ARROW_4)
info[i++] = "You can fire a heavy missile.";
- if (r_ptr->flags4 & RF4_BR_ACID)
+ if (r_ptr->spells & SF_BR_ACID)
info[i++] = "You can breathe acid.";
- if (r_ptr->flags4 & RF4_BR_ELEC)
+ if (r_ptr->spells & SF_BR_ELEC)
info[i++] = "You can breathe electricity.";
- if (r_ptr->flags4 & RF4_BR_FIRE)
+ if (r_ptr->spells & SF_BR_FIRE)
info[i++] = "You can breathe fire.";
- if (r_ptr->flags4 & RF4_BR_COLD)
+ if (r_ptr->spells & SF_BR_COLD)
info[i++] = "You can breathe cold.";
- if (r_ptr->flags4 & RF4_BR_POIS)
+ if (r_ptr->spells & SF_BR_POIS)
info[i++] = "You can breathe poison.";
- if (r_ptr->flags4 & RF4_BR_NETH)
+ if (r_ptr->spells & SF_BR_NETH)
info[i++] = "You can breathe nether.";
- if (r_ptr->flags4 & RF4_BR_LITE)
+ if (r_ptr->spells & SF_BR_LITE)
info[i++] = "You can breathe light.";
- if (r_ptr->flags4 & RF4_BR_DARK)
+ if (r_ptr->spells & SF_BR_DARK)
info[i++] = "You can breathe darkness.";
- if (r_ptr->flags4 & RF4_BR_CONF)
+ if (r_ptr->spells & SF_BR_CONF)
info[i++] = "You can breathe confusion.";
- if (r_ptr->flags4 & RF4_BR_SOUN)
+ if (r_ptr->spells & SF_BR_SOUN)
info[i++] = "You can breathe sound.";
- if (r_ptr->flags4 & RF4_BR_CHAO)
+ if (r_ptr->spells & SF_BR_CHAO)
info[i++] = "You can breathe chaos.";
- if (r_ptr->flags4 & RF4_BR_DISE)
+ if (r_ptr->spells & SF_BR_DISE)
info[i++] = "You can breathe disenchantment.";
- if (r_ptr->flags4 & RF4_BR_NEXU)
+ if (r_ptr->spells & SF_BR_NEXU)
info[i++] = "You can breathe nexus.";
- if (r_ptr->flags4 & RF4_BR_TIME)
+ if (r_ptr->spells & SF_BR_TIME)
info[i++] = "You can breathe time.";
- if (r_ptr->flags4 & RF4_BR_INER)
+ if (r_ptr->spells & SF_BR_INER)
info[i++] = "You can breathe inertia.";
- if (r_ptr->flags4 & RF4_BR_GRAV)
+ if (r_ptr->spells & SF_BR_GRAV)
info[i++] = "You can breathe gravity.";
- if (r_ptr->flags4 & RF4_BR_SHAR)
+ if (r_ptr->spells & SF_BR_SHAR)
info[i++] = "You can breathe shards.";
- if (r_ptr->flags4 & RF4_BR_PLAS)
+ if (r_ptr->spells & SF_BR_PLAS)
info[i++] = "You can breathe plasma.";
- if (r_ptr->flags4 & RF4_BR_WALL)
+ if (r_ptr->spells & SF_BR_WALL)
info[i++] = "You can breathe force.";
- if (r_ptr->flags4 & RF4_BR_MANA)
+ if (r_ptr->spells & SF_BR_MANA)
info[i++] = "You can breathe mana.";
- if (r_ptr->flags4 & RF4_BR_NUKE)
+ if (r_ptr->spells & SF_BR_NUKE)
info[i++] = "You can breathe nuke.";
- if (r_ptr->flags4 & RF4_BR_DISI)
+ if (r_ptr->spells & SF_BR_DISI)
info[i++] = "You can breathe disintegration.";
- if (r_ptr->flags5 & RF5_BA_ACID)
+ if (r_ptr->spells & SF_BA_ACID)
info[i++] = "You can cast a ball of acid.";
- if (r_ptr->flags5 & RF5_BA_ELEC)
+ if (r_ptr->spells & SF_BA_ELEC)
info[i++] = "You can cast a ball of electricity.";
- if (r_ptr->flags5 & RF5_BA_FIRE)
+ if (r_ptr->spells & SF_BA_FIRE)
info[i++] = "You can cast a ball of fire.";
- if (r_ptr->flags5 & RF5_BA_COLD)
+ if (r_ptr->spells & SF_BA_COLD)
info[i++] = "You can cast a ball of cold.";
- if (r_ptr->flags5 & RF5_BA_POIS)
+ if (r_ptr->spells & SF_BA_POIS)
info[i++] = "You can cast a ball of poison.";
- if (r_ptr->flags5 & RF5_BA_NETH)
+ if (r_ptr->spells & SF_BA_NETH)
info[i++] = "You can cast a ball of nether.";
- if (r_ptr->flags5 & RF5_BA_WATE)
+ if (r_ptr->spells & SF_BA_WATE)
info[i++] = "You can cast a ball of water.";
- /* Not implemented */
- if (r_ptr->flags5 & RF5_DRAIN_MANA)
+ if (r_ptr->spells & SF_DRAIN_MANA)
info[i++] = "You can drain mana.";
- if (r_ptr->flags5 & RF5_MIND_BLAST)
+ if (r_ptr->spells & SF_MIND_BLAST)
info[i++] = "You can cause mind blasting.";
- if (r_ptr->flags5 & RF5_BRAIN_SMASH)
+ if (r_ptr->spells & SF_BRAIN_SMASH)
info[i++] = "You can cause brain smashing.";
- if (r_ptr->flags5 & RF5_CAUSE_1)
+ if (r_ptr->spells & SF_CAUSE_1)
info[i++] = "You can cause light wounds.";
- if (r_ptr->flags5 & RF5_CAUSE_2)
+ if (r_ptr->spells & SF_CAUSE_2)
info[i++] = "You can cause serious wounds.";
- if (r_ptr->flags5 & RF5_CAUSE_3)
+ if (r_ptr->spells & SF_CAUSE_3)
info[i++] = "You can cause critical wounds.";
- if (r_ptr->flags5 & RF5_CAUSE_4)
+ if (r_ptr->spells & SF_CAUSE_4)
info[i++] = "You can cause mortal wounds.";
- if (r_ptr->flags5 & RF5_BO_ACID)
+ if (r_ptr->spells & SF_BO_ACID)
info[i++] = "You can cast a bolt of acid.";
- if (r_ptr->flags5 & RF5_BO_ELEC)
+ if (r_ptr->spells & SF_BO_ELEC)
info[i++] = "You can cast a bolt of electricity.";
- if (r_ptr->flags5 & RF5_BO_FIRE)
+ if (r_ptr->spells & SF_BO_FIRE)
info[i++] = "You can cast a bolt of fire.";
- if (r_ptr->flags5 & RF5_BO_COLD)
+ if (r_ptr->spells & SF_BO_COLD)
info[i++] = "You can cast a bolt of cold.";
- if (r_ptr->flags5 & RF5_BO_POIS)
+ if (r_ptr->spells & SF_BO_POIS)
info[i++] = "You can cast a bolt of poison.";
- if (r_ptr->flags5 & RF5_BO_NETH)
+ if (r_ptr->spells & SF_BO_NETH)
info[i++] = "You can cast a bolt of nether.";
- if (r_ptr->flags5 & RF5_BO_WATE)
+ if (r_ptr->spells & SF_BO_WATE)
info[i++] = "You can cast a bolt of water.";
- if (r_ptr->flags5 & RF5_BO_MANA)
+ if (r_ptr->spells & SF_BO_MANA)
info[i++] = "You can cast a bolt of mana.";
- if (r_ptr->flags5 & RF5_BO_PLAS)
+ if (r_ptr->spells & SF_BO_PLAS)
info[i++] = "You can cast a bolt of plasma.";
- if (r_ptr->flags5 & RF5_BO_ICEE)
+ if (r_ptr->spells & SF_BO_ICEE)
info[i++] = "You can cast a bolt of ice.";
- if (r_ptr->flags5 & RF5_MISSILE)
+ if (r_ptr->spells & SF_MISSILE)
info[i++] = "You can cast magic missile.";
- if (r_ptr->flags5 & RF5_SCARE)
+ if (r_ptr->spells & SF_SCARE)
info[i++] = "You can terrify.";
- if (r_ptr->flags5 & RF5_BLIND)
+ if (r_ptr->spells & SF_BLIND)
info[i++] = "You can blind.";
- if (r_ptr->flags5 & RF5_CONF)
+ if (r_ptr->spells & SF_CONF)
info[i++] = "You can use confusion.";
- if (r_ptr->flags5 & RF5_SLOW)
+ if (r_ptr->spells & SF_SLOW)
info[i++] = "You can cast slow.";
- if (r_ptr->flags5 & RF5_HOLD)
+ if (r_ptr->spells & SF_HOLD)
info[i++] = "You can touch to paralyze.";
- if (r_ptr->flags6 & RF6_HASTE)
+ if (r_ptr->spells & SF_HASTE)
info[i++] = "You can haste yourself.";
- if (r_ptr->flags6 & RF6_HAND_DOOM)
+ if (r_ptr->spells & SF_HAND_DOOM)
info[i++] = "You can invoke Hand of Doom.";
- if (r_ptr->flags6 & RF6_HEAL)
+ if (r_ptr->spells & SF_HEAL)
info[i++] = "You can heal yourself.";
- if (r_ptr->flags6 & RF6_BLINK)
+ if (r_ptr->spells & SF_BLINK)
info[i++] = "You can blink.";
- if (r_ptr->flags6 & RF6_TPORT)
+ if (r_ptr->spells & SF_TPORT)
info[i++] = "You can teleport.";
- if (r_ptr->flags6 & RF6_TELE_TO)
+ if (r_ptr->spells & SF_TELE_TO)
info[i++] = "You can go between places.";
- if (r_ptr->flags6 & RF6_TELE_AWAY)
+ if (r_ptr->spells & SF_TELE_AWAY)
info[i++] = "You can teleport away.";
- if (r_ptr->flags6 & RF6_TELE_LEVEL)
+ if (r_ptr->spells & SF_TELE_LEVEL)
info[i++] = "You can teleport level.";
- if (r_ptr->flags6 & RF6_DARKNESS)
+ if (r_ptr->spells & SF_DARKNESS)
info[i++] = "You can create darkness.";
- if (r_ptr->flags6 & RF6_TRAPS)
+ if (r_ptr->spells & SF_TRAPS)
info[i++] = "You can create traps.";
- /* Not implemented */
- if (r_ptr->flags6 & RF6_FORGET)
+ if (r_ptr->spells & SF_FORGET)
info[i++] = "You can fade memories.";
- if (r_ptr->flags6 & RF6_RAISE_DEAD)
+ if (r_ptr->spells & SF_RAISE_DEAD)
info[i++] = "You can Raise the Dead.";
- if (r_ptr->flags6 & RF6_S_BUG)
+ if (r_ptr->spells & SF_S_BUG)
info[i++] = "You can magically summon a Software Bugs.";
- if (r_ptr->flags6 & RF6_S_RNG)
+ if (r_ptr->spells & SF_S_RNG)
info[i++] = "You can magically summon the RNG.";
- if (r_ptr->flags6 & RF6_S_THUNDERLORD)
+ if (r_ptr->spells & SF_S_THUNDERLORD)
info[i++] = "You can magically summon some Thunderlords.";
- if (r_ptr->flags6 & RF6_S_KIN)
+ if (r_ptr->spells & SF_S_KIN)
info[i++] = "You can magically summon some Kins.";
- if (r_ptr->flags6 & RF6_S_HI_DEMON)
+ if (r_ptr->spells & SF_S_HI_DEMON)
info[i++] = "You can magically summon greater demons.";
- if (r_ptr->flags6 & RF6_S_MONSTER)
+ if (r_ptr->spells & SF_S_MONSTER)
info[i++] = "You can magically summon a monster.";
- if (r_ptr->flags6 & RF6_S_MONSTERS)
+ if (r_ptr->spells & SF_S_MONSTERS)
info[i++] = "You can magically summon monsters.";
- if (r_ptr->flags6 & RF6_S_ANT)
+ if (r_ptr->spells & SF_S_ANT)
info[i++] = "You can magically summon ants.";
- if (r_ptr->flags6 & RF6_S_SPIDER)
+ if (r_ptr->spells & SF_S_SPIDER)
info[i++] = "You can magically summon spiders.";
- if (r_ptr->flags6 & RF6_S_HOUND)
+ if (r_ptr->spells & SF_S_HOUND)
info[i++] = "You can magically summon hounds.";
- if (r_ptr->flags6 & RF6_S_HYDRA)
+ if (r_ptr->spells & SF_S_HYDRA)
info[i++] = "You can magically summon hydras.";
- if (r_ptr->flags6 & RF6_S_ANGEL)
+ if (r_ptr->spells & SF_S_ANGEL)
info[i++] = "You can magically summon an angel.";
- if (r_ptr->flags6 & RF6_S_DEMON)
+ if (r_ptr->spells & SF_S_DEMON)
info[i++] = "You can magically summon a demon.";
- if (r_ptr->flags6 & RF6_S_UNDEAD)
+ if (r_ptr->spells & SF_S_UNDEAD)
info[i++] = "You can magically summon an undead.";
- if (r_ptr->flags6 & RF6_S_DRAGON)
+ if (r_ptr->spells & SF_S_DRAGON)
info[i++] = "You can magically summon a dragon.";
- if (r_ptr->flags6 & RF6_S_HI_UNDEAD)
+ if (r_ptr->spells & SF_S_HI_UNDEAD)
info[i++] = "You can magically summon greater undead.";
- if (r_ptr->flags6 & RF6_S_HI_DRAGON)
+ if (r_ptr->spells & SF_S_HI_DRAGON)
info[i++] = "You can magically summon greater dragons.";
- if (r_ptr->flags6 & RF6_S_WRAITH)
+ if (r_ptr->spells & SF_S_WRAITH)
info[i++] = "You can magically summon a wraith.";
- /* Not implemented */
- if (r_ptr->flags6 & RF6_S_UNIQUE)
+ if (r_ptr->spells & SF_S_UNIQUE)
info[i++] = "You can magically summon an unique monster.";
/* Not implemented */
if (r_ptr->flags7 & RF7_AQUATIC)
diff --git a/src/tables.cc b/src/tables.cc
index 24328ac9..02bdfedf 100644
--- a/src/tables.cc
+++ b/src/tables.cc
@@ -10,6 +10,7 @@
#include "tables.h"
#include "modules.hpp"
+#include "monster_spell_flag.hpp"
#include "options.hpp"
#include "q_library.hpp"
#include "q_fireprof.hpp"
@@ -3931,106 +3932,97 @@ quest_type quest[MAX_Q_IDX] =
/* List of powers for Symbiants/Powers */
-monster_power monster_powers[96] =
- {
- { RF4_SHRIEK, "Aggravate Monster", 1, FALSE },
- { RF4_MULTIPLY, "Multiply", 10, FALSE },
- { RF4_S_ANIMAL, "Summon Animal", 30, FALSE },
- { RF4_ROCKET, "Fire a Rocket", 40, TRUE },
- { RF4_ARROW_1, "Light Arrow", 1, FALSE },
- { RF4_ARROW_2, "Minor Arrow", 3, FALSE },
- { RF4_ARROW_3, "Major Arrow", 7, TRUE },
- { RF4_ARROW_4, "Great Arrow", 9, TRUE },
- { RF4_BR_ACID, "Breathe Acid", 10, FALSE },
- { RF4_BR_ELEC, "Breathe Lightning", 10, FALSE },
- { RF4_BR_FIRE, "Breathe Fire", 10, FALSE },
- { RF4_BR_COLD, "Breathe Cold", 10, FALSE },
- { RF4_BR_POIS, "Breathe Poison", 15, TRUE },
- { RF4_BR_NETH, "Breathe Nether", 30, TRUE },
- { RF4_BR_LITE, "Breathe Light", 20, TRUE },
- { RF4_BR_DARK, "Breathe Dark", 20, TRUE },
- { RF4_BR_CONF, "Breathe Confusion", 15, TRUE },
- { RF4_BR_SOUN, "Breathe Sound", 30, TRUE },
- { RF4_BR_CHAO, "Breathe Chaos", 30, TRUE },
- { RF4_BR_DISE, "Breathe Disenchantment", 30, TRUE },
- { RF4_BR_NEXU, "Breathe Nexus", 30, TRUE },
- { RF4_BR_TIME, "Breathe Time", 30, TRUE },
- { RF4_BR_INER, "Breathe Inertia", 30, TRUE },
- { RF4_BR_GRAV, "Breathe Gravity", 30, TRUE },
- { RF4_BR_SHAR, "Breathe Shards", 30, TRUE },
- { RF4_BR_PLAS, "Breathe Plasma", 30, TRUE },
- { RF4_BR_WALL, "Breathe Force", 30, TRUE },
- { RF4_BR_MANA, "Breathe Mana", 40, TRUE },
- { RF4_BA_NUKE, "Nuke Ball", 30, TRUE },
- { RF4_BR_NUKE, "Breathe Nuke", 40, TRUE },
- { RF4_BA_CHAO, "Chaos Ball", 30, TRUE },
- { RF4_BR_DISI, "Breathe Disintegration", 40, TRUE },
-
- { RF5_BA_ACID, "Acid Ball", 8, FALSE },
- { RF5_BA_ELEC, "Lightning Ball", 8, FALSE },
- { RF5_BA_FIRE, "Fire Ball", 8, FALSE },
- { RF5_BA_COLD, "Cold Ball", 8, FALSE },
- { RF5_BA_POIS, "Poison Ball", 20, TRUE },
- { RF5_BA_NETH, "Nether Ball", 20, TRUE },
- { RF5_BA_WATE, "Water Ball", 20, TRUE },
- { RF5_BA_MANA, "Mana Ball", 50, TRUE },
- { RF5_BA_DARK, "Darkness Ball", 20, TRUE },
- { 0, "(none)", 0, FALSE },
- { 0, "(none)", 0, FALSE },
- { 0, "(none)", 0, FALSE },
- { RF5_CAUSE_1, "Cause Light Wounds", 20, FALSE },
- { RF5_CAUSE_2, "Cause Medium Wounds", 30, FALSE },
- { RF5_CAUSE_3, "Cause Critical Wounds", 35, TRUE },
- { RF5_CAUSE_4, "Cause Mortal Wounds", 45, TRUE },
- { RF5_BO_ACID, "Acid Bolt", 5, FALSE },
- { RF5_BO_ELEC, "Lightning Bolt", 5, FALSE },
- { RF5_BO_FIRE, "Fire Bolt", 5, FALSE },
- { RF5_BO_COLD, "Cold Bolt", 5, FALSE },
- { RF5_BO_POIS, "Poison Bolt", 10, TRUE },
- { RF5_BO_NETH, "Nether Bolt", 15, TRUE },
- { RF5_BO_WATE, "Water Bolt", 20, TRUE },
- { RF5_BO_MANA, "Mana Bolt", 25, TRUE },
- { RF5_BO_PLAS, "Plasma Bolt", 20, TRUE },
- { RF5_BO_ICEE, "Ice Bolt", 20, TRUE },
- { RF5_MISSILE, "Magic Missile", 1, FALSE },
- { RF5_SCARE, "Scare", 4, FALSE },
- { RF5_BLIND, "Blindness", 6, FALSE },
- { RF5_CONF, "Confusion", 7, FALSE },
- { RF5_SLOW, "Slowness", 10, FALSE },
- { RF5_HOLD, "Paralyse", 10, FALSE },
-
- { RF6_HASTE, "Haste Self", 50, FALSE },
- { RF6_HAND_DOOM, "Hand of Doom", 30, TRUE },
- { RF6_HEAL, "Healing", 60, FALSE },
- { RF6_S_ANIMALS, "Summon Animals", 60, TRUE },
- { RF6_BLINK, "Phase Door", 2, FALSE },
- { RF6_TPORT, "Teleport", 10, FALSE },
- { RF6_TELE_TO, "Teleport To", 20, TRUE },
- { RF6_TELE_AWAY, "Teleport Away", 20, FALSE },
- { RF6_TELE_LEVEL, "Teleport Level", 20, TRUE },
- { RF6_DARKNESS, "Darkness", 3, FALSE },
- { RF6_TRAPS, "Create Traps", 10, TRUE },
- { 0, "(none)", 0, FALSE },
- { RF6_RAISE_DEAD, "Raise the Dead", 400, TRUE },
- { 0, "(none)", 0, FALSE },
- { 0, "(none)", 0, FALSE },
- { RF6_S_THUNDERLORD, "Summon Thunderlords", 90, TRUE },
- { RF6_S_KIN, "Summon Kin", 80, FALSE },
- { RF6_S_HI_DEMON, "Summon Greater Demons", 90, TRUE },
- { RF6_S_MONSTER, "Summon Monster", 50, FALSE },
- { RF6_S_MONSTERS, "Summon Monsters", 60, TRUE },
- { RF6_S_ANT, "Summon Ants", 30, FALSE },
- { RF6_S_SPIDER, "Summon Spider", 30, FALSE },
- { RF6_S_HOUND, "Summon Hound", 50, TRUE },
- { RF6_S_HYDRA, "Summon Hydra", 40, TRUE },
- { RF6_S_ANGEL, "Summon Angel", 60, TRUE },
- { RF6_S_DEMON, "Summon Demon", 60, TRUE },
- { RF6_S_UNDEAD, "Summon Undead", 70, TRUE },
- { RF6_S_DRAGON, "Summon Dragon", 70, TRUE },
- { RF6_S_HI_UNDEAD, "Summon High Undead", 90, TRUE },
- { RF6_S_HI_DRAGON, "Summon High Dragon", 90, TRUE },
- { RF6_S_WRAITH, "Summon Wraith", 90, TRUE },
- { 0, "(none)", 0, FALSE },
+monster_power monster_powers[] =
+ {
+ { SF_SHRIEK_IDX, "Aggravate Monster", 1, FALSE },
+ { SF_MULTIPLY_IDX, "Multiply", 10, FALSE },
+ { SF_S_ANIMAL_IDX, "Summon Animal", 30, FALSE },
+ { SF_ROCKET_IDX, "Fire a Rocket", 40, TRUE },
+ { SF_ARROW_1_IDX, "Light Arrow", 1, FALSE },
+ { SF_ARROW_2_IDX, "Minor Arrow", 3, FALSE },
+ { SF_ARROW_3_IDX, "Major Arrow", 7, TRUE },
+ { SF_ARROW_4_IDX, "Great Arrow", 9, TRUE },
+ { SF_BR_ACID_IDX, "Breathe Acid", 10, FALSE },
+ { SF_BR_ELEC_IDX, "Breathe Lightning", 10, FALSE },
+ { SF_BR_FIRE_IDX, "Breathe Fire", 10, FALSE },
+ { SF_BR_COLD_IDX, "Breathe Cold", 10, FALSE },
+ { SF_BR_POIS_IDX, "Breathe Poison", 15, TRUE },
+ { SF_BR_NETH_IDX, "Breathe Nether", 30, TRUE },
+ { SF_BR_LITE_IDX, "Breathe Light", 20, TRUE },
+ { SF_BR_DARK_IDX, "Breathe Dark", 20, TRUE },
+ { SF_BR_CONF_IDX, "Breathe Confusion", 15, TRUE },
+ { SF_BR_SOUN_IDX, "Breathe Sound", 30, TRUE },
+ { SF_BR_CHAO_IDX, "Breathe Chaos", 30, TRUE },
+ { SF_BR_DISE_IDX, "Breathe Disenchantment", 30, TRUE },
+ { SF_BR_NEXU_IDX, "Breathe Nexus", 30, TRUE },
+ { SF_BR_TIME_IDX, "Breathe Time", 30, TRUE },
+ { SF_BR_INER_IDX, "Breathe Inertia", 30, TRUE },
+ { SF_BR_GRAV_IDX, "Breathe Gravity", 30, TRUE },
+ { SF_BR_SHAR_IDX, "Breathe Shards", 30, TRUE },
+ { SF_BR_PLAS_IDX, "Breathe Plasma", 30, TRUE },
+ { SF_BR_WALL_IDX, "Breathe Force", 30, TRUE },
+ { SF_BR_MANA_IDX, "Breathe Mana", 40, TRUE },
+ { SF_BA_NUKE_IDX, "Nuke Ball", 30, TRUE },
+ { SF_BR_NUKE_IDX, "Breathe Nuke", 40, TRUE },
+ { SF_BA_CHAO_IDX, "Chaos Ball", 30, TRUE },
+ { SF_BR_DISI_IDX, "Breathe Disintegration", 40, TRUE },
+ { SF_BA_ACID_IDX, "Acid Ball", 8, FALSE },
+ { SF_BA_ELEC_IDX, "Lightning Ball", 8, FALSE },
+ { SF_BA_FIRE_IDX, "Fire Ball", 8, FALSE },
+ { SF_BA_COLD_IDX, "Cold Ball", 8, FALSE },
+ { SF_BA_POIS_IDX, "Poison Ball", 20, TRUE },
+ { SF_BA_NETH_IDX, "Nether Ball", 20, TRUE },
+ { SF_BA_WATE_IDX, "Water Ball", 20, TRUE },
+ { SF_BA_MANA_IDX, "Mana Ball", 50, TRUE },
+ { SF_BA_DARK_IDX, "Darkness Ball", 20, TRUE },
+ { SF_CAUSE_1_IDX, "Cause Light Wounds", 20, FALSE },
+ { SF_CAUSE_2_IDX, "Cause Medium Wounds", 30, FALSE },
+ { SF_CAUSE_3_IDX, "Cause Critical Wounds", 35, TRUE },
+ { SF_CAUSE_4_IDX, "Cause Mortal Wounds", 45, TRUE },
+ { SF_BO_ACID_IDX, "Acid Bolt", 5, FALSE },
+ { SF_BO_ELEC_IDX, "Lightning Bolt", 5, FALSE },
+ { SF_BO_FIRE_IDX, "Fire Bolt", 5, FALSE },
+ { SF_BO_COLD_IDX, "Cold Bolt", 5, FALSE },
+ { SF_BO_POIS_IDX, "Poison Bolt", 10, TRUE },
+ { SF_BO_NETH_IDX, "Nether Bolt", 15, TRUE },
+ { SF_BO_WATE_IDX, "Water Bolt", 20, TRUE },
+ { SF_BO_MANA_IDX, "Mana Bolt", 25, TRUE },
+ { SF_BO_PLAS_IDX, "Plasma Bolt", 20, TRUE },
+ { SF_BO_ICEE_IDX, "Ice Bolt", 20, TRUE },
+ { SF_MISSILE_IDX, "Magic Missile", 1, FALSE },
+ { SF_SCARE_IDX, "Scare", 4, FALSE },
+ { SF_BLIND_IDX, "Blindness", 6, FALSE },
+ { SF_CONF_IDX, "Confusion", 7, FALSE },
+ { SF_SLOW_IDX, "Slowness", 10, FALSE },
+ { SF_HOLD_IDX, "Paralyse", 10, FALSE },
+ { SF_HASTE_IDX, "Haste Self", 50, FALSE },
+ { SF_HAND_DOOM_IDX, "Hand of Doom", 30, TRUE },
+ { SF_HEAL_IDX, "Healing", 60, FALSE },
+ { SF_S_ANIMALS_IDX, "Summon Animals", 60, TRUE },
+ { SF_BLINK_IDX, "Phase Door", 2, FALSE },
+ { SF_TPORT_IDX, "Teleport", 10, FALSE },
+ { SF_TELE_TO_IDX, "Teleport To", 20, TRUE },
+ { SF_TELE_AWAY_IDX, "Teleport Away", 20, FALSE },
+ { SF_TELE_LEVEL_IDX, "Teleport Level", 20, TRUE },
+ { SF_DARKNESS_IDX, "Darkness", 3, FALSE },
+ { SF_TRAPS_IDX, "Create Traps", 10, TRUE },
+ { SF_RAISE_DEAD_IDX, "Raise the Dead", 400, TRUE },
+ { SF_S_THUNDERLORD_IDX, "Summon Thunderlords", 90, TRUE },
+ { SF_S_KIN_IDX, "Summon Kin", 80, FALSE },
+ { SF_S_HI_DEMON_IDX, "Summon Greater Demons", 90, TRUE },
+ { SF_S_MONSTER_IDX, "Summon Monster", 50, FALSE },
+ { SF_S_MONSTERS_IDX, "Summon Monsters", 60, TRUE },
+ { SF_S_ANT_IDX, "Summon Ants", 30, FALSE },
+ { SF_S_SPIDER_IDX, "Summon Spider", 30, FALSE },
+ { SF_S_HOUND_IDX, "Summon Hound", 50, TRUE },
+ { SF_S_HYDRA_IDX, "Summon Hydra", 40, TRUE },
+ { SF_S_ANGEL_IDX, "Summon Angel", 60, TRUE },
+ { SF_S_DEMON_IDX, "Summon Demon", 60, TRUE },
+ { SF_S_UNDEAD_IDX, "Summon Undead", 70, TRUE },
+ { SF_S_DRAGON_IDX, "Summon Dragon", 70, TRUE },
+ { SF_S_HI_UNDEAD_IDX, "Summon High Undead", 90, TRUE },
+ { SF_S_HI_DRAGON_IDX, "Summon High Dragon", 90, TRUE },
+ { SF_S_WRAITH_IDX, "Summon Wraith", 90, TRUE },
};
/* Tval descriptions */
diff --git a/src/wizard1.cc b/src/wizard1.cc
index 9624bcc2..a6072dad 100644
--- a/src/wizard1.cc
+++ b/src/wizard1.cc
@@ -4,6 +4,7 @@
#include "cmd7.hpp"
#include "ego_item_type.hpp"
#include "monster_race.hpp"
+#include "monster_spell_flag.hpp"
#include "object1.hpp"
#include "object2.hpp"
#include "object_kind.hpp"
@@ -1462,8 +1463,6 @@ static void spoil_mon_info(cptr fname)
bool_ breath, magic, sin;
cptr p, q;
cptr vp[64];
- u32b flags1, flags2, flags3, flags4, flags5, flags6, flags9;
-
/* Build the filename */
path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
@@ -1492,13 +1491,11 @@ static void spoil_mon_info(cptr fname)
monster_race *r_ptr = &r_info[n];
/* Extract the flags */
- flags1 = r_ptr->flags1;
- flags2 = r_ptr->flags2;
- flags3 = r_ptr->flags3;
- flags4 = r_ptr->flags4;
- flags5 = r_ptr->flags5;
- flags6 = r_ptr->flags6;
- flags9 = r_ptr->flags9;
+ auto const flags1 = r_ptr->flags1;
+ auto const flags2 = r_ptr->flags2;
+ auto const flags3 = r_ptr->flags3;
+ auto const flags9 = r_ptr->flags9;
+ auto const spells = r_ptr->spells;
breath = FALSE;
magic = FALSE;
@@ -1670,12 +1667,12 @@ static void spoil_mon_info(cptr fname)
/* Collect innate attacks */
vn = 0;
- if (flags4 & RF4_SHRIEK) vp[vn++] = "shriek for help";
- if (flags4 & RF4_ROCKET) vp[vn++] = "shoot a rocket";
- if (flags4 & (RF4_ARROW_1)) vp[vn++] = "fire arrows";
- if (flags4 & (RF4_ARROW_2)) vp[vn++] = "fire arrows";
- if (flags4 & (RF4_ARROW_3)) vp[vn++] = "fire missiles";
- if (flags4 & (RF4_ARROW_4)) vp[vn++] = "fire missiles";
+ if (spells & SF_SHRIEK) vp[vn++] = "shriek for help";
+ if (spells & SF_ROCKET) vp[vn++] = "shoot a rocket";
+ if (spells & SF_ARROW_1) vp[vn++] = "fire arrows";
+ if (spells & SF_ARROW_2) vp[vn++] = "fire arrows";
+ if (spells & SF_ARROW_3) vp[vn++] = "fire missiles";
+ if (spells & SF_ARROW_4) vp[vn++] = "fire missiles";
if (vn)
{
@@ -1692,28 +1689,28 @@ static void spoil_mon_info(cptr fname)
/* Collect breaths */
vn = 0;
- if (flags4 & RF4_BR_ACID) vp[vn++] = "acid";
- if (flags4 & RF4_BR_ELEC) vp[vn++] = "lightning";
- if (flags4 & RF4_BR_FIRE) vp[vn++] = "fire";
- if (flags4 & RF4_BR_COLD) vp[vn++] = "frost";
- if (flags4 & RF4_BR_POIS) vp[vn++] = "poison";
- if (flags4 & RF4_BR_NETH) vp[vn++] = "nether";
- if (flags4 & RF4_BR_LITE) vp[vn++] = "light";
- if (flags4 & RF4_BR_DARK) vp[vn++] = "darkness";
- if (flags4 & RF4_BR_CONF) vp[vn++] = "confusion";
- if (flags4 & RF4_BR_SOUN) vp[vn++] = "sound";
- if (flags4 & RF4_BR_CHAO) vp[vn++] = "chaos";
- if (flags4 & RF4_BR_DISE) vp[vn++] = "disenchantment";
- if (flags4 & RF4_BR_NEXU) vp[vn++] = "nexus";
- if (flags4 & RF4_BR_TIME) vp[vn++] = "time";
- if (flags4 & RF4_BR_INER) vp[vn++] = "inertia";
- if (flags4 & RF4_BR_GRAV) vp[vn++] = "gravity";
- if (flags4 & RF4_BR_SHAR) vp[vn++] = "shards";
- if (flags4 & RF4_BR_PLAS) vp[vn++] = "plasma";
- if (flags4 & RF4_BR_WALL) vp[vn++] = "force";
- if (flags4 & RF4_BR_MANA) vp[vn++] = "mana";
- if (flags4 & RF4_BR_NUKE) vp[vn++] = "toxic waste";
- if (flags4 & RF4_BR_DISI) vp[vn++] = "disintegration";
+ if (spells & SF_BR_ACID) vp[vn++] = "acid";
+ if (spells & SF_BR_ELEC) vp[vn++] = "lightning";
+ if (spells & SF_BR_FIRE) vp[vn++] = "fire";
+ if (spells & SF_BR_COLD) vp[vn++] = "frost";
+ if (spells & SF_BR_POIS) vp[vn++] = "poison";
+ if (spells & SF_BR_NETH) vp[vn++] = "nether";
+ if (spells & SF_BR_LITE) vp[vn++] = "light";
+ if (spells & SF_BR_DARK) vp[vn++] = "darkness";
+ if (spells & SF_BR_CONF) vp[vn++] = "confusion";
+ if (spells & SF_BR_SOUN) vp[vn++] = "sound";
+ if (spells & SF_BR_CHAO) vp[vn++] = "chaos";
+ if (spells & SF_BR_DISE) vp[vn++] = "disenchantment";
+ if (spells & SF_BR_NEXU) vp[vn++] = "nexus";
+ if (spells & SF_BR_TIME) vp[vn++] = "time";
+ if (spells & SF_BR_INER) vp[vn++] = "inertia";
+ if (spells & SF_BR_GRAV) vp[vn++] = "gravity";
+ if (spells & SF_BR_SHAR) vp[vn++] = "shards";
+ if (spells & SF_BR_PLAS) vp[vn++] = "plasma";
+ if (spells & SF_BR_WALL) vp[vn++] = "force";
+ if (spells & SF_BR_MANA) vp[vn++] = "mana";
+ if (spells & SF_BR_NUKE) vp[vn++] = "toxic waste";
+ if (spells & SF_BR_DISI) vp[vn++] = "disintegration";
if (vn)
{
@@ -1731,73 +1728,73 @@ static void spoil_mon_info(cptr fname)
/* Collect spells */
vn = 0;
- if (flags5 & RF5_BA_ACID) vp[vn++] = "produce acid balls";
- if (flags5 & RF5_BA_ELEC) vp[vn++] = "produce lightning balls";
- if (flags5 & RF5_BA_FIRE) vp[vn++] = "produce fire balls";
- if (flags5 & RF5_BA_COLD) vp[vn++] = "produce frost balls";
- if (flags5 & RF5_BA_POIS) vp[vn++] = "produce poison balls";
- if (flags5 & RF5_BA_NETH) vp[vn++] = "produce nether balls";
- if (flags5 & RF5_BA_WATE) vp[vn++] = "produce water balls";
- if (flags4 & RF4_BA_NUKE) vp[vn++] = "produce balls of radiation";
- if (flags5 & RF5_BA_MANA) vp[vn++] = "produce mana storms";
- if (flags5 & RF5_BA_DARK) vp[vn++] = "produce darkness storms";
- if (flags4 & RF4_BA_CHAO) vp[vn++] = "invoke raw Chaos";
- if (flags6 & RF6_HAND_DOOM) vp[vn++] = "invoke the Hand of Doom";
- if (flags5 & RF5_DRAIN_MANA) vp[vn++] = "drain mana";
- if (flags5 & RF5_MIND_BLAST) vp[vn++] = "cause mind blasting";
- if (flags5 & RF5_BRAIN_SMASH) vp[vn++] = "cause brain smashing";
- if (flags5 & (RF5_CAUSE_1)) vp[vn++] = "cause light wounds and cursing";
- if (flags5 & (RF5_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing";
- if (flags5 & (RF5_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing";
- if (flags5 & (RF5_CAUSE_4)) vp[vn++] = "cause mortal wounds";
- if (flags5 & RF5_BO_ACID) vp[vn++] = "produce acid bolts";
- if (flags5 & RF5_BO_ELEC) vp[vn++] = "produce lightning bolts";
- if (flags5 & RF5_BO_FIRE) vp[vn++] = "produce fire bolts";
- if (flags5 & RF5_BO_COLD) vp[vn++] = "produce frost bolts";
- if (flags5 & RF5_BO_POIS) vp[vn++] = "produce poison bolts";
- if (flags5 & RF5_BO_NETH) vp[vn++] = "produce nether bolts";
- if (flags5 & RF5_BO_WATE) vp[vn++] = "produce water bolts";
- if (flags5 & RF5_BO_MANA) vp[vn++] = "produce mana bolts";
- if (flags5 & RF5_BO_PLAS) vp[vn++] = "produce plasma bolts";
- if (flags5 & RF5_BO_ICEE) vp[vn++] = "produce ice bolts";
- if (flags5 & RF5_MISSILE) vp[vn++] = "produce magic missiles";
- if (flags5 & RF5_SCARE) vp[vn++] = "terrify";
- if (flags5 & RF5_BLIND) vp[vn++] = "blind";
- if (flags5 & RF5_CONF) vp[vn++] = "confuse";
- if (flags5 & RF5_SLOW) vp[vn++] = "slow";
- if (flags5 & RF5_HOLD) vp[vn++] = "paralyse";
- if (flags6 & RF6_HASTE) vp[vn++] = "haste-self";
- if (flags6 & RF6_HEAL) vp[vn++] = "heal-self";
- if (flags6 & RF6_BLINK) vp[vn++] = "blink-self";
- if (flags6 & RF6_TPORT) vp[vn++] = "teleport-self";
- if (flags6 & RF6_S_BUG) vp[vn++] = "summon software bugs";
- if (flags6 & RF6_S_RNG) vp[vn++] = "summon RNGs";
- if (flags6 & RF6_TELE_TO) vp[vn++] = "teleport to";
- if (flags6 & RF6_TELE_AWAY) vp[vn++] = "teleport away";
- if (flags6 & RF6_TELE_LEVEL) vp[vn++] = "teleport level";
- if (flags6 & RF6_DARKNESS) vp[vn++] = "create darkness";
- if (flags6 & RF6_TRAPS) vp[vn++] = "create traps";
- if (flags6 & RF6_FORGET) vp[vn++] = "cause amnesia";
- if (flags6 & RF6_RAISE_DEAD) vp[vn++] = "raise dead";
- if (flags6 & RF6_S_THUNDERLORD) vp[vn++] = "summon a thunderlord";
- if (flags6 & RF6_S_MONSTER) vp[vn++] = "summon a monster";
- if (flags6 & RF6_S_MONSTERS) vp[vn++] = "summon monsters";
- if (flags6 & RF6_S_KIN) vp[vn++] = "summon aid";
- if (flags6 & RF6_S_ANT) vp[vn++] = "summon ants";
- if (flags6 & RF6_S_SPIDER) vp[vn++] = "summon spiders";
- if (flags6 & RF6_S_HOUND) vp[vn++] = "summon hounds";
- if (flags6 & RF6_S_HYDRA) vp[vn++] = "summon hydras";
- if (flags6 & RF6_S_ANGEL) vp[vn++] = "summon an angel";
- if (flags6 & RF6_S_DEMON) vp[vn++] = "summon a demon";
- if (flags6 & RF6_S_UNDEAD) vp[vn++] = "summon an undead";
- if (flags6 & RF6_S_DRAGON) vp[vn++] = "summon a dragon";
- if (flags4 & RF4_S_ANIMAL) vp[vn++] = "summon animal";
- if (flags6 & RF6_S_ANIMALS) vp[vn++] = "summon animals";
- if (flags6 & RF6_S_HI_UNDEAD) vp[vn++] = "summon greater undead";
- if (flags6 & RF6_S_HI_DRAGON) vp[vn++] = "summon ancient dragons";
- if (flags6 & RF6_S_HI_DEMON) vp[vn++] = "summon greater demons";
- if (flags6 & RF6_S_WRAITH) vp[vn++] = "summon Ringwraith";
- if (flags6 & RF6_S_UNIQUE) vp[vn++] = "summon unique monsters";
+ if (spells & SF_BA_ACID) vp[vn++] = "produce acid balls";
+ if (spells & SF_BA_ELEC) vp[vn++] = "produce lightning balls";
+ if (spells & SF_BA_FIRE) vp[vn++] = "produce fire balls";
+ if (spells & SF_BA_COLD) vp[vn++] = "produce frost balls";
+ if (spells & SF_BA_POIS) vp[vn++] = "produce poison balls";
+ if (spells & SF_BA_NETH) vp[vn++] = "produce nether balls";
+ if (spells & SF_BA_WATE) vp[vn++] = "produce water balls";
+ if (spells & SF_BA_NUKE) vp[vn++] = "produce balls of radiation";
+ if (spells & SF_BA_MANA) vp[vn++] = "produce mana storms";
+ if (spells & SF_BA_DARK) vp[vn++] = "produce darkness storms";
+ if (spells & SF_BA_CHAO) vp[vn++] = "invoke raw Chaos";
+ if (spells & SF_HAND_DOOM) vp[vn++] = "invoke the Hand of Doom";
+ if (spells & SF_DRAIN_MANA) vp[vn++] = "drain mana";
+ if (spells & SF_MIND_BLAST) vp[vn++] = "cause mind blasting";
+ if (spells & SF_BRAIN_SMASH) vp[vn++] = "cause brain smashing";
+ if (spells & (SF_CAUSE_1)) vp[vn++] = "cause light wounds and cursing";
+ if (spells & (SF_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing";
+ if (spells & (SF_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing";
+ if (spells & (SF_CAUSE_4)) vp[vn++] = "cause mortal wounds";
+ if (spells & SF_BO_ACID) vp[vn++] = "produce acid bolts";
+ if (spells & SF_BO_ELEC) vp[vn++] = "produce lightning bolts";
+ if (spells & SF_BO_FIRE) vp[vn++] = "produce fire bolts";
+ if (spells & SF_BO_COLD) vp[vn++] = "produce frost bolts";
+ if (spells & SF_BO_POIS) vp[vn++] = "produce poison bolts";
+ if (spells & SF_BO_NETH) vp[vn++] = "produce nether bolts";
+ if (spells & SF_BO_WATE) vp[vn++] = "produce water bolts";
+ if (spells & SF_BO_MANA) vp[vn++] = "produce mana bolts";
+ if (spells & SF_BO_PLAS) vp[vn++] = "produce plasma bolts";
+ if (spells & SF_BO_ICEE) vp[vn++] = "produce ice bolts";
+ if (spells & SF_MISSILE) vp[vn++] = "produce magic missiles";
+ if (spells & SF_SCARE) vp[vn++] = "terrify";
+ if (spells & SF_BLIND) vp[vn++] = "blind";
+ if (spells & SF_CONF) vp[vn++] = "confuse";
+ if (spells & SF_SLOW) vp[vn++] = "slow";
+ if (spells & SF_HOLD) vp[vn++] = "paralyse";
+ if (spells & SF_HASTE) vp[vn++] = "haste-self";
+ if (spells & SF_HEAL) vp[vn++] = "heal-self";
+ if (spells & SF_BLINK) vp[vn++] = "blink-self";
+ if (spells & SF_TPORT) vp[vn++] = "teleport-self";
+ if (spells & SF_S_BUG) vp[vn++] = "summon software bugs";
+ if (spells & SF_S_RNG) vp[vn++] = "summon RNGs";
+ if (spells & SF_TELE_TO) vp[vn++] = "teleport to";
+ if (spells & SF_TELE_AWAY) vp[vn++] = "teleport away";
+ if (spells & SF_TELE_LEVEL) vp[vn++] = "teleport level";
+ if (spells & SF_DARKNESS) vp[vn++] = "create darkness";
+ if (spells & SF_TRAPS) vp[vn++] = "create traps";
+ if (spells & SF_FORGET) vp[vn++] = "cause amnesia";
+ if (spells & SF_RAISE_DEAD) vp[vn++] = "raise dead";
+ if (spells & SF_S_THUNDERLORD) vp[vn++] = "summon a thunderlord";
+ if (spells & SF_S_MONSTER) vp[vn++] = "summon a monster";
+ if (spells & SF_S_MONSTERS) vp[vn++] = "summon monsters";
+ if (spells & SF_S_KIN) vp[vn++] = "summon aid";
+ if (spells & SF_S_ANT) vp[vn++] = "summon ants";
+ if (spells & SF_S_SPIDER) vp[vn++] = "summon spiders";
+ if (spells & SF_S_HOUND) vp[vn++] = "summon hounds";
+ if (spells & SF_S_HYDRA) vp[vn++] = "summon hydras";
+ if (spells & SF_S_ANGEL) vp[vn++] = "summon an angel";
+ if (spells & SF_S_DEMON) vp[vn++] = "summon a demon";
+ if (spells & SF_S_UNDEAD) vp[vn++] = "summon an undead";
+ if (spells & SF_S_DRAGON) vp[vn++] = "summon a dragon";
+ if (spells & SF_S_ANIMAL) vp[vn++] = "summon animal";
+ if (spells & SF_S_ANIMALS) vp[vn++] = "summon animals";
+ if (spells & SF_S_HI_UNDEAD) vp[vn++] = "summon greater undead";
+ if (spells & SF_S_HI_DRAGON) vp[vn++] = "summon ancient dragons";
+ if (spells & SF_S_HI_DEMON) vp[vn++] = "summon greater demons";
+ if (spells & SF_S_WRAITH) vp[vn++] = "summon Ringwraith";
+ if (spells & SF_S_UNIQUE) vp[vn++] = "summon unique monsters";
if (vn)
{
@@ -1877,7 +1874,7 @@ static void spoil_mon_info(cptr fname)
spoil_out(wd_che[msex]);
spoil_out(" is rarely detected by telepathy. ");
}
- if (flags4 & RF4_MULTIPLY)
+ if (spells & SF_MULTIPLY)
{
spoil_out(wd_che[msex]);
spoil_out(" breeds explosively. ");