From 673bdae75485d14f759af597c3c62b99601f9a43 Mon Sep 17 00:00:00 2001 From: peterb12 Date: Thu, 21 Jul 2005 02:34:44 +0000 Subject: Initial revision git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3 c06c8d41-db1a-0410-9941-cceddc491573 --- trunk/source/direct.cc | 1195 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1195 insertions(+) create mode 100644 trunk/source/direct.cc (limited to 'trunk/source/direct.cc') diff --git a/trunk/source/direct.cc b/trunk/source/direct.cc new file mode 100644 index 0000000000..3284ce7413 --- /dev/null +++ b/trunk/source/direct.cc @@ -0,0 +1,1195 @@ +/* + * File: direct.cc + * Summary: Functions used when picking squares. + * Written by: Linley Henzell + * + * Change History (most recent first): + * + * <5> 01/08/01 GDL complete rewrite of direction() + * <4> 11/23/99 LRH Looking at monsters now + * displays more info + * <3> 5/12/99 BWR changes to allow for space selection of target. + * CR, ESC, and 't' in targeting. + * <2> 5/09/99 JDJ look_around no longer prints a prompt. + * <1> -/--/-- LRH Created + */ + +#include "AppHdr.h" +#include "direct.h" + +#include +#include +#include + +#ifdef DOS +#include +#endif + +#include "externs.h" + +#include "debug.h" +#include "describe.h" +#include "itemname.h" +#include "monstuff.h" +#include "mon-util.h" +#include "player.h" +#include "shopping.h" +#include "stuff.h" +#include "spells4.h" +#include "view.h" + +#ifdef USE_MACROS +#include "macro.h" +#endif + +// x and y offsets in the following order: +// SW, S, SE, W, E, NW, N, NE +static const char xcomp[9] = { -1, 0, 1, -1, 0, 1, -1, 0, 1 }; +static const char ycomp[9] = { 1, 1, 1, 0, 0, 0, -1, -1, -1 }; +static const char dirchars[19] = { "b1j2n3h4.5l6y7k8u9" }; +static const char DOSidiocy[10] = { "OPQKSMGHI" }; +static const char *aim_prompt = "Aim (move cursor or -/+/=, change mode with CTRL-F, select with . or >)"; + +static void describe_cell(int mx, int my); +static char mons_find( unsigned char xps, unsigned char yps, + FixedVector &mfp, char direction, + int mode = TARG_ANY ); + +//--------------------------------------------------------------- +// +// direction +// +// input: restricts : DIR_NONE accepts keypad dir or targetting +// DIR_TARGET must use targetting. +// DIR_DIR must use keypad direction +// +// +// outputs: dist structure: +// +// isValid a valid target or direction was chosen +// isCancel player hit 'escape' +// isTarget targetting was used +// tx,ty target x,y or logical beam extension to +// edge of map if keypad direction used. +// dx,dy direction delta if keypad used {-1,0,1} +// +// SYNOPSIS: +// +// gets a direction, or any of the follwing: +// +// * go to targetting mode +// +,= go to targetting mode, next monster +// - " , prev monster +// t,p auto-select previous target +// +// +// targetting mode is handled by look_around() +//--------------------------------------------------------------- +void direction( struct dist &moves, int restrict, int mode ) +{ + bool dirChosen = false; + bool targChosen = false; + int dir = 0; + + // init + moves.isValid = false; + moves.isTarget = false; + moves.isMe = false; + moves.isCancel = false; + moves.dx = moves.dy = 0; + moves.tx = moves.ty = 0; + + // XXX. this is ALWAYS in relation to the player. But a bit of a hack + // nonetheless! --GDL + gotoxy( 18, 9 ); + + int keyin = getch(); + + if (keyin == 0) // DOS idiocy (emulated by win32 console) + { + keyin = getch(); // grrr. + if (keyin == '*') + { + targChosen = true; + dir = 0; + } + else + { + if (strchr(DOSidiocy, keyin) == NULL) + return; + dirChosen = true; + dir = (int)(strchr(DOSidiocy, keyin) - DOSidiocy); + } + } + else + { + if (strchr( dirchars, keyin ) != NULL) + { + dirChosen = true; + dir = (int)(strchr(dirchars, keyin) - dirchars) / 2; + } + else + { + switch (keyin) + { + case CONTROL('F'): + mode = (mode + 1) % TARG_NUM_MODES; + + snprintf( info, INFO_SIZE, "Targeting mode is now: %s", + (mode == TARG_ANY) ? "any" : + (mode == TARG_ENEMY) ? "enemies" + : "friends" ); + + mpr( info ); + + targChosen = true; + dir = 0; + break; + + case '-': + targChosen = true; + dir = -1; + break; + + case '*': + targChosen = true; + dir = 0; + break; + + case '+': + case '=': + targChosen = true; + dir = 1; + break; + + case 't': + case 'p': + targChosen = true; + dir = 2; + break; + + case ESCAPE: + moves.isCancel = true; + return; + + default: + break; + } + } + } + + // at this point, we know exactly the input - validate + if (!(targChosen || dirChosen) || (targChosen && restrict == DIR_DIR)) + { + mpr("What an unusual direction."); + return; + } + + // special case: they typed a dir key, but they're in target-only mode + if (dirChosen && restrict == DIR_TARGET) + { + mpr(aim_prompt); + look_around( moves, false, dir, mode ); + return; + } + + if (targChosen) + { + if (dir < 2) + { + mpr(aim_prompt); + moves.prev_target = dir; + look_around( moves, false, -1, mode ); + if (moves.prev_target != -1) // -1 means they pressed 'p' + return; + } + + // chose to aim at previous target. do we have one? + if (you.prev_targ == MHITNOT || you.prev_targ == MHITYOU) + { + mpr("You haven't got a target."); + return; + } + + // we have a valid previous target (maybe) + struct monsters *montarget = &menv[you.prev_targ]; + + if (!mons_near(montarget) || !player_monster_visible( montarget )) + { + mpr("You can't see that creature any more."); + return; + } + else + { + moves.isValid = true; + moves.isTarget = true; + moves.tx = montarget->x; + moves.ty = montarget->y; + } + return; + } + + // at this point, we have a direction, and direction is allowed. + moves.isValid = true; + moves.isTarget = false; + moves.dx = xcomp[dir]; + moves.dy = ycomp[dir]; + if (xcomp[dir] == 0 && ycomp[dir] == 0) + moves.isMe = true; + + // now the tricky bit - extend the target x,y out to map edge. + int mx, my; + mx = my = 0; + + if (moves.dx > 0) + mx = (GXM - 1) - you.x_pos; + if (moves.dx < 0) + mx = you.x_pos; + + if (moves.dy > 0) + my = (GYM - 1) - you.y_pos; + if (moves.dy < 0) + my = you.y_pos; + + if (!(mx == 0 || my == 0)) + { + if (mx < my) + my = mx; + else + mx = my; + } + moves.tx = you.x_pos + moves.dx * mx; + moves.ty = you.y_pos + moves.dy * my; +} + +//--------------------------------------------------------------- +// +// look_around +// +// Accessible by the x key and when using cursor aiming. Lets you +// find out what symbols mean, and is the way to access monster +// descriptions. +// +// input: dist.prev_target : -1 is last monster +// 0 is no monster selected +// 1 is next monster +// +// input: first_move is -1 if no initial cursor move, otherwise +// make 1 move in that direction. +// +// +// output: if dist.prev_target is -1 on OUTPUT, it means that +// player selected 'p' ot 't' for last targetted monster. +// +// otherwise, usual dist fields are filled in (dx and dy are +// always zero coming back from this function) +// +//--------------------------------------------------------------- + +void look_around(struct dist &moves, bool justLooking, int first_move, int mode) +{ + int keyin = 0; + bool dirChosen = false; + bool targChosen = false; + int dir = 0; + int cx = 17; + int cy = 9; + int newcx, newcy; + int mx, my; // actual map x,y (scratch) + int mid; // monster id (scratch) + FixedVector < char, 2 > monsfind_pos; + + monsfind_pos[0] = you.x_pos; + monsfind_pos[1] = you.y_pos; + + message_current_target(); + + // setup initial keystroke + if (first_move >= 0) + keyin = (int)'1' + first_move; + if (moves.prev_target == -1) + keyin = '-'; + if (moves.prev_target == 1) + keyin = '+'; + // reset + moves.prev_target = 0; + + // loop until some exit criteria reached + while(true) + { + dirChosen = false; + targChosen = false; + newcx = cx; + newcy = cy; + + // move cursor to current position + gotoxy(cx+1, cy); + + if (keyin == 0) + keyin = getch(); + + // DOS idiocy + if (keyin == 0) + { + // get the extended key + keyin = getch(); + + // look for CR - change to '5' to indicate selection + if (keyin == 13) + keyin = 'S'; + + if (strchr(DOSidiocy, keyin) == NULL) + break; + dirChosen = true; + dir = (int)(strchr(DOSidiocy, keyin) - DOSidiocy); + } + else + { + if (strchr(dirchars, keyin) != NULL) + { + dirChosen = true; + dir = (int)(strchr(dirchars, keyin) - dirchars) / 2; + } + else + { + // handle non-directional keys + switch (keyin) + { + case CONTROL('F'): + mode = (mode + 1) % TARG_NUM_MODES; + + snprintf( info, INFO_SIZE, "Targeting mode is now: %s", + (mode == TARG_ANY) ? "any" : + (mode == TARG_ENEMY) ? "enemies" + : "friends" ); + + mpr( info ); + targChosen = true; + break; + + case '-': + if (mons_find( cx, cy, monsfind_pos, -1, mode ) == 0) + flush_input_buffer( FLUSH_ON_FAILURE ); + else + { + newcx = monsfind_pos[0]; + newcy = monsfind_pos[1]; + } + targChosen = true; + break; + + case '+': + case '=': + if (mons_find( cx, cy, monsfind_pos, 1, mode ) == 0) + flush_input_buffer( FLUSH_ON_FAILURE ); + else + { + newcx = monsfind_pos[0]; + newcy = monsfind_pos[1]; + } + targChosen = true; + break; + + case 't': + case 'p': + moves.prev_target = -1; + break; + + case '?': + targChosen = true; + mx = you.x_pos + cx - 17; + my = you.y_pos + cy - 9; + mid = mgrd[mx][my]; + + if (mid == NON_MONSTER) + break; + +#if (!DEBUG_DIAGNOSTICS) + if (!player_monster_visible( &menv[mid] )) + break; +#endif + + describe_monsters( menv[ mid ].type, mid ); + redraw_screen(); + mesclr( true ); + // describe the cell again. + describe_cell(you.x_pos + cx - 17, you.y_pos + cy - 9); + break; + + case '\r': + case '\n': + case '>': + case ' ': + case '.': + dirChosen = true; + dir = 4; + break; + + case ESCAPE: + moves.isCancel = true; + mesclr( true ); + return; + + default: + break; + } + } + } + + // now we have parsed the input character completely. Reset & Evaluate: + keyin = 0; + if (!targChosen && !dirChosen) + break; + + // check for SELECTION + if (dirChosen && dir == 4) + { + // RULE: cannot target what you cannot see + if (env.show[cx - 8][cy] == 0 && !(cx == 17 && cy == 9)) + { + if (!justLooking) + mpr("Sorry, you can't target what you can't see."); + return; + } + + moves.isValid = true; + moves.isTarget = true; + moves.tx = you.x_pos + cx - 17; + moves.ty = you.y_pos + cy - 9; + + if (moves.tx == you.x_pos && moves.ty == you.y_pos) + moves.isMe = true; + else + { + // try to set you.previous target + mx = you.x_pos + cx - 17; + my = you.y_pos + cy - 9; + mid = mgrd[mx][my]; + + if (mid == NON_MONSTER) + break; + + if (!player_monster_visible( &(menv[mid]) )) + break; + + you.prev_targ = mid; + } + break; + } + + // check for MOVE + if (dirChosen) + { + newcx = cx + xcomp[dir]; + newcy = cy + ycomp[dir]; + } + + // bounds check for newcx, newcy + if (newcx < 9) newcx = 9; + if (newcx > 25) newcx = 25; + if (newcy < 1) newcy = 1; + if (newcy > 17) newcy = 17; + + // no-op if the cursor doesn't move. + if (newcx == cx && newcy == cy) + continue; + + // CURSOR MOVED - describe new cell. + cx = newcx; + cy = newcy; + mesclr( true ); + if (env.show[cx - 8][cy] == 0 && !(cx == 17 && cy == 9)) + { + mpr("You can't see that place."); + continue; + } + describe_cell(you.x_pos + cx - 17, you.y_pos + cy - 9); + } // end WHILE + + mesclr( true ); +} // end look_around() + +//--------------------------------------------------------------- +// +// mons_find +// +// Finds the next monster (moving in a spiral outwards from the +// player, so closer monsters are chosen first; starts to player's +// left) and puts its coordinates in mfp. Returns 1 if it found +// a monster, zero otherwise. If direction is -1, goes backwards. +// +//--------------------------------------------------------------- +static char mons_find( unsigned char xps, unsigned char yps, + FixedVector &mfp, char direction, int mode ) +{ + unsigned char temp_xps = xps; + unsigned char temp_yps = yps; + char x_change = 0; + char y_change = 0; + + int i, j; + + if (direction == 1 && temp_xps == 9 && temp_yps == 17) + return (0); // end of spiral + + while (temp_xps >= 8 && temp_xps <= 25 && temp_yps <= 17) // yps always >= 0 + { + if (direction == -1 && temp_xps == 17 && temp_yps == 9) + return (0); // can't go backwards from you + + if (direction == 1) + { + if (temp_xps == 8) + { + x_change = 0; + y_change = -1; + } + else if (temp_xps - 17 == 0 && temp_yps - 9 == 0) + { + x_change = -1; + y_change = 0; + } + else if (abs(temp_xps - 17) <= abs(temp_yps - 9)) + { + if (temp_xps - 17 >= 0 && temp_yps - 9 <= 0) + { + if (abs(temp_xps - 17) > abs(temp_yps - 9 + 1)) + { + x_change = 0; + y_change = -1; + if (temp_xps - 17 > 0) + y_change = 1; + goto finished_spiralling; + } + } + x_change = -1; + if (temp_yps - 9 < 0) + x_change = 1; + y_change = 0; + } + else + { + x_change = 0; + y_change = -1; + if (temp_xps - 17 > 0) + y_change = 1; + } + } // end if (direction == 1) + else + { + /* + This part checks all eight surrounding squares to find the + one that leads on to the present square. + */ + for (i = -1; i < 2; i++) + { + for (j = -1; j < 2; j++) + { + if (i == 0 && j == 0) + continue; + + if (temp_xps + i == 8) + { + x_change = 0; + y_change = -1; + } + else if (temp_xps + i - 17 == 0 && temp_yps + j - 9 == 0) + { + x_change = -1; + y_change = 0; + } + else if (abs(temp_xps + i - 17) <= abs(temp_yps + j - 9)) + { + const int xi = temp_xps + i - 17; + const int yj = temp_yps + j - 9; + + if (xi >= 0 && yj <= 0) + { + if (abs(xi) > abs(yj + 1)) + { + x_change = 0; + y_change = -1; + if (xi > 0) + y_change = 1; + goto finished_spiralling; + } + } + + x_change = -1; + if (yj < 0) + x_change = 1; + y_change = 0; + } + else + { + x_change = 0; + y_change = -1; + if (temp_xps + i - 17 > 0) + y_change = 1; + } + + if (temp_xps + i + x_change == temp_xps + && temp_yps + j + y_change == temp_yps) + { + goto finished_spiralling; + } + } + } + } // end else + + + finished_spiralling: + x_change *= direction; + y_change *= direction; + + temp_xps += x_change; + if (temp_yps + y_change <= 17) // it can wrap, unfortunately + temp_yps += y_change; + + const int targ_x = you.x_pos + temp_xps - 17; + const int targ_y = you.y_pos + temp_yps - 9; + + // We don't want to be looking outside the bounds of the arrays: + if (temp_xps > 25 || temp_xps < 8 || temp_yps > 17 || temp_yps < 1) + continue; + + if (targ_x < 0 || targ_x >= GXM || targ_y < 0 || targ_y >= GYM) + continue; + + const int targ_mon = mgrd[ targ_x ][ targ_y ]; + + if (targ_mon != NON_MONSTER + && env.show[temp_xps - 8][temp_yps] != 0 + && player_monster_visible( &(menv[targ_mon]) ) + && !mons_is_mimic( menv[targ_mon].type ) + && (mode == TARG_ANY + || (mode == TARG_FRIEND && mons_friendly( &menv[targ_mon] )) + || (mode == TARG_ENEMY && !mons_friendly( &menv[targ_mon] )))) + { + //mpr("Found something!"); + //more(); + mfp[0] = temp_xps; + mfp[1] = temp_yps; + return (1); + } + } + + return (0); +} + +static void describe_cell(int mx, int my) +{ + int trf; // used for trap type?? + char str_pass[ ITEMNAME_SIZE ]; + bool mimic_item = false; + + if (mgrd[mx][my] != NON_MONSTER) + { + int i = mgrd[mx][my]; + + if (grd[mx][my] == DNGN_SHALLOW_WATER) + { + if (!player_monster_visible(&menv[i]) && !mons_flies(&menv[i])) + { + mpr("There is a strange disturbance in the water here."); + } + } + +#if DEBUG_DIAGNOSTICS + if (!player_monster_visible( &menv[i] )) + mpr( "There is a non-visible monster here.", MSGCH_DIAGNOSTICS ); +#else + if (!player_monster_visible( &menv[i] )) + goto look_clouds; +#endif + + const int mon_wep = menv[i].inv[MSLOT_WEAPON]; + const int mon_arm = menv[i].inv[MSLOT_ARMOUR]; + + strcpy(info, ptr_monam( &(menv[i]), DESC_CAP_A )); + strcat(info, "."); + mpr(info); + + if (menv[i].type != MONS_DANCING_WEAPON && mon_wep != NON_ITEM) + { + snprintf( info, INFO_SIZE, "%s is wielding ", mons_pronoun( menv[i].type, + PRONOUN_CAP )); + it_name(mon_wep, DESC_NOCAP_A, str_pass); + strcat(info, str_pass); + + // 2-headed ogres can wield 2 weapons + if ((menv[i].type == MONS_TWO_HEADED_OGRE + || menv[i].type == MONS_ETTIN) + && menv[i].inv[MSLOT_MISSILE] != NON_ITEM) + { + strcat( info, " and " ); + it_name(menv[i].inv[MSLOT_MISSILE], DESC_NOCAP_A, str_pass); + strcat(info, str_pass); + strcat(info, "."); + + mpr(info); + } + else + { + strcat(info, "."); + mpr(info); + } + } + + if (mon_arm != NON_ITEM) + { + it_name( mon_arm, DESC_PLAIN, str_pass ); + snprintf( info, INFO_SIZE, "%s is wearing %s.", + mons_pronoun( menv[i].type, PRONOUN_CAP ), + str_pass ); + + mpr( info ); + } + + + if (menv[i].type == MONS_HYDRA) + { + snprintf( info, INFO_SIZE, "It has %d heads.", menv[i].number ); + mpr( info ); + } + + print_wounds(&menv[i]); + + + if (mons_is_mimic( menv[i].type )) + mimic_item = true; + else if (!mons_flag(menv[i].type, M_NO_EXP_GAIN)) + { + if (menv[i].behaviour == BEH_SLEEP) + { + strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP)); + strcat(info, " doesn't appear to have noticed you."); + mpr(info); + } + // wandering hostile with no target in LOS + else if (menv[i].behaviour == BEH_WANDER && !mons_friendly(&menv[i]) + && menv[i].foe == MHITNOT) + { + // special case: batty monsters get set to BEH_WANDER as + // part of their special behaviour. + if (!testbits(menv[i].flags, MF_BATTY)) + { + strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP)); + strcat(info, " doesn't appear to be interested in you."); + mpr(info); + } + } + } + + if (menv[i].attitude == ATT_FRIENDLY) + { + strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP)); + strcat(info, " is friendly."); + mpr(info); + } + + for (int p = 0; p < NUM_MON_ENCHANTS; p++) + { + strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP)); + switch (menv[i].enchantment[p]) + { + case ENCH_YOUR_ROT_I: + case ENCH_YOUR_ROT_II: + case ENCH_YOUR_ROT_III: + case ENCH_YOUR_ROT_IV: + strcat(info, " is rotting away."); //jmf: "covered in sores"? + break; + case ENCH_BACKLIGHT_I: + case ENCH_BACKLIGHT_II: + case ENCH_BACKLIGHT_III: + case ENCH_BACKLIGHT_IV: + strcat(info, " is softly glowing."); + break; + case ENCH_SLOW: + strcat(info, " is moving slowly."); + break; + case ENCH_HASTE: + strcat(info, " is moving very quickly."); + break; + case ENCH_CONFUSION: + strcat(info, " appears to be bewildered and confused."); + break; + case ENCH_INVIS: + strcat(info, " is slightly transparent."); + break; + case ENCH_CHARM: + strcat(info, " is in your thrall."); + break; + case ENCH_YOUR_STICKY_FLAME_I: + case ENCH_YOUR_STICKY_FLAME_II: + case ENCH_YOUR_STICKY_FLAME_III: + case ENCH_YOUR_STICKY_FLAME_IV: + case ENCH_STICKY_FLAME_I: + case ENCH_STICKY_FLAME_II: + case ENCH_STICKY_FLAME_III: + case ENCH_STICKY_FLAME_IV: + strcat(info, " is covered in liquid flames."); + break; + default: + info[0] = '\0'; + break; + } // end switch + if (info[0]) + mpr(info); + } + +#if DEBUG_DIAGNOSTICS + stethoscope(i); +#endif + } + +#if (!DEBUG_DIAGNOSTICS) + // removing warning + look_clouds: +#endif + if (env.cgrid[mx][my] != EMPTY_CLOUD) + { + const char cloud_inspected = env.cgrid[mx][my]; + + const char cloud_type = env.cloud[ cloud_inspected ].type; + + strcpy(info, "There is a cloud of "); + strcat(info, + (cloud_type == CLOUD_FIRE + || cloud_type == CLOUD_FIRE_MON) ? "flame" : + (cloud_type == CLOUD_STINK + || cloud_type == CLOUD_STINK_MON) ? "noxious fumes" : + (cloud_type == CLOUD_COLD + || cloud_type == CLOUD_COLD_MON) ? "freezing vapour" : + (cloud_type == CLOUD_POISON + || cloud_type == CLOUD_POISON_MON) ? "poison gases" : + (cloud_type == CLOUD_GREY_SMOKE + || cloud_type == CLOUD_GREY_SMOKE_MON) ? "grey smoke" : + (cloud_type == CLOUD_BLUE_SMOKE + || cloud_type == CLOUD_BLUE_SMOKE_MON) ? "blue smoke" : + (cloud_type == CLOUD_PURP_SMOKE + || cloud_type == CLOUD_PURP_SMOKE_MON) ? "purple smoke" : + (cloud_type == CLOUD_STEAM + || cloud_type == CLOUD_STEAM_MON) ? "steam" : + (cloud_type == CLOUD_MIASMA + || cloud_type == CLOUD_MIASMA_MON) ? "foul pestilence" : + (cloud_type == CLOUD_BLACK_SMOKE + || cloud_type == CLOUD_BLACK_SMOKE_MON) ? "black smoke" + : "buggy goodness"); + strcat(info, " here."); + mpr(info); + } + + int targ_item = igrd[ mx ][ my ]; + + if (targ_item != NON_ITEM) + { + // If a mimic is on this square, we pretend its the first item -- bwr + if (mimic_item) + mpr("There is something else lying underneath."); + else + { + if (mitm[ targ_item ].base_type == OBJ_GOLD) + { + mpr( "A pile of gold coins." ); + } + else + { + strcpy(info, "You see "); + it_name( targ_item, DESC_NOCAP_A, str_pass); + strcat(info, str_pass); + strcat(info, " here."); + mpr(info); + } + + if (mitm[ targ_item ].link != NON_ITEM) + mpr("There is something else lying underneath."); + } + } + + switch (grd[mx][my]) + { + case DNGN_STONE_WALL: + mpr("A stone wall."); + break; + case DNGN_ROCK_WALL: + case DNGN_SECRET_DOOR: + if (you.level_type == LEVEL_PANDEMONIUM) + mpr("A wall of the weird stuff which makes up Pandemonium."); + else + mpr("A rock wall."); + break; + case DNGN_PERMAROCK_WALL: + mpr("An unnaturally hard rock wall."); + break; + case DNGN_CLOSED_DOOR: + mpr("A closed door."); + break; + case DNGN_METAL_WALL: + mpr("A metal wall."); + break; + case DNGN_GREEN_CRYSTAL_WALL: + mpr("A wall of green crystal."); + break; + case DNGN_ORCISH_IDOL: + mpr("An orcish idol."); + break; + case DNGN_WAX_WALL: + mpr("A wall of solid wax."); + break; + case DNGN_SILVER_STATUE: + mpr("A silver statue."); + break; + case DNGN_GRANITE_STATUE: + mpr("A granite statue."); + break; + case DNGN_ORANGE_CRYSTAL_STATUE: + mpr("An orange crystal statue."); + break; + case DNGN_LAVA: + mpr("Some lava."); + break; + case DNGN_DEEP_WATER: + mpr("Some deep water."); + break; + case DNGN_SHALLOW_WATER: + mpr("Some shallow water."); + break; + case DNGN_UNDISCOVERED_TRAP: + case DNGN_FLOOR: + mpr("Floor."); + break; + case DNGN_OPEN_DOOR: + mpr("An open door."); + break; + case DNGN_ROCK_STAIRS_DOWN: + mpr("A rock staircase leading down."); + break; + case DNGN_STONE_STAIRS_DOWN_I: + case DNGN_STONE_STAIRS_DOWN_II: + case DNGN_STONE_STAIRS_DOWN_III: + mpr("A stone staircase leading down."); + break; + case DNGN_ROCK_STAIRS_UP: + mpr("A rock staircase leading upwards."); + break; + case DNGN_STONE_STAIRS_UP_I: + case DNGN_STONE_STAIRS_UP_II: + case DNGN_STONE_STAIRS_UP_III: + mpr("A stone staircase leading up."); + break; + case DNGN_ENTER_HELL: + mpr("A gateway to hell."); + break; + case DNGN_BRANCH_STAIRS: + mpr("A staircase to a branch level."); + break; + case DNGN_TRAP_MECHANICAL: + case DNGN_TRAP_MAGICAL: + case DNGN_TRAP_III: + for (trf = 0; trf < MAX_TRAPS; trf++) + { + if (env.trap[trf].x == mx + && env.trap[trf].y == my) + { + break; + } + + if (trf == MAX_TRAPS - 1) + { + mpr("Error - couldn't find that trap."); + error_message_to_player(); + break; + } + } + + switch (env.trap[trf].type) + { + case TRAP_DART: + mpr("A dart trap."); + break; + case TRAP_ARROW: + mpr("An arrow trap."); + break; + case TRAP_SPEAR: + mpr("A spear trap."); + break; + case TRAP_AXE: + mpr("An axe trap."); + break; + case TRAP_TELEPORT: + mpr("A teleportation trap."); + break; + case TRAP_AMNESIA: + mpr("An amnesia trap."); + break; + case TRAP_BLADE: + mpr("A blade trap."); + break; + case TRAP_BOLT: + mpr("A bolt trap."); + break; + case TRAP_ZOT: + mpr("A Zot trap."); + break; + case TRAP_NEEDLE: + mpr("A needle trap."); + break; + default: + mpr("An undefined trap. Huh?"); + error_message_to_player(); + break; + } + break; + case DNGN_ENTER_SHOP: + mpr(shop_name(mx, my)); + break; + case DNGN_ENTER_LABYRINTH: + mpr("A labyrinth entrance."); + break; + case DNGN_ENTER_DIS: + mpr("A gateway to the Iron City of Dis."); + break; + case DNGN_ENTER_GEHENNA: + mpr("A gateway to Gehenna."); + break; + case DNGN_ENTER_COCYTUS: + mpr("A gateway to the freezing wastes of Cocytus."); + break; + case DNGN_ENTER_TARTARUS: + mpr("A gateway to the decaying netherworld of Tartarus."); + break; + case DNGN_ENTER_ABYSS: + mpr("A gateway to the infinite Abyss."); + break; + case DNGN_EXIT_ABYSS: + mpr("A gateway leading out of the Abyss."); + break; + case DNGN_STONE_ARCH: + mpr("An empty arch of ancient stone."); + break; + case DNGN_ENTER_PANDEMONIUM: + mpr("A gate leading to the halls of Pandemonium."); + break; + case DNGN_EXIT_PANDEMONIUM: + mpr("A gate leading out of Pandemonium."); + break; + case DNGN_TRANSIT_PANDEMONIUM: + mpr("A gate leading to another region of Pandemonium."); + break; + case DNGN_ENTER_ORCISH_MINES: + mpr("A staircase to the Orcish Mines."); + break; + case DNGN_ENTER_HIVE: + mpr("A staircase to the Hive."); + break; + case DNGN_ENTER_LAIR: + mpr("A staircase to the Lair."); + break; + case DNGN_ENTER_SLIME_PITS: + mpr("A staircase to the Slime Pits."); + break; + case DNGN_ENTER_VAULTS: + mpr("A staircase to the Vaults."); + break; + case DNGN_ENTER_CRYPT: + mpr("A staircase to the Crypt."); + break; + case DNGN_ENTER_HALL_OF_BLADES: + mpr("A staircase to the Hall of Blades."); + break; + case DNGN_ENTER_ZOT: + mpr("A gate to the Realm of Zot."); + break; + case DNGN_ENTER_TEMPLE: + mpr("A staircase to the Ecumenical Temple."); + break; + case DNGN_ENTER_SNAKE_PIT: + mpr("A staircase to the Snake Pit."); + break; + case DNGN_ENTER_ELVEN_HALLS: + mpr("A staircase to the Elven Halls."); + break; + case DNGN_ENTER_TOMB: + mpr("A staircase to the Tomb."); + break; + case DNGN_ENTER_SWAMP: + mpr("A staircase to the Swamp."); + break; + case DNGN_RETURN_FROM_ORCISH_MINES: + case DNGN_RETURN_FROM_HIVE: + case DNGN_RETURN_FROM_LAIR: + case DNGN_RETURN_FROM_VAULTS: + case DNGN_RETURN_FROM_TEMPLE: + mpr("A staircase back to the Dungeon."); + break; + case DNGN_RETURN_FROM_SLIME_PITS: + case DNGN_RETURN_FROM_SNAKE_PIT: + case DNGN_RETURN_FROM_SWAMP: + mpr("A staircase back to the Lair."); + break; + case DNGN_RETURN_FROM_CRYPT: + case DNGN_RETURN_FROM_HALL_OF_BLADES: + mpr("A staircase back to the Vaults."); + break; + case DNGN_RETURN_FROM_ELVEN_HALLS: + mpr("A staircase back to the Mines."); + break; + case DNGN_RETURN_FROM_TOMB: + mpr("A staircase back to the Crypt."); + break; + case DNGN_RETURN_FROM_ZOT: + mpr("A gate leading back out of this place."); + break; + case DNGN_ALTAR_ZIN: + mpr("A glowing white marble altar of Zin."); + break; + case DNGN_ALTAR_SHINING_ONE: + mpr("A glowing golden altar of the Shining One."); + break; + case DNGN_ALTAR_KIKUBAAQUDGHA: + mpr("An ancient bone altar of Kikubaaqudgha."); + break; + case DNGN_ALTAR_YREDELEMNUL: + mpr("A basalt altar of Yredelemnul."); + break; + case DNGN_ALTAR_XOM: + mpr("A shimmering altar of Xom."); + break; + case DNGN_ALTAR_VEHUMET: + mpr("A shining altar of Vehumet."); + break; + case DNGN_ALTAR_OKAWARU: + mpr("An iron altar of Okawaru."); + break; + case DNGN_ALTAR_MAKHLEB: + mpr("A burning altar of Makhleb."); + break; + case DNGN_ALTAR_SIF_MUNA: + mpr("A deep blue altar of Sif Muna."); + break; + case DNGN_ALTAR_TROG: + mpr("A bloodstained altar of Trog."); + break; + case DNGN_ALTAR_NEMELEX_XOBEH: + mpr("A sparkling altar of Nemelex Xobeh."); + break; + case DNGN_ALTAR_ELYVILON: + mpr("A silver altar of Elyvilon."); + break; + case DNGN_BLUE_FOUNTAIN: + mpr("A fountain of clear blue water."); + break; + case DNGN_SPARKLING_FOUNTAIN: + mpr("A fountain of sparkling water."); + break; + case DNGN_DRY_FOUNTAIN_I: + case DNGN_DRY_FOUNTAIN_II: + case DNGN_DRY_FOUNTAIN_IV: + case DNGN_DRY_FOUNTAIN_VI: + case DNGN_DRY_FOUNTAIN_VIII: + case DNGN_PERMADRY_FOUNTAIN: + mpr("A dry fountain."); + break; + } +} -- cgit v1.2.3-54-g00ecf