home · contact · privacy
Server: Force FOV on every actor, but update it on movement only.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 14 May 2014 02:09:35 +0000 (04:09 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 14 May 2014 02:09:35 +0000 (04:09 +0200)
README
confserver/world
src/server/ai.c
src/server/configfile.c
src/server/init.c
src/server/io.c
src/server/map_object_actions.c
src/server/map_object_actions.h
src/server/map_objects.c
src/server/map_objects.h

diff --git a/README b/README
index 1923471d851ed791720fbc071a5eb9ff8de3bee6..2a0206deb2935950eeb388b70ac7a09c0812a840 100644 (file)
--- a/README
+++ b/README
@@ -12,10 +12,8 @@ to gain hitpoints. Note that different kinds of movements/actions take different
 numbers of turns to finish.
 
 Enemies' AI is very dumb so far: Each turn, they try to move towards their
-shortest-path-wise nearest enemy. If no enemy is found in their surroundings,
-they just wait. Contrary to the player, they by default see the whole map. (To
-make them see only what is in their line of sight, enable ENEMY_FOV in the
-server config file; see below "Hacking / server internals and configuration".)
+shortest-path-wise nearest enemy visible to them. If they see no enemy, they
+just wait.
 
 Once you start a new world, every move of yours is recorded in a file called
 "record". Once you re-start the game, all of your previous moves are replayed
@@ -134,10 +132,7 @@ after, it may even be the same). "START_NUMBER" sets the number of objects that
 are to appear of the given type on the map on game start.
 
 A line of "PLAYER_TYPE" followed by a number sets the map object type (id) of
-the player's creature. "ENEMY_FOV" followed by "0" or "1" sets whether enemies
-see the whole map or only that to which they have an unobstructed line of sight.
-Since plomrogue's FOV algorithm is currently very expensive, this is disabled by
-default.
+the player's creature.
 
 All these definition block members must be present within their blocks, but only
 "ACTION" / "OBJECT" / "MAP_TYPE" must be positioned at their respective blocks'
index bf2488cb102eeeca631e1d31b351ca176bb10c8e..724d0120f2d6056fb439383712443fd42cc672b2 100644 (file)
@@ -3,7 +3,6 @@ HEIGHT 64
 WIDTH 64
 
 PLAYER_TYPE 0
-ENEMY_FOV 0
 
 ACTION 1
 NAME wait
index d099c5748ce2d69ca6df26e3652d9141532d787c..1596d5ae1915d600712ed99657e2e0bffd563dcc 100644 (file)
@@ -5,7 +5,7 @@
 #include <stdint.h> /* uint8_t, uint16_t, uint32_t, UINT16_MAX */
 #include <stdlib.h> /* free() */
 #include "../common/try_malloc.h" /* try_malloc() */
-#include "field_of_view.h" /* build_fov_map() */
+#include "field_of_view.h" /* VISIBLE */
 #include "map_object_actions.h" /* get_moa_id_by_name() */
 #include "map_objects.h" /* struct MapObj */
 #include "world.h" /* global world */
@@ -129,20 +129,11 @@ static char get_dir_to_nearest_enemy(struct MapObj * mo_origin)
     uint32_t map_size = world.map.size.y * world.map.size.x;
     uint16_t max_score = UINT16_MAX - 1;
     uint16_t * score_map = try_malloc(map_size * sizeof(uint16_t), f_name);
-    uint8_t * fov_map = world.enemy_fov ? build_fov_map(mo_origin) : NULL;
     uint32_t i;
     for (i = 0; i < map_size; i++)
     {
-        if (world.enemy_fov)
-        {
-            score_map[i] = fov_map[i] & VISIBLE ? max_score : UINT16_MAX;
-        }
-        else
-        {
-            score_map[i] = max_score;
-        }
+        score_map[i] = mo_origin->fov_map[i] & VISIBLE ? max_score : UINT16_MAX;
     }
-    free(fov_map);
     struct MapObj * mo = world.map_objs;
     for (; mo != NULL; mo = mo->next)
     {
index 14464396dc7e93ff6af93396d8a0faee0e2f78bf..fc2c771f42d952a3c5c5721d8dd533153ee264f1 100644 (file)
@@ -93,9 +93,6 @@ static void test_corpse_ids();
 /* set_members() helper specifically for editing world.map members. */
 static uint8_t set_map_members(char * token0,char * token1,uint8_t * map_flags);
 
-/* If "token0" matches "comparand", set world.enemy_fov to "token1". */
-static uint8_t set_enemy_fov(char * token0, char * comparand, char * token1);
-
 /* If "token0" matches "comparand", set world.player_type to int in "token1". */
 static uint8_t set_player_type(char * token0, char * comparand, char * token1);
 
@@ -124,7 +121,6 @@ static void tokens_into_entries(char * token0, char * token1)
     char * str_obj = "OBJECT";
     char * str_map = "MAP_TYPE";
     char * str_player = "PLAYER_TYPE";
-    char * str_enemyfov = "ENEMY_FOV";
     static struct MapObjAct ** moa_p_p = &world.map_obj_acts;
     static struct MapObjDef ** mod_p_p = &world.map_obj_defs;
     static uint8_t action_flags = READY_ACT;
@@ -133,8 +129,7 @@ static void tokens_into_entries(char * token0, char * token1)
     static struct EntryHead * moa = NULL;
     static struct EntryHead * mod = NULL;
     if (!token0 || !strcmp(token0, str_act) || !strcmp(token0, str_obj)
-                || !strcmp(token0, str_map) || !strcmp(token0, str_player)
-                || !strcmp(token0, str_enemyfov))
+                || !strcmp(token0, str_map) || !strcmp(token0, str_player))
     {
         parse_and_reduce_to_readyflag(&action_flags, READY_ACT);
         parse_and_reduce_to_readyflag(&object_flags, READY_OBJ);
@@ -157,7 +152,6 @@ static void tokens_into_entries(char * token0, char * token1)
                                   (struct EntryHead *) world.map_obj_defs)
                    || start_map(token0, str_map, &map_flags)
                    || set_player_type(token0, str_player, token1)
-                   || set_enemy_fov(token0, str_enemyfov, token1)
                    || set_members(token0, token1, &object_flags, &action_flags,
                                   &map_flags, (struct MapObjDef *)mod,
                                   (struct MapObjAct *) moa)))
@@ -261,21 +255,6 @@ static uint8_t set_map_members(char * token0, char * token1,uint8_t * map_flags)
 
 
 
-static uint8_t set_enemy_fov(char * token0, char * comparand, char * token1)
-{
-    if (strcmp(token0, comparand))
-    {
-        return 0;
-    }
-    parsetest_int(token1, '8');
-    int test = atoi(token1) > 1;
-    err_line(test, "Value must be 0 or 1.");
-    world.enemy_fov = atoi(token1);
-    return 1;
-}
-
-
-
 static uint8_t set_player_type(char * token0, char * comparand, char * token1)
 {
     if (strcmp(token0, comparand))
index 89eea4f8844d1ee64f9ee243a2002ce67b8f1728..d8ae94f753a1fc66ddbd733c99875a12453254a5 100644 (file)
 #include "../common/rexit.h" /* exit_err() */
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "cleanup.h" /* set_cleanup_flag() */
+#include "field_of_view.h" /* build_fov_map() */
 #include "map.h" /* init_map() */
-#include "map_objects.h" /* MapObjDef, free_map_objects(), add_map_objects() */
+#include "map_objects.h" /* MapObj, MapObjDef, free_map_objects(),
+                          * add_map_objects(), get_player()
+                          */
 #include "run.h" /* obey_msg(), io_loop() */
 #include "world.h" /* global world */
 
@@ -103,6 +106,11 @@ extern void remake_world(uint32_t seed)
         }
     }
     set_cleanup_flag(CLEANUP_MAP_OBJECTS);
+    struct MapObj * mo;
+    for (mo = world.map_objs; NULL != mo; mo = mo->next)
+    {
+        mo->fov_map = mo->lifepoints ? build_fov_map(mo) : NULL;
+    }
     if (world.turn)
     {
         exit_trouble(unlink(world.path_record), f_name, "unlink()");
index 7fbb511055b2e30842a24b713bcfb5502dbf42ae..964e06a69f53a6b389f5f038997cc96f6c9f4b6a 100644 (file)
                                   */
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "cleanup.h" /* set_cleanup_flag() */
-#include "field_of_view.h" /* VISIBLE, build_fov_map() */
+#include "field_of_view.h" /* VISIBLE */
 #include "map.h" /* yx_to_map_pos() */
-#include "map_objects.h" /* structs MapObj, MapObjDef, get_map_obj_def() */
+#include "map_objects.h" /* structs MapObj, MapObjDef, get_map_obj_def(),
+                          * get_player()
+                          */
 #include "world.h" /* global world  */
 
 
@@ -197,14 +199,13 @@ static void write_inventory(struct MapObj * player, FILE * file)
 static char * build_visible_map(struct MapObj * player)
 {
     char * f_name = "build_visible_map()";
-    uint8_t * fov_map = build_fov_map(player);
     uint32_t map_size = world.map.size.y * world.map.size.x;
     char * visible_map = try_malloc(map_size, f_name);
     memset(visible_map, ' ', map_size);
     uint16_t pos_i;
     for (pos_i = 0; pos_i < map_size; pos_i++)
     {
-        if (fov_map[pos_i] & VISIBLE)
+        if (player->fov_map[pos_i] & VISIBLE)
         {
             visible_map[pos_i] = world.map.cells[pos_i];
         }
@@ -217,7 +218,7 @@ static char * build_visible_map(struct MapObj * player)
     {
         for (o = world.map_objs; o != 0; o = o->next)
         {
-            if (   fov_map[yx_to_map_pos(&o->pos)] & VISIBLE
+            if (   player->fov_map[yx_to_map_pos(&o->pos)] & VISIBLE
                 && (   (0 == i && 0 == o->lifepoints)
                     || (1 == i && 0 < o->lifepoints)))
             {
@@ -227,7 +228,6 @@ static char * build_visible_map(struct MapObj * player)
             }
         }
     }
-    free(fov_map);
     return visible_map;
 }
 
index 978683292af5b76ab902e8cb5f3525b540bd9d1c..6c92d07577eaade92234e042b2d64beb0d3c572e 100644 (file)
@@ -9,6 +9,7 @@
 #include "../common/rexit.h" /* exit_err() */
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "../common/yx_uint8.h" /* struct yx_uint8 */
+#include "field_of_view.h" /* build_fov_map() */
 #include "map_objects.h" /* structs MapObj, MapObjDef, get_player(),
                           * set_object_position(), own_map_object(),
                           * get_map_object_def()
@@ -262,6 +263,8 @@ extern void actor_move(struct MapObj * mo)
     if (passable)
     {
         set_object_position(mo, target);
+        free(mo->fov_map);
+        mo->fov_map = build_fov_map(mo);
     }
     if (mo == get_player())
     {
index 8133e538451f00df7195b0bfafa222a126cee79a..7192cb4d97515a91ad806684ea496393c863ba1f 100644 (file)
@@ -37,6 +37,7 @@ extern void actor_wait(struct MapObj * mo);
  * (where noth-east is 'e', east 'd' etc.) Move either succeeds, or another
  * actor is encountered and hit (which leads ot its lifepoint decreasing by one
  * and eventually death), or the move fails due to an impassable target square.
+ * On success, update object's field of view map.
  */
 extern void actor_move(struct MapObj * mo);
 
index ac36394ae9f5169bc37dcac87181d197a6ef634d..975c7487fe98906bf4d588c7b4350d02d0da6a13 100644 (file)
@@ -117,6 +117,7 @@ extern void free_map_objects(struct MapObj * mo_start)
     }
     free_map_objects(mo_start->owns);
     free_map_objects(mo_start->next);
+    free(mo_start->fov_map);
     free(mo_start);
     if (mo_start == world.map_objs)  /* So add_map_objects()' NULL-delimited  */
     {                                /* map object iteration loop does not    */
index d18e3c259f4df1f422420dc77da12a34c4ee74e2..1e32318e1c503f10e4d50481ac46408f0e280be6 100644 (file)
@@ -17,6 +17,7 @@ struct MapObj
     struct MapObj * next;        /* pointer to next one in map object chain */
     struct MapObj * owns;        /* chain of map objects owned / in inventory */
     struct yx_uint8 pos;         /* coordinate on map */
+    uint8_t * fov_map;           /* map of the object's field of view */
     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 */