summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-11-23 14:22:58 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-11-23 14:22:58 +0000
commitf7d34b29bdd41086a10c8135466e4b974674eae5 (patch)
treea1ae965a8010f0b535c2a9f2bcfe4cb509521cf8 /crawl-ref
parent76c82d66daed178db22ec0fe9bd91cfb23cfb28c (diff)
downloadcrawl-ref-f7d34b29bdd41086a10c8135466e4b974674eae5.tar.gz
crawl-ref-f7d34b29bdd41086a10c8135466e4b974674eae5.zip
Allow place:X in MONS specifications to place random monsters suitable for place X.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7550 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/docs/level_design.txt22
-rw-r--r--crawl-ref/source/dungeon.cc38
-rw-r--r--crawl-ref/source/mapdef.cc41
-rw-r--r--crawl-ref/source/mapdef.h8
4 files changed, 104 insertions, 5 deletions
diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt
index bb5096a940..0615d49ec6 100644
--- a/crawl-ref/docs/level_design.txt
+++ b/crawl-ref/docs/level_design.txt
@@ -589,6 +589,28 @@ MONS: (list of monsters)
Note that 8, 9, 0 also place monsters (see the table).
+ If you want to place a random monster suitable for the level
+ the map is generated on, you can use
+ MONS: random
+
+ If you want to place a random monster suitable for some other
+ place, you can use a place: tag in the monster spec:
+ MONS: place:Abyss
+ or
+ MONS: place:Slime:6
+
+ Using place: with MONS implies that you want a random monster.
+ You can also request zombies from random monsters suitable
+ for some other depth as:
+ MONS: place:Elf:7 zombie
+ or
+ MONS: place:Zot:5 simulacrum
+ or
+ MONS: place:Vault:8 spectre
+
+ The available modifiers are "zombie", "skeleton",
+ "simulacrum" and "spectre".
+
A monster can be given specific items by following the monster
name with a semi-colon and then with an item list as described
in ITEM:, but with slashes replaced with pipes and commas replaced
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index a57c96010d..9d8bc2c6f7 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -4918,6 +4918,36 @@ bool dgn_place_monster(mons_spec &mspec,
}
mgen_data mg(static_cast<monster_type>(mid));
+
+ if (mg.cls == RANDOM_MONSTER && mspec.place.is_valid())
+ {
+ int lev = monster_level;
+
+ if (mspec.place.level_type == LEVEL_DUNGEON)
+ lev = absdungeon_depth(mspec.place.branch, mspec.place.depth);
+
+ if (mlev == -8)
+ lev = 4 + lev * 2;
+ else if (mlev == -9)
+ lev += 5;
+
+ int tries = 100;
+ do
+ {
+ mg.cls = pick_random_monster(mspec.place, lev, lev);
+ } while (mg.cls != MONS_PROGRAM_BUG
+ && mons_class_is_zombified(mspec.monbase)
+ && !mons_zombie_size(mg.cls)
+ && tries-- > 0);
+
+ if (mg.cls == MONS_PROGRAM_BUG
+ || (mons_class_is_zombified(mspec.monbase)
+ && !mons_zombie_size(mg.cls)))
+ {
+ mg.cls = RANDOM_MONSTER;
+ }
+ }
+
mg.power = monster_level;
mg.behaviour = (m_generate_awake) ? BEH_WANDER : BEH_SLEEP;
mg.base_type = mspec.monbase;
@@ -4925,6 +4955,14 @@ bool dgn_place_monster(mons_spec &mspec,
mg.colour = mspec.colour;
mg.pos = where;
+ if (mons_class_is_zombified(mg.base_type))
+ {
+ if (mons_class_is_zombified(mg.cls))
+ mg.base_type = MONS_PROGRAM_BUG;
+ else
+ std::swap(mg.base_type, mg.cls);
+ }
+
if (m_patrolling)
mg.flags |= MG_PATROLLING;
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 1c6a82c4cc..9058fde162 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -1990,6 +1990,26 @@ mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec)
mspec.generate_awake = strip_tag(mon_str, "generate_awake");
mspec.patrolling = strip_tag(mon_str, "patrolling");
+ // place:Elf:7 to choose monsters appropriate for that level,
+ // for example.
+ const std::string place = strip_tag_prefix(mon_str, "place:");
+ if (!place.empty())
+ {
+ try
+ {
+ mspec.place = level_id::parse_level_id(place);
+ }
+ catch (const std::string &err)
+ {
+ error = err;
+ return (slot);
+ }
+ }
+
+ mspec.mlevel = strip_number_tag(mon_str, "lev:");
+ if (mspec.mlevel == TAG_UNFOUND)
+ mspec.mlevel = 0;
+
std::string colour = strip_tag_prefix(mon_str, "col:");
if (!colour.empty())
{
@@ -2010,6 +2030,22 @@ mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec)
mspec.mlevel = -9;
else if (check_mimic(mon_str, &mspec.mid, &mspec.fix_mons))
;
+ else if (mspec.place.is_valid())
+ {
+ // For monster specs such as place:Orc:4 zombie, we may
+ // have a monster modifier, in which case we set the
+ // modifier in monbase.
+ const mons_spec nspec = mons_by_name("orc " + mon_str);
+ if (nspec.mid != MONS_PROGRAM_BUG)
+ {
+ // Is this a modified monster?
+ if (nspec.monbase != MONS_PROGRAM_BUG
+ && mons_class_is_zombified(nspec.mid))
+ {
+ mspec.monbase = static_cast<monster_type>(nspec.mid);
+ }
+ }
+ }
else if (mon_str != "0")
{
const mons_spec nspec = mons_by_name(mon_str);
@@ -2094,7 +2130,7 @@ void mons_list::get_zombie_type(std::string s, mons_spec &spec) const
{
static const char *zombie_types[] =
{
- " zombie", " skeleton", " simulacrum", NULL
+ " zombie", " skeleton", " simulacrum", " spectre", NULL
};
// This order must match zombie_types, indexed from one.
@@ -2103,7 +2139,8 @@ void mons_list::get_zombie_type(std::string s, mons_spec &spec) const
{ MONS_PROGRAM_BUG, MONS_PROGRAM_BUG },
{ MONS_ZOMBIE_SMALL, MONS_ZOMBIE_LARGE },
{ MONS_SKELETON_SMALL, MONS_SKELETON_LARGE },
- { MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE }
+ { MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE },
+ { MONS_SPECTRAL_THING, MONS_SPECTRAL_THING },
};
const int mod = ends_with(s, zombie_types);
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 52bb196070..1b9dd721dc 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -361,6 +361,7 @@ struct item_spec
int level;
int race;
int qty;
+ level_id place;
item_spec() : genweight(10), base_type(OBJ_RANDOM), sub_type(OBJ_RANDOM),
plus(0), plus2(0), ego(0), allow_uniques(1), level(-1),
@@ -411,6 +412,7 @@ class mons_spec
{
public:
int mid;
+ level_id place;
monster_type monbase; // Base monster for zombies and dracs.
int number; // Head count for hydras
int genweight, mlevel;
@@ -426,9 +428,9 @@ class mons_spec
int num = 0,
int gw = 10, int ml = 0,
bool _fixmons = false, bool awaken = false, bool patrol = false)
- : mid(id), monbase(base), number(num), genweight(gw), mlevel(ml),
- fix_mons(_fixmons), generate_awake(awaken), patrolling(false),
- colour(BLACK), items()
+ : mid(id), place(), monbase(base), number(num), genweight(gw),
+ mlevel(ml), fix_mons(_fixmons), generate_awake(awaken),
+ patrolling(false), colour(BLACK), items()
{
}
};