summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-08-23 18:52:05 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-08-23 18:52:05 +0000
commita42cf252322e22af17e24e3f5e8f2f7a35cc0bd7 (patch)
tree36bd351605e76e4d35492ed03a258d8b303ba325
parent72acf198cb29df6fc60463fc042356f549f10b43 (diff)
downloadcrawl-ref-a42cf252322e22af17e24e3f5e8f2f7a35cc0bd7.tar.gz
crawl-ref-a42cf252322e22af17e24e3f5e8f2f7a35cc0bd7.zip
Monsters coming up or down staircases will now
be chosen according to the destination. And yes, this does mean that occasionally an elf summoner will cross the Orc/Elf border etc, which could make things harder. On the other hand, that's just one staircase out of (at least!) seven, and monsters entering the level through the upstairs will likewise be a bit easier. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2030 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/mon-util.cc5
-rw-r--r--crawl-ref/source/monplace.cc153
-rw-r--r--crawl-ref/source/stuff.cc25
-rw-r--r--crawl-ref/source/stuff.h2
4 files changed, 146 insertions, 39 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index dd656a3f26..fe214c47fb 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -3933,8 +3933,11 @@ void monsters::apply_enchantment(const mon_enchant &me)
case ENCH_HELD:
{
- if (mons_is_paralysed(this) || this->behaviour == BEH_SLEEP)
+ if (mons_is_stationary(this) || mons_is_paralysed(this)
+ || this->behaviour == BEH_SLEEP)
+ {
break;
+ }
int net = get_trapping_net(x,y);
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 55bc258d88..3e0c01ac01 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -13,6 +13,7 @@
#include "AppHdr.h"
#include "monplace.h"
+#include "branch.h"
#include "externs.h"
#include "lev-pand.h"
#include "makeitem.h"
@@ -301,7 +302,7 @@ monster_type pick_random_monster(const level_id &place,
mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
count++;
}
- while (mons_rarity(mon_type) == 0 && count < 2000);
+ while (mons_rarity(mon_type, place) == 0 && count < 2000);
if (count == 2000)
return (MONS_PROGRAM_BUG);
@@ -332,6 +333,13 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
int band_monsters[BIG_BAND]; // band monster types
int lev_mons = power; // final 'power'
int i;
+
+ // player shoved out of the way?
+ bool shoved = false;
+ unsigned char stair_gfx = 0;
+ int tries = 0;
+ int pval = 0;
+ level_id place = level_id::current();
// set initial id to -1 (unsuccessful create)
id = -1;
@@ -341,18 +349,89 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
return (false);
// (2) take care of random monsters
- if (mon_type == RANDOM_MONSTER
- && player_in_branch( BRANCH_HALL_OF_BLADES ))
- {
- mon_type = MONS_DANCING_WEAPON;
- }
-
if (mon_type == RANDOM_MONSTER)
{
- mon_type = pick_random_monster(level_id::current(), lev_mons,
+ // respect destination level for staircases
+ if (proximity == PROX_NEAR_STAIRS)
+ {
+ while(++tries <= 320)
+ {
+ px = 5 + random2(GXM - 10);
+ py = 5 + random2(GYM - 10);
+
+ if (mgrd[px][py] != NON_MONSTER
+ || (px == you.x_pos && py == you.y_pos))
+ {
+ continue;
+ }
+
+ // Is the monster happy where we want to put it?
+ unsigned char grid_wanted = monster_habitat(mon_type);
+ if (!grid_compatible(grid_wanted, grd[px][py], true))
+ continue;
+
+ // Is the grid verboten?
+ if (!unforbidden( coord_def(px, py), mmask ))
+ continue;
+
+ // don't generate monsters on top of teleport traps
+ int trap = trap_at_xy(px, py);
+ if (trap >= 0)
+ {
+ if (env.trap[trap].type == TRAP_TELEPORT)
+ continue;
+ }
+
+ // check whether there's a stair
+ // and whether it leads to another branch
+ pval = near_stairs(px, py, 1, stair_gfx, place.branch);
+
+ // no monsters spawned in the Temple
+ if (branches[place.branch].id == BRANCH_ECUMENICAL_TEMPLE)
+ continue;
+
+ // found a position near the stairs!
+ if (pval > 0)
+ break;
+ }
+ if (tries > 320)
+ { // give up and try somewhere else
+ proximity = PROX_AWAY_FROM_PLAYER;
+ }
+ else
+ {
+ if ( stair_gfx == '>' ) // deeper level
+ lev_mons++;
+ else if (stair_gfx == '<') // higher level
+ {
+ // monsters don't come from outside the dungeon
+ if (lev_mons <= 0)
+ {
+ proximity = PROX_AWAY_FROM_PLAYER;
+ // or maybe allow 1st level monsters, having visited the
+ // surface, to re-enter the dungeon
+ // in that case lev_mons stays as it is
+ }
+ else
+ lev_mons--;
+ }
+// mprf("branch := %d, level := %d",
+// branches[place.branch].id, lev_mons+1);
+
+ }
+ } // end proximity check
+
+ if (branches[place.branch].id == 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);
+
+ if (mon_type == MONS_PROGRAM_BUG)
+ return (false);
+ }
}
// (3) decide on banding (good lord!)
@@ -368,22 +447,24 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
band_monsters[i] = band_member( band, power );
}
- // Monsters that can't move shouldn't be taking the stairs -- bwr
- if (proximity == PROX_NEAR_STAIRS && mons_class_is_stationary( mon_type ))
- proximity = PROX_AWAY_FROM_PLAYER;
+ if (proximity == PROX_NEAR_STAIRS)
+ {
+ // for some cases disallow monsters on stairs
+ if (mons_class_is_stationary( mon_type )
+ || pval == 2 && (mons_speed(mon_type) == 0
+ || grd[px][py] == DNGN_LAVA || grd[px][py] == DNGN_DEEP_WATER))
+ {
+ proximity = PROX_AWAY_FROM_PLAYER;
+ }
+ }
// (4) for first monster, choose location. This is pretty intensive.
bool proxOK;
bool close_to_player;
- // player shoved out of the way?
- bool shoved = false;
- unsigned char stair_gfx = 0;
- int pval = 0;
-
if (!summoned)
{
- int tries = 0;
+ tries = 0;
// try to pick px, py that is
// a) not occupied
// b) compatible
@@ -391,23 +472,27 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
unsigned char grid_wanted = monster_habitat(mon_type);
while(true)
{
- tries ++;
- // give up on stair placement?
- if (proximity == PROX_NEAR_STAIRS)
+ // handled above, won't change anymore
+ if (proximity == PROX_NEAR_STAIRS && tries)
{
- if (tries > 320)
- {
- proximity = PROX_AWAY_FROM_PLAYER;
- tries = 0;
- }
+ proximity = PROX_AWAY_FROM_PLAYER;
+ tries = 0;
}
// Dropped number of tries from 60.
- else if (tries > 45)
+ else if (tries >= 45)
return (false);
- px = 5 + random2(GXM - 10);
- py = 5 + random2(GYM - 10);
-
+ tries ++;
+
+ // placement already decided for PROX_NEAR_STAIRS
+ if (proximity != PROX_NEAR_STAIRS)
+ {
+ px = 5 + random2(GXM - 10);
+ py = 5 + random2(GYM - 10);
+ }
+
+ // Let's recheck these even for PROX_NEAR_STAIRS, just in case
+
// occupied?
if (mgrd[px][py] != NON_MONSTER
|| (px == you.x_pos && py == you.y_pos))
@@ -456,8 +541,7 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
break;
case PROX_NEAR_STAIRS:
- pval = near_stairs(px, py, 1, stair_gfx);
- if (pval == 2)
+ if (pval == 2) // player on stairs
{
// 0 speed monsters can't shove player out of their way.
if (mons_speed(mon_type) == 0)
@@ -546,9 +630,6 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
lev_mons, extra, false, dur);
}
- // if summoned onto traps, directly affect monster
- menv[id].apply_location_effects();
-
// placement of first monster, at least, was a success.
return (true);
}
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 6d0f282909..251e9cd9b9 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -53,6 +53,7 @@
#include "libunix.h"
#endif
+#include "branch.h"
#include "delay.h"
#include "externs.h"
#include "items.h"
@@ -1062,7 +1063,7 @@ int fuzz_value(int val, int lowfuzz, int highfuzz, int naverage)
// returns 1 if the point is near unoccupied stairs
// returns 2 if the point is near player-occupied stairs
-int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx)
+int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx, branch_type &branch)
{
int i,j;
@@ -1081,7 +1082,29 @@ int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx)
&& grd[x][y] <= DNGN_RETURN_FROM_SWAMP
&& grd[x][y] != DNGN_ENTER_SHOP) // silly
{
+ // shouldn't happen for escape hatches
+ if (grd[x][y] == DNGN_ROCK_STAIRS_DOWN
+ || grd[x][y] == DNGN_ROCK_STAIRS_UP)
+ {
+ continue;
+ }
+
stair_gfx = get_sightmap_char(grd[x][y]);
+
+ // is it a branch stair?
+ for ( i = 0; i < NUM_BRANCHES; ++i )
+ {
+ if (branches[i].entry_stairs == grd[x][y])
+ {
+ branch = branches[i].id;
+ break;
+ }
+ else if (branches[i].exit_stairs == grd[x][y])
+ {
+ branch = branches[i].parent_branch;
+ break;
+ }
+ }
return ((x == you.x_pos && y == you.y_pos) ? 2 : 1);
}
}
diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h
index 4186484b95..4b23042cbb 100644
--- a/crawl-ref/source/stuff.h
+++ b/crawl-ref/source/stuff.h
@@ -110,7 +110,7 @@ char index_to_letter (int the_index);
int letter_to_index(int the_letter);
-int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx);
+int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx, branch_type &branch);
inline bool testbits(unsigned long flags, unsigned long test)
{