home · contact · privacy
Server: Add inanimate things to map memory, integrate into AI searches.
authorChristian Heller <c.heller@plomlompom.de>
Sun, 17 Aug 2014 01:58:06 +0000 (03:58 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sun, 17 Aug 2014 01:58:06 +0000 (03:58 +0200)
SERVER_COMMANDS
src/server/ai.c
src/server/field_of_view.c
src/server/god_commands.c
src/server/god_commands.h
src/server/hardcoded_strings.c
src/server/hardcoded_strings.h
src/server/io.c
src/server/run.c
src/server/things.c
src/server/things.h

index 50ac853fe343e84a065304e021a9c85c6e950064..8af195fbdc5283a6e396666e669ff3dcf6716533 100644 (file)
@@ -164,6 +164,10 @@ T_MEMMAP [0 to 255] [string]
 Set part of selected thing's memory of the game map to string argument: the line
 of the argument's number.
 
+T_MEMTHING [0 to 255] [0 to 255] [0 to 255]
+Add to selected thing's memory of things on map thing of ID of first argument,
+y position of second argument and x position of third argument.
+
 TT_ID [-32768 to 32767]
 Select thing type to manipulate by argument as ID. If argument is <0 or <255,
 change it to the lowest unused thing type ID. If thing type of ID does not exist
index b6c8cbc4f77316f03b84ceb530f7447ff44ada92..cdefca844bb78dc87277b409d25f2f12ce183137 100644 (file)
@@ -7,7 +7,7 @@
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "hardcoded_strings.h" /* s */
 #include "thing_actions.h" /* get_thing_action_id_by_name() */
-#include "things.h" /* Thing, ThingType */
+#include "things.h" /* Thing, ThingType, ThingInMemory */
 #include "world.h" /* world */
 
 
@@ -39,18 +39,18 @@ static void init_score_map(char filter, uint16_t * score_map, uint32_t map_size,
                            struct Thing * t_eye);
 
 /* Set (if possible) as "t_eye"'s command a move to the path to the path-wise
- * nearest thing that is in "t_eye"'s field of view and not "t_eye" and fits
- * criteria set by "filter". On success, return 1, else 0. Values for "filter":
- * "e": thing searched for animate, but not of "t_eye"'s thing type; build
- *      path as avoiding things of "t_eye"'s type
- * "c": thing searched for is consumable.
+ * nearest thing that is not "t_eye" and fits criteria set by "filter". On
+ * success, return 1, else 0. Values for "filter":
+ * "e": thing in FOV is animate, but not of "t_eye"'s thing type; build path as
+ *      avoiding things of "t_eye"'s type
+ * "c": thing in memorized map is consumable.
  */
 static uint8_t get_dir_to_nearest_thing(struct Thing * t_eye, char filter);
 
-/* Return 1 if any thing not "t_eye" is in its FOV and fulfills some criterion
- * defined by "filter", else 0. Values for "filter":
- * "e": thing searched for is animate, but not of "t_eye"'s thing type
- * "c": thing searched for is consumable
+/* Return 1 if any thing not "t_eye" is known and fulfills some criteria defined
+ * by "filter", else 0. Values for "filter":
+ * "e": thing in FOV is animate, but not of "t_eye"'s thing type
+ * "c": thing in memorized map is consumable
  */
 static uint8_t seeing_thing(struct Thing * t_eye, char filter);
 
@@ -150,16 +150,13 @@ static void init_score_map(char filter, uint16_t * score_map, uint32_t map_size,
             score_map[i] = UINT16_MAX-1;
         }
     }
-    struct Thing * t = world.things;
-    for (; t != NULL; t = t->next)
+    if      ('e' == filter)
     {
-        if (t==t_eye || 'H'==t_eye->fov_map[t->pos.y*world.map.length+t->pos.x])
-        {
-            continue;
-        }
-        if      ('e' == filter)
+        struct Thing * t = world.things;
+        for (; t; t = t->next)
         {
-            if (!t->lifepoints)
+            if (   t==t_eye || !t->lifepoints
+                || 'H' == t_eye->fov_map[t->pos.y*world.map.length + t->pos.x])
             {
                 continue;
             }
@@ -168,16 +165,25 @@ static void init_score_map(char filter, uint16_t * score_map, uint32_t map_size,
                 score_map[t->pos.y * world.map.length + t->pos.x] = UINT16_MAX;
                 continue;
             }
+            score_map[t->pos.y * world.map.length + t->pos.x] = 0;
         }
-        else if ('c' == filter)
+    }
+    else if ('c' == filter)
+    {
+        struct ThingInMemory * tm = t_eye->t_mem;
+        for (; tm; tm = tm->next)
         {
-            struct ThingType * tt = get_thing_type(t->type);
+            if (' ' == t_eye->mem_map[tm->pos.y * world.map.length + tm->pos.x])
+            {
+                continue;
+            }
+            struct ThingType * tt = get_thing_type(tm->type);
             if (!tt->consumable)
             {
                 continue;
             }
+            score_map[tm->pos.y * world.map.length + tm->pos.x] = 0;
         }
-        score_map[t->pos.y * world.map.length + t->pos.x] = 0;
     }
 }
 
@@ -221,25 +227,32 @@ static uint8_t get_dir_to_nearest_thing(struct Thing * t_eye, char filter)
 
 static uint8_t seeing_thing(struct Thing * t_eye, char filter)
 {
-    if (t_eye->fov_map)
+    if (t_eye->fov_map && 'e' == filter)
     {
         struct Thing * t = world.things;
-        for (; t != NULL; t = t->next)
+        for (; t; t = t->next)
         {
             if (   t != t_eye
                 && 'v' == t_eye->fov_map[t->pos.y*world.map.length + t->pos.x])
             {
-                if ('e' == filter && t->lifepoints && t->type != t_eye->type)
+                if (t->lifepoints && t->type != t_eye->type)
                 {
                     return 1;
                 }
-                else if ('c' == filter)
+            }
+        }
+    }
+    else if (t_eye->mem_map && 'c' == filter)
+    {
+        struct ThingInMemory * tm = t_eye->t_mem;
+        for (; tm; tm = tm->next)
+        {
+            if (' ' != t_eye->mem_map[tm->pos.y * world.map.length + tm->pos.x])
+            {
+                struct ThingType * tt = get_thing_type(tm->type);
+                if (tt->consumable)
                 {
-                    struct ThingType * tt = get_thing_type(t->type);
-                    if (tt->consumable)
-                    {
-                        return 1;
-                    }
+                    return 1;
                 }
             }
         }
index ae8aa9cbaa0887dbde1478f07ac808f6bc525a1f..4b1ac00194d6a9498b2e3a5a3a8bba818bb147cd 100644 (file)
@@ -6,7 +6,7 @@
 #include <string.h> /* memset() */
 #include "../common/rexit.h" /* exit_trouble() */
 #include "../common/try_malloc.h" /* try_malloc() */
-#include "things.h" /* Thing */
+#include "things.h" /* Thing, ThingInMemory, add_thing_to_memory_map() */
 #include "yx_uint8.h" /* yx_uint8 */
 #include "world.h" /* world  */
 
@@ -84,7 +84,9 @@ static void eval_position(uint16_t dist, uint16_t hex_i, char * fov_map,
                           struct yx_uint8 * test_pos,
                           struct shadow_angle ** shadows);
 
-/* Update "t"'s .mem_map memory with what's in its current field of view. */
+/* Update "t"'s .mem_map memory with what's in its current FOV, remove from its
+ * .t_mem all memorized things in FOV and add inanimiate things in FOV to it.
+ */
 static void update_map_memory(struct Thing * t, uint32_t map_size);
 
 
@@ -354,19 +356,49 @@ static void eval_position(uint16_t dist, uint16_t hex_i, char * fov_map,
 
 
 
-static void update_map_memory(struct Thing * t, uint32_t map_size)
+static void update_map_memory(struct Thing * t_eye, uint32_t map_size)
 {
-    if (!t->mem_map)
+    if (!t_eye->mem_map)
     {
-        t->mem_map = try_malloc(map_size, __func__);
-        memset(t->mem_map, ' ', map_size);
+        t_eye->mem_map = try_malloc(map_size, __func__);
+        memset(t_eye->mem_map, ' ', map_size);
     }
     uint32_t i;
     for (i = 0; i < map_size; i++)
     {
-        if (' ' == t->mem_map[i] && t->fov_map[i] == 'v')
+        if (' ' == t_eye->mem_map[i] && t_eye->fov_map[i] == 'v')
+        {
+            t_eye->mem_map[i] = world.map.cells[i];
+        }
+    }
+    struct ThingInMemory * tm = t_eye->t_mem;
+    struct ThingInMemory * tm_prev = NULL;
+    struct ThingInMemory * tm_next = NULL;
+    for (; tm != NULL; tm = tm_next)
+    {
+        tm_next = tm->next;
+        if ('v' == t_eye->fov_map[tm->pos.y * world.map.length + tm->pos.x])
+        {
+            if (tm_prev)
+            {
+                tm_prev->next = tm->next;
+            }
+            else
+            {
+                t_eye->t_mem = tm->next;
+            }
+            free(tm);
+            continue;
+        }
+        tm_prev = tm;
+    }
+    struct Thing * t = world.things;
+    for (; t != NULL; t = t->next)
+    {
+        if (   !t->lifepoints
+            && 'v' == t_eye->fov_map[t->pos.y * world.map.length + t->pos.x])
         {
-            t->mem_map[i] = world.map.cells[i];
+            add_thing_to_memory_map(t_eye, t->type, t->pos.y, t->pos.x);
         }
     }
 }
index 755acd5881b4ff8bf4ba604c08d89c0f8d83e986..09aeecec624d60e48d0703478c0f46787d550968 100644 (file)
@@ -18,7 +18,7 @@
                             * actor_use(), actor_pickup(), actor_drop()
                             */
 #include "things.h" /* Thing, ThingType, add_thing(), get_thing(), own_thing(),
-                     * free_things()
+                     * free_things(), add_thing_to_memory_map(),get_thing_type()
                      */
 #include "world.h" /* world */
 
@@ -475,3 +475,34 @@ extern uint8_t parse_god_command_2arg(char * tok0, char * tok1, char * tok2)
     }
     return 1;
 }
+
+
+
+extern uint8_t parse_god_command_3arg(char * tok0, char * tok1, char * tok2,
+                                      char * tok3)
+{
+    if (!t && !strcmp(tok0, s[S_CMD_T_MEMTHING]))
+    {
+        err_line(1, "No thing defined to manipulate yet.");
+        return 1;
+    }
+    if (!strcmp(tok0, s[S_CMD_T_MEMTHING]))
+    {
+        uint8_t id = atoi(tok1);
+        uint8_t y  = atoi(tok2);
+        uint8_t x  = atoi(tok3);
+        if (   parsetest_int(tok1, '8') || !get_thing_type(id)
+            || parsetest_int(tok2, '8') || y >= world.map.length
+            || parsetest_int(tok3, '8') || x >= world.map.length)
+        {
+            err_line(1, "Illegal value for thing type or position.");
+            return 1;
+        }
+        add_thing_to_memory_map(t, id, y, x);
+    }
+    else
+    {
+        return 0;
+    }
+    return 1;
+}
index d9b1558b48f26568efa126d1705e26ca43d9b9df..7899b20c6ced2630a3164f8f188fa91811dc3313 100644 (file)
@@ -14,6 +14,8 @@
 /* Parse/apply god command "tok0" with argument "tok1", "tok2" etc. . */
 extern uint8_t parse_god_command_1arg(char * tok0, char * tok1);
 extern uint8_t parse_god_command_2arg(char * tok0, char * tok1, char * tok2);
+extern uint8_t parse_god_command_3arg(char * tok0, char * tok1, char * tok2,
+                                      char * tok3);
 
 
 
index 82f7a3ebf462dde84a1d96e02ac8f8099f763925..64bcc59b1acf44a8c99fff7e16337f608ad07051 100644 (file)
@@ -4,7 +4,7 @@
 
 
 
-char * s[40];
+char * s[41];
 
 
 
@@ -37,6 +37,7 @@ extern void init_strings()
     s[S_CMD_T_HP] = "T_LIFEPOINTS";
     s[S_CMD_T_CARRIES] = "T_CARRIES";
     s[S_CMD_T_MEMMAP] = "T_MEMMAP";
+    s[S_CMD_T_MEMTHING] = "T_MEMTHINGß";
     s[S_CMD_AI] = "ai";
     s[S_CMD_WAIT] = "wait";
     s[S_CMD_MOVE] = "move";
index ebfa0799528dc2dad2767afad7bf178e8bf1b4f3..7ee0ec9ac598e5b888a3aca0918adc92872137de 100644 (file)
@@ -37,6 +37,7 @@ enum string_num
     S_CMD_T_HP,
     S_CMD_T_CARRIES,
     S_CMD_T_MEMMAP,
+    S_CMD_T_MEMTHING,
     S_CMD_AI,
     S_CMD_WAIT,
     S_CMD_MOVE,
@@ -54,7 +55,7 @@ enum string_num
 
 extern void init_strings();
 
-extern char * s[40];
+extern char * s[41];
 
 
 
index 0f65cea8c5e36060fa094af9eccd2f03629412b8..8f8f738b46533dcbf099e08948f7524dc650e163 100644 (file)
@@ -18,8 +18,8 @@
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "cleanup.h" /* set_cleanup_flag() */
 #include "hardcoded_strings.h" /* s */
-#include "things.h" /* Thing, ThingType, ThingAction, get_thing_type(),
-                     * get_player()
+#include "things.h" /* Thing, ThingType, ThingInMemory, ThingAction,
+                     * get_thing_type(), get_player()
                      */
 #include "world.h" /* global world  */
 
@@ -67,7 +67,7 @@ static char * build_visible_map(struct Thing * player);
 
 /* Write to "file" game map as visible to "player" right now, as drawn by
  * build_visible_map(), and thereafter game map as memorized by player in its
- * .mem_map. Write one row per \n-delimited line.
+ * .mem_map and .t_mem. Write one row per \n-delimited line.
  */
 static void write_map(struct Thing * player, FILE * file);
 
@@ -165,6 +165,17 @@ static void write_thing(FILE * file, struct Thing * t)
             try_fputc('\n', file, __func__);
         }
         free(mem_map_copy);
+        struct ThingInMemory * tm = t->t_mem;
+        for (; tm; tm = tm->next)
+        {
+            write_key_space(file, s[S_CMD_T_MEMTHING]);
+            write_value(file, tm->type);
+            try_fputc(' ', file, __func__);
+            write_value(file, tm->pos.y);
+            try_fputc(' ', file, __func__);
+            write_value(file, tm->pos.x);
+            try_fputc('\n', file, __func__);
+        }
     }
     try_fputc('\n', file, __func__);
 }
@@ -354,14 +365,36 @@ static void write_map(struct Thing * player, FILE * file)
         try_fputc('\n', file, __func__);
     }
     free(visible_map);
+    uint32_t map_size = world.map.length * world.map.length;
+    char * mem_map = try_malloc(map_size, __func__);
+    memcpy(mem_map, player->mem_map, map_size);
+    uint8_t i;
+    struct ThingInMemory * tm;
+    for (i = 0; i < 2; i++)
+    {
+        for (tm = player->t_mem; tm != NULL; tm = tm->next)
+        {
+            if (' ' != player->mem_map[tm->pos.y*world.map.length+tm->pos.x])
+            {
+                struct ThingType * tt = get_thing_type(tm->type);
+                if (   (0 == i && !tt->consumable)
+                    || (1 == i &&  tt->consumable))
+                {
+                    char c = tt->char_on_map;
+                    mem_map[tm->pos.y * world.map.length + tm->pos.x] = c;
+                }
+            }
+        }
+    }
     for (y = 0; y < world.map.length; y++)
     {
         for (x = 0; x < world.map.length; x++)
         {
-            try_fputc(player->mem_map[y*world.map.length+x], file, __func__);
+            try_fputc(mem_map[y * world.map.length + x], file, __func__);
         }
         try_fputc('\n', file, __func__);
     }
+    free(mem_map);
 }
 
 
index 8c1297d1da1172a51a802578c5d01c5ce99f016a..906bed266ae54f76edf06d5659a1f87d0fc24ce4 100644 (file)
@@ -20,7 +20,7 @@
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "ai.h" /* ai() */
 #include "cleanup.h" /* unset_cleanup_flag() */
-#include "god_commands.h" /* parse_god_command_1arg(),parse_god_command_2arg()*/
+#include "god_commands.h" /* parse_god_command_(1|2|3)arg() */
 #include "hardcoded_strings.h" /* s */
 #include "io.h" /* io_round(), save_world() */
 #include "things.h" /* Thing, get_thing_action_id_by_name(), get_player() */
@@ -165,6 +165,14 @@ static uint8_t parse_command(char * tok0)
             {
                 return 1;
             }
+            else
+            {
+                char * tok3 = token_from_line(NULL);
+                if (tok2 && parse_god_command_3arg(tok0, tok1, tok2, tok3))
+                {
+                    return 1;
+                }
+            }
         }
     }
     return 0;
index e73a09a283c09fb843292996c0b6ee3561f68d2f..7d0f62d9b19be98ab2da6d1a145887b529aa04a2 100644 (file)
@@ -28,6 +28,9 @@ struct NextAndId
 
 
 
+/* Free ThingsInMemory chain starting at "tm". */
+static void free_things_in_memory(struct ThingInMemory * tm);
+
 /* To linked list of NextAndId structs (or rather structs whose start region is
  * compatible to it) starting at "start", add newly allocated element of
  * "n_size" and an ID that is either "id" or, if "id" is <= UINT8_MAX and >=
@@ -40,6 +43,18 @@ static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
 
 
 
+static void free_things_in_memory(struct ThingInMemory * tm)
+{
+    if (NULL == tm)
+    {
+        return;
+    }
+    free_things_in_memory(tm->next);
+    free(tm);
+}
+
+
+
 static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
                                              int16_t id, uint8_t struct_id,
                                              struct NextAndId ** start)
@@ -121,6 +136,19 @@ extern struct Thing * add_thing(int16_t id, uint8_t type, uint8_t y, uint8_t x)
 
 
 
+extern void add_thing_to_memory_map(struct Thing * t, uint8_t type,
+                                    uint8_t y, uint8_t x)
+{
+    struct ThingInMemory * tm=try_malloc(sizeof(struct ThingInMemory),__func__);
+    tm->type = type;
+    tm->pos.y = y;
+    tm->pos.x = x;
+    tm->next = t->t_mem;
+    t->t_mem = tm;
+}
+
+
+
 extern void free_thing_actions(struct ThingAction * ta)
 {
     if (NULL == ta)
@@ -157,6 +185,7 @@ extern void free_things(struct Thing * t)
     free_things(t->next);
     free(t->fov_map);
     free(t->mem_map);
+    free_things_in_memory(t->t_mem);
     free(t);
     if (t == world.things)         /* So add_things()' NULL-delimited thing   */
     {                              /* iteration loop does not iterate over    */
index ea37a81487160471b85bd8746c270380b1fc4de7..365e308b4c4cb8da0ab67bca087c92ef92694171 100644 (file)
 struct Thing
 {
     struct Thing * next;
-    uint8_t id;                  /* individual thing's unique identifier */
-    struct Thing * owns;         /* chain of things owned / in inventory */
-    struct yx_uint8 pos;         /* coordinate on map */
-    char * fov_map;              /* thing's FOV map; 'v':visible, 'H':hidden */
-    char * mem_map;              /* map knowledge of thing by FOV and memory */
-    uint8_t type;                /* ID of appropriate thing definition */
-    uint8_t lifepoints;          /* 0: thing is inanimate; >0: hitpoints */
-    uint8_t command;             /* thing's current action; 0 if none */
-    uint8_t arg;                 /* optional field for .command argument */
-    uint8_t progress;            /* turns already passed to realize .command */
+    uint8_t id;                   /* individual thing's unique identifier */
+    struct Thing * owns;          /* chain of things owned / in inventory */
+    struct ThingInMemory * t_mem; /* chain of things remembered */
+    struct yx_uint8 pos;          /* coordinate on map */
+    char * fov_map;               /* thing's FOV map; 'v':visible, 'H':hidden */
+    char * mem_map;               /* map knowledge of thing by FOV and memory */
+    uint8_t type;                 /* ID of appropriate thing definition */
+    uint8_t lifepoints;           /* 0: thing is inanimate; >0: hitpoints */
+    uint8_t command;              /* thing's current action; 0 if none */
+    uint8_t arg;                  /* optional field for .command argument */
+    uint8_t progress;             /* turns already passed to realize .command */
+};
+
+struct ThingInMemory
+{
+    struct ThingInMemory * next;
+    struct yx_uint8 pos;                             /* position on memorized */
+    uint8_t type;                                    /* thing type identifier */
 };
 
 struct ThingType
@@ -67,7 +75,11 @@ extern struct ThingType * add_thing_type(int16_t id);
  */
 extern struct Thing * add_thing(int16_t id, uint8_t type, uint8_t y, uint8_t x);
 
-/* Free ThingAction/ThingType/Thing * chain starting at "ta"/"tt"/"t". */
+/* Add to thing memory of "t" thing of type id "type" and position "y"/"x". */
+extern void add_thing_to_memory_map(struct Thing * t, uint8_t type,
+                                    uint8_t y, uint8_t x);
+
+/* Free ThingAction/ThingType/Thing chain starting at "ta"/"tt"/"t". */
 extern void free_thing_actions(struct ThingAction * ta);
 extern void free_thing_types(struct ThingType * tt);
 extern void free_things(struct Thing * t);