From d3c2214dea8cb19bcaa4dfe1303f0368e8cdf4aa Mon Sep 17 00:00:00 2001 From: Matthew Cline Date: Thu, 5 Nov 2009 23:30:01 -0800 Subject: Error for non-monster spells in monster specs Give an error when parsing a monster spec if it lists a spell a monster can't cast, rather than causing an assertion when the monster tries to cast it. --- crawl-ref/source/acr.cc | 2 ++ crawl-ref/source/mapdef.cc | 7 +++++++ crawl-ref/source/mon-cast.cc | 41 ++++++++++++++++++++++++++++++++++++++++- crawl-ref/source/mon-cast.h | 6 +++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 2a7ef4c6ee..4a020a2183 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -85,6 +85,7 @@ #include "message.h" #include "misc.h" #include "mon-act.h" +#include "mon-cast.h" #include "monplace.h" #include "monstuff.h" #include "mon-util.h" @@ -3533,6 +3534,7 @@ static bool _initialise(void) init_monster_symbols(); init_spell_descs(); // This needs to be way up top. {dlb} init_mon_name_cache(); + init_mons_spells(); // init_item_name_cache() needs to be redone after init_char_table() // and init_show_table() have been called, so that the glyphs will diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index a9e0ee0412..402652713e 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -30,6 +30,7 @@ #include "mapmark.h" #include "maps.h" #include "misc.h" +#include "mon-cast.h" #include "monplace.h" #include "mon-util.h" #include "place.h" @@ -2368,6 +2369,12 @@ void mons_list::parse_mons_spells(mons_spec &spec, const std::string &spells) spname.c_str(), spells.c_str()); return; } + if (!is_valid_mon_spell(sp)) + { + error = make_stringf("Not a monster spell: '%s'", + spname.c_str()); + return; + } spec.spells[i] = sp; } } diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc index 1a7e53ee76..cc51dc36aa 100644 --- a/crawl-ref/source/mon-cast.cc +++ b/crawl-ref/source/mon-cast.cc @@ -34,6 +34,38 @@ #include "view.h" #include "viewchar.h" +static bool _valid_mon_spells[NUM_SPELLS]; + +void init_mons_spells() +{ + monsters fake_mon; + fake_mon.type = MONS_BLACK_DRACONIAN; + fake_mon.hit_points = 1; + + for (int i = 0; i < NUM_SPELLS; i++) + { + spell_type spell = (spell_type) i; + + _valid_mon_spells[i] = false; + + if (!is_valid_spell(spell)) + continue; + + bolt beam = mons_spells(&fake_mon, spell, 1, true); + + if (beam.flavour != NUM_BEAMS) + _valid_mon_spells[i] = true; + } +} + +bool is_valid_mon_spell(spell_type spell) +{ + if (spell < 0 || spell >= NUM_SPELLS) + return (false); + + return (_valid_mon_spells[spell]); +} + static void _scale_draconian_breath(bolt& beam, int drac_type) { int scaling = 100; @@ -126,7 +158,8 @@ static bool _set_allied_target(monsters * caster, bolt & pbolt) return (false); } -bolt mons_spells( monsters *mons, spell_type spell_cast, int power ) +bolt mons_spells( monsters *mons, spell_type spell_cast, int power, + bool check_validity ) { ASSERT(power > 0); @@ -606,6 +639,12 @@ bolt mons_spells( monsters *mons, spell_type spell_cast, int power ) break; default: + if (check_validity) + { + beam.flavour = NUM_BEAMS; + return (beam); + } + if (!is_valid_spell(real_spell)) DEBUGSTR("Invalid spell #%d cast by %s", (int) real_spell, mons->name(DESC_PLAIN, true).c_str()); diff --git a/crawl-ref/source/mon-cast.h b/crawl-ref/source/mon-cast.h index 5d10125d98..6d7d023abc 100644 --- a/crawl-ref/source/mon-cast.h +++ b/crawl-ref/source/mon-cast.h @@ -12,9 +12,13 @@ class monsters; class bolt; +void init_mons_spells(); +bool is_valid_mon_spell(spell_type spell); + bool handle_mon_spell(monsters *monster, bolt &beem); -bolt mons_spells(monsters *mons, spell_type spell_cast, int power); +bolt mons_spells(monsters *mons, spell_type spell_cast, int power, + bool check_validity = false); void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast, bool do_noise = true); void mons_cast_noise(monsters *monster, bolt &pbolt, spell_type spell_cast); -- cgit v1.2.3-54-g00ecf