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
#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 */
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);
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;
}
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;
}
}
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;
}
}
}
#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 */
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);
-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);
}
}
}
* 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 */
}
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;
+}
/* 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);
-char * s[40];
+char * s[41];
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";
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,
extern void init_strings();
-extern char * s[40];
+extern char * s[41];
#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 */
/* 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);
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__);
}
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);
}
#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() */
{
return 1;
}
+ else
+ {
+ char * tok3 = token_from_line(NULL);
+ if (tok2 && parse_god_command_3arg(tok0, tok1, tok2, tok3))
+ {
+ return 1;
+ }
+ }
}
}
return 0;
+/* 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 >=
+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)
+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)
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 */
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
*/
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);