diff options
-rw-r--r-- | crawl-ref/docs/crawl_manual.txt | 3 | ||||
-rw-r--r-- | crawl-ref/source/acr.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/cmd-keys.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 200 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/items.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/items.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/macro.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/menu.cc | 4 |
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) { |