home · contact · privacy
Server: Refactor yx_uint8 moving; handle actors hitting the map edge.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 21 Aug 2014 23:19:51 +0000 (01:19 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 21 Aug 2014 23:19:51 +0000 (01:19 +0200)
TODO
src/server/field_of_view.c
src/server/map.c
src/server/map.h
src/server/thing_actions.c
src/server/yx_uint8.c
src/server/yx_uint8.h

diff --git a/TODO b/TODO
index c9645c9081c9eb310f903d0084737109441aad9a..a5eb09432b8f8b604ace9f715fc6f9a1e9196343 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,10 +4,6 @@ IN GENERAL:
 
 - expand use of hardcoded_strings module(s)
 
-SERVER:
-
-- handle case of actors hitting the map edge
-
 BOTH SERVER/CLIENT:
 
 - make server and client communicate by specific world state info requests 
index 45f3108aafcb2a2f2be773d7e81d5f26aafdbd8f..b4303970cdee2bcb283ed223aa5a6832f3ca0cb2 100644 (file)
@@ -6,8 +6,9 @@
 #include <string.h> /* memset() */
 #include "../common/rexit.h" /* exit_trouble() */
 #include "../common/try_malloc.h" /* try_malloc() */
+#include "map.h" /* mv_yx_in_dir_legal() */
 #include "things.h" /* Thing, ThingInMemory, add_thing_to_memory_map() */
-#include "yx_uint8.h" /* yx_uint8 */
+#include "yx_uint8.h" /* yx_uint8, mv_yx_in_hex_dir(), mv_yx_in_dir_wrap(), */
 #include "world.h" /* world  */
 
 
@@ -30,22 +31,6 @@ struct shadow_angle
 
 
 
-/* Move "yx" into hex direction "d". */
-static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx);
-
-/* Move "yx" into hex direction "d". If this moves "yx" beyond the minimal (0)
- * or maximal (UINT8_MAX) column or row, it wraps to the opposite side. Such
- * wrapping is returned as a wraps enum value and stored, so that further calls
- * to move "yx" back into the opposite direction may unwrap it again. Pass an
- * "unwrap" of !0 to re-set the internal wrap memory to 0.
- */
-static uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap);
-
-/* Wrapper to mv_yx_in_dir_wrap(), returns 1 if the wrapped function moved "yx"
- * within the wrap borders and the map size, else 0.
- */
-static uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx);
-
 /* Recalculate angle < 0 or > CIRCLE to a value between these two limits. */
 static uint32_t correct_angle(int32_t angle);
 
@@ -91,86 +76,6 @@ static void update_map_memory(struct Thing * t, uint32_t map_size);
 
 
 
-static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx)
-{
-    if     (d == 'e')
-    {
-        yx->x = yx->x + (yx->y % 2);
-        yx->y--;
-    }
-    else if (d == 'd')
-    {
-        yx->x++;
-    }
-    else if (d == 'c')
-    {
-        yx->x = yx->x + (yx->y % 2);
-        yx->y++;
-    }
-    else if (d == 'x')
-    {
-        yx->x = yx->x - !(yx->y % 2);
-        yx->y++;
-    }
-    else if (d == 's')
-    {
-        yx->x--;
-    }
-    else if (d == 'w')
-    {
-        yx->x = yx->x - !(yx->y % 2);
-        yx->y--;
-    }
-}
-
-
-
-static uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap)
-{
-    static int8_t wrap_west_east   = 0;
-    static int8_t wrap_north_south = 0;
-    if (unwrap)
-    {
-        wrap_west_east = wrap_north_south = 0;
-        return 0;
-    }
-    struct yx_uint8 original;
-    original.y = yx->y;
-    original.x = yx->x;
-    mv_yx_in_hex_dir(d, yx);
-    if      (strchr("edc", d) && yx->x < original.x)
-    {
-        wrap_west_east++;
-    }
-    else if (strchr("xsw", d) && yx->x > original.x)
-    {
-        wrap_west_east--;
-    }
-    if      (strchr("we", d) && yx->y > original.y)
-    {
-        wrap_north_south--;
-    }
-    else if (strchr("xc", d) && yx->y < original.y)
-    {
-        wrap_north_south++;
-    }
-    return (wrap_west_east != 0) + (wrap_north_south != 0);
-}
-
-
-
-static uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx)
-{
-    uint8_t wraptest = mv_yx_in_dir_wrap(dir, yx, 0);
-    if (!wraptest && yx->x < world.map.length && yx->y < world.map.length)
-    {
-        return 1;
-    }
-    return 0;
-}
-
-
-
 static uint32_t correct_angle(int32_t angle)
 {
     while (angle < 0)
index 8ed37d9b50cbd017baf0cb2c0464e5e547aebeab..50c7bf1560105c5e6b3f2af12971637492ae2ac5 100644 (file)
@@ -7,6 +7,7 @@
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "../common/yx_uint8.h" /* struct yx_uint8 */
 #include "rrand.h" /* rrand() */
+#include "yx_uint8.h" /* mv_yx_in_dir_wrap() */
 #include "world.h" /* global world */
 
 
@@ -160,3 +161,15 @@ extern uint8_t is_passable(struct yx_uint8 pos)
     }
     return passable;
 }
+
+
+
+extern uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx)
+{
+    uint8_t wraptest = mv_yx_in_dir_wrap(dir, yx, 0);
+    if (!wraptest && yx->x < world.map.length && yx->y < world.map.length)
+    {
+        return 1;
+    }
+    return 0;
+}
index b1ad4c716b1ddd9ef64c5ebd58219454ea02eeac..e3a28f9dc99b15dbccd5f03278779356ef524ab0 100644 (file)
@@ -6,8 +6,8 @@
 #ifndef MAP_H_SERVER
 #define MAP_H_SERVER
 
-#include <stdint.h> /* uint8_t, uint16_t */
-#include "../common/yx_uint8.h" /* yx_uint8 struct */
+#include <stdint.h> /* uint8_t */
+#include "../common/yx_uint8.h" /* yx_uint8 */
 
 
 
@@ -26,6 +26,10 @@ extern void remake_map();
  */
 extern uint8_t is_passable(struct yx_uint8 pos);
 
+/* Wrapper to mv_yx_in_dir_wrap(), returns 1 if the wrapped function moved "yx"
+ * within the wrap borders and the map size, else 0.
+ */
+extern uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx);
 
 
 #endif
index 9befd76234bc1efba1f2c9edf0c047d99eb7946c..d12087692514d70569c297a4fee893ae3b2d76ce 100644 (file)
@@ -15,8 +15,8 @@
                      * set_thing_position(), get_thing_type(),
                      * free_things_in_memory()
                      */
-#include "map.h" /* is_passable() */
-#include "yx_uint8.h" /* mv_yx_in_dir(), yx_uint8_cmp() */
+#include "map.h" /* mv_yx_in_dir_legal(), is_passable() */
+#include "yx_uint8.h" /* mv_yx_in_dir_wrap(), yx_uint8_cmp() */
 #include "world.h" /* global world */
 
 
@@ -259,21 +259,26 @@ extern void actor_wait(struct Thing * t)
 extern void actor_move(struct Thing * t)
 {
     char d = t->arg;
-    struct yx_uint8 target = mv_yx_in_dir(d, t->pos);
     struct Thing * other_t;
-    for (other_t = world.things; other_t != 0; other_t = other_t->next)
+    struct yx_uint8 target = t->pos;
+    uint8_t legal_move = mv_yx_in_dir_legal(d, &target);
+    mv_yx_in_dir_wrap(0, NULL, 1);
+    if (legal_move)
     {
-        if (0 == other_t->lifepoints || other_t == t)
+        for (other_t = world.things; other_t != 0; other_t = other_t->next)
         {
-            continue;
-        }
-        if (yx_uint8_cmp(&target, &other_t->pos))
-        {
-            actor_hits_actor(t, other_t);
-            return;
+            if (0 == other_t->lifepoints || other_t == t)
+            {
+                continue;
+            }
+            if (yx_uint8_cmp(&target, &other_t->pos))
+            {
+                actor_hits_actor(t, other_t);
+               return;
+            }
         }
     }
-    uint8_t passable = is_passable(target);
+    uint8_t passable = legal_move && is_passable(target);
     if (passable)
     {
         set_thing_position(t, target);
index 626f9b4c6672044b6214bd8d2822c2a4bcd07bd6..c6a816dbc31ed355c4dc4906b4752c52ed6a6b72 100644 (file)
@@ -1,8 +1,48 @@
 /* src/server/yx_uint8.c */
 
 #include "yx_uint8.h"
-#include <stdint.h> /* uint8_t, UINT8_MAX */
-#include "../common/yx_uint8.h" /* yx_uint8 struct */
+#include <stdint.h> /* uint8_t, int8_t */
+#include <string.h> /* strchr() */
+#include "../common/yx_uint8.h" /* yx_uint8 */
+
+
+
+/* Move "yx" into hex direction "d". */
+static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx);
+
+
+
+static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx)
+{
+    if     (d == 'e')
+    {
+        yx->x = yx->x + (yx->y % 2);
+        yx->y--;
+    }
+    else if (d == 'd')
+    {
+        yx->x++;
+    }
+    else if (d == 'c')
+    {
+        yx->x = yx->x + (yx->y % 2);
+        yx->y++;
+    }
+    else if (d == 'x')
+    {
+        yx->x = yx->x - !(yx->y % 2);
+        yx->y++;
+    }
+    else if (d == 's')
+    {
+        yx->x--;
+    }
+    else if (d == 'w')
+    {
+        yx->x = yx->x - !(yx->y % 2);
+        yx->y--;
+    }
+}
 
 
 
@@ -17,35 +57,34 @@ 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)
+extern uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap)
 {
-    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 == 'd' && yx.x < UINT8_MAX)
+    static int8_t wrap_west_east   = 0;
+    static int8_t wrap_north_south = 0;
+    if (unwrap)
     {
-        yx.x++;
+        wrap_west_east = wrap_north_south = 0;
+        return 0;
     }
-    else if (d == 'c' && yx.y < UINT8_MAX && (yx.x < UINT8_MAX || !(yx.y % 2)))
+    struct yx_uint8 original;
+    original.y = yx->y;
+    original.x = yx->x;
+    mv_yx_in_hex_dir(d, yx);
+    if      (strchr("edc", d) && yx->x < original.x)
     {
-        yx.x = yx.x + (yx.y % 2);
-        yx.y++;
+        wrap_west_east++;
     }
-    else if (d == 'x' && yx.y < UINT8_MAX && (yx.x > 0 || yx.y % 2))
+    else if (strchr("xsw", d) && yx->x > original.x)
     {
-        yx.x = yx.x - !(yx.y % 2);
-        yx.y++;
+        wrap_west_east--;
     }
-    else if (d == 's' && yx.x > 0)
+    if      (strchr("we", d) && yx->y > original.y)
     {
-        yx.x--;
+        wrap_north_south--;
     }
-    else if (d == 'w' && yx.y > 0         && (yx.x > 0 || yx.y % 2))
+    else if (strchr("xc", d) && yx->y < original.y)
     {
-        yx.x = yx.x - !(yx.y % 2);
-        yx.y--;
+        wrap_north_south++;
     }
-    return yx;
+    return (wrap_west_east != 0) + (wrap_north_south != 0);
 }
index ccfaa25ad336844f8dc6b71f9bb9264f2e7595c6..62cc9ce1f9c74fb07eb8df071039bbe8e1299e32 100644 (file)
@@ -7,19 +7,22 @@
 #define YX_UINT8_H_SERVER
 
 #include <stdint.h> /* uint8_t */
-#include "../common/yx_uint8.h" /* yx_uint8 struct */
+#include "../common/yx_uint8.h" /* yx_uint8 */
 
 
 
 /* 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" ('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.
+/* Move "yx" into hex direction "d". If this moves "yx" beyond the minimal (0)
+ * or maximal (UINT8_MAX) column or row, it wraps to the opposite side. Such
+ * wrapping is returned as a wraps enum value and stored, so that further calls
+ * to move "yx" back into the opposite direction may unwrap it again. Pass an
+ * "unwrap" of !0 to re-set the internal wrap memory to 0.
+ * Hex direction values for "d": 'e' (north-east), 'd' (east), 'c' (south-east),
+ * 'x' (south-west), 's' (west), 'w' (north-west)
  */
-extern struct yx_uint8 mv_yx_in_dir(char dir, struct yx_uint8 yx);
+extern uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap);