summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/abyss.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-30 05:56:13 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-30 05:56:13 +0000
commitfc944616f69e347423c408a9d3e3efee9140a46d (patch)
tree342a77d3a517969c7ac57c6d6bc0408dc07422c3 /crawl-ref/source/abyss.cc
parentcc20c6d673722c6dd4ca32290d9cc66e55597f3c (diff)
downloadcrawl-ref-fc944616f69e347423c408a9d3e3efee9140a46d.tar.gz
crawl-ref-fc944616f69e347423c408a9d3e3efee9140a46d.zip
This commit breaks save file compatability.
Lots of new things that amuse/stimulate Xom, and a few things which don't amuse him as much anymore. Among the new things is a corpse turning into a skeleton while butchering it; if this is too harsh to do just for Xom's amusement (previously turning into a skeleton while butchering was an ignored case and still produced chunks of flesh) it can be changed back. Also, if a Xom worshiper draws the Blank card, Xom makes it act like a Xom card, since a plain old Blank card is boring. Keep track of which branch the Orb is in, if the player isn't carrying it. Keep track of how/why the player ended up in a particular level type (Abyss, Pan, etc). Changed most "a distortion effect" cause strings for distortion caused tranlsocation miscast effects to something more specific. Added new wizard commands 'C' to curse or uncruse an item, and 'Ctrl-A' to re-generate the Abyss. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2256 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/abyss.cc')
-rw-r--r--crawl-ref/source/abyss.cc146
1 files changed, 146 insertions, 0 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index 3a6a951205..f059eb2435 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -33,6 +33,7 @@
#include "terrain.h"
#include "traps.h"
#include "view.h"
+#include "xom.h"
// public for abyss generation
void generate_abyss(void)
@@ -40,6 +41,10 @@ void generate_abyss(void)
int i, j; // loop variables
int temp_rand; // probability determination {dlb}
+#if DEBUG_ABYSS
+ mpr("generate_abyss().", MSGCH_DIAGNOSTICS);
+#endif
+
for (i = 5; i < (GXM - 5); i++)
{
for (j = 5; j < (GYM - 5); j++)
@@ -62,6 +67,10 @@ void generate_abyss(void)
static void generate_area(int gx1, int gy1, int gx2, int gy2)
{
+#if DEBUG_ABYSS
+ mpr("generate_area().", MSGCH_DIAGNOSTICS);
+#endif
+
int items_placed = 0;
const int thickness = random2(70) + 30;
int thing_created;
@@ -127,6 +136,9 @@ static void generate_area(int gx1, int gy1, int gx2, int gy2)
{
thing_created = items(1, OBJ_MISCELLANY,
MISC_RUNE_OF_ZOT, true, 51, 51);
+#if DEBUG_ABYSS
+ mpr("Placing an Abyssal rune.", MSGCH_DIAGNOSTICS);
+#endif
}
else
{
@@ -143,6 +155,9 @@ static void generate_area(int gx1, int gy1, int gx2, int gy2)
}
}
+ int exits_wanted = 0;
+ int altars_wanted = 0;
+
for (int i = gx1; i <= gx2; i++)
{
for (int j = gy1; j <= gy2; j++)
@@ -151,9 +166,23 @@ static void generate_area(int gx1, int gy1, int gx2, int gy2)
grd[i][j] = replaced[random2(5)];
if (one_chance_in(7500)) // place an exit
+ exits_wanted++;
+
+ // Don't place exit under items
+ if (exits_wanted > 0 && igrd[i][j] == NON_ITEM)
+ {
grd[i][j] = DNGN_EXIT_ABYSS;
+ exits_wanted--;
+#if DEBUG_ABYSS
+ mpr("Placing Abyss exit.", MSGCH_DIAGNOSTICS);
+#endif
+ }
if (one_chance_in(10000)) // place an altar
+ altars_wanted++;
+
+ // Don't place altars under items.
+ if (altars_wanted > 0 && igrd[i][j] == NON_ITEM)
{
do
{
@@ -168,8 +197,103 @@ static void generate_area(int gx1, int gy1, int gx2, int gy2)
// Lugonu has a flat 50% chance of corrupting the altar
if ( coinflip() )
grd[i][j] = DNGN_ALTAR_LUGONU;
+
+ altars_wanted--;
+#if DEBUG_ABYSS
+ mpr("Placing altar.", MSGCH_DIAGNOSTICS);
+#endif
+ }
+ }
+ }
+}
+
+static int abyss_exit_nearness()
+{
+ int nearness = INFINITE_DISTANCE;
+
+ for (int x = you.x_pos - LOS_RADIUS; x < you.x_pos + LOS_RADIUS; x++)
+ for (int y = you.y_pos - LOS_RADIUS; y < you.y_pos + LOS_RADIUS; y++)
+ {
+ if (!in_bounds(x, y))
+ continue;
+
+ // HACK: Why doesn't is_terrain_known() work here?
+ if (grd[x][y] == DNGN_EXIT_ABYSS
+ && get_screen_glyph(x, y) != '\0')
+ {
+ nearness = MIN(nearness,
+ grid_distance(you.x_pos, you.y_pos,
+ x, y));
+ }
+ }
+
+ return (nearness);
+}
+
+static int abyss_rune_nearness()
+{
+ int nearness = INFINITE_DISTANCE;
+
+ for (int x = you.x_pos - LOS_RADIUS; x < you.x_pos + LOS_RADIUS; x++)
+ for (int y = you.y_pos - LOS_RADIUS; y < you.y_pos + LOS_RADIUS; y++)
+ {
+ if (!in_bounds(x, y))
+ continue;
+
+ // HACK: Why doesn't is_terrain_known() work here?
+ if (get_screen_glyph(x, y) != '\0')
+ {
+ int i = igrd[x][y];
+
+ while (i != NON_ITEM)
+ {
+ item_def& item(mitm[i]);
+ if (is_rune(item) && item.plus == RUNE_ABYSSAL)
+ nearness = MIN(nearness,
+ grid_distance(you.x_pos, you.y_pos,
+ x, y));
+ i = item.link;
+ }
}
}
+
+ return (nearness);
+}
+
+static int exit_was_near;
+static int rune_was_near;
+
+static void xom_check_nearness_setup()
+{
+ exit_was_near = abyss_exit_nearness();
+ rune_was_near = abyss_rune_nearness();
+}
+
+// If the player was almost to the exit when it disppeared, Xom is
+// exteremely amused. He's also extremely amused if the player winds
+// up right next to an exit when there wasn't one there before. The
+// same applies to Abyssal runes.
+static void xom_check_nearness()
+{
+ // Update known terrain
+ viewwindow(true, false);
+
+ int exit_is_near = abyss_exit_nearness();
+ if ((exit_was_near < INFINITE_DISTANCE &&
+ exit_is_near == INFINITE_DISTANCE)
+ || (exit_was_near == INFINITE_DISTANCE &&
+ exit_is_near < INFINITE_DISTANCE))
+ {
+ xom_is_stimulated(255);
+ }
+
+ int rune_is_near = abyss_rune_nearness();
+ if ((rune_was_near < INFINITE_DISTANCE &&
+ rune_is_near == INFINITE_DISTANCE)
+ || (rune_was_near == INFINITE_DISTANCE &&
+ rune_is_near < INFINITE_DISTANCE))
+ {
+ xom_is_stimulated(255);
}
}
@@ -184,6 +308,12 @@ static void abyss_lose_monster(monsters &mons)
void area_shift(void)
/*******************/
{
+#if DEBUG_ABYSS
+ mpr("area_shift().", MSGCH_DIAGNOSTICS);
+#endif
+
+ xom_check_nearness_setup();
+
for (unsigned int i = 0; i < MAX_MONSTERS; i++)
{
monsters &m = menv[i];
@@ -267,6 +397,8 @@ void area_shift(void)
generate_area(5, 5, (GXM - 5), (GYM - 5));
+ xom_check_nearness();
+
for (unsigned int mcount = 0; mcount < 15; mcount++)
{
mons_place( RANDOM_MONSTER, BEH_HOSTILE, MHITNOT, false, 1, 1,
@@ -290,6 +422,8 @@ void save_abyss_uniques()
void abyss_teleport( bool new_area )
/**********************************/
{
+ xom_check_nearness_setup();
+
int x, y, i, j, k;
if (!new_area)
@@ -311,11 +445,19 @@ void abyss_teleport( bool new_area )
if (i < 100)
{
+#if DEBUG_ABYSS
+ mpr("Non-new area Abyss teleport.", MSGCH_DIAGNOSTICS);
+#endif
you.moveto(x, y);
+ xom_check_nearness();
return;
}
}
+#if DEBUG_ABYSS
+ mpr("New area Abyss teleport.", MSGCH_DIAGNOSTICS);
+#endif
+
// teleport to a new area of the abyss:
init_pandemonium(); // get new monsters
@@ -343,6 +485,8 @@ void abyss_teleport( bool new_area )
UNIQ_LOST_IN_ABYSS );
}
+ xom_check_lost_item( mitm[k] );
+
destroy_item( k );
}
}
@@ -367,6 +511,8 @@ void abyss_teleport( bool new_area )
generate_area( 10, 10, (GXM - 10), (GYM - 10) );
+ xom_check_nearness();
+
grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
if ( one_chance_in(5) )
grd[you.x_pos + 1][you.y_pos] = DNGN_ALTAR_LUGONU;