home · contact · privacy
The player is now a map object like any other. All actor contacts now lead to violenc...
authorChristian Heller <c.heller@plomlompom.de>
Thu, 26 Sep 2013 02:39:21 +0000 (04:39 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 26 Sep 2013 02:39:21 +0000 (04:39 +0200)
12 files changed:
config/defs
src/control.c
src/draw_wins.c
src/main.c
src/main.h
src/map.c
src/map.h
src/map_object_actions.c
src/map_object_actions.h
src/map_objects.c
src/map_objects.h
src/misc.c

index dda0c774442ec384b43ce3ca424018e364e5f191..4689c6c60f21d8ada00eede5278a1a280717e2f4 100644 (file)
@@ -1,3 +1,4 @@
+0 5 @ 5 HUMAN
 1 4 a 1 ANT
 2 5 z 3 ZOMBIE
 3 5 S 9 SHOGGOTH
index 975010e49fbb1cd6133455c91bcbce01456c63d4..874601b90d32092e946e97c95ffc6911c38b2ccf 100644 (file)
@@ -8,7 +8,7 @@
 #include "keybindings.h" /* for get_keycode_to_action(), mod_selected_keyb(),
                           * move_keyb_mod_selection()
                           */
-#include "map.h" /* for map_scroll(), map_center_player(), dir enum */
+#include "map.h" /* for map_scroll(), map_center_object() */
 #include "main.h" /* for World struct */
 #include "rexit.h" /* for exit_err() */
 #include "wincontrol.h" /* for scroll_pad(), toggle_window(),
@@ -20,6 +20,8 @@
 #include "misc.h" /* for load_interface_conf(), unload_interface_conf(),
                    * save_interface_conf()
                    */
+#include "yx_uint16.h" /* for dir enum */
+#include "map_objects.h" /* for get_player() */
 
 
 
@@ -302,7 +304,7 @@ extern uint8_t meta_control(int key, struct World * world)
     }
     else if (key == get_available_keycode_to_action(world, "map_c"))
     {
-        map_center_player(world->map, world->player, win_map->frame.size);
+        map_center_object(world->map, get_player(world), win_map->frame.size);
     }
     else if (key == get_available_keycode_to_action(world, "reload_conf"))
     {
index 2b04ff4e93f6f2a6c4a7e8915e284305f9fe20b6..1ca2c85820ff941151fc8bbd12e2e1ef024d0730 100644 (file)
@@ -8,7 +8,9 @@
 #include "windows.h"     /* for structs Win, Frame, for draw_scroll_hint() */
 #include "misc.h"        /* for center_offset(), try_malloc() */
 #include "keybindings.h" /* for struct KeyBinding, for get_name_to_keycode() */
-#include "map_objects.h" /* for structs MapObj, Player, get_map_object_def() */
+#include "map_objects.h" /* for structs MapObj, get_map_object_def(),
+                          * get_player()
+                          */
 #include "map.h"         /* for Map struct */
 #include "main.h"        /* for World struct */
 #include "rexit.h"       /* for err_exit() */
@@ -192,17 +194,23 @@ static void draw_map_objects(struct World * world, struct MapObj * start,
     struct MapObj * o;
     struct MapObjDef * d;
     char c;
-    for (o = start; o != 0; o = o->next)
+    uint8_t i;
+    for (i = 0; i < 2; i++)
     {
-        if (   o->pos.y >= map->offset.y
-            && o->pos.y <  map->offset.y + win->frame.size.y
-            && o->pos.x >= map->offset.x
-            && o->pos.x <  map->offset.x + win->frame.size.x)
+        for (o = start; o != 0; o = o->next)
         {
-            d = get_map_object_def(world, o->type);
-            c = d->char_on_map;
-            mvwaddch(win->frame.curses_win,
-                     o->pos.y - map->offset.y, o->pos.x - map->offset.x, c);
+            if (   (   (0 == i && 0 == o->lifepoints)      /* Draw in-animate */
+                    || (1 == i && 0 < o->lifepoints))      /* objects first.  */
+                && o->pos.y >= map->offset.y
+                && o->pos.y <  map->offset.y + win->frame.size.y
+                && o->pos.x >= map->offset.x
+                && o->pos.x <  map->offset.x + win->frame.size.x)
+            {
+                d = get_map_object_def(world, o->type);
+                c = d->char_on_map;
+                mvwaddch(win->frame.curses_win,
+                         o->pos.y - map->offset.y, o->pos.x - map->offset.x, c);
+            }
         }
     }
 }
@@ -324,7 +332,6 @@ extern void draw_win_map(struct Win * win)
 {
     struct World * world = (struct World *) win->data;
     struct Map * map = world->map;
-    struct Player * player = world->player;
     char * cells = map->cells;
     uint16_t width_map_av  = map->size.x  - map->offset.x;
     uint16_t height_map_av = map->size.y - map->offset.y;
@@ -342,15 +349,6 @@ extern void draw_win_map(struct Win * win)
         }
     }
     draw_map_objects(world, world->map_objs, map, win);
-    if (   player->pos.y >= map->offset.y
-        && player->pos.y <  map->offset.y + win->frame.size.y
-        && player->pos.x >= map->offset.x
-        && player->pos.x <  map->offset.x + win->frame.size.x)
-    {
-        mvwaddch(win->frame.curses_win,
-                 player->pos.y - map->offset.y, player->pos.x - map->offset.x,
-                 '@');
-    }
 }
 
 
@@ -364,9 +362,10 @@ extern void draw_win_info(struct Win * win)
     uint16_t maxl = strlen(dsc_turn) + strlen(dsc_hitpoints) + strlen(dsc_score)
                     + 10 + 5 + 10;       /* max strlens of numbers to be used */
     char text[maxl + 1];
+    struct MapObj * player = get_player(world);
     sprintf(text, "%s%d%s%d%s%d",
             dsc_turn, world->turn,
-            dsc_hitpoints, world->player->hitpoints,
+            dsc_hitpoints, player->lifepoints,
             dsc_score, world->score);
     draw_with_linebreaks(win, text, 0);
 }
index 06156fc5b01f3cd117de54dad1051044d0e79c95..adeddceec5753080b9416d704b59aec3074631ca 100644 (file)
                         * write_uint32_bigendian(), try_fopen(), try_fclose(),
                         * try_fclose_unlink_rename()
                         */
-#include "map_objects.h" /* for structs MapObj Player, init_map_object_defs(),
-                          * build_map_objects()
+#include "map_objects.h" /* for structs MapObj, init_map_object_defs(),
+                          * build_map_objects(), get_player()
                           */
-#include "map.h" /* for struct Map, init_map() */
+#include "map.h" /* for struct Map, init_map(), map_center_object() */
 #include "misc.h" /* for update_log(), find_passable_pos(), save_game(),
                    * try_calloc(), check_tempfile(), check_xor_files(),
                    * load_interface_conf(), load_game()
@@ -78,17 +78,14 @@ int main(int argc, char *argv[])
         }
     }
 
-    /* Initialize log, player, monster/item definitions and monsters/items. */
+    /* Initialize log and map object definitions. */
     world.score = 0;
     world.log = try_calloc(1, sizeof(char), &world, f_name);
     set_cleanup_flag(CLEANUP_LOG);
     update_log(&world, " ");
-    struct Player player;
-    player.hitpoints = 5;
-    world.player = &player;
     init_map_object_defs(&world, "config/defs");
     set_cleanup_flag(CLEANUP_MAP_OBJECT_DEFS);
-    world.map_obj_count = 1;
+    world.map_obj_count = 0;
 
     /* For interactive mode, try to load world state from savefile. */
     char * err_r = "Trouble loading game (in main()) / "
@@ -137,8 +134,9 @@ int main(int argc, char *argv[])
     set_cleanup_flag(CLEANUP_MAP);
     if (0 == world.turn)
     {
-        player.pos = find_passable_pos(world.map);
         world.map_objs = NULL;
+        world.last_map_obj = NULL;
+        add_map_objects(&world, 0, 1);
         add_map_objects(&world, 1, 1 + rrand() % 27);
         add_map_objects(&world, 2, 1 + rrand() % 9);
         add_map_objects(&world, 3, 1 + rrand() % 3);
@@ -163,8 +161,9 @@ int main(int argc, char *argv[])
     err_winmem = "Trouble with draw_all_wins() in main().";
 
     /* Focus map on player. */
+    struct MapObj * player = get_player(&world);
     struct Win * win_map = get_win_by_id(&world, 'm');
-    map_center_player(&map, &player, win_map->frame.size);
+    map_center_object(&map, player, win_map->frame.size);
 
     /* Replay mode. */
     int key;
@@ -231,7 +230,7 @@ int main(int argc, char *argv[])
 
             if  (   (1 == wc->view && wingeom_control(key, &world))
                  || (2 == wc->view && winkeyb_control(key, &world))
-                 || (0 != player.hitpoints && player_control(key, &world)))
+                 || (0 != player->lifepoints && player_control(key, &world)))
             {
                 continue;
             }
index a2900997a76873ec6a66ab7b87fd2eb8050bb418..cd6e6c0657e950b173c2fff4f75c334f246d62ce 100644 (file)
@@ -34,10 +34,10 @@ struct World
     struct WinMeta * wmeta;           /* Pointer to window manager's WinMeta. */
     struct WinConf * winconfs;        /* Pointer to windows' configurations. */
     char * winconf_ids;               /* Pointer to string of Winconfs' ids. */
-    struct Player * player;           /* Pointer to the player data. */
     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;         /* Map objects chain. */
+    struct MapObj * map_objs;         /* Pointer to map objects chain start. */
+    struct MapObj * last_map_obj;     /* Pointer to map objects chain end. */
 };
 
 
index 94def7631c69527f0163847db13027eef0f54e84..368c0e2c0ac6d8d8fe08f7c9e08ddd7ec0f10a78 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -77,9 +77,9 @@ void map_scroll (struct Map * map, enum dir d, struct yx_uint16 win_size)
 
 
 
-void map_center_player(struct Map * map, struct Player * player,
+void map_center_object(struct Map * map, struct MapObj * object,
                        struct yx_uint16 win_size)
 {
-    map->offset.y = center_offset (player->pos.y, map->size.y, win_size.y);
-    map->offset.x = center_offset (player->pos.x, map->size.x, win_size.x);
+    map->offset.y = center_offset(object->pos.y, map->size.y, win_size.y);
+    map->offset.x = center_offset(object->pos.x, map->size.x, win_size.x);
 }
index ac303a40036fe3660938c015cf9a33fb6fcda5b9..73825c0446845b051fc2eacd3380a8ba07f391f8 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -9,8 +9,7 @@
 
 
 #include "yx_uint16.h" /* for yx_uint16 and dir enums */
-struct Player;
-
+struct MapObj;
 
 
 struct Map
@@ -38,10 +37,10 @@ extern struct Map init_map();
  */
 extern void map_scroll(struct Map * map, enum dir d, struct yx_uint16 win_size);
 
-/* Scroll map to center on the player by changing the scroll offset following
+/* Scroll map to center on the "object" by changing the scroll offset following
  * (and constrained by) the window size as described by "win_size".
  */
-extern void map_center_player(struct Map * map, struct Player * player,
+extern void map_center_object(struct Map * map, struct MapObj * object,
                               struct yx_uint16 win_size);
 
 
index 23152e229de5d78476178c20feb3d6e179b68900..3e9ead2e2846e09dcc2a74ab63818ad41806c519 100644 (file)
 #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 "misc.h" /* for update_log(), turn_over() */
 #include "map.h" /* for Map struct */
 #include "main.h" /* for World struct */
-#include "map_objects.h" /* for structs MapObj, MapObjDef,
-                          * get_map_object_def()
-                          */
-#include "rrand.h" /* for rrand() */
 #include "command_db.h" /* for get_command_id() */
 
 
 
-/* Log monster (described by "dsc_monster1") bumping into "monster2". */
-static void monster_bumps_monster(struct World * world, char * dsc_monster1,
-                                  struct MapObj * monster2);
-
-/* Decrement player HPs due to attack of monster described by "dsc_monster",
- * kill player if his HP hit zero; log the whole action.
- */
-static void monster_hits_player(struct World * world, char * dsc_monster);
-
-/* Decrement HP of "monster" hit by player, kill it if its HP hit zero, create a
- * corpse and increment player's score by the amount of hitpoints the monster
- * started with; log the whole action.
- */
-static void player_hits_monster(struct World * world, struct MapObj * monster);
-
-/* Try moving the player in direction "d" towards coordinate "target"; log
- * success or failure of the whole action.
+/* One actor "wounds" another actor, decrementing his lifepoints and, if they
+ * reach zero in the process, killing it. Generates appropriate log message.
  */
-static void try_player_move(struct World * world,
-                            enum dir d, struct yx_uint16 target);
-
-
-
-static void monster_bumps_monster(struct World * world, char * dsc_monster1,
-                                  struct MapObj * monster2)
-{
-    char * bump_dsc = " bumps into ";
-    struct MapObjDef * mod = get_map_object_def(world, monster2->type);
-    char msg[strlen(dsc_monster1) + strlen(bump_dsc) + strlen(mod->name) + 3];
-    sprintf(msg, "\n%s%s%s.", dsc_monster1, bump_dsc, mod->name);
-    update_log(world, msg);
-}
+static void actor_hits_actor(struct World * world, struct MapObj * hitter,
+                             struct MapObj * hitted)
 
 
 
-static void monster_hits_player(struct World * world, char * dsc_monster)
+static void actor_hits_actor(struct World * world, struct MapObj * hitter,
+                             struct MapObj * hitted)
 {
-    char * hit_dsc = " hits you";
-    char msg[strlen(dsc_monster) + strlen(hit_dsc) + 3];
-    sprintf(msg, "\n%s%s.", dsc_monster, hit_dsc);
-    update_log(world, msg);
-    world->player->hitpoints--;
-
-    if (0 == world->player->hitpoints)
-    {
-        update_log(world, "\nYou are dead.");
-    }
-}
-
-
-
-static void player_hits_monster(struct World * world, struct MapObj * monster)
-{
-    struct MapObjDef * mod = get_map_object_def(world, monster->type);
-    char * hit_dsc = "You hit the ";
-    char * monster_dsc = mod->name;
-    char hitmsg[strlen(hit_dsc) + strlen(monster_dsc) + 3];
-    sprintf(hitmsg, "\n%s%s.", hit_dsc, monster_dsc);
-    update_log(world, hitmsg);
-    monster->lifepoints--;
-    if (0 == monster->lifepoints)
-    {
-        hit_dsc = "You kill the ";
-        char kill_msg[strlen(hit_dsc) + strlen(monster_dsc) + 3];
-        sprintf(kill_msg, "\n%s%s.", hit_dsc, monster_dsc);
-        update_log(world, kill_msg);
-        struct MapObjDef * md = mod;
-        monster->type = md->corpse_id;
-        uint8_t score = md->lifepoints;
-        world->score = world->score + score;
-    }
-}
-
-
-
-static void try_player_move(struct World * world,
-                            enum dir d, struct yx_uint16 target)
-{
-    char * dsc_dir;
-    if      (NORTH == d)
-    {
-        dsc_dir = "north";
-    }
-    else if (EAST  == d)
-    {
-        dsc_dir = "east" ;
-    }
-    else if (SOUTH == d)
+    struct MapObjDef * mod_hitter = get_map_object_def(world, hitter->type);
+    struct MapObjDef * mod_hitted = get_map_object_def(world, hitted->type);
+    struct MapObj * player = get_player(world);
+    char * msg1 = "You";
+    char * msg2 = "wound";
+    char * msg3 = "you";
+    if      (player != hitter)
     {
-        dsc_dir = "south";
+        msg1 = mod_hitter->name;
+        msg2 = "wounds";
     }
-    else if (WEST  == d)
+    if (player != hitted)
     {
-        dsc_dir = "west" ;
+        msg3 = mod_hitted->name;
     }
-    char * dsc_move = "You fail to move ";
-    if (is_passable(world->map, target))
+    uint8_t len = 1 + strlen(msg1) + 1 + strlen(msg2) + 1 + strlen(msg3) + 2;
+    char msg[len];
+    sprintf(msg, "\n%s %s %s.", msg1, msg2, msg3);
+    update_log(world, msg);
+    hitted->lifepoints--;
+    if (0 == hitted->lifepoints)
     {
-        dsc_move = "You move ";
-        world->player->pos = target;
+        hitted->type = mod_hitted->corpse_id;
+        if (player == hitted)
+        {
+            update_log(world, " You die.");
+        }
+        else
+        {
+            update_log(world, " It dies.");
+            if (player == hitter)
+            {
+                world->score = world->score + mod_hitted->lifepoints;
+            }
+        }
     }
-    char msg[strlen(dsc_move) + strlen (dsc_dir) + 3];
-    sprintf(msg, "\n%s%s.", dsc_move, dsc_dir);
-    update_log(world, msg);
 }
 
 
 
-extern void move_monster(struct World * world, struct MapObj * monster)
+extern uint8_t move_actor(struct World * world, struct MapObj * actor,
+                          enum dir d)
 {
-    char d = rrand() % 5;
-    struct yx_uint16 t = mv_yx_in_dir(d, monster->pos);
-    struct MapObjDef * mod = get_map_object_def(world, monster->type);
-    char * dsc = mod->name;
-    if (yx_uint16_cmp(&t, &world->player->pos))
+    struct yx_uint16 target = mv_yx_in_dir(d, actor->pos);
+    struct MapObj * other_actor;
+    for (other_actor = world->map_objs;
+         other_actor != 0;
+         other_actor = other_actor->next)
     {
-        monster_hits_player(world, dsc);
-        return;
-    }
-    struct MapObj * other_monster;
-    for (other_monster = world->map_objs;
-         other_monster != 0;
-         other_monster = other_monster->next)
-    {
-        if (0 == other_monster->lifepoints || other_monster == monster)
+        if (0 == other_actor->lifepoints || other_actor == actor)
         {
             continue;
         }
-        if (yx_uint16_cmp(&t, &other_monster->pos))
+        if (yx_uint16_cmp(&target, &other_actor->pos))
         {
-            monster_bumps_monster(world, dsc, other_monster);
-            return;
+            actor_hits_actor(world, actor, other_actor);
+            return 2;
         }
     }
-    if (is_passable(world->map, t))
+    if (is_passable(world->map, target))
     {
-        monster->pos = t;
+        actor->pos = target;
+        return 0;
     }
+    return 1;
 }
 
 
 
 extern void move_player(struct World * world, enum dir d)
 {
+    char * dsc_dir;
     char * action_dsc_prototype = "player_";
-    uint8_t len = strlen(action_dsc_prototype);
-    char action_dsc[len + 2];
-    memcpy(action_dsc, action_dsc_prototype, len);
+    uint8_t len_action_dsc_prototype = strlen(action_dsc_prototype);
+    char action_dsc[len_action_dsc_prototype + 2];
+    memcpy(action_dsc, action_dsc_prototype, len_action_dsc_prototype);
     if      (NORTH == d)
     {
-        action_dsc[len] = 'u';
+        dsc_dir = "north";
+        action_dsc[len_action_dsc_prototype] = 'u';
     }
-    else if (SOUTH == d)
+    else if (EAST  == d)
     {
-        action_dsc[len] = 'd';
+        dsc_dir = "east" ;
+        action_dsc[len_action_dsc_prototype] = 'r';
     }
-    else if (WEST  == d)
+    else if (SOUTH == d)
     {
-        action_dsc[len] = 'l';
+        dsc_dir = "south";
+        action_dsc[len_action_dsc_prototype] = 'd';
     }
-    else if (EAST  == d)
+    else if (WEST  == d)
     {
-        action_dsc[len] = 'r';
+        dsc_dir = "west" ;
+        action_dsc[len_action_dsc_prototype] = 'l';
     }
-    action_dsc[len + 1] = '\0';
-    uint8_t action_id = get_command_id(world, action_dsc);
-    struct yx_uint16 t = mv_yx_in_dir(d, world->player->pos);
-    struct MapObj * monster;
-    for (monster = world->map_objs;
-         monster != 0;
-         monster = monster->next)
+    action_dsc[len_action_dsc_prototype + 1] = '\0';
+    uint8_t res = move_actor(world, get_player(world), d);
+    if (1 >= res)
     {
-        if (0 < monster->lifepoints && yx_uint16_cmp(&t, &monster->pos))
+        char * dsc_move = "You fail to move ";
+        if   (0 == res)
         {
-            player_hits_monster(world, monster);
-            turn_over(world, action_id);
-            return;
-          }
+            dsc_move = "You move ";
+        }
+        char msg[strlen(dsc_move) + strlen (dsc_dir) + 3];
+        sprintf(msg, "\n%s%s.", dsc_move, dsc_dir);
+        update_log(world, msg);
     }
-    try_player_move(world, d, t);
-    turn_over(world, action_id);
+    turn_over(world, get_command_id(world, action_dsc));
 }
 
 
 
-extern void player_wait (struct World * world)
+extern void player_wait(struct World * world)
 {
     update_log(world, "\nYou wait.");
     turn_over(world, get_command_id(world, "wait"));
@@ -207,7 +144,7 @@ extern void player_wait (struct World * world)
 
 
 
-extern char is_passable (struct Map * map, struct yx_uint16 pos)
+extern char is_passable(struct Map * map, struct yx_uint16 pos)
 {
     char passable = 0;
     if (0 <= pos.x && pos.x < map->size.x && 0 <= pos.y && pos.y < map->size.y)
index ae764b9f1ea746d97fd1c555f9eb003f977e3cf3..3041c9c2fc0c4089d40feb4fac3f71931fce2889 100644 (file)
@@ -15,22 +15,21 @@ struct MapObj;
 
 
 
-/* Try to move "monster" in random direction. On contact with other monster,
- * only bump. On contact with player, fight / reduce player's hitpoints,
- * and thereby potentially trigger the player's death. Update the log for any
- * contact action.
+/* Try to move "actor" one step in direction "d" and handle the consequences:
+ * either the move succeeds, or another actor is encountered and hit (which leads
+ * to its lifepoint decreasing by one and potentially its death), or the target
+ * square is not passable and the move fails.
  */
-extern void move_monster(struct World * world, struct MapObj * monster);
+extern uint8_t move_actor(struct World * world, struct MapObj * actor,
+                          enum dir d);
 
 
 
-/* Try to move player in direction "d". On contact with monster, fight / reduce
- * monster's hitpoints, and thereby potentially trigger the monster's death,
- * create a corpse and increment the player's score by the amount of hitpoints
- * the monster started with. Update the log on whatever the player did and turn
- * control over to the enemy.
+/* Wrapper for using move_actor() on the MapObj representing the player; updates
+ * the game log with appropriate messages on the move attempt and its results;
+ * turns over to turn_over() when finished.
  */
-extern void move_player (struct World * world, enum dir d);
+extern void move_player(struct World * world, enum dir d);
 
 
 
@@ -44,7 +43,7 @@ extern void player_wait(struct World * world);
 /* Check if coordinate pos on (or beyond) map is accessible to map object
  * movement.
  */
-extern char is_passable (struct Map * map, struct yx_uint16 pos);
+extern char is_passable(struct Map * map, struct yx_uint16 pos);
 
 
 
index 7e2472d0da521abe19b873088e7cb96f36571563..e825755b86a991b1b823756038d1df0a4181ec89 100644 (file)
@@ -78,9 +78,10 @@ extern void read_map_objects(struct World * world, FILE * file, char * line,
     char * f_name = "read_map_objects()";
     struct MapObj ** mo_ptr_ptr = &world->map_objs;
     char * delim = " ";
+    struct MapObj * mo;
     while (try_fgets(line, linemax + 1, file, world, f_name))
     {
-        struct MapObj * mo = malloc(sizeof(struct MapObj));
+        mo = malloc(sizeof(struct MapObj));
         mo->next = NULL;
         mo->id = atoi(strtok(line, delim));
         if (mo->id > world->map_obj_count)
@@ -94,6 +95,7 @@ extern void read_map_objects(struct World * world, FILE * file, char * line,
         * mo_ptr_ptr = mo;
         mo_ptr_ptr = &mo->next;
     }
+    world->last_map_obj = mo;
 }
 
 
@@ -108,8 +110,16 @@ extern void add_map_object(struct World * world, uint8_t type)
     mo->type = mod->id;
     mo->lifepoints = mod->lifepoints;
     mo->pos = find_passable_pos(world->map);
-    mo->next = world->map_objs;
-    world->map_objs = mo;
+    mo->next = NULL;
+    if (NULL == world->last_map_obj)
+    {
+        world->map_objs = mo;
+    }
+    else
+    {
+        world->last_map_obj->next = mo;
+    }
+    world->last_map_obj = mo;
 }
 
 
@@ -137,6 +147,25 @@ extern void free_map_objects(struct MapObj * mo_start)
 
 
 
+extern struct MapObj * get_player(struct World * world)
+{
+    struct MapObj * ptr = world->map_objs;
+    while (1)
+    {
+        if (NULL == ptr)
+        {
+            return ptr;
+        }
+        if (0 == ptr->id)
+        {
+            return ptr;
+        }
+        ptr = ptr->next;
+    }
+}
+
+
+
 extern struct MapObjDef * get_map_object_def(struct World * w, uint8_t id)
 {
     struct MapObjDef * mod = w->map_obj_defs;
index ced2ab3f161b4cc237d642bc0fabd28effe1ce14..a56595f79aaad4c7358b092c22817fca3f66b7db 100644 (file)
@@ -16,15 +16,6 @@ struct World;
 
 
 
-/* Player is non-standard: single and of a hard-coded type. */
-struct Player
-{
-    struct yx_uint16 pos;
-    uint8_t hitpoints;
-};
-
-
-
 struct MapObj
 {
     struct MapObj * next;        /* pointer to next one in map object chain */
@@ -80,6 +71,11 @@ extern void free_map_objects(struct MapObj * mo_start);
 
 
 
+/* Get pointer to the MapObj struct that represents the player. */
+extern struct MapObj * get_player(struct World * world);
+
+
+
 /* Get pointer to the map object definition of identifier "def_id". */
 extern struct MapObjDef * get_map_object_def(struct World * w, uint8_t id);
 
index 16ddc38a3f89cbff028bc1729cb34597fbe20bb8..522af09b9a8ea807c1ac4595cd4f1751a4666a90 100644 (file)
@@ -9,10 +9,10 @@
 #include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian](),
                         * try_fopen(), try_fclose()
                         */
-#include "map_objects.h" /* for struct Monster, read_map_objects(),
+#include "map_objects.h" /* for struct MapObj, read_map_objects(),
                           * write_map_objects()
                           */
-#include "map_object_actions.h" /* for is_passable(), move_monster() */
+#include "map_object_actions.h" /* for is_passable(), move_actor() */
 #include "map.h" /* for Map struct */
 #include "main.h" /* for World struct */
 #include "yx_uint16.h" /* for yx_uint16 struct */
@@ -222,9 +222,9 @@ extern void turn_over(struct World * world, char action)
          monster != 0;
          monster = monster->next)
     {
-        if (0 < monster->lifepoints)
+        if (0 < monster->lifepoints && 0 != monster->id)
         {
-            move_monster(world, monster);
+            move_actor(world, monster, rrand() % 5);
         }
     }
 }
@@ -246,12 +246,6 @@ extern void save_game(struct World * world)
     try_fwrite(line, strlen(line), 1, file, world, f_name);
     sprintf(line, "%d\n", world->score);
     try_fwrite(line, strlen(line), 1, file, world, f_name);
-    sprintf(line, "%d\n", world->player->hitpoints);
-    try_fwrite(line, strlen(line), 1, file, world, f_name);
-    sprintf(line, "%d\n", world->player->pos.y);
-    try_fwrite(line, strlen(line), 1, file, world, f_name);
-    sprintf(line, "%d\n", world->player->pos.x);
-    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);
@@ -272,12 +266,6 @@ extern void load_game(struct World * world)
     world->turn = atoi(line);
     try_fgets(line, linemax + 1, file, world, f_name);
     world->score = atoi(line);
-    try_fgets(line, linemax + 1, file, world, f_name);
-    world->player->hitpoints = atoi(line);
-    try_fgets(line, linemax + 1, file, world, f_name);
-    world->player->pos.y = atoi(line);
-    try_fgets(line, linemax + 1, file, world, f_name);
-    world->player->pos.x = atoi(line);
     read_map_objects(world, file, line, linemax);
     try_fclose(file, world, f_name);
 }