From 4266e8b48fc5481ce24c0bf02fdd517217f8390a Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 14 May 2014 04:09:35 +0200 Subject: [PATCH 1/1] Server: Force FOV on every actor, but update it on movement only. --- README | 11 +++-------- confserver/world | 1 - src/server/ai.c | 13 ++----------- src/server/configfile.c | 23 +---------------------- src/server/init.c | 10 +++++++++- src/server/io.c | 12 ++++++------ src/server/map_object_actions.c | 3 +++ src/server/map_object_actions.h | 1 + src/server/map_objects.c | 1 + src/server/map_objects.h | 1 + 10 files changed, 27 insertions(+), 49 deletions(-) diff --git a/README b/README index 1923471..2a0206d 100644 --- 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' diff --git a/confserver/world b/confserver/world index bf2488c..724d012 100644 --- a/confserver/world +++ b/confserver/world @@ -3,7 +3,6 @@ HEIGHT 64 WIDTH 64 PLAYER_TYPE 0 -ENEMY_FOV 0 ACTION 1 NAME wait diff --git a/src/server/ai.c b/src/server/ai.c index d099c57..1596d5a 100644 --- a/src/server/ai.c +++ b/src/server/ai.c @@ -5,7 +5,7 @@ #include /* uint8_t, uint16_t, uint32_t, UINT16_MAX */ #include /* 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) { diff --git a/src/server/configfile.c b/src/server/configfile.c index 1446439..fc2c771 100644 --- a/src/server/configfile.c +++ b/src/server/configfile.c @@ -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)) diff --git a/src/server/init.c b/src/server/init.c index 89eea4f..d8ae94f 100644 --- a/src/server/init.c +++ b/src/server/init.c @@ -18,8 +18,11 @@ #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()"); diff --git a/src/server/io.c b/src/server/io.c index 7fbb511..964e06a 100644 --- a/src/server/io.c +++ b/src/server/io.c @@ -16,9 +16,11 @@ */ #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; } diff --git a/src/server/map_object_actions.c b/src/server/map_object_actions.c index 9786832..6c92d07 100644 --- a/src/server/map_object_actions.c +++ b/src/server/map_object_actions.c @@ -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()) { diff --git a/src/server/map_object_actions.h b/src/server/map_object_actions.h index 8133e53..7192cb4 100644 --- a/src/server/map_object_actions.h +++ b/src/server/map_object_actions.h @@ -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); diff --git a/src/server/map_objects.c b/src/server/map_objects.c index ac36394..975c748 100644 --- a/src/server/map_objects.c +++ b/src/server/map_objects.c @@ -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 */ diff --git a/src/server/map_objects.h b/src/server/map_objects.h index d18e3c2..1e32318 100644 --- a/src/server/map_objects.h +++ b/src/server/map_objects.h @@ -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 */ -- 2.30.2