summaryrefslogtreecommitdiffstats
path: root/trunk/source/view.cc
diff options
context:
space:
mode:
authorpeterb12 <peterb12@c06c8d41-db1a-0410-9941-cceddc491573>2005-07-21 02:34:44 +0000
committerpeterb12 <peterb12@c06c8d41-db1a-0410-9941-cceddc491573>2005-07-21 02:34:44 +0000
commit673bdae75485d14f759af597c3c62b99601f9a43 (patch)
tree368103f29fe0ce5dcf98060d9b5faa04590085fb /trunk/source/view.cc
parent7e900be770db24b0405fd2162491c405a425873e (diff)
downloadcrawl-ref-673bdae75485d14f759af597c3c62b99601f9a43.tar.gz
crawl-ref-673bdae75485d14f759af597c3c62b99601f9a43.zip
Initial revision
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'trunk/source/view.cc')
-rw-r--r--trunk/source/view.cc3524
1 files changed, 3524 insertions, 0 deletions
diff --git a/trunk/source/view.cc b/trunk/source/view.cc
new file mode 100644
index 0000000000..0e2fccd58e
--- /dev/null
+++ b/trunk/source/view.cc
@@ -0,0 +1,3524 @@
+/*
+ * File: view.cc
+ * Summary: Misc function used to render the dungeon.
+ * Written by: Linley Henzell
+ *
+ * Change History (most recent first):
+ *
+ * <10> 29 Jul 00 JDJ show_map iterates horizontally to 79 instead of 80.
+ * item no longer indexes past the end of environ::grid.
+ * <9> 19 Jun 00 GDL Complete rewrite of LOS code
+ * <8> 11/23/99 LRH Added colour-coded play-screen map & clean_map
+ * init options
+ * <7> 9/29/99 BCR Removed first argument from draw_border
+ * <6> 9/11/99 LRH Added calls to overmap functions
+ * <5> 6/22/99 BWR Fixed and improved the stealth
+ * <4> 5/20/99 BWR show_map colours all portals,
+ * exits from subdungeons now
+ * look like up stairs.
+ * <3> 5/09/99 JDJ show_map draws shops in yellow.
+ * <2> 5/09/99 JDJ show_map accepts '\r' along with '.'.
+ * <1> -/--/-- LRH Created
+ */
+
+#include "AppHdr.h"
+#include "view.h"
+
+#include <string.h>
+
+#ifdef DOS
+#include <conio.h>
+#endif
+
+#include "externs.h"
+
+#include "debug.h"
+#include "insult.h"
+#include "macro.h"
+#include "monstuff.h"
+#include "mon-util.h"
+#include "overmap.h"
+#include "player.h"
+#include "skills2.h"
+#include "stuff.h"
+#include "spells4.h"
+
+
+unsigned char your_sign; // accessed as extern in transfor.cc and acr.cc
+unsigned char your_colour; // accessed as extern in transfor.cc and acr.cc
+
+FixedArray < unsigned int, 20, 19 > show_backup;
+
+unsigned char show_green;
+extern int stealth; // defined in acr.cc
+extern FixedVector<char, 10> Visible_Statue; // defined in acr.cc
+
+// char colour_code_map(unsigned char map_value);
+char colour_code_map( int x, int y );
+
+unsigned char (*mapch) (unsigned char);
+unsigned char (*mapch2) (unsigned char);
+unsigned char mapchar(unsigned char ldfk);
+unsigned char mapchar2(unsigned char ldfk);
+unsigned char mapchar3(unsigned char ldfk);
+unsigned char mapchar4(unsigned char ldfk);
+void cloud_grid(void);
+void monster_grid(bool do_updates);
+
+//---------------------------------------------------------------
+//
+// get_number_of_lines
+//
+// Made this a function instead of a #define. This should help
+// considering the fact that the curses version is a macro
+// (curses tends to be implemented with a large number of
+// preprocessor macros, which can wreak havoc with things
+// like the C++ string class, so we want to isolate that
+// away to keep portability up).
+//
+// Other OSes might want to hook into reading system environment
+// variables or player set options to determine the screen size
+// (see the Options and SysEnv structures, as well as initfile.cc).
+//
+// This might be better to move to the lib*.cc files, but we
+// don't really have a standard API defined for them, or the
+// all important libdos.cc. It would be a good idea to eventually
+// head that way. -- bwr
+//
+//---------------------------------------------------------------
+int get_number_of_lines(void)
+{
+#ifdef LINUX
+ return (get_number_of_lines_from_curses());
+#elif MAC
+ return (MAC_NUMBER_OF_LINES);
+#else
+ return (25);
+#endif
+}
+
+
+//---------------------------------------------------------------
+//
+// get_ibm_symbol
+//
+// Returns the DOS character code and color for everything drawn
+// with the IBM graphics option.
+//
+//---------------------------------------------------------------
+static void get_ibm_symbol(unsigned int object, unsigned short *ch,
+ unsigned short *color)
+{
+ ASSERT(color != NULL);
+ ASSERT(ch != NULL);
+
+ switch (object)
+ {
+ case DNGN_UNSEEN:
+ *ch = 0;
+ break;
+
+ case DNGN_ROCK_WALL:
+ case DNGN_PERMAROCK_WALL:
+ *color = env.rock_colour;
+ *ch = 177;
+ break; // remember earth elementals
+
+ // stone in the realm of Zot is coloured the same as rock
+ case DNGN_STONE_WALL:
+ *color = (player_in_branch( BRANCH_HALL_OF_ZOT ) ? env.rock_colour
+ : LIGHTGREY);
+ *ch = 177;
+ break;
+
+ case DNGN_CLOSED_DOOR:
+ *ch = 254;
+ break;
+
+ case DNGN_METAL_WALL:
+ *ch = 177;
+ *color = CYAN;
+ break;
+
+ case DNGN_SECRET_DOOR:
+ *ch = 177;
+ *color = env.rock_colour;
+ break;
+
+ case DNGN_GREEN_CRYSTAL_WALL:
+ *ch = 177;
+ *color = GREEN;
+ break;
+
+ case DNGN_ORCISH_IDOL:
+ *ch = '8';
+ *color = DARKGREY;
+ break;
+
+ case DNGN_WAX_WALL:
+ *ch = 177;
+ *color = YELLOW;
+ break; // wax wall
+ /* Anything added here must also be added to the PLAIN_TERMINAL
+ viewwindow2 below */
+
+ case DNGN_SILVER_STATUE:
+ *ch = '8';
+ *color = WHITE;
+ Visible_Statue[ STATUE_SILVER ] = 1;
+ break;
+
+ case DNGN_GRANITE_STATUE:
+ *ch = '8';
+ *color = LIGHTGREY;
+ break;
+
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ *ch = '8';
+ *color = LIGHTRED;
+ Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
+ break;
+
+ case DNGN_LAVA:
+ *ch = 247;
+ *color = RED;
+ break;
+
+ case DNGN_DEEP_WATER:
+ *ch = 247; // this wavy thing also used for water elemental
+ *color = BLUE;
+ break;
+
+ case DNGN_SHALLOW_WATER:
+ *ch = 247; // this wavy thing also used for water elemental
+ *color = CYAN;
+ break;
+
+ case DNGN_FLOOR:
+ *color = env.floor_colour;
+ *ch = 249;
+ break;
+
+ case DNGN_ENTER_HELL:
+ *ch = 239;
+ *color = RED;
+ seen_other_thing(object);
+ break;
+
+ case DNGN_OPEN_DOOR:
+ *ch = 39;
+ break;
+
+ case DNGN_BRANCH_STAIRS:
+ *ch = 240;
+ *color = BROWN;
+ break;
+
+ case DNGN_TRAP_MECHANICAL:
+ *color = LIGHTCYAN;
+ *ch = 94;
+ break;
+
+ case DNGN_TRAP_MAGICAL:
+ *color = MAGENTA;
+ *ch = 94;
+ break;
+
+ case DNGN_TRAP_III:
+ *color = LIGHTGREY;
+ *ch = 94;
+ break;
+
+ case DNGN_UNDISCOVERED_TRAP:
+ *ch = 249;
+ *color = env.floor_colour;
+ break;
+
+ case DNGN_ENTER_SHOP:
+ *ch = 239;
+ *color = YELLOW;
+
+ seen_other_thing(object);
+ break;
+ // if I change anything above here, must also change magic mapping!
+
+ case DNGN_ENTER_LABYRINTH:
+ *ch = 239;
+ *color = LIGHTGREY;
+ seen_other_thing(object);
+ break;
+
+ // not sure why we have "odd" here, but "ladders" are special in
+ // that they all lead to the first staircase of the next level
+ // (and returning from there will take you somewhere different)
+ // ... that's why they're brown... it's a warning -- bwr
+ case DNGN_ROCK_STAIRS_DOWN:
+ *color = BROWN; // ladder // odd {dlb}
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ *ch = '>';
+ break;
+
+ case DNGN_ROCK_STAIRS_UP:
+ *color = BROWN; // ladder // odd {dlb}
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ *ch = '<';
+ break;
+
+ case DNGN_ENTER_DIS:
+ *color = CYAN;
+ *ch = 239;
+ break;
+
+ case DNGN_ENTER_GEHENNA:
+ *color = RED;
+ *ch = 239;
+ break;
+
+ case DNGN_ENTER_COCYTUS:
+ *color = LIGHTCYAN;
+ *ch = 239;
+ break;
+
+ case DNGN_ENTER_TARTARUS:
+ *color = DARKGREY;
+ *ch = 239;
+ break;
+
+ case DNGN_ENTER_ABYSS:
+ *color = random2(16);
+ *ch = 239;
+ seen_other_thing(object);
+ break;
+
+ case DNGN_EXIT_ABYSS:
+ *color = random2(16);
+ *ch = 239;
+ break;
+
+ case DNGN_STONE_ARCH:
+ *color = LIGHTGREY;
+ *ch = 239;
+ break;
+
+ case DNGN_ENTER_PANDEMONIUM:
+ *color = LIGHTBLUE;
+ *ch = 239;
+ seen_other_thing(object);
+ break;
+
+ case DNGN_EXIT_PANDEMONIUM:
+ *color = LIGHTBLUE;
+ *ch = 239;
+ break;
+
+ case DNGN_TRANSIT_PANDEMONIUM:
+ *color = LIGHTGREEN;
+ *ch = 239;
+ break;
+
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ *color = YELLOW;
+ *ch = '>';
+ seen_staircase(object);
+ break;
+
+ case DNGN_ENTER_ZOT:
+ *color = MAGENTA;
+ *ch = 239;
+ seen_staircase(object);
+ break;
+
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ *color = YELLOW;
+ *ch = '<';
+ break;
+
+ case DNGN_RETURN_FROM_ZOT:
+ *color = MAGENTA;
+ *ch = 239;
+ break;
+
+ case DNGN_ALTAR_ZIN:
+ *color = WHITE;
+ *ch = 220;
+ seen_altar(GOD_ZIN);
+ break;
+
+ case DNGN_ALTAR_SHINING_ONE:
+ *color = YELLOW;
+ *ch = 220;
+ seen_altar(GOD_SHINING_ONE);
+ break;
+
+ case DNGN_ALTAR_KIKUBAAQUDGHA:
+ *color = DARKGREY;
+ *ch = 220;
+ seen_altar(GOD_KIKUBAAQUDGHA);
+ break;
+
+ case DNGN_ALTAR_YREDELEMNUL:
+ *color = ((one_chance_in(3)) ? RED : DARKGREY);
+ *ch = 220;
+ seen_altar(GOD_YREDELEMNUL);
+ break;
+
+ case DNGN_ALTAR_XOM:
+ *color = random_colour();
+ *ch = 220;
+ seen_altar(GOD_XOM);
+ break;
+
+ case DNGN_ALTAR_VEHUMET:
+ *color = LIGHTBLUE;
+ if (one_chance_in(3))
+ *color = LIGHTMAGENTA;
+ if (one_chance_in(3))
+ *color = LIGHTRED;
+ *ch = 220;
+ seen_altar(GOD_VEHUMET);
+ break;
+
+ case DNGN_ALTAR_OKAWARU:
+ *color = CYAN;
+ *ch = 220;
+ seen_altar(GOD_OKAWARU);
+ break;
+
+ case DNGN_ALTAR_MAKHLEB:
+ *color = RED;
+ if (one_chance_in(3))
+ *color = LIGHTRED;
+ if (one_chance_in(3))
+ *color = YELLOW;
+ *ch = 220;
+ seen_altar(GOD_MAKHLEB);
+ break;
+
+ case DNGN_ALTAR_SIF_MUNA:
+ *color = BLUE;
+ *ch = 220;
+ seen_altar(GOD_SIF_MUNA);
+ break;
+
+ case DNGN_ALTAR_TROG:
+ *color = RED;
+ *ch = 220;
+ seen_altar(GOD_TROG);
+ break;
+
+ case DNGN_ALTAR_NEMELEX_XOBEH:
+ *color = LIGHTMAGENTA;
+ *ch = 220;
+ seen_altar(GOD_NEMELEX_XOBEH);
+ break;
+
+ case DNGN_ALTAR_ELYVILON:
+ *color = LIGHTGREY;
+ *ch = 220;
+ seen_altar(GOD_ELYVILON);
+ break;
+
+ case DNGN_BLUE_FOUNTAIN:
+ *color = BLUE;
+ *ch = 159;
+ break;
+
+ case DNGN_SPARKLING_FOUNTAIN:
+ *color = LIGHTBLUE;
+ *ch = 159;
+ break;
+
+ case DNGN_DRY_FOUNTAIN_I:
+ case DNGN_DRY_FOUNTAIN_II:
+ case DNGN_PERMADRY_FOUNTAIN:
+ *color = LIGHTGREY;
+ *ch = 159;
+ break;
+
+ case 256:
+ *ch = '0';
+ break;
+
+ case 257:
+ *color = CYAN;
+ *ch = '~';
+ break; /* Invis creature walking through water */
+
+ case 258:
+ *ch = ')';
+ break; // weapon )
+
+ case 259:
+ *ch = '[';
+ break; // armour [
+
+ case 260:
+ *ch = '/';
+ break; // wands, etc.
+
+ case 261:
+ *ch = '%';
+ break; // food
+
+ case 262:
+ *ch = '+';
+ break; // books +
+
+ case 263:
+ *ch = '?';
+ break; // scroll ?
+
+ case 264:
+ *ch = '=';
+ break; // ring = etc
+
+ case 265:
+ *ch = '!';
+ break; // potions !
+
+ case 266:
+ *ch = '(';
+ break; // stones
+
+ case 267:
+ *ch = '+';
+ break; // book +
+
+ case 268:
+ *ch = '%';
+ break; // corpses part 1
+
+ case 269:
+ *ch = '\\';
+ break; // magical staves
+
+ case 270:
+ *ch = '}';
+ break; // gems
+
+ case 271:
+ *ch = '%';
+ break; // don't know ?
+
+ case 272:
+ *ch = '$';
+ break; // $ gold
+
+ case 273:
+ *ch = '"';
+ break; // amulet
+
+ default:
+ *ch = ((object >= 297) ? mons_char(object - 297) : object);
+ break;
+ }
+} // end get_ibm_symbol()
+
+
+//---------------------------------------------------------------
+//
+// viewwindow2
+//
+// Draws the main window using the extended IBM character set.
+//
+// This function should not interfer with the game condition,
+// unless do_updates is set (ie. stealth checks for visible
+// monsters).
+//
+//---------------------------------------------------------------
+void viewwindow2(char draw_it, bool do_updates)
+{
+ const long BUFFER_SIZE = 1550;
+#ifdef DOS_TERM
+ // DOS functions like gettext() and puttext() can only
+ // work with arrays of characters, not shorts.
+ FixedVector < unsigned char, BUFFER_SIZE > buffy; //[800]; //392];
+#else
+ FixedVector < unsigned short, BUFFER_SIZE > buffy; //[800]; //392];
+#endif
+
+ unsigned short ch, color;
+
+ losight(env.show, grd, you.x_pos, you.y_pos);
+
+ int count_x, count_y;
+
+ for (count_x = 0; count_x < 18; count_x++)
+ {
+ for (count_y = 0; count_y < 18; count_y++)
+ {
+ env.show_col[count_x][count_y] = LIGHTGREY;
+ show_backup[count_x][count_y] = 0;
+ }
+ }
+
+ item();
+ cloud_grid();
+ monster_grid(do_updates);
+ int bufcount = 0;
+
+ if (draw_it == 1)
+ {
+ _setcursortype(_NOCURSOR);
+ for (count_y = you.y_pos - 8; count_y < you.y_pos + 9; count_y++)
+ {
+ bufcount += 16;
+
+ for (count_x = you.x_pos - 8; count_x < you.x_pos + 9; count_x++)
+ {
+ // may be overriden by the code below
+ color = env.show_col[ count_x - you.x_pos + 9 ]
+ [ count_y - you.y_pos + 9 ];
+
+ unsigned int object = env.show[ count_x - you.x_pos + 9 ]
+ [ count_y - you.y_pos + 9 ];
+
+ get_ibm_symbol(object, &ch, &color);
+
+ if (count_x == you.x_pos && count_y == you.y_pos)
+ {
+ ch = your_sign;
+
+ if (player_is_swimming())
+ {
+ color = (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
+ ? BLUE : CYAN;
+ }
+ else
+ {
+ color = your_colour;
+ }
+ }
+
+ ASSERT(bufcount + 1 < BUFFER_SIZE);
+ buffy[bufcount] = ch;
+ buffy[bufcount + 1] = color;
+
+ bufcount += 2;
+ }
+
+ bufcount += 16;
+ }
+
+ if (you.level_type != LEVEL_LABYRINTH && you.level_type != LEVEL_ABYSS)
+ {
+ bufcount = 0;
+
+ for (count_y = 0; count_y < 17; count_y++)
+ {
+ bufcount += 16;
+
+ for (count_x = 0; count_x < 17; count_x++)
+ {
+ ASSERT(bufcount < BUFFER_SIZE);
+
+ if (buffy[bufcount] != 0)
+ {
+ env.map[ count_x + you.x_pos - 9 ]
+ [ count_y + you.y_pos - 9 ] = buffy[bufcount];
+ }
+
+ if (Options.clean_map == 1
+ && show_backup[count_x + 1][count_y + 1] != 0)
+ {
+ get_ibm_symbol(show_backup[count_x + 1][count_y + 1],
+ &ch, &color);
+ env.map[ count_x + you.x_pos - 9 ]
+ [ count_y + you.y_pos - 9 ] = ch;
+ }
+ bufcount += 2;
+ }
+ bufcount += 16;
+ }
+ }
+
+ bufcount = 0;
+ for (count_y = 0; count_y < 17; count_y++)
+ {
+ for (count_x = 0; count_x < 33; count_x++)
+ {
+ if (count_x + you.x_pos - 17 < 3
+ || count_y + you.y_pos - 9 < 3
+ || count_x + you.x_pos - 14 > 77
+ || count_y + you.y_pos - 9 > 67)
+ {
+ ASSERT(bufcount < BUFFER_SIZE);
+ buffy[bufcount] = 0;
+ bufcount++;
+ buffy[bufcount] = 0;
+ bufcount++;
+ continue;
+ }
+
+ if (count_x >= 8 && count_x <= 24 && count_y >= 0
+ && count_y <= 16 && buffy[bufcount] != 0)
+ {
+ bufcount += 2;
+ continue;
+ }
+
+ ASSERT(bufcount + 1 < BUFFER_SIZE);
+
+ buffy[bufcount] = env.map[ count_x + you.x_pos - 17 ]
+ [ count_y + you.y_pos - 9 ];
+
+ buffy[bufcount + 1] = DARKGREY;
+ if (Options.colour_map)
+ {
+ if (env.map[ count_x + you.x_pos - 16 ]
+ [ count_y + you.y_pos - 8 ] != 0)
+ {
+ buffy[bufcount + 1]
+ = colour_code_map( count_x + you.x_pos - 17,
+ count_y + you.y_pos - 9 );
+ }
+ }
+ bufcount += 2;
+ }
+ }
+
+ if (you.berserker)
+ {
+ for (count_x = 1; count_x < 1400; count_x += 2)
+ {
+ if (buffy[count_x] != DARKGREY)
+ buffy[count_x] = RED;
+ }
+ }
+
+ if (show_green != BLACK)
+ {
+ for (count_x = 1; count_x < 1400; count_x += 2)
+ {
+ if (buffy[count_x] != DARKGREY)
+ buffy[count_x] = show_green;
+ }
+
+ show_green = BLACK;
+
+ if (you.special_wield == SPWLD_SHADOW)
+ show_green = DARKGREY;
+ }
+
+#ifdef DOS_TERM
+ puttext(2, 1, 34, 17, buffy.buffer());
+#endif
+
+#ifdef PLAIN_TERM
+ gotoxy(2, 1);
+ bufcount = 0;
+
+ // following lines are purely optional.
+ // if used, players will 'jump' move.
+ // Resting will be a LOT faster too.
+ if (you.running == 0)
+ {
+ for (count_x = 0; count_x < 1120; count_x += 2)
+ { // 1056
+ ch = buffy[count_x];
+ color = buffy[count_x + 1];
+// ASSERT(color < 16);
+ ASSERT(ch < 255);
+
+ textcolor(color);
+ putch(ch);
+
+ if (count_x % 66 == 64 && count_x > 0)
+ gotoxy(2, wherey() + 1);
+ }
+ // remember to comment out the line below if you comment out jump move.
+ }
+ _setcursortype(_NORMALCURSOR);
+#endif
+ }
+} // end viewwindow2()
+
+char colour_code_map( int x, int y )
+{
+ // XXX: Yes, the map array and the grid array are off by one. -- bwr
+ const int map_value = env.map[x][y];
+ const int grid_value = grd[x + 1][y + 1];
+
+ // XXX: Yeah, this is ugly, but until we have stored layers in the
+ // map we can't tell if we've seen a square, detected it, or just
+ // detected the item or monster on top... giving colour here will
+ // result in detect creature/item detecting features like stairs. -- bwr
+ if (map_value != mapch2( grid_value ))
+ return (DARKGREY);
+
+ switch (grid_value)
+ {
+ case DNGN_TRAP_MECHANICAL:
+ return (LIGHTCYAN);
+
+ case DNGN_TRAP_MAGICAL:
+ case DNGN_TRAP_III:
+ return (MAGENTA);
+
+ case DNGN_ENTER_SHOP:
+ return (YELLOW);
+
+ case DNGN_ENTER_DIS:
+ return (CYAN);
+
+ case DNGN_ENTER_HELL:
+ case DNGN_ENTER_GEHENNA:
+ return (RED);
+
+ case DNGN_ENTER_COCYTUS:
+ return (LIGHTCYAN);
+
+ case DNGN_ENTER_ABYSS:
+ return random2(16); // so it can be black - is this right? {dlb}
+
+ case DNGN_ENTER_LABYRINTH:
+ case DNGN_STONE_ARCH:
+ return (LIGHTGREY);
+
+ case DNGN_ENTER_PANDEMONIUM:
+ return (LIGHTBLUE);
+
+ case DNGN_EXIT_PANDEMONIUM:
+ // Exit pandemonium gates won't show up on the map as light blue
+ // unless the character has the "gate to pandemonium" demonspawn
+ // mutation. This is so that the player can't quickly use a
+ // crystal ball to find their way out. -- bwr
+ return (you.mutation[MUT_PANDEMONIUM] ? LIGHTBLUE : LIGHTGREEN);
+
+ case DNGN_TRANSIT_PANDEMONIUM:
+ return (LIGHTGREEN);
+
+ case DNGN_ENTER_ZOT:
+ case DNGN_RETURN_FROM_ZOT:
+ return (MAGENTA);
+
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ case DNGN_ROCK_STAIRS_DOWN:
+ return (RED);
+
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ case DNGN_ROCK_STAIRS_UP:
+ return (BLUE);
+
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ return (LIGHTRED);
+
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ return (LIGHTBLUE);
+
+ default:
+ break;
+ }
+
+ return (DARKGREY);
+}
+
+
+void monster_grid(bool do_updates)
+{
+ struct monsters *monster = 0; // NULL {dlb}
+
+ for (int s = 0; s < MAX_MONSTERS; s++)
+ {
+ monster = &menv[s];
+
+ if (monster->type != -1 && mons_near(monster))
+ {
+ if (do_updates
+ && (monster->behaviour == BEH_SLEEP
+ || monster->behaviour == BEH_WANDER)
+ && check_awaken(s))
+ {
+ behaviour_event( monster, ME_ALERT, MHITYOU );
+
+ if (you.turn_is_over == 1
+ && mons_shouts(monster->type) > 0
+ && random2(30) >= you.skills[SK_STEALTH])
+ {
+ int noise_level = 8;
+
+ if (!mons_friendly(monster)
+ && (!silenced(you.x_pos, you.y_pos)
+ && !silenced(monster->x, monster->y)))
+ {
+ if (mons_is_demon( monster->type ) && coinflip())
+ {
+ if (monster->type == MONS_IMP
+ || monster->type == MONS_WHITE_IMP
+ || monster->type == MONS_SHADOW_IMP)
+ {
+ imp_taunt( monster );
+ }
+ else
+ {
+ demon_taunt( monster );
+ }
+ }
+ else
+ {
+ int the_shout = mons_shouts(monster->type);
+
+ strcpy(info, "You hear ");
+ switch (the_shout)
+ {
+ case S_SILENT:
+ default:
+ strcat(info, "buggy behaviour!");
+ break;
+ case S_SHOUT:
+ strcat(info, "a shout!");
+ break;
+ case S_BARK:
+ strcat(info, "a bark!");
+ break;
+ case S_SHOUT2:
+ strcat(info, "two shouts!");
+ noise_level = 12;
+ break;
+ case S_ROAR:
+ strcat(info, "a roar!");
+ noise_level = 12;
+ break;
+ case S_SCREAM:
+ strcat(info, "a hideous shriek!");
+ break;
+ case S_BELLOW:
+ strcat(info, "a bellow!");
+ break;
+ case S_SCREECH:
+ strcat(info, "a screech!");
+ break;
+ case S_BUZZ:
+ strcat(info, "an angry buzzing noise.");
+ break;
+ case S_MOAN:
+ strcat(info, "a chilling moan.");
+ break;
+ case S_WHINE:
+ strcat(info,
+ "an irritating high-pitched whine.");
+ break;
+ case S_CROAK:
+ if (coinflip())
+ strcat(info, "a loud, deep croak!");
+ else
+ strcat(info, "a croak.");
+ break;
+ case S_GROWL:
+ strcat(info, "an angry growl!");
+ break;
+ case S_HISS:
+ strcat(info, "an angry hiss!");
+ noise_level = 4; // not very loud -- bwr
+ break;
+ }
+
+ mpr(info);
+ }
+ }
+
+ noisy( noise_level, monster->x, monster->y );
+ }
+ }
+
+ if (!player_monster_visible( monster ))
+ {
+ // ripple effect?
+ if (grd[monster->x][monster->y] == DNGN_SHALLOW_WATER
+ && !mons_flies(monster))
+ {
+ show_backup[ monster->x - you.x_pos + 9 ]
+ [ monster->y - you.y_pos + 9]
+ = env.show[ monster->x - you.x_pos + 9 ]
+ [ monster->y - you.y_pos + 9 ];
+ env.show[monster->x - you.x_pos + 9]
+ [monster->y - you.y_pos + 9] = 257;
+ }
+ continue;
+ }
+ else if (!mons_friendly( monster )
+ && !mons_is_mimic( monster->type )
+ && !mons_flag( monster->type, M_NO_EXP_GAIN )
+ && you.running > 0)
+ {
+ // Friendly monsters, mimics, or harmless monsters
+ // don't disturb the player's running/resting.
+ //
+ // Doing it this way causes players in run mode 2
+ // to move one square, and in mode 1 to stop. This
+ // means that the character will run one square if
+ // a monster is in sight... we automatically jump
+ // to zero if we're resting. -- bwr
+ if (you.run_x == 0 && you.run_y == 0)
+ you.running = 0;
+ else
+ you.running--;
+ }
+
+ // mimics are always left on map
+ if (!mons_is_mimic( monster->type ))
+ {
+ show_backup[monster->x - you.x_pos + 9]
+ [monster->y - you.y_pos + 9]
+ = env.show[monster->x - you.x_pos + 9]
+ [monster->y - you.y_pos + 9];
+ }
+
+ env.show[monster->x - you.x_pos + 9]
+ [monster->y - you.y_pos + 9] = monster->type + 297;
+
+ env.show_col[monster->x - you.x_pos + 9]
+ [monster->y - you.y_pos + 9]
+ = ((mcolour[monster->type] == BLACK)
+ ? monster->number : mcolour[monster->type]);
+#ifdef USE_COLOUR_OPTS
+ if (mons_friendly(monster))
+ {
+ env.show_col[monster->x - you.x_pos + 9]
+ [monster->y - you.y_pos + 9]
+ |= COLFLAG_FRIENDLY_MONSTER;
+ }
+#endif
+ } // end "if (monster->type != -1 && mons_ner)"
+ } // end "for s"
+} // end monster_grid()
+
+
+bool check_awaken(int mons_aw)
+{
+ int mons_perc = 0;
+ struct monsters *monster = &menv[mons_aw];
+ const int mon_holy = mons_holiness( monster->type );
+
+ // berserkers aren't really concerned about stealth
+ if (you.berserker)
+ return (true);
+
+ // Repel undead is a holy aura, to which evil creatures are sensitive.
+ // Note that even though demons aren't affected by repel undead, they
+ // do sense this type of divine aura. -- bwr
+ if (you.duration[DUR_REPEL_UNDEAD]
+ && (mon_holy == MH_UNDEAD || mon_holy == MH_DEMONIC))
+ {
+ return (true);
+ }
+
+ // I assume that creatures who can see invisible are very perceptive
+ mons_perc = 10 + (mons_intel(monster->type) * 4) + monster->hit_dice
+ + mons_see_invis(monster) * 5;
+
+ // critters that are wandering still have MHITYOU as their foe are
+ // still actively on guard for the player, even if they can't see
+ // him. Give them a large bonus (handle_behaviour() will nuke 'foe'
+ // after a while, removing this bonus.
+ if (monster->behaviour == BEH_WANDER && monster->foe == MHITYOU)
+ mons_perc += 15;
+
+ if (!mons_player_visible(monster))
+ mons_perc -= 75;
+
+ if (monster->behaviour == BEH_SLEEP)
+ {
+ if (mon_holy == MH_NATURAL)
+ {
+ // monster is "hibernating"... reduce chance of waking
+ if (mons_has_ench( monster, ENCH_SLEEP_WARY ))
+ mons_perc -= 10;
+ }
+ else // unnatural creature
+ {
+ // Unnatural monsters don't actually "sleep", they just
+ // haven't noticed an intruder yet... we'll assume that
+ // they're diligently on guard.
+ mons_perc += 10;
+ }
+ }
+
+ // glowing with magical contamination isn't very stealthy
+ if (you.magic_contamination > 10)
+ mons_perc += you.magic_contamination - 10;
+
+ if (mons_perc < 0)
+ mons_perc = 0;
+
+ return (random2(stealth) <= mons_perc);
+} // end check_awaken()
+
+
+void item()
+{
+ char count_x, count_y;
+
+ for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
+ {
+ for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
+ {
+ if (count_x >= 0 && count_x < GXM && count_y >= 0 && count_y < GYM)
+ {
+ if (igrd[count_x][count_y] != NON_ITEM)
+ {
+ if (env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] != 0)
+ {
+ if (grd[count_x][count_y] == DNGN_SHALLOW_WATER)
+ {
+ env.show_col[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = CYAN;
+ }
+ else
+ {
+ env.show_col[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9]
+ = mitm[igrd[count_x][count_y]].colour;
+ }
+
+ switch (mitm[igrd[count_x][count_y]].base_type)
+ {
+ case OBJ_ORBS:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 256;
+ break;
+ // need + 6 because show is 0 - 12, not -6 - +6
+ case OBJ_WEAPONS:
+ case OBJ_MISSILES:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 258;
+ break;
+ case OBJ_ARMOUR:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 259;
+ break;
+ case OBJ_WANDS:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 260;
+ break;
+ case OBJ_FOOD:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 261;
+ break;
+ case OBJ_UNKNOWN_I:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 262;
+ break;
+ case OBJ_SCROLLS:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 263;
+ break;
+
+ case OBJ_JEWELLERY:
+ if (mitm[igrd[count_x][count_y]].sub_type >= AMU_RAGE)
+ {
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 273;
+ }
+ else
+ {
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 264;
+ }
+ break;
+
+ case OBJ_POTIONS:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 265;
+ break;
+ case OBJ_UNKNOWN_II:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 266;
+ break;
+ case OBJ_BOOKS:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 267;
+ break;
+ case OBJ_STAVES:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 269;
+ break;
+ case OBJ_MISCELLANY:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 270;
+ break;
+ case OBJ_CORPSES:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 271;
+ break;
+
+ case OBJ_GOLD:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = 272;
+
+ env.show_col[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = YELLOW;
+ break;
+
+ default:
+ env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9] = '8';
+ break;
+ }
+ }
+ }
+ }
+ } // end of "for count_y, count_x"
+ }
+} // end item()
+
+
+void cloud_grid(void)
+{
+ int mnc = 0;
+
+ // btw, this is also the 'default' color {dlb}
+ unsigned char which_color = LIGHTGREY;
+
+ for (int s = 0; s < MAX_CLOUDS; s++)
+ {
+ // can anyone explain this??? {dlb}
+ // its an optimization to avoid looking past the last cloud -bwr
+ if (mnc > env.cloud_no)
+ break;
+
+ if (env.cloud[s].type != CLOUD_NONE)
+ {
+ mnc++;
+
+ if (see_grid(env.cloud[s].x, env.cloud[s].y))
+ {
+ show_backup[env.cloud[s].x - you.x_pos + 9]
+ [env.cloud[s].y - you.y_pos + 9]
+ = env.show[env.cloud[s].x - you.x_pos + 9]
+ [env.cloud[s].y - you.y_pos + 9];
+
+ env.show[env.cloud[s].x - you.x_pos + 9]
+ [env.cloud[s].y - you.y_pos + 9] = '#';
+
+ switch (env.cloud[s].type)
+ {
+ case CLOUD_FIRE:
+ case CLOUD_FIRE_MON:
+ if (env.cloud[s].decay <= 20)
+ which_color = RED;
+ else if (env.cloud[s].decay <= 40)
+ which_color = LIGHTRED;
+ else if (one_chance_in(4))
+ which_color = RED;
+ else if (one_chance_in(4))
+ which_color = LIGHTRED;
+ else
+ which_color = YELLOW;
+ break;
+
+ case CLOUD_STINK:
+ case CLOUD_STINK_MON:
+ which_color = GREEN;
+ break;
+
+ case CLOUD_COLD:
+ case CLOUD_COLD_MON:
+ if (env.cloud[s].decay <= 20)
+ which_color = BLUE;
+ else if (env.cloud[s].decay <= 40)
+ which_color = LIGHTBLUE;
+ else if (one_chance_in(4))
+ which_color = BLUE;
+ else if (one_chance_in(4))
+ which_color = LIGHTBLUE;
+ else
+ which_color = WHITE;
+ break;
+
+ case CLOUD_POISON:
+ case CLOUD_POISON_MON:
+ which_color = (one_chance_in(3) ? LIGHTGREEN : GREEN);
+ break;
+
+ case CLOUD_BLUE_SMOKE:
+ case CLOUD_BLUE_SMOKE_MON:
+ which_color = LIGHTBLUE;
+ break;
+
+ case CLOUD_PURP_SMOKE:
+ case CLOUD_PURP_SMOKE_MON:
+ which_color = MAGENTA;
+ break;
+
+ case CLOUD_MIASMA:
+ case CLOUD_MIASMA_MON:
+ case CLOUD_BLACK_SMOKE:
+ case CLOUD_BLACK_SMOKE_MON:
+ which_color = DARKGREY;
+ break;
+
+ default:
+ which_color = LIGHTGREY;
+ break;
+ }
+
+ env.show_col[env.cloud[s].x - you.x_pos + 9]
+ [env.cloud[s].y - you.y_pos + 9] = which_color;
+ }
+ } // end 'if != CLOUD_NONE'
+ } // end 'for s' loop
+} // end cloud_grid()
+
+
+void noisy( int loudness, int nois_x, int nois_y )
+{
+ int p;
+ struct monsters *monster = 0; // NULL {dlb}
+
+ if (silenced( nois_x, nois_y ))
+ return;
+
+ int dist = loudness * loudness;
+
+ for (p = 0; p < MAX_MONSTERS; p++)
+ {
+ monster = &menv[p];
+
+ if (monster->type < 0)
+ continue;
+
+ if (distance(monster->x, monster->y, nois_x, nois_y) <= dist
+ && !silenced(monster->x, monster->y))
+ {
+ // If the noise came from the character, any nearby monster
+ // will be jumping on top of them.
+ if (nois_x == you.x_pos && nois_y == you.y_pos)
+ behaviour_event( monster, ME_ALERT, MHITYOU );
+ else
+ behaviour_event( monster, ME_DISTURB, MHITNOT, nois_x, nois_y );
+ }
+ }
+} // end noisy()
+
+/* ========================================================================
+ * brand new LOS code
+ * ========================================================================
+ * The new LOS works via a new (I think) shadow casting algorithm,
+ * plus an esthetic tweak for more pleasing corner illumination. More
+ * detail can be had by contacting its author, Gordon Lipford. */
+
+#define MAX_LIGHT_RADIUS 20
+#define CIRC_MAX 32000
+#define BIG_SHADOW 32000
+
+// the following two constants represent the 'middle' of the sh array.
+// since the current shown area is 19x19, centering the view at (9,9)
+// means it will be exactly centered.
+// This is done to accomodate possible future changes in viewable screen
+// area - simply change sh_xo and sh_yo to the new view center.
+
+const int sh_xo = 9; // X and Y origins for the sh array
+const int sh_yo = 9;
+
+// the Cell class, used in the shadow-casting LOS algorithm
+class Cell
+{
+
+public:
+ int up_count;
+ int up_max;
+ int low_count;
+ int low_max;
+ bool lit;
+ bool lit_delay;
+ bool visible; // for blockers only
+ void init();
+ bool reachedLower();
+ bool reachedUpper();
+
+ Cell()
+ {
+ init();
+ };
+};
+
+void Cell::init()
+{
+ up_count = 0;
+ up_max = 0;
+ low_count = 0;
+ low_max = 0;
+ lit = true;
+ visible = true;
+ lit_delay = false;
+}
+
+bool Cell::reachedLower()
+{
+ // integer math: a 'step' has a value of 10
+ // see if we're within a half step of the max. VERY important
+ // to use 'half step' or else things look really stupid.
+ if (low_max != 0 && low_count + 5 >= low_max && low_count - 5 < low_max)
+ return true;
+
+ return false;
+}
+
+bool Cell::reachedUpper()
+{
+ // see if we're within a half step of the max. VERY important
+ // to use 'half step' or else things look really stupid.
+ if (up_max != 0 && up_count + 5 >= up_max && up_count - 5 < up_max)
+ return true;
+
+ return false;
+}
+
+// the cell array
+static FixedVector < Cell, MAX_LIGHT_RADIUS + 1 > cells;
+
+// the 'circle' array. For any given row, we won't check higher than
+// this given cell.
+static FixedVector < int, MAX_LIGHT_RADIUS + 1 > circle;
+
+// current light radius
+static int LR = 0;
+
+// View constant
+const int view = 2; // 1=widest LOS .. 5=narrowest
+
+// initialize LOS code for a given light radius
+extern void setLOSRadius(int newLR)
+{
+ int i, j;
+
+ // sanity check - also allows multiple calls w/out performance loss
+ if (LR == newLR)
+ return;
+
+ LR = newLR;
+ // cells should already be initted. calculate the circle array.
+
+ // note that rows 0 and 1 will always go to infinity.
+ circle[0] = circle[1] = CIRC_MAX;
+
+ // for the rest, simply calculate max height based on light rad.
+ for (i = 2; i <= LR; i++)
+ {
+ // check top
+ if (2 * i * i <= LR * LR)
+ {
+ circle[i] = CIRC_MAX;
+ continue;
+ }
+
+ for (j = i - 1; j >= 0; j--)
+ {
+ // check that Distance (I^2 + J^2) is no more than (R+0.5)^2
+ // this rounding allows for *much* better looking circles.
+ if (i * i + j * j <= LR * LR + LR)
+ {
+ circle[i] = j;
+ break;
+ }
+ }
+ }
+}
+
+static int calcUpper(int bX, int bY)
+{
+ // got a blocker at row bX, cell bY. do all values
+ // and scale by a factor of 10 for the integer math.
+ int upper;
+
+ upper = (10 * (10 * bX - view)) / (10 * bY + view);
+ if (upper < 10) // upper bound for blocker on diagonal
+ upper = 10;
+
+ return upper;
+}
+
+static int calcLower(int bX, int bY)
+{
+ // got a blocker at row bX, cell bY. do all values
+ // and scale by a factor of 10 for the integer math.
+
+ if (bY == 0)
+ return BIG_SHADOW;
+
+ return (10 * (10 * bX + view)) / (10 * bY - view);
+}
+
+// for easy x,y octant translation
+static int xxcomp[8] = { 1, 0, 0, -1, -1, 0, 0, 1 };
+static int xycomp[8] = { 0, 1, -1, 0, 0, -1, 1, 0 };
+static int yxcomp[8] = { 0, 1, 1, 0, 0, -1, -1, 0 };
+static int yycomp[8] = { 1, 0, 0, 1, -1, 0, 0, -1 };
+
+static void los_octant(int o, FixedArray < unsigned int, 19, 19 > &sh,
+ FixedArray < unsigned char, 80, 70 > &gr, int x_p,
+ int y_p)
+{
+ int row, cell, top, south;
+ int tx, ty; // translated x, y deltas for this octant
+ unsigned char gv; // grid value
+ bool row_dark, all_dark;
+ bool blocker, vis_corner;
+ int up_inc, low_inc;
+
+ // leave [0,0] alone, because the old LOS code seems to.
+
+ // init cell[0]. this is the only one that needs clearing.
+ cells[0].init();
+ all_dark = false;
+ vis_corner = false;
+
+ // loop through each row
+ for (row = 1; row <= LR; row++)
+ {
+ row_dark = true;
+
+ // loop through each cell, up to the max allowed by circle[]
+ top = circle[row];
+ if (top > row)
+ top = row;
+
+ for (cell = 0; cell <= top; cell++)
+ {
+ // translate X,Y co'ord + bounds check
+ tx = row * xxcomp[o] + cell * xycomp[o];
+ ty = row * yxcomp[o] + cell * yycomp[o];
+
+ if (x_p + tx < 0 || x_p + tx > 79 || y_p + ty < 0 || y_p + ty > 69)
+ continue;
+
+ // check for all_dark - we've finished the octant but
+ // have yet to fill in '0' for the rest of the sight grid
+ if (all_dark == true)
+ {
+ sh[sh_xo + tx][sh_yo + ty] = 0;
+ continue;
+ }
+
+ // get grid value.. see if it blocks LOS
+ gv = gr[x_p + tx][y_p + ty];
+ blocker = (gv < MINSEE);
+
+ // init some other variables
+ up_inc = 10;
+ low_inc = 10;
+ south = cell - 1;
+
+ // STEP 1 - inherit values from immediate West, if possible
+ if (cell < row)
+ {
+ // check for delayed lighting
+ if (cells[cell].lit_delay)
+ {
+ if (!blocker)
+ { // blockers don't light up with lit_delay.
+ if (cells[south].lit)
+ {
+ if (cells[south].low_max != 0)
+ {
+ cells[cell].lit = false;
+ // steal lower values
+ cells[cell].low_max = cells[south].low_max;
+ cells[cell].low_count = cells[south].low_count;
+ cells[south].low_count = 0;
+ cells[south].low_max = 0;
+ low_inc = 0; // avoid double-inc.
+ }
+ else
+ cells[cell].lit = true;
+ }
+ }
+ cells[cell].lit_delay = false;
+ }
+ }
+ else
+ {
+ // initialize new cell.
+ cells[cell].init();
+ }
+
+ // STEP 2 - check for blocker
+ // a dark blocker in shadow's edge will be visible
+ if (blocker)
+ {
+ if (cells[cell].lit || (cell != 0 && cells[south].lit)
+ || vis_corner)
+ {
+ // hack: make 'corners' visible
+ vis_corner = cells[cell].lit;
+
+ cells[cell].lit = false;
+ cells[cell].visible = true;
+
+ int upper = calcUpper(row, cell);
+ int lower = calcLower(row, cell);
+
+ if (upper < cells[cell].up_max || cells[cell].up_max == 0)
+ {
+ // new upper shadow
+ cells[cell].up_max = upper;
+ cells[cell].up_count = 0;
+ up_inc = 0;
+ }
+
+ if (lower > cells[cell].low_max || cells[cell].low_max == 0)
+ {
+ // new lower shadow
+ cells[cell].low_max = lower;
+ cells[cell].low_count = -10;
+ low_inc = 0;
+ if (lower <= 30) // somewhat arbitrary
+ cells[cell].lit_delay = true;
+ // set dark_delay if lower > 20?? how to decide?
+ }
+ }
+ else
+ {
+ cells[cell].visible = false;
+ }
+ }
+ else
+ {
+ cells[cell].visible = false; // special flags for blockers
+ }
+
+ // STEP 3 - add increments to upper, lower counts
+ cells[cell].up_count += up_inc;
+ cells[cell].low_count += low_inc;
+
+ // STEP 4 - check south for dark
+ if (south >= 0)
+ if (cells[south].reachedUpper() == true)
+ {
+ if (cells[cell].reachedUpper() == false)
+ {
+ cells[cell].up_max = cells[south].up_max;
+ cells[cell].up_count = cells[south].up_count;
+ cells[cell].up_count -= cells[south].up_max;
+ }
+ cells[cell].lit = false;
+ cells[cell].visible = false;
+ }
+
+ // STEP 5 - nuke lower if south lower
+ if (south >= 0)
+ {
+ if (cells[south].reachedLower())
+ {
+ cells[cell].low_max = cells[south].low_max;
+ cells[cell].low_count = cells[south].low_count;
+ cells[cell].low_count -= cells[south].low_max;
+ cells[south].low_count = cells[south].low_max = 0;
+ }
+
+ if (cells[south].low_max != 0
+ || (cells[south].lit == false
+ && cells[south].low_max == 0))
+ {
+ cells[cell].low_count = cells[cell].low_max + 10;
+ }
+ }
+
+ // STEP 6 - light up if we've reached lower bound
+ if (cells[cell].reachedLower() == true)
+ cells[cell].lit = true;
+
+ // now place appropriate value in sh
+ if (cells[cell].lit == true
+ || (blocker == true && cells[cell].visible == true))
+ {
+ sh[sh_xo + tx][sh_yo + ty] = gv;
+ }
+ else
+ sh[sh_xo + tx][sh_yo + ty] = 0;
+
+ if (cells[cell].lit == true)
+ row_dark = false;
+ } // end for - cells
+
+ vis_corner = false; // don't carry over to next row. :)
+ if (row_dark == true)
+ all_dark = true;
+ } // end for - rows
+}
+
+void losight(FixedArray < unsigned int, 19, 19 > &sh,
+ FixedArray < unsigned char, 80, 70 > &gr, int x_p, int y_p)
+{
+ int o;
+
+ for (o = 0; o < 8; o++)
+ los_octant(o, sh, gr, x_p, y_p);
+}
+
+
+void draw_border(void)
+{
+ textcolor( BORDER_COLOR );
+ clrscr();
+ redraw_skill( you.your_name, player_title() );
+
+ gotoxy(40, 2);
+ cprintf( "%s %s", species_name( you.species, you.experience_level ),
+ (you.wizard ? "*WIZARD*" : "" ) );
+
+ gotoxy(40, 3); cprintf("HP:");
+ gotoxy(40, 4); cprintf("Magic:");
+ gotoxy(40, 5); cprintf("AC:");
+ gotoxy(40, 6); cprintf("EV:");
+ gotoxy(40, 7); cprintf("Str:");
+ gotoxy(40, 8); cprintf("Int:");
+ gotoxy(40, 9); cprintf("Dex:");
+ gotoxy(40, 10); cprintf("Gold:");
+ gotoxy(40, 11); cprintf("Experience:");
+ gotoxy(40, 12); cprintf("Level");
+} // end draw_border()
+
+// show_map() now centers the known map along x or y. This prevents
+// the player from getting "artificial" location clues by using the
+// map to see how close to the end they are. They'll need to explore
+// to get that. This function is still a mess, though. -- bwr
+void show_map( FixedVector<int, 2> &spec_place )
+{
+ int i, j;
+
+ int bufcount2 = 0;
+
+ char move_x = 0;
+ char move_y = 0;
+ char getty = 0;
+
+#ifdef DOS_TERM
+ char buffer[4800];
+#endif
+
+ // buffer2[GYM * GXM * 2] segfaults my box {dlb}
+ char buffer2[GYM * GXM * 2];
+
+ char min_x = 80, max_x = 0, min_y = 0, max_y = 0;
+ bool found_y = false;
+
+ const int num_lines = get_number_of_lines();
+ const int half_screen = num_lines / 2 - 1;
+
+ for (j = 0; j < GYM; j++)
+ {
+ for (i = 0; i < GXM; i++)
+ {
+ if (env.map[i][j])
+ {
+ if (!found_y)
+ {
+ found_y = true;
+ min_y = j;
+ }
+
+ max_y = j;
+
+ if (i < min_x)
+ min_x = i;
+
+ if (i > max_x)
+ max_x = i;
+ }
+ }
+ }
+
+ const int map_lines = max_y - min_y + 1;
+
+ const int start_x = min_x + (max_x - min_x + 1) / 2 - 40; // no x scrolling
+ int start_y; // y does scroll
+
+ int screen_y = you.y_pos;
+
+ // if close to top of known map, put min_y on top
+ // else if close to bottom of known map, put max_y on bottom.
+ //
+ // The num_lines comparisons are done to keep things neat, by
+ // keeping things at the top of the screen. By shifting an
+ // additional one in the num_lines > map_lines case, we can
+ // keep the top line clear... which makes things look a whole
+ // lot better for small maps.
+ if (num_lines > map_lines)
+ screen_y = min_y + half_screen - 1;
+ else if (num_lines == map_lines || screen_y - half_screen < min_y)
+ screen_y = min_y + half_screen;
+ else if (screen_y + half_screen > max_y)
+ screen_y = max_y - half_screen;
+
+ int curs_x = you.x_pos - start_x;
+ int curs_y = you.y_pos - screen_y + half_screen;
+
+#ifdef DOS_TERM
+ gettext(1, 1, 80, 25, buffer);
+ window(1, 1, 80, 25);
+#endif
+
+ clrscr();
+ textcolor(DARKGREY);
+
+ put_screen:
+ bufcount2 = 0;
+
+ _setcursortype(_NOCURSOR);
+
+#ifdef PLAIN_TERM
+ gotoxy(1, 1);
+#endif
+
+ start_y = screen_y - half_screen;
+
+ for (j = 0; j < num_lines; j++)
+ {
+ for (i = 0; i < 80; i++)
+ {
+ if (start_y + j >= 65 || start_y + j <= 3
+ || start_x + i < 0 || start_x + i >= GXM - 1)
+ {
+ buffer2[bufcount2 + 1] = DARKGREY;
+ buffer2[bufcount2] = 0;
+ bufcount2 += 2;
+
+#ifdef PLAIN_TERM
+ goto print_it;
+#endif
+
+#ifdef DOS_TERM
+ continue;
+#endif
+
+ }
+
+ buffer2[bufcount2 + 1] = colour_code_map(start_x + i, start_y + j);
+
+ if (start_x + i + 1 == you.x_pos && start_y + j + 1 == you.y_pos)
+ buffer2[bufcount2 + 1] = WHITE;
+
+ buffer2[bufcount2] = env.map[start_x + i][start_y + j];
+ bufcount2 += 2;
+
+#ifdef PLAIN_TERM
+
+ print_it:
+ // avoid line wrap
+ if (i == 79)
+ continue;
+
+ // newline
+ if (i == 0 && j > 0)
+ gotoxy( 1, j + 1 );
+
+ textcolor( buffer2[bufcount2 - 1] );
+ putch( buffer2[bufcount2 - 2] );
+#endif
+ }
+ }
+
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer2);
+#endif
+
+ _setcursortype(_NORMALCURSOR);
+ gotoxy(curs_x, curs_y);
+
+ gettything:
+ getty = getch();
+
+ if (spec_place[0] == 0 && getty != 0 && getty != '+' && getty != '-'
+ && getty != 'h' && getty != 'j' && getty != 'k' && getty != 'l'
+ && getty != 'y' && getty != 'u' && getty != 'b' && getty != 'n'
+#ifdef LINUX
+ && getty != 'H' && getty != 'J' && getty != 'K' && getty != 'L'
+ && getty != 'Y' && getty != 'U' && getty != 'B' && getty != 'N'
+#endif
+ && (getty < '0' || getty > '9'))
+ {
+ goto putty;
+ }
+
+ if (spec_place[0] == 1 && getty != 0 && getty != '+' && getty != '-'
+ && getty != 'h' && getty != 'j' && getty != 'k' && getty != 'l'
+ && getty != 'y' && getty != 'u' && getty != 'b' && getty != 'n'
+#ifdef LINUX
+ && getty != 'H' && getty != 'J' && getty != 'K' && getty != 'L'
+ && getty != 'Y' && getty != 'U' && getty != 'B' && getty != 'N'
+#endif
+ && getty != '.' && getty != 'S' && (getty < '0' || getty > '9'))
+ {
+ goto gettything;
+ }
+
+ if (getty == 0)
+ getty = getch();
+
+ switch (getty)
+ {
+ case 'b':
+ case '1':
+ move_x = -1;
+ move_y = 1;
+ break;
+
+ case 'j':
+ case '2':
+ move_y = 1;
+ move_x = 0;
+ break;
+
+ case 'u':
+ case '9':
+ move_x = 1;
+ move_y = -1;
+ break;
+
+ case 'k':
+ case '8':
+ move_y = -1;
+ move_x = 0;
+ break;
+
+ case 'y':
+ case '7':
+ move_y = -1;
+ move_x = -1;
+ break;
+
+ case 'h':
+ case '4':
+ move_x = -1;
+ move_y = 0;
+ break;
+
+ case 'n':
+ case '3':
+ move_y = 1;
+ move_x = 1;
+ break;
+
+ case 'l':
+ case '6':
+ move_x = 1;
+ move_y = 0;
+ break;
+
+#ifndef LINUX
+ // This is old DOS keypad support
+ case 'H':
+ move_y = -1;
+ move_x = 0;
+ break;
+ case 'P':
+ move_y = 1;
+ move_x = 0;
+ break;
+ case 'K':
+ move_x = -1;
+ move_y = 0;
+ break;
+ case 'M':
+ move_x = 1;
+ move_y = 0;
+ break;
+ case 'O':
+ move_x = -1;
+ move_y = 1;
+ break;
+ case 'I':
+ move_x = 1;
+ move_y = -1;
+ break;
+ case 'G':
+ move_y = -1;
+ move_x = -1;
+ break;
+ case 'Q':
+ move_y = 1;
+ move_x = 1;
+ break;
+
+#else
+
+ case 'B':
+ move_x = -10;
+ move_y = 10;
+ break;
+
+ case 'J':
+ move_y = 10;
+ move_x = 0;
+ break;
+
+ case 'U':
+ move_x = 10;
+ move_y = -10;
+ break;
+
+ case 'K':
+ move_y = -10;
+ move_x = 0;
+ break;
+
+ case 'Y':
+ move_y = -10;
+ move_x = -10;
+ break;
+
+ case 'H':
+ move_x = -10;
+ move_y = 0;
+ break;
+
+ case 'N':
+ move_y = 10;
+ move_x = 10;
+ break;
+
+ case 'L':
+ move_x = 10;
+ move_y = 0;
+ break;
+
+#endif
+
+ case '+':
+ move_y = 20;
+ move_x = 0;
+ break;
+ case '-':
+ move_y = -20;
+ move_x = 0;
+ break;
+ case '.':
+ case '\r':
+ case 'S':
+ spec_place[0] = start_x + curs_x;
+ spec_place[1] = start_y + curs_y;
+ goto putty;
+
+ default:
+ move_x = 0;
+ move_y = 0;
+ break;
+ }
+
+ if (curs_x + move_x < 1 || curs_x + move_x > 80)
+ move_x = 0;
+
+ curs_x += move_x;
+
+ if (num_lines < map_lines)
+ {
+ // Scrolling only happens when we don't have a large enough
+ // display to show the known map.
+ if (getty == '-' || getty == '+')
+ {
+ if (getty == '-')
+ screen_y -= 20;
+
+ if (screen_y <= min_y + half_screen)
+ screen_y = min_y + half_screen;
+
+ if (getty == '+')
+ screen_y += 20;
+
+ if (screen_y >= max_y - half_screen)
+ screen_y = max_y - half_screen;
+
+ goto put_screen;
+ }
+
+ if (curs_y + move_y < 1)
+ {
+ // screen_y += (curs_y + move_y) - 1;
+ screen_y += move_y;
+
+ if (screen_y < min_y + half_screen)
+ screen_y = min_y + half_screen;
+
+ move_y = 0;
+ }
+
+ if (curs_y + move_y > num_lines - 1)
+ {
+ // screen_y += (curs_y + move_y) - num_lines + 1;
+ screen_y += move_y;
+
+ if (screen_y > max_y - half_screen)
+ screen_y = max_y - half_screen;
+
+ move_y = 0;
+ }
+ }
+
+ if (curs_y + move_y < 1 || curs_y + move_y > num_lines)
+ move_y = 0;
+
+ curs_y += move_y;
+ goto put_screen;
+
+ putty:
+
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+
+ return;
+} // end show_map()
+
+
+void magic_mapping(int map_radius, int proportion)
+{
+ int i, j, k, l, empty_count;
+
+ if (map_radius > 50)
+ map_radius = 50;
+
+ for (i = you.x_pos - map_radius; i < you.x_pos + map_radius; i++)
+ {
+ for (j = you.y_pos - map_radius; j < you.y_pos + map_radius; j++)
+ {
+ if (random2(100) > proportion)
+ continue; // note that proportion can be over 100
+
+ if (i < 5 || j < 5 || i > (GXM - 5) || j > (GYM - 5))
+ continue;
+
+ if (env.map[i][j] == mapch2(grd[i + 1][j + 1]))
+ continue;
+
+ empty_count = 8;
+
+ if (grd[i][j] < DNGN_LAVA && grd[i][j] != DNGN_CLOSED_DOOR)
+ {
+ for (k = 0; k < 3; k++)
+ {
+ for (l = 0; l < 3; l++)
+ {
+ if (k == 1 && l == 1)
+ continue;
+
+ if (grd[i + k][j + l] <= 60
+ && grd[i + k][j + l] != DNGN_CLOSED_DOOR)
+ {
+ empty_count--;
+ }
+ }
+ }
+ }
+
+ if (empty_count > 0)
+ env.map[i][j] = mapch(grd[i + 1][j + 1]);
+ }
+ }
+} // end magic_mapping()
+
+
+/* mapchars 3 & 4 are for non-ibm char sets */
+unsigned char mapchar(unsigned char ldfk)
+{
+ unsigned char showed = 0;
+
+ switch (ldfk)
+ {
+ case DNGN_UNSEEN:
+ showed = 0;
+ break;
+
+ case DNGN_SECRET_DOOR:
+ case DNGN_ROCK_WALL:
+ case DNGN_PERMAROCK_WALL:
+ case DNGN_STONE_WALL:
+ case DNGN_METAL_WALL:
+ case DNGN_GREEN_CRYSTAL_WALL:
+ case DNGN_WAX_WALL:
+ showed = 176;
+ break;
+
+ case DNGN_CLOSED_DOOR:
+ showed = 206;
+ break;
+
+ case 20: // orcish idol
+ case 24: // ???
+ case 25: // ???
+ case DNGN_SILVER_STATUE:
+ case DNGN_GRANITE_STATUE:
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ showed = '8';
+ break;
+
+ case DNGN_LAVA_X:
+ case DNGN_WATER_X:
+ case DNGN_LAVA:
+ case DNGN_DEEP_WATER:
+ case DNGN_SHALLOW_WATER:
+ showed = 247;
+ break;
+
+ case DNGN_FLOOR:
+ case DNGN_UNDISCOVERED_TRAP:
+ showed = 250;
+ break;
+
+ //case 68: showed = '>'; break; // < (60)
+
+ case DNGN_OPEN_DOOR:
+ showed = 39;
+ break;
+
+ //case 72: showed = '<'; break;
+
+ case DNGN_TRAP_MECHANICAL:
+ case DNGN_TRAP_MAGICAL:
+ case DNGN_TRAP_III:
+ showed = '^';
+ break;
+
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ case DNGN_ROCK_STAIRS_DOWN:
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ showed = '>';
+ break;
+
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ case DNGN_ROCK_STAIRS_UP:
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ showed = '<';
+ break;
+
+ case DNGN_ENTER_HELL:
+ case DNGN_ENTER_LABYRINTH:
+ case DNGN_ENTER_SHOP:
+ case DNGN_ENTER_DIS:
+ case DNGN_ENTER_GEHENNA:
+ case DNGN_ENTER_COCYTUS:
+ case DNGN_ENTER_TARTARUS:
+ case DNGN_ENTER_ABYSS:
+ case DNGN_EXIT_ABYSS:
+ case DNGN_STONE_ARCH:
+ case DNGN_ENTER_PANDEMONIUM:
+ case DNGN_EXIT_PANDEMONIUM:
+ case DNGN_TRANSIT_PANDEMONIUM:
+ case DNGN_ENTER_ZOT:
+ case DNGN_RETURN_FROM_ZOT:
+ showed = 239;
+ break;
+
+ case DNGN_ALTAR_ZIN:
+ case DNGN_ALTAR_SHINING_ONE:
+ case DNGN_ALTAR_KIKUBAAQUDGHA:
+ case DNGN_ALTAR_YREDELEMNUL:
+ case DNGN_ALTAR_XOM:
+ case DNGN_ALTAR_VEHUMET:
+ case DNGN_ALTAR_OKAWARU:
+ case DNGN_ALTAR_MAKHLEB:
+ case DNGN_ALTAR_SIF_MUNA:
+ case DNGN_ALTAR_TROG:
+ case DNGN_ALTAR_NEMELEX_XOBEH:
+ case DNGN_ALTAR_ELYVILON:
+ showed = 220;
+ break;
+
+ case DNGN_BLUE_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_I:
+ case DNGN_SPARKLING_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_II:
+ case DNGN_DRY_FOUNTAIN_III:
+ case DNGN_DRY_FOUNTAIN_IV:
+ case DNGN_DRY_FOUNTAIN_V:
+ case DNGN_DRY_FOUNTAIN_VI:
+ case DNGN_DRY_FOUNTAIN_VII:
+ case DNGN_DRY_FOUNTAIN_VIII:
+ case DNGN_PERMADRY_FOUNTAIN:
+ showed = 159;
+ break;
+
+ default:
+ showed = 0;
+ break;
+ }
+
+ return showed;
+}
+
+
+unsigned char mapchar2(unsigned char ldfk)
+{
+ unsigned char showed = 0;
+
+ switch (ldfk)
+ {
+ case DNGN_UNSEEN:
+ showed = 0;
+ break;
+
+ case DNGN_SECRET_DOOR:
+ case DNGN_ROCK_WALL:
+ case DNGN_PERMAROCK_WALL:
+ case DNGN_STONE_WALL:
+ case DNGN_METAL_WALL:
+ case DNGN_GREEN_CRYSTAL_WALL:
+ case DNGN_WAX_WALL:
+ showed = 177;
+ break;
+
+ case DNGN_CLOSED_DOOR:
+ showed = 254;
+ break;
+
+ //case DNGN_LAVA_X: showed = 247; break; // deprecated? {dlb}
+ //case DNGN_WATER_X: showed = 247; break; // deprecated? {dlb}
+
+ case 20: // orcish idol
+ case 24: // ???
+ case 25: // ???
+ case DNGN_SILVER_STATUE:
+ case DNGN_GRANITE_STATUE:
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ showed = '8';
+ break;
+
+ case DNGN_LAVA:
+ case DNGN_DEEP_WATER:
+ case DNGN_SHALLOW_WATER:
+ showed = 247;
+ break;
+
+ case DNGN_FLOOR:
+ case DNGN_UNDISCOVERED_TRAP:
+ showed = 249;
+ break;
+
+ case 68:
+ showed = '>';
+ break; // <
+
+ case DNGN_OPEN_DOOR:
+ showed = 39;
+ break;
+
+ case 72:
+ showed = '<';
+ break; // <
+
+ case DNGN_TRAP_MECHANICAL:
+ case DNGN_TRAP_MAGICAL:
+ case DNGN_TRAP_III:
+ showed = '^';
+ break;
+
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ case DNGN_ROCK_STAIRS_DOWN:
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ showed = '>';
+ break;
+
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ case DNGN_ROCK_STAIRS_UP:
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ showed = '<';
+ break;
+
+ case DNGN_ENTER_HELL:
+ case DNGN_ENTER_LABYRINTH:
+ case DNGN_ENTER_SHOP:
+ case DNGN_ENTER_DIS:
+ case DNGN_ENTER_GEHENNA:
+ case DNGN_ENTER_COCYTUS:
+ case DNGN_ENTER_TARTARUS:
+ case DNGN_ENTER_ABYSS:
+ case DNGN_EXIT_ABYSS:
+ case DNGN_STONE_ARCH:
+ case DNGN_ENTER_PANDEMONIUM:
+ case DNGN_EXIT_PANDEMONIUM:
+ case DNGN_TRANSIT_PANDEMONIUM:
+ case DNGN_ENTER_ZOT:
+ case DNGN_RETURN_FROM_ZOT:
+ showed = 239;
+ break;
+
+ case DNGN_ALTAR_ZIN:
+ case DNGN_ALTAR_SHINING_ONE:
+ case DNGN_ALTAR_KIKUBAAQUDGHA:
+ case DNGN_ALTAR_YREDELEMNUL:
+ case DNGN_ALTAR_XOM:
+ case DNGN_ALTAR_VEHUMET:
+ case DNGN_ALTAR_OKAWARU:
+ case DNGN_ALTAR_MAKHLEB:
+ case DNGN_ALTAR_SIF_MUNA:
+ case DNGN_ALTAR_TROG:
+ case DNGN_ALTAR_NEMELEX_XOBEH:
+ case DNGN_ALTAR_ELYVILON:
+ showed = 220;
+ break;
+
+ case DNGN_BLUE_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_I:
+ case DNGN_SPARKLING_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_II:
+ case DNGN_DRY_FOUNTAIN_III:
+ case DNGN_DRY_FOUNTAIN_IV:
+ case DNGN_DRY_FOUNTAIN_V:
+ case DNGN_DRY_FOUNTAIN_VI:
+ case DNGN_DRY_FOUNTAIN_VII:
+ case DNGN_DRY_FOUNTAIN_VIII:
+ case DNGN_PERMADRY_FOUNTAIN:
+ showed = 159;
+ break;
+ default:
+ showed = 0;
+ break;
+ }
+
+ return showed;
+}
+
+
+// realize that this is simply a repackaged version of
+// stuff::see_grid() -- make certain they correlate {dlb}:
+bool mons_near(struct monsters *monster, unsigned int foe)
+{
+ // early out -- no foe!
+ if (foe == MHITNOT)
+ return (false);
+
+ if (foe == MHITYOU)
+ {
+ if (monster->x > you.x_pos - 9 && monster->x < you.x_pos + 9
+ && monster->y > you.y_pos - 9 && monster->y < you.y_pos + 9)
+ {
+ if (env.show[monster->x - you.x_pos + 9][monster->y - you.y_pos + 9])
+ return (true);
+ }
+ return (false);
+ }
+
+ // must be a monster
+ struct monsters *myFoe = &menv[foe];
+ if (myFoe->type >= 0)
+ {
+ if (monster->x > myFoe->x - 9 && monster->x < myFoe->x + 9
+ && monster->y > myFoe->y - 9 && monster->y < myFoe->y + 9)
+ {
+ return (true);
+ }
+ }
+
+ return (false);
+} // end mons_near()
+
+
+//---------------------------------------------------------------
+//
+// get_non_ibm_symbol
+//
+// Returns the character code and color for everything drawn
+// without the IBM graphics option.
+//
+//---------------------------------------------------------------
+static void get_non_ibm_symbol(unsigned int object, unsigned short *ch,
+ unsigned short *color)
+{
+ ASSERT(color != NULL);
+ ASSERT(ch != NULL);
+
+ switch (object)
+ {
+
+ case DNGN_UNSEEN:
+ *ch = 0;
+ break;
+
+ case DNGN_ROCK_WALL:
+ case DNGN_PERMAROCK_WALL:
+ *color = env.rock_colour;
+ *ch = '#';
+ break;
+
+ case DNGN_STONE_WALL:
+ if (player_in_branch( BRANCH_HALL_OF_ZOT ))
+ *color = env.rock_colour;
+ else
+ *color = LIGHTGREY;
+ *ch = '#';
+ break;
+
+ case DNGN_CLOSED_DOOR:
+ *ch = '+';
+ break;
+
+ case DNGN_METAL_WALL:
+ *ch = '#';
+ *color = CYAN;
+ break;
+
+ case DNGN_SECRET_DOOR:
+ *ch = '#';
+ *color = env.rock_colour;
+ break;
+
+ case DNGN_GREEN_CRYSTAL_WALL:
+ *ch = '#';
+ *color = GREEN;
+ break;
+
+ case DNGN_ORCISH_IDOL:
+ *ch = '8';
+ *color = DARKGREY;
+ break;
+
+ case DNGN_WAX_WALL:
+ *ch = '#';
+ *color = YELLOW;
+ break;
+
+ case DNGN_SILVER_STATUE:
+ *ch = '8';
+ *color = WHITE;
+ Visible_Statue[ STATUE_SILVER ] = 1;
+ break;
+
+ case DNGN_GRANITE_STATUE:
+ *ch = '8';
+ *color = LIGHTGREY;
+ break;
+
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ *ch = '8';
+ *color = LIGHTRED;
+ Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
+ break;
+
+ case DNGN_LAVA:
+ *ch = '{';
+ *color = RED;
+ break;
+
+ case DNGN_DEEP_WATER:
+ *ch = '{';
+ // this wavy thing also used for water elemental
+ // note that some monsters which use IBM graphics aren't set
+ // for this function - too tricky for now.
+ *color = BLUE;
+ break;
+
+ case DNGN_SHALLOW_WATER:
+ *color = CYAN;
+ *ch = '{';
+ break;
+
+ case DNGN_FLOOR:
+ *color = env.floor_colour;
+ *ch = '.';
+ break;
+
+ case DNGN_ENTER_HELL:
+ *color = RED;
+ *ch = '\\';
+ seen_other_thing(DNGN_ENTER_HELL);
+ break;
+
+ case DNGN_OPEN_DOOR:
+ *ch = '\'';
+ break;
+
+ case DNGN_BRANCH_STAIRS:
+ *color = BROWN;
+ *ch = '>';
+ break;
+
+ case DNGN_TRAP_MECHANICAL:
+ *color = 11;
+ *ch = '^';
+ break;
+
+ case DNGN_TRAP_MAGICAL:
+ *color = MAGENTA;
+ *ch = '^';
+ break;
+
+ case DNGN_TRAP_III:
+ *color = LIGHTGREY;
+ *ch = '^';
+ break;
+
+ case DNGN_UNDISCOVERED_TRAP:
+ *color = env.floor_colour;
+ *ch = '.';
+ break;
+
+ case DNGN_ENTER_SHOP:
+ *color = YELLOW;
+ *ch = '\\';
+ seen_other_thing(DNGN_ENTER_SHOP);
+ break;
+// if I change anything above here, must also change magic mapping!
+
+ case DNGN_ENTER_LABYRINTH:
+ *color = LIGHTGREY;
+ *ch = '\\';
+ seen_other_thing(DNGN_ENTER_LABYRINTH);
+ break;
+
+ case DNGN_ROCK_STAIRS_DOWN:
+ *color = BROWN; // ladder
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ *ch = '>';
+ break;
+
+ case DNGN_ROCK_STAIRS_UP:
+ *color = BROWN; // ladder
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ *ch = '<';
+ break;
+
+ case DNGN_ENTER_DIS:
+ *color = CYAN;
+ *ch = '\\';
+ break;
+
+ case DNGN_ENTER_GEHENNA:
+ *color = RED;
+ *ch = '\\';
+ break;
+
+ case DNGN_ENTER_COCYTUS:
+ *color = LIGHTCYAN;
+ *ch = '\\';
+ break;
+
+ case DNGN_ENTER_TARTARUS:
+ *color = DARKGREY;
+ *ch = '\\';
+ break;
+
+ case DNGN_ENTER_ABYSS:
+ *color = random2(16);
+ *ch = '\\';
+ seen_other_thing(DNGN_ENTER_ABYSS);
+ break;
+
+ case DNGN_EXIT_ABYSS:
+ *color = random2(16);
+ *ch = '\\';
+ break;
+
+ case DNGN_STONE_ARCH:
+ *color = LIGHTGREY;
+ *ch = '\\';
+ break;
+
+ case DNGN_ENTER_PANDEMONIUM:
+ *color = LIGHTBLUE;
+ *ch = '\\';
+ seen_other_thing(DNGN_ENTER_PANDEMONIUM);
+ break;
+
+ case DNGN_EXIT_PANDEMONIUM:
+ *color = LIGHTBLUE;
+ *ch = '\\';
+ break;
+
+ case DNGN_TRANSIT_PANDEMONIUM:
+ *color = LIGHTGREEN;
+ *ch = '\\';
+ break; // gate to other part of pandemonium
+
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ *color = YELLOW;
+ *ch = '>';
+ seen_staircase(object);
+ break;
+
+ case DNGN_ENTER_ZOT:
+ *color = MAGENTA;
+ *ch = '\\';
+ seen_staircase(object);
+ break;
+
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ *color = YELLOW;
+ *ch = '<';
+ break;
+
+ case DNGN_RETURN_FROM_ZOT:
+ *color = MAGENTA;
+ *ch = '\\';
+ break;
+
+ case DNGN_ALTAR_ZIN:
+ *color = WHITE;
+ *ch = '_';
+ seen_altar(GOD_ZIN);
+ break;
+
+ case DNGN_ALTAR_SHINING_ONE:
+ *color = YELLOW;
+ *ch = '_';
+ seen_altar(GOD_SHINING_ONE);
+ break;
+
+ case DNGN_ALTAR_KIKUBAAQUDGHA:
+ *color = DARKGREY;
+ *ch = '_';
+ seen_altar(GOD_KIKUBAAQUDGHA);
+ break;
+
+ case DNGN_ALTAR_YREDELEMNUL:
+ *color = DARKGREY;
+ if (one_chance_in(3))
+ *color = RED;
+ *ch = '_';
+ seen_altar(GOD_YREDELEMNUL);
+ break;
+
+ case DNGN_ALTAR_XOM:
+ *color = random_colour();
+ *ch = '_';
+ seen_altar(GOD_XOM);
+ break;
+
+ case DNGN_ALTAR_VEHUMET:
+ *color = LIGHTBLUE;
+ if (one_chance_in(3))
+ *color = LIGHTMAGENTA;
+ if (one_chance_in(3))
+ *color = LIGHTRED;
+ *ch = '_';
+ seen_altar(GOD_VEHUMET);
+ break;
+
+ case DNGN_ALTAR_OKAWARU:
+ *color = CYAN;
+ *ch = '_';
+ seen_altar(GOD_OKAWARU);
+ break;
+
+ case DNGN_ALTAR_MAKHLEB:
+ *color = RED;
+ if (one_chance_in(3))
+ *color = LIGHTRED;
+ if (one_chance_in(3))
+ *color = YELLOW;
+ *ch = '_';
+ seen_altar(GOD_MAKHLEB);
+ break;
+
+ case DNGN_ALTAR_SIF_MUNA:
+ *color = BLUE;
+ *ch = '_';
+ seen_altar(GOD_SIF_MUNA);
+ break;
+
+ case DNGN_ALTAR_TROG:
+ *color = RED;
+ *ch = '_';
+ seen_altar(GOD_TROG);
+ break;
+
+ case DNGN_ALTAR_NEMELEX_XOBEH:
+ *color = LIGHTMAGENTA;
+ *ch = '_';
+ seen_altar(GOD_NEMELEX_XOBEH);
+ break;
+
+ case DNGN_ALTAR_ELYVILON:
+ *color = LIGHTGREY;
+ *ch = '_';
+ seen_altar(GOD_ELYVILON);
+ break;
+
+ case DNGN_BLUE_FOUNTAIN:
+ *color = BLUE;
+ *ch = '}';
+ break;
+
+ case DNGN_SPARKLING_FOUNTAIN:
+ *color = LIGHTBLUE;
+ *ch = '}';
+ break;
+
+ case DNGN_DRY_FOUNTAIN_I:
+ case DNGN_DRY_FOUNTAIN_II:
+ case DNGN_PERMADRY_FOUNTAIN:
+ *color = LIGHTGREY;
+ *ch = '}';
+ break;
+
+ case 256:
+ *ch = '0';
+ break;
+
+ case 257:
+ *color = CYAN;
+ *ch = '~';
+ break; /* Invis creature walking through water */
+
+ case 258:
+ *ch = ')';
+ break; // weapon )
+
+ case 259:
+ *ch = '[';
+ break; // armour [
+
+ case 260:
+ *ch = '/';
+ break; // wands, etc.
+
+ case 261:
+ *ch = '%';
+ break; // food
+
+ case 262:
+ *ch = '+';
+ break; // books +
+
+ case 263:
+ *ch = '?';
+ break; // scroll ?
+
+ case 264:
+ *ch = '=';
+ break; // ring = etc
+
+ case 265:
+ *ch = '!';
+ break; // potions !
+
+ case 266:
+ *ch = '(';
+ break; // stones
+
+ case 267:
+ *ch = ':';
+ break; // book +
+
+ case 268:
+ *ch = '%';
+ break; // corpses part 1
+
+ case 269:
+ *ch = '|';
+ break; // magical staves
+
+ case 270:
+ *ch = '}';
+ break; // gems
+
+ case 271:
+ *ch = '%';
+ break; // don't know ?
+
+ case 272:
+ *ch = '$';
+ break; // $ gold
+
+ case 273:
+ *ch = '"';
+ break; // amulet
+
+ default:
+ int mnr = object;
+ *ch = ((mnr >= 297) ? mons_char(mnr - 297) : object); // yeah
+ break;
+ }
+}
+
+
+/*
+ This is the viewwindow function for computers without IBM graphic displays.
+ It is activated by a command line argument, which sets a function pointer.
+ */
+void viewwindow3(char draw_it, bool do_updates)
+{
+ int bufcount = 0;
+ FixedVector < unsigned short, 1500 > buffy; //[800]; //392];
+
+ unsigned short ch, color;
+
+ int count_x, count_y;
+
+ losight(env.show, grd, you.x_pos, you.y_pos);
+
+ for (count_x = 0; count_x < 18; count_x++)
+ {
+ for (count_y = 0; count_y < 18; count_y++)
+ {
+ env.show_col[count_x][count_y] = LIGHTGREY;
+ show_backup[count_x][count_y] = 0;
+ }
+ }
+
+ item();
+ cloud_grid();
+ monster_grid(do_updates);
+ bufcount = 0;
+
+ if (draw_it == 1)
+ {
+ _setcursortype(_NOCURSOR);
+ for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
+ {
+ bufcount += 16;
+
+ for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
+ {
+ color = env.show_col[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9];
+
+ if (count_x == you.x_pos && count_y == you.y_pos)
+ {
+ ch = your_sign;
+
+ if (player_is_swimming())
+ {
+ color = (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
+ ? BLUE : CYAN;
+ }
+ else
+ {
+ color = your_colour;
+ }
+ }
+ else
+ {
+ unsigned int object = env.show[count_x - you.x_pos + 9]
+ [count_y - you.y_pos + 9];
+
+ get_non_ibm_symbol(object, &ch, &color);
+ }
+
+ buffy[bufcount] = ch; //showed;
+ buffy[bufcount + 1] = color;
+ bufcount += 2;
+ }
+
+ bufcount += 16;
+ }
+
+ bufcount = 0;
+
+ if (you.level_type != LEVEL_LABYRINTH
+ && you.level_type != LEVEL_ABYSS)
+ {
+ for (count_y = 0; count_y < 17; count_y++)
+ {
+ bufcount += 16;
+ for (count_x = 0; count_x < 17; count_x++)
+ {
+ if (buffy[bufcount] != 0
+ && (count_x + you.x_pos - 9) >= 0
+ && (count_y + you.y_pos - 9) >= 0)
+ {
+ env.map[count_x + you.x_pos - 9]
+ [count_y + you.y_pos - 9] = buffy[bufcount];
+ }
+
+ if (Options.clean_map == 1
+ && show_backup[count_x + 1][count_y + 1] != 0
+ && (count_x + you.x_pos - 9) >= 0
+ && (count_y + you.y_pos - 9) >= 0)
+ {
+ get_non_ibm_symbol( show_backup[count_x + 1]
+ [count_y + 1],
+ &ch, &color );
+ env.map[count_x + you.x_pos - 9]
+ [count_y + you.y_pos - 9] = ch;
+ }
+ bufcount += 2;
+ }
+ bufcount += 16;
+ }
+ }
+
+ bufcount = 0;
+
+ for (count_y = 0; count_y < 17; count_y++)
+ {
+ for (count_x = 0; count_x < 33; count_x++)
+ {
+ if (count_x + you.x_pos - 17 < 3
+ || count_y + you.y_pos - 9 < 3
+ || count_x + you.x_pos - 14 > (GXM - 3)
+ || count_y + you.y_pos - 9 > (GYM - 3))
+ {
+ buffy[bufcount] = 0;
+ bufcount++;
+ buffy[bufcount] = 0;
+ bufcount++;
+ continue;
+ }
+
+ if (count_x >= 8 && count_x <= 24 && count_y >= 0
+ && count_y <= 16 && buffy[bufcount] != 0)
+ {
+ bufcount += 2;
+ continue;
+ }
+
+ buffy[bufcount] = env.map[count_x + you.x_pos - 17]
+ [count_y + you.y_pos - 9];
+
+ buffy[bufcount + 1] = DARKGREY;
+
+ if (Options.colour_map)
+ {
+ if (env.map[count_x + you.x_pos - 16]
+ [count_y + you.y_pos - 8] != 0)
+ {
+ buffy[bufcount + 1]
+ = colour_code_map( count_x + you.x_pos - 17,
+ count_y + you.y_pos - 9 );
+ }
+ }
+
+ bufcount += 2;
+ }
+ }
+
+ if (you.berserker)
+ {
+ for (count_x = 1; count_x < 1400; count_x += 2)
+ {
+ if (buffy[count_x] != DARKGREY)
+ buffy[count_x] = RED;
+ }
+ }
+
+ if (show_green != BLACK)
+ {
+ for (count_x = 1; count_x < 1400; count_x += 2)
+ {
+ if (buffy[count_x] != DARKGREY)
+ buffy[count_x] = show_green;
+ }
+
+ show_green = ((you.special_wield == SPWLD_SHADOW) ? DARKGREY
+ : BLACK);
+ }
+
+#ifdef DOS_TERM
+ puttext(2, 1, 34, 17, buffy.buffer());
+#endif
+
+#ifdef PLAIN_TERM
+ gotoxy(2, 1);
+ bufcount = 0;
+
+ if (you.running == 0) // this line is purely optional
+ {
+ for (count_x = 0; count_x < 1120; count_x += 2) // 1056
+ {
+ textcolor(buffy[count_x + 1]);
+ putch(buffy[count_x]);
+
+ if (count_x % 66 == 64 && count_x > 0)
+#ifdef DOS_TERM
+ cprintf(EOL " ");
+#endif
+
+#ifdef PLAIN_TERM
+ gotoxy(2, wherey() + 1);
+#endif
+ }
+ }
+#endif
+ _setcursortype(_NORMALCURSOR);
+ } // end of (if brek...)
+} // end viewwindow3()
+
+
+unsigned char mapchar3(unsigned char ldfk)
+{
+ unsigned char showed = 0;
+
+ switch (ldfk)
+ {
+ case DNGN_UNSEEN:
+ showed = 0;
+ break;
+
+ case DNGN_SECRET_DOOR:
+ case DNGN_ROCK_WALL:
+ case DNGN_PERMAROCK_WALL:
+ case DNGN_STONE_WALL:
+ case DNGN_METAL_WALL:
+ case DNGN_GREEN_CRYSTAL_WALL:
+ case DNGN_WAX_WALL:
+ showed = '*';
+ break;
+
+ case DNGN_CLOSED_DOOR:
+ showed = '+';
+ break;
+
+ case 20: // orcish idol
+ case 24: // ???
+ case 25: // ???
+ case DNGN_SILVER_STATUE:
+ case DNGN_GRANITE_STATUE:
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ showed = '8';
+ break;
+
+ case DNGN_LAVA_X:
+ case DNGN_WATER_X:
+ case DNGN_LAVA:
+ case DNGN_DEEP_WATER:
+ case DNGN_SHALLOW_WATER:
+ showed = '{';
+ break;
+
+ case DNGN_FLOOR:
+ case DNGN_UNDISCOVERED_TRAP:
+ showed = ',';
+ break;
+
+ //case 68: showed = '>'; break; // < (60)
+
+ case DNGN_OPEN_DOOR:
+ showed = 39;
+ break; // open door
+
+ //case 72: showed = '<'; break;
+
+ case DNGN_TRAP_MECHANICAL:
+ case DNGN_TRAP_MAGICAL:
+ case DNGN_TRAP_III:
+ showed = '^';
+ break;
+
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ case DNGN_ROCK_STAIRS_DOWN:
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ showed = '>';
+ break;
+
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ case DNGN_ROCK_STAIRS_UP:
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ showed = '<';
+ break;
+
+ case DNGN_ENTER_HELL:
+ case DNGN_ENTER_LABYRINTH:
+ case DNGN_ENTER_SHOP:
+ case DNGN_ENTER_DIS:
+ case DNGN_ENTER_GEHENNA:
+ case DNGN_ENTER_COCYTUS:
+ case DNGN_ENTER_TARTARUS:
+ case DNGN_ENTER_ABYSS:
+ case DNGN_EXIT_ABYSS:
+ case DNGN_STONE_ARCH:
+ case DNGN_ENTER_PANDEMONIUM:
+ case DNGN_EXIT_PANDEMONIUM:
+ case DNGN_TRANSIT_PANDEMONIUM:
+ case DNGN_ENTER_ZOT:
+ case DNGN_RETURN_FROM_ZOT:
+ showed = '\\';
+ break;
+
+ case DNGN_ALTAR_ZIN:
+ case DNGN_ALTAR_SHINING_ONE:
+ case DNGN_ALTAR_KIKUBAAQUDGHA:
+ case DNGN_ALTAR_YREDELEMNUL:
+ case DNGN_ALTAR_XOM:
+ case DNGN_ALTAR_VEHUMET:
+ case DNGN_ALTAR_OKAWARU:
+ case DNGN_ALTAR_MAKHLEB:
+ case DNGN_ALTAR_SIF_MUNA:
+ case DNGN_ALTAR_TROG:
+ case DNGN_ALTAR_NEMELEX_XOBEH:
+ case DNGN_ALTAR_ELYVILON:
+ showed = '_';
+ break;
+
+ case DNGN_BLUE_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_I:
+ case DNGN_SPARKLING_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_II:
+ case DNGN_DRY_FOUNTAIN_III:
+ case DNGN_DRY_FOUNTAIN_IV:
+ case DNGN_DRY_FOUNTAIN_V:
+ case DNGN_DRY_FOUNTAIN_VI:
+ case DNGN_DRY_FOUNTAIN_VII:
+ case DNGN_DRY_FOUNTAIN_VIII:
+ case DNGN_PERMADRY_FOUNTAIN:
+ showed = '}';
+ break;
+
+ default:
+ showed = 0;
+ break;
+ }
+
+ return showed;
+}
+
+
+unsigned char mapchar4(unsigned char ldfk)
+{
+ unsigned char showed = 0;
+
+ switch (ldfk)
+ {
+ case DNGN_UNSEEN:
+ showed = 0;
+ break;
+
+ case DNGN_CLOSED_DOOR:
+ showed = '+';
+ break;
+
+ case DNGN_SECRET_DOOR:
+ case DNGN_ROCK_WALL:
+ case DNGN_PERMAROCK_WALL:
+ case DNGN_STONE_WALL:
+ case DNGN_METAL_WALL:
+ case DNGN_GREEN_CRYSTAL_WALL:
+ case DNGN_WAX_WALL:
+ showed = '#';
+ break;
+
+ case 20: // orcish idol
+ case 24: // ???
+ case 25: // ???
+ case DNGN_SILVER_STATUE:
+ case DNGN_GRANITE_STATUE:
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ showed = '8';
+ break;
+
+ case DNGN_LAVA_X:
+ case DNGN_WATER_X:
+ case DNGN_LAVA:
+ case DNGN_DEEP_WATER:
+ case DNGN_SHALLOW_WATER:
+ showed = '{';
+ break;
+
+ case DNGN_FLOOR:
+ case DNGN_UNDISCOVERED_TRAP:
+ showed = '.';
+ break;
+
+ case 68:
+ showed = '>'; // <
+ break;
+
+ case DNGN_OPEN_DOOR:
+ showed = 39;
+ break;
+
+ case 72:
+ showed = '<';
+ break;
+
+ case DNGN_TRAP_MECHANICAL:
+ case DNGN_TRAP_MAGICAL:
+ case DNGN_TRAP_III:
+ showed = '^';
+ break;
+
+ case DNGN_STONE_STAIRS_DOWN_I:
+ case DNGN_STONE_STAIRS_DOWN_II:
+ case DNGN_STONE_STAIRS_DOWN_III:
+ case DNGN_ROCK_STAIRS_DOWN:
+ case DNGN_ENTER_ORCISH_MINES:
+ case DNGN_ENTER_HIVE:
+ case DNGN_ENTER_LAIR:
+ case DNGN_ENTER_SLIME_PITS:
+ case DNGN_ENTER_VAULTS:
+ case DNGN_ENTER_CRYPT:
+ case DNGN_ENTER_HALL_OF_BLADES:
+ case DNGN_ENTER_TEMPLE:
+ case DNGN_ENTER_SNAKE_PIT:
+ case DNGN_ENTER_ELVEN_HALLS:
+ case DNGN_ENTER_TOMB:
+ case DNGN_ENTER_SWAMP:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ showed = '>';
+ break;
+
+ case DNGN_STONE_STAIRS_UP_I:
+ case DNGN_STONE_STAIRS_UP_II:
+ case DNGN_STONE_STAIRS_UP_III:
+ case DNGN_ROCK_STAIRS_UP:
+ case DNGN_RETURN_FROM_ORCISH_MINES:
+ case DNGN_RETURN_FROM_HIVE:
+ case DNGN_RETURN_FROM_LAIR:
+ case DNGN_RETURN_FROM_SLIME_PITS:
+ case DNGN_RETURN_FROM_VAULTS:
+ case DNGN_RETURN_FROM_CRYPT:
+ case DNGN_RETURN_FROM_HALL_OF_BLADES:
+ case DNGN_RETURN_FROM_TEMPLE:
+ case DNGN_RETURN_FROM_SNAKE_PIT:
+ case DNGN_RETURN_FROM_ELVEN_HALLS:
+ case DNGN_RETURN_FROM_TOMB:
+ case DNGN_RETURN_FROM_SWAMP:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ showed = '<';
+ break;
+
+ case DNGN_ENTER_HELL:
+ case DNGN_ENTER_LABYRINTH:
+ case DNGN_ENTER_SHOP:
+ case DNGN_ENTER_DIS:
+ case DNGN_ENTER_GEHENNA:
+ case DNGN_ENTER_COCYTUS:
+ case DNGN_ENTER_TARTARUS:
+ case DNGN_ENTER_ABYSS:
+ case DNGN_EXIT_ABYSS:
+ case DNGN_STONE_ARCH:
+ case DNGN_ENTER_PANDEMONIUM:
+ case DNGN_EXIT_PANDEMONIUM:
+ case DNGN_TRANSIT_PANDEMONIUM:
+ case DNGN_ENTER_ZOT:
+ case DNGN_RETURN_FROM_ZOT:
+ showed = '\\';
+ break;
+
+ case DNGN_ALTAR_ZIN:
+ case DNGN_ALTAR_SHINING_ONE:
+ case DNGN_ALTAR_KIKUBAAQUDGHA:
+ case DNGN_ALTAR_YREDELEMNUL:
+ case DNGN_ALTAR_XOM:
+ case DNGN_ALTAR_VEHUMET:
+ case DNGN_ALTAR_OKAWARU:
+ case DNGN_ALTAR_MAKHLEB:
+ case DNGN_ALTAR_SIF_MUNA:
+ case DNGN_ALTAR_TROG:
+ case DNGN_ALTAR_NEMELEX_XOBEH:
+ case DNGN_ALTAR_ELYVILON:
+ showed = '_';
+ break;
+
+ case DNGN_BLUE_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_I:
+ case DNGN_SPARKLING_FOUNTAIN:
+ case DNGN_DRY_FOUNTAIN_II:
+ case DNGN_DRY_FOUNTAIN_III:
+ case DNGN_DRY_FOUNTAIN_IV:
+ case DNGN_DRY_FOUNTAIN_V:
+ case DNGN_DRY_FOUNTAIN_VI:
+ case DNGN_DRY_FOUNTAIN_VII:
+ case DNGN_DRY_FOUNTAIN_VIII:
+ case DNGN_PERMADRY_FOUNTAIN:
+ showed = '}';
+ break;
+
+ default:
+ showed = 0;
+ break;
+ }
+
+ return showed;
+}