Added farlook() functionality
authorMartin Read <martin@blackswordsonics.com>
Tue, 18 Feb 2014 22:46:01 +0000 (22:46 +0000)
committerMartin Read <martin@blackswordsonics.com>
Tue, 18 Feb 2014 22:46:01 +0000 (22:46 +0000)
* display-nc.cc: Added internal functions is_movekey(), movekey_to_direction(),
  farlook(), examine_square() to provide "farlook" functionality, bound to
  keystroke ';'.

display-nc.cc

index 65c1d92..5dd83dc 100644 (file)
@@ -47,6 +47,7 @@ void hide_inv(void);
 void show_inv(void);
 void update_inv(enum poclass_num filter);
 int inv_select(enum poclass_num filter, char const *action, int accept_blank);
+static void farlook(void);
 WINDOW *status_window;
 WINDOW *world_window;
 WINDOW *message_window;
@@ -967,7 +968,7 @@ void get_player_action(Action *act)
             }
             break;
         case ';':
-            print_msg(Msg_prio::Bug, "TODO: implement monster examination.\n");
+            farlook();
             break;
         case '#':
             show_terrain = 1;
@@ -1437,6 +1438,120 @@ static void run_main_menu(void)
     }
 }
 
+bool is_movekey(chtype ch)
+{
+    switch (ch)
+    {
+    case 'h': case 'H': case '4':
+    case 'j': case 'J': case '2':
+    case 'k': case 'K': case '8':
+    case 'l': case 'L': case '6':
+    case 'y': case 'Y': case '7':
+    case 'u': case 'U': case '9':
+    case 'b': case 'B': case '1':
+    case 'n': case 'N': case '3':
+    case '.': case '5': return true;
+    default: return false;
+    }
+}
+
+Offset movekey_to_direction(chtype ch)
+{
+    switch (ch)
+    {
+    case 'h': case 'H': case '4': return West;
+    case 'j': case 'J': case '2': return South;
+    case 'k': case 'K': case '8': return North;
+    case 'l': case 'L': case '6': return East;
+    case 'y': case 'Y': case '7': return Northwest;
+    case 'u': case 'U': case '9': return Northeast;
+    case 'b': case 'B': case '1': return Southwest;
+    case 'n': case 'N': case '3': return Southeast;
+    case '.': case '5': return Stationary;
+    default: return Stationary;
+    }
+}
+
+static void examine_square(Offset o)
+{
+    Coord c = u.pos + o;
+    uint32_t flags;
+    int mon;
+    int obj;
+    Terrain terr;
+    if ((c.y < 0) || (c.x < 0) || (c.y >= (lvl.chunks_high << CHUNK_SHIFT)) ||
+        (c.x >= (lvl.chunks_wide << CHUNK_SHIFT)))
+    {
+        print_msg("That square is beyond the bounds of the level.\n");
+        return;
+    }
+    flags = lvl.flags_at(c);
+    if (!flags & MAPFLAG_EXPLORED)
+    {
+        print_msg("Unexplored territory.\n");
+        return;
+    }
+    mon = lvl.mon_at(c);
+    obj = lvl.obj_at(c);
+    terr = lvl.terrain_at(c);
+    print_msg("%s\n", terrain_props[terr]);
+    if ((mon != NO_MON) && mon_visible(mon))
+    {
+        print_msg("%s\n%s\n", permons[monsters[mon].mon_id].name, permons[monsters[mon].mon_id].description);
+    }
+    if (obj != NO_OBJ)
+    {
+        print_msg("%s\n%s\n", permobjs[objects[obj].obj_id].name, permobjs[objects[obj].obj_id].description);
+    }
+}
+
+static void farlook(void)
+{
+    bool done = false;
+    chtype ch;
+    Offset screendelta = { 0, 0 };
+    print_msg("Use movement keys to move the cursor. Use '5' or '.' to examine the selected square. Press ESC or space when done.\n");
+    wmove(world_window, 10, 10);
+    curs_set(1);
+    update_panels();
+    doupdate();
+    do
+    {
+        Offset o;
+        ch = mvwgetch(world_window, 10 + screendelta.y, 10 + screendelta.x);
+        switch (ch)
+        {
+        case ' ':
+        case '\x1b':
+            done = true;
+            break;
+        case '5':
+        case '.':
+            examine_square(screendelta);
+            wmove(world_window, 10 + screendelta.y, 10 + screendelta.x);
+            update_panels();
+            doupdate();
+            break;
+        default:
+            o = movekey_to_direction(ch);
+            if (o != Stationary)
+            {
+                screendelta += o;
+                screendelta.clamp(-10, -10, 10, 10);
+                wmove(world_window, 10 + screendelta.y, 10 + screendelta.x);
+                update_panels();
+                doupdate();
+            }
+            break;
+        }
+    } while (!done);
+    wmove(world_window, 10, 10);
+    curs_set(0);
+    update_panels();
+    doupdate();
+    print_msg("Done.\n");
+}
+
 void welcome(void)
 {
     print_msg("Welcome to the Abyss, Princess %s.\n", u.name);