summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/docs/crawl_manual.txt3
-rw-r--r--crawl-ref/source/acr.cc4
-rw-r--r--crawl-ref/source/cmd-keys.h2
-rw-r--r--crawl-ref/source/describe.cc8
-rw-r--r--crawl-ref/source/directn.cc200
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/items.cc18
-rw-r--r--crawl-ref/source/items.h6
-rw-r--r--crawl-ref/source/macro.cc2
-rw-r--r--crawl-ref/source/menu.cc4
10 files changed, 227 insertions, 21 deletions
diff --git a/crawl-ref/docs/crawl_manual.txt b/crawl-ref/docs/crawl_manual.txt
index e1d12733e6..fa9e92c2c3 100644
--- a/crawl-ref/docs/crawl_manual.txt
+++ b/crawl-ref/docs/crawl_manual.txt
@@ -2488,7 +2488,8 @@ When roaming the dungeon, the surroundings mode is activated by 'x'.
It lets you have a look at items or monsters in line of sight. You may
also examine stashed items outside current view using the option
target_oos = true (if using this, check the option target_los_first).
- x, Esc, Space Return to playing mode.
+ Esc, Space Return to playing mode.
+ x List all monsters and items in view.
? Special help screen.
* or ' Cycle objects forward.
/ or ; Cycle objects backward.
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 1bf74dc7a4..01f8fa54b3 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -2161,8 +2161,8 @@ void process_command( command_type cmd )
case CMD_LOOK_AROUND:
{
mpr("Move the cursor around to observe a square "
- "(v - describe square, ? - help)",
- MSGCH_PROMPT);
+ "(x - list visible monsters and items, v - describe square, "
+ "? - help)", MSGCH_PROMPT);
struct dist lmove; // Will be initialized by direction().
direction(lmove, DIR_TARGET, TARG_ANY, -1, true);
diff --git a/crawl-ref/source/cmd-keys.h b/crawl-ref/source/cmd-keys.h
index 1f5b4ba60e..b27c0b2a12 100644
--- a/crawl-ref/source/cmd-keys.h
+++ b/crawl-ref/source/cmd-keys.h
@@ -121,7 +121,6 @@
{CONTROL('W'), CMD_FIX_WAYPOINT},
{CONTROL('X'), CMD_SAVE_GAME_NOW},
{CONTROL('Z'), CMD_SUSPEND_GAME},
-{'x', CMD_TARGET_CANCEL},
{ESCAPE, CMD_TARGET_CANCEL},
#ifdef WIZARD
{'F', CMD_TARGET_WIZARD_MAKE_FRIENDLY},
@@ -134,6 +133,7 @@
{'M', CMD_TARGET_WIZARD_MISCAST},
#endif
{'v', CMD_TARGET_DESCRIBE},
+{'x', CMD_TARGET_ALL_DESCRIBE},
{'?', CMD_TARGET_HELP},
{' ', CMD_TARGET_SELECT}, // XXX hack: can also be CMD_TARGET_CANCEL
{CONTROL('P'), CMD_TARGET_SHOW_PROMPT},
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 7776dc183b..592ff73fac 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2360,8 +2360,10 @@ void describe_monsters(const monsters& mons)
if (mons_is_mimic(mons.type) && mons.type != MONS_GOLD_MIMIC)
body << getLongDescription("mimic");
else
+ {
body << getLongDescription(mons.base_name(DESC_DBNAME, false),
mons.type == MONS_DANCING_WEAPON);
+ }
std::string symbol = "";
symbol += get_monster_data(mons.type)->showchar;
@@ -2454,9 +2456,9 @@ void describe_monsters(const monsters& mons)
case MONS_PROGRAM_BUG:
body << "If this monster is a \"program bug\", then it's "
- "recommended that you save your game and reload. Please report "
- "monsters who masquerade as program bugs or run around the "
- "dungeon without a proper description to the authorities.";
+ "recommended that you save your game and reload. Please report "
+ "monsters who masquerade as program bugs or run around the "
+ "dungeon without a proper description to the authorities.";
break;
default:
break;
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 6a5e4897bf..757173d7ec 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -39,7 +39,9 @@
#include "debug.h"
#include "describe.h"
#include "dungeon.h"
+#include "initfile.h"
#include "itemname.h"
+#include "items.h"
#include "mapmark.h"
#include "message.h"
#include "menu.h"
@@ -445,6 +447,194 @@ static void _direction_again(dist& moves, targeting_type restricts,
return;
}
+static void _describe_monster(const monsters *mon);
+
+// Lists all the monsters and items currently in view by the player.
+// Internals:
+// Menu items have meaningful tags. 'i' means item and 'm' means monster.
+//
+void _full_describe_view()
+{
+ const coord_def start = view2grid(coord_def(1,1));
+ const coord_def end(start.x + crawl_view.viewsz.x,
+ start.y + crawl_view.viewsz.y);
+
+ std::vector<monsters*> list_mons;
+ std::vector<const item_def*> list_items;
+
+ coord_def p;
+
+ // Iterate over viewport and get all the items and monsters in view.
+ // TODO: Allow sorting of monster and items lists.
+ for (p.x = start.x; p.x < end.x; p.x++)
+ for (p.y = start.y; p.y < end.y; p.y++)
+ {
+ if (!in_bounds(p.x,p.y) || !see_grid(p.x,p.y))
+ continue;
+
+ const int mid = mgrd(p);
+ const int oid = igrd(p);
+
+ if (mid != NON_MONSTER && player_monster_visible(&menv[mid]))
+ list_mons.push_back(&menv[mid]);
+
+ if (oid != NON_ITEM)
+ {
+ std::vector<const item_def*> items;
+ item_list_on_square( items, oid, true );
+ list_items.insert(list_items.end(), items.begin(), items.end());
+ }
+ }
+
+ if (!list_mons.size() && !list_items.size())
+ {
+ mprf("Neither monsters nor items are visible.");
+ return;
+ }
+
+ Menu desc_menu(MF_SINGLESELECT | MF_ANYPRINTABLE |
+ /*MF_ALWAYS_SHOW_MORE |*/ MF_ALLOW_FORMATTING);
+
+ desc_menu.set_highlighter(NULL);
+ desc_menu.set_title(new MenuEntry("Visible Monsters/Items:",
+ MEL_TITLE));
+
+ desc_menu.set_tag("description");
+
+ int menu_index = -1;
+ // Build menu entries for monsters.
+ if (!list_mons.empty())
+ {
+ desc_menu.add_entry( new MenuEntry("Monsters", MEL_SUBTITLE) );
+ for (unsigned int i = 0; i < list_mons.size(); ++i)
+ {
+ // List monsters in the form
+ // (g) A goblin wielding an orcish dagger
+
+ ++menu_index;
+ const char letter = index_to_letter(menu_index);
+
+ // Get colour-coded letter.
+ unsigned char colour = mons_class_colour(list_mons[i]->type);
+ if (colour == BLACK)
+ colour = LIGHTGREY;
+
+ std::string prefix = "(<";
+ prefix += colour_to_str(colour);
+ prefix += ">";
+ prefix += stringize_glyph(mons_char( list_mons[i]->type) );
+ prefix += "</";
+ prefix += colour_to_str(colour);
+ prefix += ">) ";
+
+ // Get damage level.
+ std::string wound_str;
+ mon_dam_level_type dam_level;
+ mons_get_damage_level(list_mons[i], wound_str, dam_level);
+
+ // Get monster description.
+ // TODO: Show monsters being friendly or neutral, if not by
+ // colour, then by description.
+ std::vector<formatted_string> fss;
+ std::string str = prefix + get_monster_desc(list_mons[i], true);
+ if (dam_level != MDAM_OKAY)
+ str = str + ", " + wound_str;
+
+ // Wraparound if the description is longer than allowed.
+ linebreak_string2(str, get_number_of_cols() - 4);
+ formatted_string::parse_string_to_multiple(str, fss);
+ MenuEntry *me;
+ for (unsigned int j = 0; j < fss.size(); j++)
+ {
+ if (j == 0)
+ {
+ me = new MenuEntry(uppercase_first(str), MEL_ITEM, 1, letter);
+ me->data = (void*) list_mons[i];
+ me->tag = "m";
+ me->quantity = 1; // Hack to make monsters selectable.
+ }
+ else
+ {
+ str = " " + fss[j].tostring();
+ me = new MenuEntry(str, MEL_ITEM, 1);
+ }
+
+ desc_menu.add_entry(me);
+ }
+ }
+ }
+
+ // Build menu entries for items.
+ if (list_items.size())
+ {
+ desc_menu.add_entry( new MenuEntry( "Items", MEL_SUBTITLE ) );
+ for (unsigned int i = 0; i < list_items.size(); ++i)
+ {
+ ++menu_index;
+ const char letter = index_to_letter(menu_index);
+
+ unsigned glyph_char;
+ // TODO: check if this can be used instead of
+ // manually doing so with item_specialness --yy
+ unsigned short glyph_col;
+ get_item_glyph( list_items[i], &glyph_char, &glyph_col );
+
+ std::string col_string;
+ int specialness = item_name_specialness(*(list_items[i]));
+ switch (specialness)
+ {
+ case 2: col_string = "yellow"; break; // artefact
+ case 1: col_string = "white"; break; // glowing/runed
+ case 0: col_string = "darkgrey"; break; // mundane
+ }
+
+ std::string prefix = "(<" + col_string + ">"
+ + (char)glyph_char
+ + "</" + col_string + ">) ";
+
+ std::string str = prefix + list_items[i]->name(DESC_PLAIN);
+
+ MenuEntry *me = new MenuEntry(uppercase_first(str),
+ MEL_ITEM, 1, letter);
+ me->data = (void*) list_items[i];
+ me->tag = "i";
+ me->quantity = 2; // Hack to make items selectable.
+ desc_menu.add_entry(me);
+ }
+ }
+
+ // Menu loop
+ while (true)
+ {
+ std::vector<MenuEntry*> sel = desc_menu.show();
+ redraw_screen();
+
+ if (sel.empty())
+ break;
+
+ // Possibility to select a menu item to get full description
+ // HACK: quantity == 1: monsters, quantity == 2: items
+ const int quant = sel[0]->quantity;
+ if (quant == 1)
+ {
+ mesclr();
+ //Monster selected
+ monsters* m = (monsters*)(sel[0]->data);
+ _describe_monster( m );
+
+ if (getch() == 0)
+ getch();
+ }
+ else if (quant == 2)
+ {
+ //Item selected
+ item_def* i = (item_def*)(sel[0]->data);
+ describe_item( *i );
+ }
+ }
+}
+
+
//---------------------------------------------------------------
//
// direction
@@ -727,7 +917,7 @@ void direction(dist& moves, targeting_type restricts,
bool loop_done = false;
coord_def old_target = moves.target;
- if ( skip_iter )
+ if (skip_iter)
old_target.x += 500; // hmmm...hack
int i, mid;
@@ -1108,6 +1298,12 @@ void direction(dist& moves, targeting_type restricts,
force_redraw = true;
break;
+ case CMD_TARGET_ALL_DESCRIBE:
+ _full_describe_view();
+ //TODO: Check if this is neccesary
+ //force_redraw = true;
+ break;
+
case CMD_TARGET_HELP:
show_targeting_help();
force_redraw = true;
@@ -2491,6 +2687,8 @@ static void _describe_monster(const monsters *mon)
mon->pronoun(PRONOUN_CAP).c_str());
}
+ // Give an indication of monsters being capable of seeing/sensing
+ // invisible creatures.
if (mons_behaviour_perceptible(mon) && !mons_is_sleeping(mon)
&& !mons_is_confused(mon)
&& (mons_see_invis(mon) || mons_sense_invis(mon)))
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index b4e0a3e47d..387078dce4 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -589,6 +589,7 @@ enum command_type
CMD_TARGET_DIR_UP,
CMD_TARGET_DIR_UP_RIGHT,
+ CMD_TARGET_ALL_DESCRIBE,
CMD_TARGET_CYCLE_TARGET_MODE,
CMD_TARGET_PREV_TARGET,
CMD_TARGET_MAYBE_PREV_TARGET,
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index c4a3c61682..9b00cd6011 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -80,8 +80,6 @@
#include "xom.h"
static bool _invisible_to_player( const item_def& item );
-static void _item_list_on_square( std::vector<const item_def*>& items,
- int obj, bool force_squelch = false );
static void _autoinscribe_item( item_def& item );
static void _autoinscribe_floor_items();
static void _autoinscribe_inventory();
@@ -196,14 +194,14 @@ static int _cull_items(void)
if (z != -1)
set_unrandart_exist(z, false);
}
-
+
if (first_cleaned == NON_ITEM)
first_cleaned = si->index();
// POOF!
destroy_item( si->index() );
}
- }
+ }
}
return (first_cleaned);
@@ -613,8 +611,8 @@ static int _count_nonsquelched_items( int obj )
// the square contains *only* squelched items, in which case they
// are included. If force_squelch is true, squelched items are
// never displayed.
-static void _item_list_on_square( std::vector<const item_def*>& items,
- int obj, bool force_squelch )
+void item_list_on_square( std::vector<const item_def*>& items,
+ int obj, bool force_squelch )
{
const bool have_nonsquelched = (force_squelch
|| _count_nonsquelched_items(obj));
@@ -639,7 +637,7 @@ void request_autopickup(bool do_pickup)
}
// 2 - artefact, 1 - glowing/runed, 0 - mundane
-static int _item_name_specialness(const item_def& item)
+int item_name_specialness(const item_def& item)
{
// All jewellery is worth looking at.
// And we can always tell from the name if it's an artefact.
@@ -711,7 +709,7 @@ void item_check(bool verbose)
std::vector<const item_def*> items;
- _item_list_on_square( items, igrd(you.pos()), true );
+ item_list_on_square( items, igrd(you.pos()), true );
if (items.empty())
{
@@ -740,7 +738,7 @@ void item_check(bool verbose)
unsigned short glyph_col;
get_item_glyph( items[i], &glyph_char, &glyph_col );
item_chars.push_back( glyph_char * 0x100 +
- (10 - _item_name_specialness(*(items[i]))) );
+ (10 - item_name_specialness(*(items[i]))) );
}
std::sort(item_chars.begin(), item_chars.end());
@@ -794,7 +792,7 @@ void item_check(bool verbose)
static void _pickup_menu(int item_link)
{
std::vector<const item_def*> items;
- _item_list_on_square( items, item_link, false );
+ item_list_on_square( items, item_link, false );
std::vector<SelItem> selected =
select_items( items, "Select items to pick up" );
diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h
index 1693a16d08..3d59851843 100644
--- a/crawl-ref/source/items.h
+++ b/crawl-ref/source/items.h
@@ -90,6 +90,12 @@ void request_autopickup(bool do_pickup = true);
* *********************************************************************** */
void pickup(void);
+/* ***********************************************************************
+ * called from: directn
+ * *********************************************************************** */
+int item_name_specialness(const item_def& item);
+void item_list_on_square( std::vector<const item_def*>& items,
+ int obj, bool force_squelch = false );
// last updated 08jun2000 {dlb}
/* ***********************************************************************
diff --git a/crawl-ref/source/macro.cc b/crawl-ref/source/macro.cc
index 595c3f0647..7b6d1d2f76 100644
--- a/crawl-ref/source/macro.cc
+++ b/crawl-ref/source/macro.cc
@@ -1053,7 +1053,7 @@ void init_keybindings()
ASSERT(i >= 130);
for (i = 0; _default_binding_list[i].cmd != CMD_NO_CMD
- && _default_binding_list[i].key != '\0'; i++)
+ && _default_binding_list[i].key != '\0'; i++)
{
default_binding &data = _default_binding_list[i];
ASSERT(VALID_BIND_COMMAND(data.cmd));
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index 996c07239d..228be0ac72 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -1482,8 +1482,8 @@ std::string get_linebreak_string(const std::string& s, int maxcol)
return r;
}
-// takes a (possibly tagged) string, breaks it into lines and
-// prints it into the given message channel
+// Takes a (possibly tagged) string, breaks it into lines and
+// prints it into the given message channel.
void print_formatted_paragraph(std::string &s, int maxcol,
msg_channel_type channel)
{