home · contact · privacy
Added primitive inventory system. Any objects may now own/contain/carry other objects.
authorChristian Heller <c.heller@plomlompom.de>
Mon, 7 Oct 2013 00:08:28 +0000 (02:08 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 7 Oct 2013 00:08:28 +0000 (02:08 +0200)
13 files changed:
config/commands
config/windows/Win_c
config/windows/Win_m
src/control.c
src/draw_wins.c
src/main.c
src/main.h
src/map_object_actions.c
src/map_object_actions.h
src/map_objects.c
src/map_objects.h
src/misc.c
src/misc.h

index 4eebf3ff4072c0c400637763c434aa75b5a0d9de..ba35ecb15674960fc4aaa3a15424b21db56dbaeb 100644 (file)
@@ -44,3 +44,7 @@
 45 map_c map center player
 46 to_a_keywin toggle view of available keybindings
 46 to_inv toggle inventory window
+47 drop drop object from inventory
+48 pick pick up object from ground
+49 inv_d inventory selection down
+50 inv_u inventory selection up
index c354ff6588735530f718916d16aa4de20dc71bdb..d6b2588b7ec371829524c1a246fb9a9f63b1cdbc 100644 (file)
@@ -2,3 +2,6 @@ Inventory
 c
 5
 33
+100 drop
+259 inv_u
+258 inv_d
index e2bdc067548059b28c8f0aeb40f3dc549e04f107..a83973fb84e376bc32dc6add31e2f86866241538 100644 (file)
@@ -2,6 +2,7 @@ Map
 m
 0
 -64
+112 pick
 58 wait
 107 player_u
 106 player_d
index 874601b90d32092e946e97c95ffc6911c38b2ccf..c59053923a7d9cf1c60d6e558d8a439cb0f5e468 100644 (file)
                          * growshrink_active_window(), toggle_winconfig(),
                          * toggle_win_height_type(), toggle_win_width_type()
                          */
-#include "map_object_actions.h" /* for player_wait(), move_player() */
+#include "map_object_actions.h" /* for player_wait(), move_player(),
+                                 * player_drop(), player_pick()
+                                 */
 #include "command_db.h" /* for is_command_id_shortdsc() */
 #include "misc.h" /* for load_interface_conf(), unload_interface_conf(),
-                   * save_interface_conf()
+                   * save_interface_conf(), nav_inventory()
                    */
 #include "yx_uint16.h" /* for dir enum */
 #include "map_objects.h" /* for get_player() */
@@ -73,13 +75,25 @@ extern void record_control(int action, struct World * world)
     {
         move_player(world, WEST);
     }
+    else if (is_command_id_shortdsc(world, action, "drop"))
+    {
+        player_drop(world);
+    }
+    else if (is_command_id_shortdsc(world, action, "pick"))
+    {
+        player_pick(world);
+    }
 }
 
 
 
 extern uint8_t player_control(int key, struct World * world)
 {
-    if      (key == get_available_keycode_to_action(world, "player_u"))
+    if      (key == get_available_keycode_to_action(world, "wait"))
+    {
+        player_wait(world);
+    }
+    else if (key == get_available_keycode_to_action(world, "player_u"))
     {
         move_player(world, NORTH);
     }
@@ -95,9 +109,13 @@ extern uint8_t player_control(int key, struct World * world)
     {
         move_player(world, WEST);
     }
-    else if (key == get_available_keycode_to_action(world, "wait"))
+    else if (key == get_available_keycode_to_action(world, "drop"))
     {
-        player_wait(world);
+        player_drop(world);
+    }
+    else if (key == get_available_keycode_to_action(world, "pick"))
+    {
+        player_pick(world);
     }
     else
     {
@@ -306,6 +324,14 @@ extern uint8_t meta_control(int key, struct World * world)
     {
         map_center_object(world->map, get_player(world), win_map->frame.size);
     }
+    else if (key == get_available_keycode_to_action(world, "inv_u"))
+    {
+        nav_inventory(world, 'u');
+    }
+    else if (key == get_available_keycode_to_action(world, "inv_d"))
+    {
+        nav_inventory(world, 'd');
+    }
     else if (key == get_available_keycode_to_action(world, "reload_conf"))
     {
         unload_interface_conf(world);
index 1ca2c85820ff941151fc8bbd12e2e1ef024d0730..797864adb5d9cb854db441bb4ab759bc585eacab 100644 (file)
@@ -43,6 +43,16 @@ static void draw_map_objects(struct World * world, struct MapObj * start,
 static char * get_kb_line_and_iterate(struct World * world,
                                       struct KeyBinding ** kb_pp);
 
+/* Draw horizontal scroll hints in "frame" at the end line or a start line of y
+ * value "start" if the current "y" fits one of these lines and the number of
+ * lines "n_owned" and the "offset" make it appropriate.
+ *
+ * Return 1 if a scroll hint was drawn, else 0.
+ */
+static uint8_t scroll_hint_helper(struct World * world, uint16_t start,
+                                  uint16_t y, uint16_t offset, uint16_t n_owned,
+                                  struct Frame * frame, char * f_name);
+
 /* Draw from line "start" on config view for keybindings defined at "kb". */
 static void draw_kb_view(struct World * world, struct Win * win,
                          char * f_name, struct KeyBiData * kb, uint8_t start);
@@ -234,32 +244,50 @@ static char * get_kb_line_and_iterate(struct World * world,
 
 
 
+static uint8_t scroll_hint_helper(struct World * world, uint16_t start,
+                                  uint16_t y, uint16_t offset, uint16_t n_owned,
+                                  struct Frame * frame, char * f_name)
+{
+    uint8_t ret = 0;
+    char * err_hint = trouble_msg(world, f_name, "draw_scroll_hint()");
+    if (start == y && offset > 0)
+    {
+        uint8_t test = draw_scroll_hint(frame, y, offset + 1, '^');
+        exit_err(test, world, err_hint);
+        ret = 1;
+    }
+    else if (   frame->size.y == y + 1
+             && n_owned > frame->size.y + offset - 1 - start)
+    {
+        uint8_t pos = n_owned - (offset + frame->size.y) + 2 + start;
+        uint8_t test = draw_scroll_hint(frame, y, pos, 'v');
+        exit_err(test, world, err_hint);
+        ret = 1;
+    }
+    free(err_hint);
+    return ret;
+}
+
+
+
 static void draw_kb_view(struct World * world, struct Win * win,
                          char * f_name, struct KeyBiData * kb, uint8_t start)
 {
     if (0 == kb->kbs)
     {
         draw_line(win, start, "(none)", 0, 0);
+        return;
     }
-    char * err_hint = trouble_msg(world, f_name, "draw_scroll_hint()");
     uint16_t kb_max = get_n_of_keybs(kb->kbs) - 1;
-    uint16_t y, offset;
+    uint16_t offset;
     offset = center_offset(kb->select, kb_max, win->frame.size.y - 1 - start);
-    uint16_t y_border = win->frame.size.y + offset - 1 - start;
     struct KeyBinding * kb_p = get_keyb_of_n(kb->kbs, offset + (offset > 0));
+    uint16_t y;
     for (y = start; 0 != kb_p && y < win->frame.size.y; y++)
     {
-        if (start == y && offset > 0)
-        {
-            uint8_t test = draw_scroll_hint(&win->frame, y, offset + 1, '^');
-            exit_err(test, world, err_hint);
-            continue;
-        }
-        else if (win->frame.size.y == y + 1 && kb_max > y_border)
+        if (scroll_hint_helper(world, start, y, offset, kb_max, &win->frame,
+                               f_name))
         {
-            uint16_t pos = kb_max - (offset + win->frame.size.y) + 2 + start;
-            uint8_t test = draw_scroll_hint(&win->frame, y, pos, 'v');
-            exit_err(test, world, err_hint);
             continue;
         }
         attr_t attri = 0;
@@ -273,9 +301,9 @@ static void draw_kb_view(struct World * world, struct Win * win,
         }
         char * kb_line = get_kb_line_and_iterate(world, &kb_p);
         draw_line(win, y, kb_line, attri, 1);
+
         free(kb_line);
     }
-    free(err_hint);
 }
 
 
@@ -374,7 +402,39 @@ extern void draw_win_info(struct Win * win)
 
 extern void draw_win_inventory(struct Win * win)
 {
-    mvwaddstr(win->frame.curses_win, 0, 0, "(empty)");
+    struct World * world = (struct World *) win->data;
+    struct MapObj * player = get_player(world);
+    if (NULL == player->owns)
+    {
+        mvwaddstr(win->frame.curses_win, 0, 0, "(empty)");
+        return;
+    }
+    char * f_name = "draw_win_inventory()";
+    struct MapObj * owned = player->owns;
+    uint8_t n_owned;
+    for (n_owned = 0; NULL != owned->next; owned = owned->next, n_owned++);
+    uint8_t offset = center_offset(world->inventory_select, n_owned,
+                                   win->frame.size.y - 1);
+    uint8_t i;
+    for (i = 0, owned = player->owns; i < offset + (offset > 0);
+         i++, owned = owned->next);
+    uint8_t y;
+    for (y = 0; NULL != owned && y < win->frame.size.y; y++)
+    {
+        if (scroll_hint_helper(world, 0, y, offset, n_owned, &win->frame,
+                               f_name))
+        {
+            continue;
+        }
+        attr_t attri = 0;
+        if (y == world->inventory_select - offset)
+        {
+            attri = A_REVERSE;
+        }
+        struct MapObjDef * mod = get_map_object_def(world, owned->type);
+        draw_line(win, y, mod->name, attri, 0);
+        owned = owned->next;
+    }
 }
 
 
index 68b1ebbfae6a88af9a3245e9e7468160b78b1879..90aa9dd5713c600e639ef63bf178a0782234db5b 100644 (file)
@@ -164,6 +164,9 @@ int main(int argc, char *argv[])
     struct Win * win_map = get_win_by_id(&world, 'm');
     map_center_object(&map, player, win_map->frame.size);
 
+    /* Initialize player's inventory selection index to start position. */
+    world.inventory_select = 0;
+
     /* Replay mode. */
     int key;
     struct WinConf * wc;
index 56d458ba4c0e933174f6b4d9bab76182c60e488a..bf86e0507ce3426ed336e4dbb602d292deaf6127 100644 (file)
@@ -37,6 +37,7 @@ struct World
     uint8_t map_obj_count;            /* Counts map objects generated so far. */
     struct MapObjDef * map_obj_defs;  /* Map object type definitions chain. */
     struct MapObj * map_objs;         /* Pointer to map objects chain start. */
+    uint8_t inventory_select;         /* Player's inventory selection index. */
 };
 
 
index 387b18a3b5d0d8b31323d34de78120fa4e7739cf..4217145843fc2d1bf80b22df7dd0cbe65f5be159 100644 (file)
@@ -2,8 +2,12 @@
 
 #include "map_object_actions.h"
 #include <string.h> /* for strlen() */
-#include "yx_uint16.h" /* for yx_uint16 struct, mv_yx_in_dir(), yx_uint16_cmp */
-#include "map_objects.h" /* for MapObj, MapObjDef structs, get_player() */
+#include "yx_uint16.h" /* for yx_uint16 struct, mv_yx_in_dir(),
+                        * yx_uint16_cmp()
+                        */
+#include "map_objects.h" /* for MapObj, MapObjDef structs, get_player(),
+                          * set_object_position(), own_map_object()
+                          */
 #include "misc.h" /* for update_log(), turn_over() */
 #include "map.h" /* for Map struct */
 #include "main.h" /* for World struct */
@@ -83,7 +87,7 @@ extern uint8_t move_actor(struct World * world, struct MapObj * actor,
     }
     if (is_passable(world->map, target))
     {
-        actor->pos = target;
+        set_object_position(actor, target);
         return 0;
     }
     return 1;
@@ -156,3 +160,53 @@ extern char is_passable(struct Map * map, struct yx_uint16 pos)
     }
     return passable;
 }
+
+
+
+extern void player_drop(struct World * world)
+{
+    struct MapObj * player = get_player(world);
+    if (NULL == player->owns)
+    {
+        update_log(world, "\nYou try to drop an object, but you own none.");
+    }
+    else
+    {
+        struct MapObj * owned = player->owns;
+        uint8_t i = 0;
+        for (; i != world->inventory_select; i++, owned = owned->next);
+        if (0 < world->inventory_select)
+        {
+            world->inventory_select--;
+        }
+        own_map_object(&world->map_objs, &player->owns, owned->id);
+        update_log(world, "\nYou drop an object.");
+    }
+    turn_over(world, get_command_id(world, "drop"));
+}
+
+
+
+extern void player_pick(struct World * world)
+{
+    struct MapObj * player = get_player(world);
+    struct MapObj * picked;
+    for (picked = world->map_objs; NULL != picked; picked = picked->next)
+    {
+        if (picked != player && yx_uint16_cmp(&picked->pos, &player->pos))
+        {
+            break;
+        }
+    }
+    if (NULL == picked)
+    {
+        update_log(world, "\nYou try to pick up an object, but there is none.");
+    }
+    else
+    {
+        own_map_object(&player->owns, &world->map_objs, picked->id);
+        set_object_position(picked, player->pos);
+        update_log(world, "\nYou pick up an object.");
+    }
+    turn_over(world, get_command_id(world, "pick"));
+}
index 3041c9c2fc0c4089d40feb4fac3f71931fce2889..30bbae39f1a3b344401df31ff9620c930d377180 100644 (file)
@@ -47,4 +47,12 @@ extern char is_passable(struct Map * map, struct yx_uint16 pos);
 
 
 
+/* Make player drop to ground map ojbect indexed by world.inventory_select. */
+extern void player_drop(struct World * world);
+
+/* Make player pick up map object from ground. */
+extern void player_pick(struct World * world);
+
+
+
 #endif
index ed41d93ac62f30ab65c5fd194182782a8d034156..3745fcf3ce05966a5bff6a542db95294dbde74d6 100644 (file)
 
 
 
+/* Write representation of "mo" and all of the map objects it owns to "file". */
+static void write_map_object(struct World * w, FILE * file, struct MapObj * mo);
+
+
+
+/* Return pointer to map object of "id" in chain starting at "ptr". */
+static struct MapObj * get_map_object(struct MapObj * ptr, uint8_t id);
+
+
+
+static void write_map_object(struct World * w, FILE * file, struct MapObj * mo)
+{
+    char * f_name = "write_map_object()";
+    struct MapObj * mo_ptr = mo->owns;
+    uint8_t i = 0;
+    for (; NULL != mo_ptr; mo_ptr = mo_ptr->next, i++);
+    uint8_t size = 3+1 + 3+1 + 3+1 + 5+1 + 5 + ((1+3)*i) + 1 + 1;
+    char line[size];
+    sprintf(line, "%d %d %d %d %d",
+                  mo->id, mo->type, mo->lifepoints, mo->pos.y, mo->pos.x);
+    for (mo_ptr = mo->owns; NULL != mo_ptr; mo_ptr = mo_ptr->next)
+    {
+        sprintf(line + strlen(line), " %d", mo_ptr->id);
+    }
+    line[strlen(line) + 1] = '\0';
+    line[strlen(line)] = '\n';
+    try_fwrite(line, strlen(line), 1, file, w, f_name);
+    for (mo_ptr = mo->owns; NULL != mo_ptr; mo_ptr = mo_ptr->next)
+    {
+        write_map_object(w, file, mo_ptr);
+    }
+}
+
+
+
+static struct MapObj * get_map_object(struct MapObj * ptr, uint8_t id)
+{
+    while (1)
+    {
+        if (NULL == ptr || id == ptr->id)
+        {
+            return ptr;
+        }
+        struct MapObj * owned_object = get_map_object(ptr->owns, id);
+        if (NULL != owned_object)
+        {
+            return ptr;
+        }
+        ptr = ptr->next;
+    }
+}
+
+
+
 extern void init_map_object_defs(struct World * world, char * filename)
 {
     char * f_name = "init_map_object_defs()";
@@ -58,15 +112,10 @@ extern void free_map_object_defs(struct MapObjDef * mod_start)
 
 extern void write_map_objects(struct World * world, FILE * file)
 {
-    char * f_name = "write_map_objects()";
     struct MapObj * mo = world->map_objs;
-    uint8_t size = 3 + 1 + 3 + 1 + 3 + 1 + 5 + 1 + 5 + 1;
-    char line[size];
     while (NULL != mo)
     {
-        sprintf(line, "%d %d %d %d %d\n",
-                mo->id, mo->type, mo->lifepoints, mo->pos.y, mo->pos.x);
-        try_fwrite(line, strlen(line), 1, file, world, f_name);
+        write_map_object(world, file, mo);
         mo = mo->next;
     }
 }
@@ -80,29 +129,54 @@ extern void read_map_objects(struct World * world, FILE * file, char * line,
     struct MapObj ** mo_ptr_ptr = &world->map_objs;
     char * delim = " ";
     struct MapObj * mo;
+    fpos_t pos;
+    exit_err(-1 == fgetpos(file, &pos), world, f_name);
     while (try_fgets(line, linemax + 1, file, world, f_name))
     {
         mo = malloc(sizeof(struct MapObj));
-        mo->next = NULL;
-        mo->id = atoi(strtok(line, delim));
+        mo->next       = NULL;
+        mo->id         = atoi(strtok(line, delim));
+        mo->type       = atoi(strtok(NULL, delim));
+        mo->lifepoints = atoi(strtok(NULL, delim));
+        mo->pos.y      = atoi(strtok(NULL, delim));
+        mo->pos.x      = atoi(strtok(NULL, delim));
+        mo->owns       = NULL;
         if (mo->id > world->map_obj_count)
         {
             world->map_obj_count = mo->id;
         }
-        mo->type = atoi(strtok(NULL, delim));
-        mo->lifepoints = atoi(strtok(NULL, delim));
-        mo->pos.y = atoi(strtok(NULL, delim));
-        mo->pos.x = atoi(strtok(NULL, delim));
         * mo_ptr_ptr = mo;
         mo_ptr_ptr = &mo->next;
     }
+    exit_err(-1 == fsetpos(file, &pos), world, f_name);
+    while (try_fgets(line, linemax + 1, file, world, f_name))
+    {
+        uint8_t id = atoi(strtok(line, delim));
+        strtok(NULL, delim);
+        strtok(NULL, delim);
+        strtok(NULL, delim);
+        strtok(NULL, delim);
+        char * owned = strtok(NULL, "\n");
+        if (NULL != owned)
+        {
+            mo = get_map_object(world->map_objs, id);
+            char * owned_id = "";
+            owned_id = strtok(owned, delim);
+            while (NULL != owned_id)
+            {
+                own_map_object(&mo->owns, &world->map_objs,
+                               (uint8_t) atoi(owned_id));
+                owned_id = strtok(NULL, delim);
+            }
+        }
+    }
 }
 
 
 
 extern void add_map_object(struct World * world, uint8_t type)
 {
-    char * f_name = "add_map_object";
+    char * f_name = "add_map_object()";
     struct MapObjDef * mod = get_map_object_def(world, type);
     struct MapObj * mo = try_malloc(sizeof(struct MapObj), world, f_name);
     mo->id = world->map_obj_count;
@@ -130,6 +204,7 @@ extern void add_map_object(struct World * world, uint8_t type)
             break;
         }
     }
+    mo->owns = NULL;
     mo->next = NULL;
     struct MapObj ** last_ptr_ptr = &world->map_objs;
     struct MapObj * mo_ptr;
@@ -160,27 +235,52 @@ extern void free_map_objects(struct MapObj * mo_start)
     {
         return;
     }
+    free_map_objects(mo_start->owns);
     free_map_objects(mo_start->next);
     free(mo_start);
 }
 
 
 
-extern struct MapObj * get_player(struct World * world)
+extern void own_map_object(struct MapObj ** target, struct MapObj ** source,
+                           uint8_t id)
 {
-    struct MapObj * ptr = world->map_objs;
-    while (1)
+    struct MapObj * mo;
+    if (id == (*source)->id)
     {
-        if (NULL == ptr)
-        {
-            return ptr;
-        }
-        if (0 == ptr->id)
+        mo = * source;
+        * source = mo->next;
+    }
+    else
+    {
+        struct MapObj * penult = * source;
+        while (1)
         {
-            return ptr;
+            if (id == penult->next->id)
+            {
+                break;
+            }
+            penult = penult->next;
         }
-        ptr = ptr->next;
+        mo = penult->next;
+        penult->next = mo->next;
     }
+    struct MapObj ** last_ptr_ptr = target;
+    struct MapObj * mo_ptr;
+    while (NULL != * last_ptr_ptr)
+    {
+        mo_ptr = * last_ptr_ptr;
+        last_ptr_ptr = & mo_ptr->next;
+    }
+    * last_ptr_ptr = mo;
+    mo->next = NULL;
+}
+
+
+
+extern struct MapObj * get_player(struct World * world)
+{
+    return get_map_object(world->map_objs, 0);
 }
 
 
@@ -194,3 +294,15 @@ extern struct MapObjDef * get_map_object_def(struct World * w, uint8_t id)
     }
     return mod;
 }
+
+
+
+extern void set_object_position(struct MapObj * mo, struct yx_uint16 pos)
+{
+    mo->pos = pos;
+    struct MapObj * owned = mo->owns;
+    for (; owned != NULL; owned = owned->next)
+    {
+        set_object_position(owned, pos);
+    }
+}
index 5cbab7bc3e44effce04aa7a124eb0809b696156a..1489711279bb4d9e96cf9ce21e16c8e31cb69a7f 100644 (file)
@@ -19,6 +19,7 @@ struct World;
 struct MapObj
 {
     struct MapObj * next;        /* pointer to next one in map object chain */
+    struct MapObj * owns;        /* chain of map objects owned / in inventory */
     uint8_t id;                  /* individual map object's unique identifier */
     uint8_t type;                /* ID of appropriate map object definition */
     uint8_t lifepoints;          /* 0: object is inanimate; >0: hitpoints */
@@ -74,6 +75,12 @@ extern void free_map_objects(struct MapObj * mo_start);
 
 
 
+/* Move object of "id" from "source" inventory to "target" inventory. */
+extern void own_map_object(struct MapObj ** target, struct MapObj ** source,
+                           uint8_t id);
+
+
+
 /* Get pointer to the MapObj struct that represents the player. */
 extern struct MapObj * get_player(struct World * world);
 
@@ -84,4 +91,9 @@ extern struct MapObjDef * get_map_object_def(struct World * w, uint8_t id);
 
 
 
+/* Move not only "mo" to "pos", but also all map objects owned by it. */
+extern void set_object_position(struct MapObj * mo, struct yx_uint16 pos);
+
+
+
 #endif
index 522af09b9a8ea807c1ac4595cd4f1751a4666a90..aa855cd19c39fbe9416fa5986fe37036da4e5c7b 100644 (file)
@@ -9,7 +9,7 @@
 #include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian](),
                         * try_fopen(), try_fclose()
                         */
-#include "map_objects.h" /* for struct MapObj, read_map_objects(),
+#include "map_objects.h" /* for struct MapObj, get_player(), read_map_objects(),
                           * write_map_objects()
                           */
 #include "map_object_actions.h" /* for is_passable(), move_actor() */
@@ -234,11 +234,9 @@ extern void turn_over(struct World * world, char action)
 extern void save_game(struct World * world)
 {
     char * f_name = "save_game()";
-
     char * savefile_tmp = "savefile_tmp";
     char * savefile     = "savefile";
     FILE * file = try_fopen(savefile_tmp, "w", world, f_name);
-
     char line[12];
     sprintf(line, "%d\n", world->seed);
     try_fwrite(line, strlen(line), 1, file, world, f_name);
@@ -247,7 +245,6 @@ extern void save_game(struct World * world)
     sprintf(line, "%d\n", world->score);
     try_fwrite(line, strlen(line), 1, file, world, f_name);
     write_map_objects(world, file);
-
     try_fclose_unlink_rename(file, savefile_tmp, savefile, world, f_name);
 }
 
@@ -282,3 +279,29 @@ extern struct yx_uint16 find_passable_pos(struct Map * map)
     }
     return pos;
 }
+
+
+
+extern void nav_inventory(struct World * world, char dir)
+{
+    if ('u' == dir)
+    {
+        if (world->inventory_select > 0)
+        {
+            world->inventory_select--;
+        }
+        return;
+    }
+    struct MapObj * player = get_player(world);
+    struct MapObj * owned = player->owns;
+    if (NULL == owned)
+    {
+        return;
+    }
+    uint8_t n_owned = 0;
+    for (; NULL != owned->next; owned = owned->next, n_owned++);
+    if (world->inventory_select < n_owned)
+    {
+        world->inventory_select++;
+    }
+}
index b6923087b5068f20af114e6d118347d409797207..c823af6223c590fddf9a41efbdbbfdba2dc0659f 100644 (file)
@@ -79,4 +79,11 @@ extern struct yx_uint16 find_passable_pos(struct Map * map);
 
 
 
+/* Navigate (as far as possible) up (dir=='u') or (else) down in player's
+ * inventory selection.
+ */
+extern void nav_inventory(struct World * world, char dir);
+
+
+
 #endif