summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/monplace.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-12 11:32:15 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-12 11:32:15 +0000
commitfed7cd6012682b1638463bdc5a0303089c967846 (patch)
treee88217f560f168f797bb895929baf3a87a83c565 /crawl-ref/source/monplace.cc
parent0dcc5cec25b63cb1649ddc501d6ea44cb0fdbc43 (diff)
downloadcrawl-ref-fed7cd6012682b1638463bdc5a0303089c967846.tar.gz
crawl-ref-fed7cd6012682b1638463bdc5a0303089c967846.zip
New Zot levels, courtesy Lemuel (David).
Added more control when specifying draconians in maps (any yellow draconian, green draconian knight, any nonbase red draconian, any base draconian, etc.). Fixed crash when dragon or draconian breathes and the player is unarmed. Replaced magic number 250 in monster creation with enum constant MONS_PROGRAM_BUG. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3253 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/monplace.cc')
-rw-r--r--crawl-ref/source/monplace.cc104
1 files changed, 68 insertions, 36 deletions
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index ceec4e4890..24828e149c 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -348,34 +348,41 @@ static bool can_place_on_trap(int mon_type, trap_type trap)
return (true);
}
-bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
- int target, bool summoned, int px, int py, bool allow_bands,
- proximity_type proximity, int extra, int dur,
- unsigned mmask)
+bool drac_colour_incompatible(int drac, int colour)
{
- int band_size = 0;
- int band_monsters[BIG_BAND]; // band monster types
- int lev_mons = power; // final 'power'
- int i;
-
- dungeon_char_type stair_type = NUM_DCHAR_TYPES;
- int tries = 0;
- int pval = 0;
- level_id place = level_id::current();
-
- // set initial id to -1 (unsuccessful create)
- id = -1;
-
- // (1) early out (summoned to occupied grid)
- if (summoned && mgrd[px][py] != NON_MONSTER)
- return (false);
+ return (drac == MONS_DRACONIAN_SCORCHER && colour == MONS_WHITE_DRACONIAN);
+}
+static int resolve_monster_type(int mon_type, proximity_type proximity,
+ int num, int px, int py, unsigned mmask,
+ dungeon_char_type *stair_type,
+ int *lev_mons)
+{
+ if (mon_type == RANDOM_DRACONIAN)
+ {
+ // Pick any random drac, constrained by colour if requested.
+ do
+ mon_type =
+ random_range(MONS_BLACK_DRACONIAN, MONS_DRACONIAN_SCORCHER);
+ while (num != MONS_PROGRAM_BUG
+ && mon_type != num
+ && (mons_species(mon_type) == mon_type
+ || drac_colour_incompatible(mon_type, num)));
+ }
+ else if (mon_type == RANDOM_BASE_DRACONIAN)
+ mon_type = random_range(MONS_BLACK_DRACONIAN, MONS_PALE_DRACONIAN);
+ else if (mon_type == RANDOM_NONBASE_DRACONIAN)
+ mon_type = random_range(MONS_DRACONIAN_CALLER, MONS_DRACONIAN_SCORCHER);
+
// (2) take care of random monsters
if (mon_type == RANDOM_MONSTER)
{
+ level_id place = level_id::current();
// respect destination level for staircases
if (proximity == PROX_NEAR_STAIRS)
{
+ int tries = 0;
+ int pval = 0;
while(++tries <= 320)
{
px = 5 + random2(GXM - 10);
@@ -402,7 +409,7 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
// check whether there's a stair
// and whether it leads to another branch
pval = near_stairs(coord_def(px, py), 1,
- stair_type, place.branch);
+ *stair_type, place.branch);
// no monsters spawned in the Temple
if (branches[place.branch].id == BRANCH_ECUMENICAL_TEMPLE)
@@ -418,34 +425,61 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
}
else
{
- if ( stair_type == DCHAR_STAIRS_DOWN ) // deeper level
- lev_mons++;
- else if (stair_type == DCHAR_STAIRS_UP) // higher level
+ if ( *stair_type == DCHAR_STAIRS_DOWN ) // deeper level
+ ++*lev_mons;
+ else if (*stair_type == DCHAR_STAIRS_UP) // higher level
{
// monsters don't come from outside the dungeon
- if (lev_mons <= 0)
+ if (*lev_mons <= 0)
{
proximity = PROX_AWAY_FROM_PLAYER;
// in that case lev_mons stays as it is
}
else
- lev_mons--;
+ --*lev_mons;
}
}
} // end proximity check
- if (branches[place.branch].id == BRANCH_HALL_OF_BLADES)
+ if (place.branch == BRANCH_HALL_OF_BLADES)
mon_type = MONS_DANCING_WEAPON;
else
{
// now pick a monster of the given branch and level
- mon_type = pick_random_monster(place, lev_mons,
- lev_mons);
-
- if (mon_type == MONS_PROGRAM_BUG)
- return (false);
+ mon_type = pick_random_monster(place, *lev_mons, *lev_mons);
}
}
+ return (mon_type);
+}
+
+bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
+ int target, bool summoned, int px, int py, bool allow_bands,
+ proximity_type proximity, int extra, int dur,
+ unsigned mmask)
+{
+ int band_size = 0;
+ int band_monsters[BIG_BAND]; // band monster types
+ int lev_mons = power; // final 'power'
+ int i;
+
+ int tries = 0;
+ int pval = 0;
+ dungeon_char_type stair_type = NUM_DCHAR_TYPES;
+
+ // set initial id to -1 (unsuccessful create)
+ id = -1;
+
+ // (1) early out (summoned to occupied grid)
+ if (summoned && mgrd[px][py] != NON_MONSTER)
+ return (false);
+
+ mon_type =
+ resolve_monster_type(mon_type, proximity, extra,
+ px, py, mmask, &stair_type,
+ &lev_mons);
+
+ if (mon_type == MONS_PROGRAM_BUG || mon_type == -1)
+ return (false);
// (3) decide on banding (good lord!)
band_size = 1;
@@ -724,7 +758,8 @@ static int place_monster_aux( int mon_type, beh_type behaviour, int target,
// now, actually create the monster (wheeee!)
menv[id].type = mon_type;
- menv[id].number = 250;
+
+ menv[id].number = extra;
menv[id].x = fx;
menv[id].y = fy;
@@ -754,9 +789,6 @@ static int place_monster_aux( int mon_type, beh_type behaviour, int target,
if (mons_is_unique(mon_type))
you.unique_creatures[mon_type] = true;
- if (extra != 250)
- menv[id].number = extra;
-
if (mons_class_flag(mon_type, M_INVIS))
menv[id].add_ench(ENCH_INVIS);