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
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'
WIDTH 64
PLAYER_TYPE 0
-ENEMY_FOV 0
ACTION 1
NAME wait
#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 */
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)
{
/* 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);
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;
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);
(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)))
-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))
#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 */
}
}
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()");
*/
#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 */
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];
}
{
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)))
{
}
}
}
- free(fov_map);
return visible_map;
}
#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()
if (passable)
{
set_object_position(mo, target);
+ free(mo->fov_map);
+ mo->fov_map = build_fov_map(mo);
}
if (mo == get_player())
{
* (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);
}
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 */
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 */