diff options
author | Darshan Shaligram <dshaligram@users.sourceforge.net> | 2009-11-04 20:09:46 +0530 |
---|---|---|
committer | Darshan Shaligram <dshaligram@users.sourceforge.net> | 2009-11-04 20:15:34 +0530 |
commit | 9ad85435681ad82c7ef07d2083e40e525e2b0f55 (patch) | |
tree | 3b16cb1129c004ad90cce5c81486373557d5f272 /crawl-ref/source/mapdef.cc | |
parent | f7c29d55ca91d539d64de5e120a5b2c301ccb938 (diff) | |
download | crawl-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.cc | 60 |
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"); |