From fc944616f69e347423c408a9d3e3efee9140a46d Mon Sep 17 00:00:00 2001 From: zelgadis Date: Sun, 30 Sep 2007 05:56:13 +0000 Subject: 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 --- crawl-ref/source/abyss.cc | 146 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) (limited to 'crawl-ref/source/abyss.cc') 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; -- cgit v1.2.3-54-g00ecf