home · contact · privacy
Make grids hexagonal, remove all diagonal movement penalty hassle.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 16 Apr 2014 14:00:11 +0000 (16:00 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 16 Apr 2014 14:00:11 +0000 (16:00 +0200)
20 files changed:
README
TODO
confclient/commands
confclient/interface_conf
confclient/single_wins/info
confclient/single_wins/inventory
confclient/single_wins/log
confclient/single_wins/map
confserver/world
src/client/draw_wins.c
src/client/map.c
src/server/ai.c
src/server/configfile.c
src/server/map.c
src/server/map.h
src/server/map_object_actions.c
src/server/map_object_actions.h
src/server/run.c
src/server/yx_uint8.c
src/server/yx_uint8.h

diff --git a/README b/README
index 2770f53c8d03cea998c9232f6f82b04975c47d35..9fc5305f72c870669fbd70c7ab0817f6d61a9133 100644 (file)
--- 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 640bbf9bf41c62d240ea6988dd9bb50a01cbe445..9226ff0def768bd29f9bbb0dc3dfa5a68a525f73 100644 (file)
--- 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
index cd7c3acbe7c5f2476e2601631359836ddd16964e..ad6048ffaa09702becdd0af998f4f7b3856c2fa9 100644 (file)
@@ -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'
index 15ab6e00ee9bdaae5084716eb0f6593be833bcd4..51b7f40b581db488d9c21555e0e2534ae4f43d67 100644 (file)
@@ -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
index 7df511cd01baa75421596db7fdc32fe1bbe3d120..cf663e82e29c853a79342130220d76d4c028bdc8 100644 (file)
@@ -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
index cd18cb425a2bd4413d56a0770cc6f46b1ed1e131..905f490cbfa333ce07a07365e9ba3e77b7f40b74 100644 (file)
@@ -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
index 77fcd84339a8541c75f587e620b3aa337fc59431..930b1c252c36ca5c3900754ef71b7ea7ac6c8c30 100644 (file)
@@ -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
index 2857967393abc029d7d3e5e5ca8583a04b27e6c3..86b10276b351ba89a759bbb41a56c79af795a1a3 100644 (file)
@@ -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
index aeae5bd7c35c72e1c636730110d6566023208a57..724d0120f2d6056fb439383712443fd42cc672b2 100644 (file)
@@ -1,8 +1,6 @@
 MAP_TYPE 0
 HEIGHT 64
 WIDTH 64
-DIST_ORTHOGONAL 5
-DIST_DIAGONAL 7
 
 PLAYER_TYPE 0
 
index 08e59270f36931451870f7c5e34a5fe6e6af9b55..dc655e76dad51d71d522794a2e240bfa50dbde19 100644 (file)
@@ -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++;
         }
     }
index 7292c89151a8ecb62a0a0b6c7c3d53e7f67c4e79..48a9b5830de67de3cb60342b8e85277fb6700726 100644 (file)
@@ -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;
 }
index a0f4793fc9881dc95041341bde469685fe55040c..9c31153c40595180c5db22d89ee725e654c7de98 100644 (file)
 
 
 
-#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])
index 537650246dd8e84e09e8d29b1ed71c5f06de89ed..fc2c771f42d952a3c5c5721d8dd533153ee264f1 100644 (file)
@@ -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;
 }
 
index 95d7e0ff4e96f875e17845e8a608c60a05307fbd..9f5b8669b762820738a905e061cb9f828fad911e 100644 (file)
@@ -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] = '.';
         }
     }
 }
index b2b1ba2ec59d74ef3734bd87b85b129c3ab936b5..e97a800ce4b1df0694a1bf2cafef56aa0abaa26c 100644 (file)
@@ -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();
 
index 17d74d5825feebad5555a81820ae4a1c7a02914e..978683292af5b76ab902e8cb5f3525b540bd9d1c 100644 (file)
@@ -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"))
     {
         ;
     }
index 17c4b1e3b8c80daa2e72aae089c7e2e0ac265d7c..8133e538451f00df7195b0bfafa222a126cee79a 100644 (file)
@@ -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);
 
index f5d0e170fd4fcbf237ca900bfa3b17f45af4d841..414549227f963db1d3c21135cdfe51891cfb24de 100644 (file)
  */
 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)))
index 06fa81db7707cf9240280d328a3a4afc4317d684..8d47c82e505d85ec275bfaf98b1bf3dfc2a4e760 100644 (file)
@@ -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;
 }
index 1463c5ff1e37cb494099610aeee6a907853c2516..ccfaa25ad336844f8dc6b71f9bb9264f2e7595c6 100644 (file)
 /* 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);