From 6b1d36c9e673fd8f8595119080dca63a39ba483b Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 16 Apr 2014 16:00:11 +0200 Subject: [PATCH] Make grids hexagonal, remove all diagonal movement penalty hassle. --- README | 15 +---- TODO | 2 + confclient/commands | 34 ++++------- confclient/interface_conf | 18 +++--- confclient/single_wins/info | 18 +++--- confclient/single_wins/inventory | 18 +++--- confclient/single_wins/log | 18 +++--- confclient/single_wins/map | 18 +++--- confserver/world | 2 - src/client/draw_wins.c | 4 +- src/client/map.c | 8 +-- src/server/ai.c | 102 +++++++++++++------------------ src/server/configfile.c | 18 ++---- src/server/map.c | 41 +++++++------ src/server/map.h | 11 ++-- src/server/map_object_actions.c | 14 ++--- src/server/map_object_actions.h | 6 +- src/server/run.c | 44 +------------ src/server/yx_uint8.c | 28 +++------ src/server/yx_uint8.h | 7 ++- 20 files changed, 160 insertions(+), 266 deletions(-) diff --git a/README b/README index 2770f53..9fc5305 100644 --- a/README +++ b/README @@ -15,8 +15,6 @@ 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. -Diagonal movement is possible, but takes (40%) longer than orthogonal movement. - 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 automatically up to the point wherere you left the game. To start over in a new @@ -47,7 +45,7 @@ In the client's default window configuration, the window appearing on the left sports a list of keybindings available globally, and additionally via the window selected as active. -Hit "w" (per default keybindings) to switch the "active" window to a view that +Hit "W" (per default keybindings) to switch the "active" window to a view that allows changing its geometry. One more hit on "w" switches the window to a view that allows changing its window-specific keybindings. The global keybindings can be changed in the "Global keys" window, those of the window geometry @@ -88,21 +86,12 @@ Here's a typical map definition block: MAP_TYPE 0 HEIGHT 64 WIDTH 64 -DIST_ORTHOGONAL 5 -DIST_DIAGONAL 7 A line of "MAP_TYPE" followed by a non-empty token starts the map definition block. In the future, the second token may differentiate different map types, but as of right now, only one is available and the value is not interpreted. The numbers after "HEIGHT" and "WIDTH" give the map's vertical and horizontal -extensions in cells. They must be >= 1 and <= 256. The numbers after -"DIST_ORTHOGONAL" and "DIST_DIAGONAL" define the diagonal movement penalty as -the second value divided by the first. The above values define a penalty ratio -of 7/5 or 1.4, i.e. it takes 40% longer in turns to move diagonally than -orthogonally. Set both to the same value to eliminate the diagonal movement -penalty. A negative penalty to realize weird geometry is possible by setting -"DIST_DIAGONAL" to a lower value than "DIST_ORTHOGONAL". Both values, however, -must be >= 1 and <= 255. +extensions in cells. They must be >= 1 and <= 256. Here's a typical action definition block: diff --git a/TODO b/TODO index 640bbf9..9226ff0 100644 --- a/TODO +++ b/TODO @@ -23,3 +23,5 @@ CLIENT: - enable toggling of window borders - make log scrollable + +- nav_inventory() expects too short inventory string length for i diff --git a/confclient/commands b/confclient/commands index cd7c3ac..ad6048f 100644 --- a/confclient/commands +++ b/confclient/commands @@ -3,45 +3,35 @@ DESCRIPTION 'wait / next turn' SERVER_COMMAND wait SERVER_ARGUMENT 0 -COMMAND move_8 -DESCRIPTION 'move north' -SERVER_COMMAND move -SERVER_ARGUMENT 8 - -COMMAND move_9 +COMMAND move_e DESCRIPTION 'move north-east' SERVER_COMMAND move -SERVER_ARGUMENT 9 +SERVER_ARGUMENT e -COMMAND move_6 +COMMAND move_d DESCRIPTION 'move east' SERVER_COMMAND move -SERVER_ARGUMENT 6 +SERVER_ARGUMENT d -COMMAND move_3 +COMMAND move_c DESCRIPTION 'move south-east' SERVER_COMMAND move -SERVER_ARGUMENT 3 - -COMMAND move_2 -DESCRIPTION 'move south' -SERVER_COMMAND move -SERVER_ARGUMENT 2 +SERVER_ARGUMENT c -COMMAND move_1 +COMMAND move_x DESCRIPTION 'move south-west' SERVER_COMMAND move -SERVER_ARGUMENT 1 +SERVER_ARGUMENT x -COMMAND move_4 +COMMAND move_s DESCRIPTION 'move west' SERVER_COMMAND move -SERVER_ARGUMENT 4 +SERVER_ARGUMENT s -COMMAND move_7 +COMMAND move_w DESCRIPTION 'move north-west' SERVER_COMMAND move -SERVER_ARGUMENT 7 +SERVER_ARGUMENT w COMMAND pick DESCRIPTION 'pick up' diff --git a/confclient/interface_conf b/confclient/interface_conf index 15ab6e0..51b7f40 100644 --- a/confclient/interface_conf +++ b/confclient/interface_conf @@ -9,7 +9,7 @@ KEY 269 to_logwin KEY 270 to_g_keywin KEY 271 to_wg_keywin KEY 272 to_wk_keywin -KEY 119 winconf +KEY 87 winconf KEY 62 cyc_win_f KEY 60 cyc_win_b KEY 262 scrl_l @@ -62,7 +62,7 @@ HEIGHT 4 KEY 100 drop KEY 259 inv_u KEY 258 inv_d -KEY 99 use +KEY 117 use WINDOW i NAME 'Info' @@ -89,14 +89,12 @@ WIDTH -59 HEIGHT 0 KEY 112 pick KEY 58 wait -KEY 107 move_8 -KEY 117 move_9 -KEY 108 move_6 -KEY 110 move_3 -KEY 106 move_2 -KEY 98 move_1 -KEY 104 move_4 -KEY 121 move_7 +KEY 101 move_e +KEY 100 move_d +KEY 99 move_c +KEY 120 move_x +KEY 115 move_s +KEY 119 move_w KEY 259 map_u KEY 258 map_d KEY 260 map_l diff --git a/confclient/single_wins/info b/confclient/single_wins/info index 7df511c..cf663e8 100644 --- a/confclient/single_wins/info +++ b/confclient/single_wins/info @@ -9,7 +9,7 @@ KEY 269 to_logwin KEY 270 to_g_keywin KEY 271 to_wg_keywin KEY 272 to_wk_keywin -KEY 119 winconf +KEY 87 winconf KEY 62 cyc_win_f KEY 60 cyc_win_b KEY 262 scrl_l @@ -18,17 +18,15 @@ KEY 82 reload_conf KEY 67 save_conf KEY 112 pick KEY 58 wait -KEY 107 move_8 -KEY 117 move_9 -KEY 108 move_6 -KEY 110 move_3 -KEY 106 move_2 -KEY 98 move_1 -KEY 104 move_4 -KEY 121 move_7 +KEY 101 move_e +KEY 100 move_d +KEY 99 move_c +KEY 120 move_x +KEY 115 move_s +KEY 119 move_w KEY 46 map_c KEY 100 drop -KEY 99 use +KEY 117 use KEYBINDINGS 'wingeom' KEY 258 shift_f diff --git a/confclient/single_wins/inventory b/confclient/single_wins/inventory index cd18cb4..905f490 100644 --- a/confclient/single_wins/inventory +++ b/confclient/single_wins/inventory @@ -9,7 +9,7 @@ KEY 269 to_logwin KEY 270 to_g_keywin KEY 271 to_wg_keywin KEY 272 to_wk_keywin -KEY 119 winconf +KEY 87 winconf KEY 62 cyc_win_f KEY 60 cyc_win_b KEY 262 scrl_l @@ -18,17 +18,15 @@ KEY 82 reload_conf KEY 67 save_conf KEY 112 pick KEY 58 wait -KEY 107 move_8 -KEY 117 move_9 -KEY 108 move_6 -KEY 110 move_3 -KEY 106 move_2 -KEY 98 move_1 -KEY 104 move_4 -KEY 121 move_7 +KEY 101 move_e +KEY 100 move_d +KEY 99 move_c +KEY 120 move_x +KEY 115 move_s +KEY 119 move_w KEY 46 map_c KEY 100 drop -KEY 99 use +KEY 117 use KEYBINDINGS 'wingeom' KEY 258 shift_f diff --git a/confclient/single_wins/log b/confclient/single_wins/log index 77fcd84..930b1c2 100644 --- a/confclient/single_wins/log +++ b/confclient/single_wins/log @@ -9,7 +9,7 @@ KEY 269 to_logwin KEY 270 to_g_keywin KEY 271 to_wg_keywin KEY 272 to_wk_keywin -KEY 119 winconf +KEY 87 winconf KEY 62 cyc_win_f KEY 60 cyc_win_b KEY 262 scrl_l @@ -18,17 +18,15 @@ KEY 82 reload_conf KEY 67 save_conf KEY 112 pick KEY 58 wait -KEY 107 move_8 -KEY 117 move_9 -KEY 108 move_6 -KEY 110 move_3 -KEY 106 move_2 -KEY 98 move_1 -KEY 104 move_4 -KEY 121 move_7 +KEY 101 move_e +KEY 100 move_d +KEY 99 move_c +KEY 120 move_x +KEY 115 move_s +KEY 119 move_w KEY 46 map_c KEY 100 drop -KEY 99 use +KEY 117 use KEYBINDINGS 'wingeom' KEY 258 shift_f diff --git a/confclient/single_wins/map b/confclient/single_wins/map index 2857967..86b1027 100644 --- a/confclient/single_wins/map +++ b/confclient/single_wins/map @@ -9,7 +9,7 @@ KEY 269 to_logwin KEY 270 to_g_keywin KEY 271 to_wg_keywin KEY 272 to_wk_keywin -KEY 119 winconf +KEY 87 winconf KEY 62 cyc_win_f KEY 60 cyc_win_b KEY 262 scrl_l @@ -18,17 +18,15 @@ KEY 82 reload_conf KEY 67 save_conf KEY 112 pick KEY 58 wait -KEY 107 move_8 -KEY 117 move_9 -KEY 108 move_6 -KEY 110 move_3 -KEY 106 move_2 -KEY 98 move_1 -KEY 104 move_4 -KEY 121 move_7 +KEY 101 move_e +KEY 100 move_d +KEY 99 move_c +KEY 120 move_x +KEY 115 move_s +KEY 119 move_w KEY 46 map_c KEY 100 drop -KEY 99 use +KEY 117 use KEYBINDINGS 'wingeom' KEY 258 shift_f diff --git a/confserver/world b/confserver/world index aeae5bd..724d012 100644 --- a/confserver/world +++ b/confserver/world @@ -1,8 +1,6 @@ MAP_TYPE 0 HEIGHT 64 WIDTH 64 -DIST_ORTHOGONAL 5 -DIST_DIAGONAL 7 PLAYER_TYPE 0 diff --git a/src/client/draw_wins.c b/src/client/draw_wins.c index 08e5927..dc655e7 100644 --- a/src/client/draw_wins.c +++ b/src/client/draw_wins.c @@ -338,14 +338,14 @@ extern void draw_win_log(struct Win * win) extern void draw_win_map(struct Win * win) { - try_resize_winmap(win, world.map.size.y, world.map.size.x); + try_resize_winmap(win, world.map.size.y, world.map.size.x * 2); uint16_t z = 0; uint16_t x, y; for (y = 0; y < world.map.size.y; y++) { for (x = 0; x < world.map.size.x; x++) { - set_ch_on_yx(win, y, x, world.map.cells[z]); + set_ch_on_yx(win, y, x * 2 + (y % 2), world.map.cells[z]); z++; } } diff --git a/src/client/map.c b/src/client/map.c index 7292c89..48a9b58 100644 --- a/src/client/map.c +++ b/src/client/map.c @@ -23,12 +23,12 @@ extern void map_scroll(char d) } win->center.y = win->center.y - ('8' == d && win->center.y > 0); } - else if (('4' == d || '6' == d) && world.map.size.x > win->frame_size.x) + else if (('4' == d || '6' == d) && (world.map.size.x*2) > win->frame_size.x) { offset = center_offset(win->center.x, - world.map.size.x, win->frame_size.x); + world.map.size.x*2, win->frame_size.x); win->center.x = offset + (win->frame_size.x / 2); - if ('6' == d && win->center.x < world.map.size.x - 1) + if ('6' == d && win->center.x < (world.map.size.x * 2) - 1) { win->center.x++; return; @@ -43,5 +43,5 @@ extern void map_center() { struct Win * win_map = get_win_by_id('m'); win_map->center.y = world.player_pos.y; - win_map->center.x = world.player_pos.x; + win_map->center.x = world.player_pos.x * 2; } diff --git a/src/server/ai.c b/src/server/ai.c index a0f4793..9c31153 100644 --- a/src/server/ai.c +++ b/src/server/ai.c @@ -11,30 +11,28 @@ -#define N_DIRS 8 +#define N_DIRS 6 -/* Write into "neighbors" scores of the eight immediate 2D neighbors of the - * "score_map" cell at "pos_i" (array index), as found in the directions north, - * north-east, east etc. (clockwise order). "max_score" is used for illegal - * neighborhoods (i.e. if the direction would lead beyond the map's border). +/* Write into "neighbors" scores of the N_DIRS immediate neighbors of the + * "score_map" cell at "pos_i" (array index), as found in the directions + * north-east, east, south-east etc. (clockwise order). Use "max_score" for + * illegal neighborhoods (i.e. if direction would lead beyond the map's border). */ -static void get_neighbor_scores(uint32_t * score_map, uint16_t pos_i, - uint32_t max_score, uint32_t * neighbors); +static void get_neighbor_scores(uint16_t * score_map, uint16_t pos_i, + uint16_t max_score, uint16_t * neighbors); -/* Iterate over scored cells in "score_map" of world.map's 2D geometry. Compare +/* Iterate over scored cells in "score_map" of world.map's geometry. Compare * each cell's score against the score of its immediate neighbors in N_DIRS * directions. If it's neighbors are low enough that the result would be lower - * than the current value, re-set it to world.map.dist_orthogonal points higher - * than its lowest-scored orthogonal neighbor or world.map.dist_diagonal points - * higher than its lowest-scored diagonal neighbor (whatever would result in a - * lower value). Repeat this whole process until all cells have settled on their + * than the current value, re-set it to 1 point higher than its lowest-scored + * neighbor- Repeat this whole process until all cells have settled on their * final score. Ignore cells whose position in "score_map" fits cells of * unreachable terrain in world.map.cells. Expect "max_score" to be the maximum * score for cells, marking them as unreachable. */ -static void dijkstra_map(uint32_t * score_map, uint32_t max_score); +static void dijkstra_map(uint16_t * score_map, uint16_t max_score); /* Return numpad char of direction ("8", "6", "2", "4" etc.) of enemy with the * shortest path to "mo_origin". If no enemy is around, return 0. @@ -43,57 +41,51 @@ static char get_dir_to_nearest_enemy(struct MapObj * mo_origin); -static void get_neighbor_scores(uint32_t * score_map, uint16_t pos_i, - uint32_t max_score, uint32_t * neighbors) +static void get_neighbor_scores(uint16_t * score_map, uint16_t pos_i, + uint16_t max_score, uint16_t * neighbors) { uint32_t map_size = world.map.size.y * world.map.size.x; uint8_t i_dir; for (i_dir = 0; i_dir < N_DIRS; neighbors[i_dir] = max_score, i_dir++); - uint8_t open_north = pos_i >= world.map.size.x; - uint8_t open_east = pos_i + 1 % world.map.size.x; - uint8_t open_south = pos_i + world.map.size.x < map_size; - uint8_t open_west = pos_i % world.map.size.x; - if (open_north) + uint8_t open_north = pos_i >= world.map.size.x; + uint8_t open_east = pos_i + 1 % world.map.size.x; + uint8_t open_south = pos_i + world.map.size.x < map_size; + uint8_t open_west = pos_i % world.map.size.x; + uint8_t is_indented = (pos_i / world.map.size.x) % 2; + uint8_t open_diag_west = is_indented || open_west; + uint8_t open_diag_east = !is_indented || open_east; + if (open_north && open_diag_east) { - neighbors[0] = score_map[pos_i - world.map.size.x]; - } - if (open_north && open_east) - { - neighbors[1] = score_map[pos_i - world.map.size.x + 1]; + neighbors[0] = score_map[pos_i - world.map.size.x + is_indented]; } if (open_east) { - neighbors[2] = score_map[pos_i + 1]; + neighbors[1] = score_map[pos_i + 1]; } - if (open_east && open_south) + if (open_south && open_diag_east) { - neighbors[3] = score_map[pos_i + 1 + world.map.size.x]; + neighbors[2] = score_map[pos_i + world.map.size.x + is_indented]; } - if (open_south) + if (open_south && open_diag_west) { - neighbors[4] = score_map[pos_i + world.map.size.x]; - } - if (open_south && open_west) - { - neighbors[5] = score_map[pos_i + world.map.size.x - 1]; + neighbors[3] = score_map[pos_i + world.map.size.x - !is_indented]; } if (open_west) { - neighbors[6] = score_map[pos_i - 1]; + neighbors[4] = score_map[pos_i - 1]; } - if (open_west && open_north) + if (open_north && open_diag_west) { - neighbors[7] = score_map[pos_i - 1 - world.map.size.x]; + neighbors[5] = score_map[pos_i - world.map.size.x - !is_indented]; } } -static void dijkstra_map(uint32_t * score_map, uint32_t max_score) +static void dijkstra_map(uint16_t * score_map, uint16_t max_score) { - uint32_t i_scans, neighbors[N_DIRS], min_neighbor_o, min_neighbor_d; uint32_t map_size = world.map.size.y * world.map.size.x; - uint16_t pos; + uint16_t pos, i_scans, neighbors[N_DIRS], min_neighbor; uint8_t scores_still_changing = 1; uint8_t i_dirs; for (i_scans = 0; scores_still_changing; i_scans++) @@ -104,27 +96,17 @@ static void dijkstra_map(uint32_t * score_map, uint32_t max_score) if ('.' == world.map.cells[pos]) { get_neighbor_scores(score_map, pos, max_score, neighbors); - min_neighbor_d = max_score; - min_neighbor_o = max_score; + min_neighbor = max_score; for (i_dirs = 0; i_dirs < N_DIRS; i_dirs++) { - if (!(i_dirs % 2) && min_neighbor_o > neighbors[i_dirs]) + if (min_neighbor > neighbors[i_dirs]) { - min_neighbor_o = neighbors[i_dirs]; + min_neighbor = neighbors[i_dirs]; } - else if (i_dirs % 2 && min_neighbor_d > neighbors[i_dirs]) - { - min_neighbor_d = neighbors[i_dirs]; - } - } - if (score_map[pos] > min_neighbor_o + world.map.dist_orthogonal) - { - score_map[pos] = min_neighbor_o + world.map.dist_orthogonal; - scores_still_changing = 1; } - if (score_map[pos] > min_neighbor_d + world.map.dist_diagonal) + if (score_map[pos] > min_neighbor + 1) { - score_map[pos] = min_neighbor_d + world.map.dist_diagonal; + score_map[pos] = min_neighbor + 1; scores_still_changing = 1; } } @@ -143,8 +125,8 @@ static char get_dir_to_nearest_enemy(struct MapObj * mo_origin) * (Actors' own cells start with a distance of 0 towards themselves.) */ uint32_t map_size = world.map.size.y * world.map.size.x; - uint32_t max_score = UINT32_MAX - (world.map.dist_diagonal + 1); - uint32_t * score_map = try_malloc(map_size * sizeof(uint32_t), f_name); + uint16_t max_score = UINT16_MAX; + uint16_t * score_map = try_malloc(map_size * sizeof(uint16_t), f_name); uint32_t i; for (i = 0; i < map_size; i++) { @@ -162,13 +144,13 @@ static char get_dir_to_nearest_enemy(struct MapObj * mo_origin) dijkstra_map(score_map, max_score); /* Return direction of "mo_origin"'s lowest-scored neighbor cell. */ - uint32_t neighbors[N_DIRS]; + uint16_t neighbors[N_DIRS]; uint16_t pos_i = (mo_origin->pos.y * world.map.size.x) + mo_origin->pos.x; get_neighbor_scores(score_map, pos_i, max_score, neighbors); free(score_map); char dir_to_nearest_enemy = 0; - uint32_t min_neighbor = max_score; - char * dirs = "89632147"; /* get_neighbor_scores()'s clockwise dir order.*/ + uint16_t min_neighbor = max_score; + char * dirs = "edcxsw"; /* get_neighbor_scores()'s clockwise dir order.*/ for (i = 0; i < N_DIRS; i++) { if (min_neighbor > neighbors[i]) diff --git a/src/server/configfile.c b/src/server/configfile.c index 5376502..fc2c771 100644 --- a/src/server/configfile.c +++ b/src/server/configfile.c @@ -28,8 +28,6 @@ enum flag { HEIGHT_SET = 0x02, WIDTH_SET = 0x04, - ORTH_SET = 0x08, - DIAG_SET = 0x10, NAME_SET = 0x02, EFFORT_SET = 0x04, CORPSE_ID_SET = 0x04, @@ -40,7 +38,7 @@ enum flag READY_ACT = NAME_SET | EFFORT_SET, READY_OBJ = NAME_SET | CORPSE_ID_SET | SYMBOL_SET | LIFEPOINTS_SET | CONSUMABLE_SET | START_N_SET, - READY_MAP = HEIGHT_SET | WIDTH_SET | ORTH_SET | DIAG_SET + READY_MAP = HEIGHT_SET | WIDTH_SET }; @@ -92,6 +90,9 @@ static void write_if_entry(struct EntryHead ** entry, */ 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.player_type to int in "token1". */ static uint8_t set_player_type(char * token0, char * comparand, char * token1); @@ -106,9 +107,6 @@ static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags, uint8_t * action_flags, uint8_t * map_flags, struct MapObjDef * mod, struct MapObjAct * moa); -/* set_members() helper specifically for editing world.map members. */ -static uint8_t set_map_members(char * token0,char * token1,uint8_t * map_flags); - /* If "name" fits "moa"->name, set "moa"->func to "func". (Derives MapObjAct * .func from .name for set_members(). */ @@ -252,14 +250,6 @@ static uint8_t set_map_members(char * token0, char * token1,uint8_t * map_flags) err_line(test, "Value must be >= 1 and <= 256."); return 1; } - else if ( parse_val(token0, token1, "DIST_ORTHOGONAL", map_flags, - ORTH_SET, '8', (char *) &world.map.dist_orthogonal) - || parse_val(token0, token1, "DIST_DIAGONAL", map_flags, - DIAG_SET, '8', (char *) &world.map.dist_diagonal)) - { - err_line(0 == atoi(token1), "Value must not be zero."); - return 1; - } return 0; } diff --git a/src/server/map.c b/src/server/map.c index 95d7e0f..9f5b866 100644 --- a/src/server/map.c +++ b/src/server/map.c @@ -24,31 +24,38 @@ extern void init_map() } uint8_t add_half_width = !(world.map.size.y % 2) * (world.map.size.x / 2); world.map.cells[(size / 2) + add_half_width] = '.'; - uint16_t curpos; + struct yx_uint8 pos; + uint16_t posi; char * err = "Map generation reached iteration limit. Change map size?"; uint32_t i; for (i = 0; ; i++, exit_err(256 * UINT16_MAX == i, err)) { - y = rrand() % world.map.size.y; - x = rrand() % world.map.size.x; - curpos = (y * world.map.size.x) + x; - if ('~' == world.map.cells[curpos] - && ( ( curpos >= world.map.size.x - && '.' == world.map.cells[curpos - world.map.size.x]) - || ( curpos < world.map.size.x * (world.map.size.y-1) - && '.' == world.map.cells[curpos + world.map.size.x]) - || ( curpos > 0 && curpos % world.map.size.x != 0 - && '.' == world.map.cells[curpos-1]) - || ( curpos < (world.map.size.x * world.map.size.y) - && (curpos+1) % world.map.size.x != 0 - && '.' == world.map.cells[curpos+1]))) + pos.y = rrand() % world.map.size.y; + pos.x = rrand() % world.map.size.x; + posi = (pos.y * world.map.size.x) + pos.x; + uint8_t ind = pos.y % 2; + uint8_t diag_west = pos.x + ind > 0; + uint8_t diag_east = pos.x + ind <= world.map.size.x - 1; + if ('~' == world.map.cells[posi] + && ( ( pos.y > 0 && diag_east + && '.' == world.map.cells[posi - world.map.size.x + ind]) + || ( pos.x < world.map.size.x - 1 + && '.' == world.map.cells[posi + 1]) + || ( pos.y < world.map.size.y - 1 && diag_east + && '.' == world.map.cells[posi + world.map.size.x + ind]) + || ( pos.y > 0 && diag_west + && '.' == world.map.cells[posi - world.map.size.x - !ind]) + || ( pos.x > 0 + && '.' == world.map.cells[posi - 1]) + || ( pos.y < world.map.size.y - 1 && diag_west + && '.' == world.map.cells[posi + world.map.size.x - !ind]))) { - if ( y == 0 || y == world.map.size.y - 1 - || x == 0 || x == world.map.size.x - 1) + if ( pos.y == 0 || pos.y == world.map.size.y - 1 + || pos.x == 0 || pos.x == world.map.size.x - 1) { break; } - world.map.cells[y * world.map.size.x + x] = '.'; + world.map.cells[posi] = '.'; } } } diff --git a/src/server/map.h b/src/server/map.h index b2b1ba2..e97a800 100644 --- a/src/server/map.h +++ b/src/server/map.h @@ -16,18 +16,15 @@ struct Map { struct yx_uint16 size; /* Map's height/width (use max. 256x256)! */ char * cells; /* Sequence of bytes encoding map cells. */ - uint8_t dist_orthogonal; /* Ratio of the diagonal movement penalty as */ - uint8_t dist_diagonal; /* encoded by (.dist_diagonal/.dist_orthonal). */ }; /* Initialize island map "~" cells representing water and "." cells representing - * land. The shape of the island is generated randomly by starting with a sea - * containing one land cell in the middle and then going into a cycle of - * repeatedly selecting a random cell on the map and transforming it into a land - * cell if it is horizontally or vertically neighbor to one; the cycle ends when - * a land cell is due to be created right at the border of the map. + * land. The island shape is built randomly by starting with a sea of one land + * cell in the middle, then going into a cycle of repeatedly selecting a random + * seal cell and transforming it into land if it is neighbor to land; the cycle + * ends when a land cell is due to be created right at the border of the map. */ extern void init_map(); diff --git a/src/server/map_object_actions.c b/src/server/map_object_actions.c index 17d74d5..9786832 100644 --- a/src/server/map_object_actions.c +++ b/src/server/map_object_actions.c @@ -139,14 +139,12 @@ static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match) static void playerbonus_move(char d, uint8_t passable) { - char * dsc_dir = "north"; - if ( match_dir(d, &dsc_dir, '6', "east") - || match_dir(d, &dsc_dir, '2', "south") - || match_dir(d, &dsc_dir, '4', "west") - || match_dir(d, &dsc_dir, '7', "north-west") - || match_dir(d, &dsc_dir, '9', "north-east") - || match_dir(d, &dsc_dir, '1', "south-west") - || match_dir(d, &dsc_dir, '3', "south-east")) + char * dsc_dir = "north-east"; + if ( match_dir(d, &dsc_dir, 'd', "east") + || match_dir(d, &dsc_dir, 'c', "south-east") + || match_dir(d, &dsc_dir, 'x', "south-west") + || match_dir(d, &dsc_dir, 's', "west") + || match_dir(d, &dsc_dir, 'w', "north-west")) { ; } diff --git a/src/server/map_object_actions.h b/src/server/map_object_actions.h index 17c4b1e..8133e53 100644 --- a/src/server/map_object_actions.h +++ b/src/server/map_object_actions.h @@ -34,9 +34,9 @@ extern uint8_t get_moa_id_by_name(char * name); extern void actor_wait(struct MapObj * mo); /* Actor "mo" tries to move one step in direction described by char mo->arg - * (where east is '6', north '8') 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. + * (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. */ extern void actor_move(struct MapObj * mo); diff --git a/src/server/run.c b/src/server/run.c index f5d0e17..4145492 100644 --- a/src/server/run.c +++ b/src/server/run.c @@ -27,17 +27,6 @@ */ static void turn_over(); -/* Helper to turn_over() to determine whether a map object's action effort has - * reached its end. The simplicity of just comparing map_object->progress to - * moa->effort is suspended for actor movement, for in this case the effort - * depends on the diagonal movement penalty expressed in the ratio of - * world.map.dist_diagonal / world.map.dist_orthogonal. (Movement being diagonal - * or orthogonal is determined by the ->arg char encoding an even or un-even - * number digit). - */ -static uint8_t is_effort_finished(struct MapObjAct * moa, - struct MapObj * map_object); - /* If "msg"'s first part matches "command_name", set player's MapObj's .command * to the command's id and its .arg to a numerical value following in the latter * part of "msg" (if no digits are found, use 0); then finish player's turn and @@ -83,7 +72,7 @@ static void turn_over() { moa = moa->next; } - if (is_effort_finished(moa, map_object)) + if (map_object->progress == moa->effort) { moa->func(map_object); map_object->command = 0; @@ -96,37 +85,6 @@ static void turn_over() -static uint8_t is_effort_finished(struct MapObjAct * moa, - struct MapObj * map_object) -{ - if (moa->func != actor_move) - { - if (map_object->progress == moa->effort) - { - return 1; - } - } - else if (strchr("8624", map_object->arg)) - { - if (map_object->progress == moa->effort) - { - return 1; - } - } - else if (strchr("1379", map_object->arg)) - { - uint16_t diagonal_effort = (moa->effort * world.map.dist_diagonal) - / world.map.dist_orthogonal; - if (map_object->progress == diagonal_effort) - { - return 1; - } - } - return 0; -} - - - static uint8_t apply_player_command(char * msg, char * command_name) { if (!strncmp(msg, command_name, strlen(command_name))) diff --git a/src/server/yx_uint8.c b/src/server/yx_uint8.c index 06fa81d..8d47c82 100644 --- a/src/server/yx_uint8.c +++ b/src/server/yx_uint8.c @@ -19,41 +19,33 @@ extern uint8_t yx_uint8_cmp(struct yx_uint8 * a, struct yx_uint8 * b) extern struct yx_uint8 mv_yx_in_dir(char d, struct yx_uint8 yx) { - if (d == '8' && yx.y > 0) + if (d == 'e' && yx.y > 0 && (yx.x < UINT8_MAX || !(yx.y % 2))) { + yx.x = yx.x + (yx.y % 2); yx.y--; } - else if (d == '9' && yx.y > 0 && yx.x < UINT8_MAX) + else if (d == 'd' && yx.x < UINT8_MAX) { - yx.y--; - yx.x++; - } - else if (d == '6' && yx.x < UINT8_MAX) - { - yx.x++; - } - else if (d == '3' && yx.x < UINT8_MAX && yx.y < UINT8_MAX) - { - yx.y++; yx.x++; } - else if (d == '2' && yx.y < UINT8_MAX) + else if (d == 'c' && yx.y < UINT8_MAX && (yx.x < UINT8_MAX || !(yx.y % 2))) { + yx.x = yx.x + (yx.y % 2); yx.y++; } - else if (d == '1' && yx.y < UINT8_MAX && yx.x > 0) + else if (d == 'x' && yx.y < UINT8_MAX && (yx.x > 0 || yx.y % 2)) { + yx.x = yx.x - !(yx.y % 2); yx.y++; - yx.x--; } - else if (d == '4' && yx.x > 0) + else if (d == 's' && yx.x > 0) { yx.x--; } - else if (d == '7' && yx.x > 0 && yx.y > 0) + else if (d == 'w' && yx.y > 0 && (yx.x > 0 || yx.y % 2)) { + yx.x = yx.x - !(yx.y % 2); yx.y--; - yx.x--; } return yx; } diff --git a/src/server/yx_uint8.h b/src/server/yx_uint8.h index 1463c5f..ccfaa25 100644 --- a/src/server/yx_uint8.h +++ b/src/server/yx_uint8.h @@ -14,9 +14,10 @@ /* Return 1 if two yx_uint8 coordinates at "a" and "b" are equal, else 0. */ extern uint8_t yx_uint8_cmp(struct yx_uint8 * a, struct yx_uint8 * b); -/* Return yx_uint8 coordinate one step from "yx" in direction "dir" (numpad - * digits: north '8', east: '6', etc.) If "dir" is invalid or would wrap the - * move around the edge of a 2^16x2^16 cells field, "yx" remains unchanged. +/* Return yx_uint8 coordinate one step from "yx" in direction "dir" ('e': + * northeast, 'd': east, 'c': south-east, 'x': south-west, 's': west, ' 'w': + * north-west). If "dir" is invalid or would wrap the move around the edge of a + * 2^8x2^8 cells field, "yx" remains unchanged. */ extern struct yx_uint8 mv_yx_in_dir(char dir, struct yx_uint8 yx); -- 2.30.2