summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mapdef.cc
diff options
context:
space:
mode:
authorDarshan Shaligram <dshaligram@users.sourceforge.net>2009-11-04 20:09:46 +0530
committerDarshan Shaligram <dshaligram@users.sourceforge.net>2009-11-04 20:15:34 +0530
commit9ad85435681ad82c7ef07d2083e40e525e2b0f55 (patch)
tree3b16cb1129c004ad90cce5c81486373557d5f272 /crawl-ref/source/mapdef.cc
parentf7c29d55ca91d539d64de5e120a5b2c301ccb938 (diff)
downloadcrawl-ref-9ad85435681ad82c7ef07d2083e40e525e2b0f55.tar.gz
crawl-ref-9ad85435681ad82c7ef07d2083e40e525e2b0f55.zip
Allow vaults to override monster spells with spells:<xyz>
Vaults can now override monster spell sets, or give non-casting monsters spells, and mark monsters as wizard or priest types. The M_ACTUAL_SPELLS, M_SPELLCASTER and M_PRIEST monster class flags are converted into MF_* flags at monster creation/polymorph time, and only the per-monster flags are checked when determining wizard/priestliness. See caveats in level_design.txt.
Diffstat (limited to 'crawl-ref/source/mapdef.cc')
-rw-r--r--crawl-ref/source/mapdef.cc60
1 files changed, 58 insertions, 2 deletions
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 3f70e543d5..f12215acef 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -35,6 +35,7 @@
#include "place.h"
#include "random.h"
#include "religion.h"
+#include "spl-util.h"
#include "stuff.h"
#include "tags.h"
@@ -2337,6 +2338,41 @@ bool mons_list::check_mimic(const std::string &s, int *mid, bool *fix) const
return (true);
}
+void mons_list::parse_mons_spells(mons_spec &spec, const std::string &spells)
+{
+ spec.explicit_spells = true;
+ spec.extra_monster_flags |= MF_SPELLCASTER;
+ const std::vector<std::string> spell_names(split_string(";", spells));
+ if (spell_names.size() > NUM_MONSTER_SPELL_SLOTS)
+ {
+ error = make_stringf("Too many monster spells (max %d) in %s",
+ NUM_MONSTER_SPELL_SLOTS,
+ spells.c_str());
+ return;
+ }
+ for (unsigned i = 0, ssize = spell_names.size(); i < ssize; ++i)
+ {
+ const std::string spname(
+ lowercase_string(replace_all_of(spell_names[i], "_", " ")));
+ if (spname.empty() || spname == "." || spname == "none"
+ || spname == "no spell")
+ {
+ spec.spells[i] = SPELL_NO_SPELL;
+ }
+ else
+ {
+ const spell_type sp(spell_by_name(spname));
+ if (sp == SPELL_NO_SPELL)
+ {
+ error = make_stringf("Unknown spell name: '%s' in '%s'",
+ spname.c_str(), spells.c_str());
+ return;
+ }
+ spec.spells[i] = sp;
+ }
+ }
+}
+
mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec)
{
mons_spec_slot slot;
@@ -2347,12 +2383,20 @@ mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec)
for (int i = 0, ssize = specs.size(); i < ssize; ++i)
{
+ mons_spec mspec;
std::string s = specs[i];
+
+ std::string spells(strip_tag_prefix(s, "spells:"));
+ if (!spells.empty())
+ {
+ parse_mons_spells(mspec, spells);
+ if (!error.empty())
+ return (slot);
+ }
+
std::vector<std::string> parts = split_string(";", s);
std::string mon_str = parts[0];
- mons_spec mspec;
-
if (parts.size() > 2)
{
error = make_stringf("Too many semi-colons for '%s' spec.",
@@ -2388,6 +2432,18 @@ mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec)
if (mspec.genweight == TAG_UNFOUND || mspec.genweight <= 0)
mspec.genweight = 10;
+ if (strip_tag(mon_str, "priest_spells"))
+ {
+ mspec.extra_monster_flags &= ~MF_ACTUAL_SPELLS;
+ mspec.extra_monster_flags |= MF_PRIEST;
+ }
+
+ if (strip_tag(mon_str, "actual_spells"))
+ {
+ mspec.extra_monster_flags &= ~MF_PRIEST;
+ mspec.extra_monster_flags |= MF_ACTUAL_SPELLS;
+ }
+
mspec.fix_mons = strip_tag(mon_str, "fix_mons");
mspec.generate_awake = strip_tag(mon_str, "generate_awake");
mspec.patrolling = strip_tag(mon_str, "patrolling");