Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2004:
[Freeciv-Dev] (PR#9482) Patch: add hex-tile support to Freeciv
Home

[Freeciv-Dev] (PR#9482) Patch: add hex-tile support to Freeciv

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9482) Patch: add hex-tile support to Freeciv
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 22 Jul 2004 21:18:43 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=9482 >

This patch adds hex-tile support to Freeciv.  I think it is simple 
enough to warrant direct inclusion at this point.

Please review.

jason

Index: client/connectdlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/connectdlg_common.c,v
retrieving revision 1.14
diff -u -r1.14 connectdlg_common.c
--- client/connectdlg_common.c  30 Jun 2004 14:34:30 -0000      1.14
+++ client/connectdlg_common.c  23 Jul 2004 03:52:55 -0000
@@ -243,12 +243,18 @@
    * get an iso-map and for a classic tileset you get a classic map.  In
    * both cases the map wraps in the X direction by default.
    *
+   * This works with hex maps too now.  A hex map always has is_isometric
+   * set.  An iso-hex map has hex_height != 0, while a non-iso hex map
+   * has hex_width != 0.
+   *
    * Setting the option here is a bit of a hack, but so long as the client
    * has sufficient permissions to do so (it doesn't have HACK access yet) it
    * is safe enough.  Note that if you load a savegame the topology will be
    * set but then overwritten during the load. */
   my_snprintf(buf, sizeof(buf), "/set topology %d",
-             TF_WRAPX | (is_isometric ? TF_ISO : 0));
+             (TF_WRAPX
+              | ((is_isometric && hex_height == 0) ? TF_ISO : 0)
+              | ((hex_width != 0 || hex_height != 0) ? TF_HEX : 0)));
   send_chat(buf);
 
   return TRUE;
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.181
diff -u -r1.181 map.c
--- common/map.c        20 Jul 2004 16:04:56 -0000      1.181
+++ common/map.c        23 Jul 2004 03:52:56 -0000
@@ -318,7 +318,7 @@
 {
   /* In TF_ISO we need to double the map.ysize factor, since xsize is
    * in native coordinates which are compressed 2x in the X direction. */ 
-  const int iso = topo_has_flag(TF_ISO) ? 2 : 1;
+  const int iso = (topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX)) ? 2 : 1;
 
   /* We have:
    *
@@ -551,7 +551,13 @@
 ****************************************************************************/
 static int map_vector_to_distance(int dx, int dy)
 {
-  return abs(dx) + abs(dy);
+  if (topo_has_flag(TF_HEX)) {
+    /* Hex: all directions are cardinal so the distance is equivalent to
+     * the real distance. */
+    return map_vector_to_real_distance(dx, dy);
+  } else {
+    return abs(dx) + abs(dy);
+  }
 }
 
 /****************************************************************************
@@ -559,7 +565,33 @@
 ****************************************************************************/
 int map_vector_to_real_distance(int dx, int dy)
 {
-  return MAX(abs(dx), abs(dy));
+  if (topo_has_flag(TF_HEX)) {
+    if (topo_has_flag(TF_ISO)) {
+      /* Iso-hex: you can't move NE or SW. */
+      if ((dx < 0 && dy > 0)
+         || (dx > 0 && dy < 0)) {
+       /* Diagonal moves in this direction aren't allowed, so it will take
+        * the full number of moves. */
+       return abs(dx) + abs(dy);
+      } else {
+       /* Diagonal moves in this direction *are* allowed. */
+       return MAX(abs(dx), abs(dy));
+      }
+    } else {
+      /* Hex: you can't move SE or NW. */
+      if ((dx > 0 && dy > 0)
+         || (dx < 0 && dy < 0)) {
+       /* Diagonal moves in this direction aren't allowed, so it will take
+        * the full number of moves. */
+       return abs(dx) + abs(dy);
+      } else {
+       /* Diagonal moves in this direction *are* allowed. */
+       return MAX(abs(dx), abs(dy));
+      }
+    }
+  } else {
+    return MAX(abs(dx), abs(dy));
+  }
 }
 
 /****************************************************************************
@@ -567,7 +599,15 @@
 ****************************************************************************/
 int map_vector_to_sq_distance(int dx, int dy)
 {
-  return dx * dx + dy * dy;
+  if (topo_has_flag(TF_HEX)) {
+    /* Hex: The square distance is just the square of the real distance; we
+     * don't worry about pythagorean calculations. */
+    int dist = map_vector_to_real_distance(dx, dy);
+
+    return dist * dist;
+  } else {
+    return dx * dx + dy * dy;
+  }
 }
 
 /***************************************************************
@@ -1736,14 +1776,16 @@
 bool is_valid_dir(enum direction8 dir)
 {
   switch (dir) {
-  case DIR8_NORTH:
+  case DIR8_SOUTHEAST:
+  case DIR8_NORTHWEST:
+    return !(topo_has_flag(TF_HEX) && !topo_has_flag(TF_ISO));
   case DIR8_NORTHEAST:
+  case DIR8_SOUTHWEST:
+    return !(topo_has_flag(TF_HEX) && topo_has_flag(TF_ISO));
+  case DIR8_NORTH:
   case DIR8_EAST:
-  case DIR8_SOUTHEAST:
   case DIR8_SOUTH:
-  case DIR8_SOUTHWEST:
   case DIR8_WEST:
-  case DIR8_NORTHWEST:
     return TRUE;
   default:
     return FALSE;
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.199
diff -u -r1.199 map.h
--- common/map.h        23 Jul 2004 03:42:30 -0000      1.199
+++ common/map.h        23 Jul 2004 03:52:56 -0000
@@ -183,7 +183,8 @@
   /* Changing these values will break map_init_topology. */
   TF_WRAPX = 1,
   TF_WRAPY = 2,
-  TF_ISO = 4
+  TF_ISO = 4,
+  TF_HEX = 8
 };
 
 #define CURRENT_TOPOLOGY (map.topology_id)
@@ -236,13 +237,13 @@
 
 /* Obscure math.  See explanation in doc/HACKING. */
 #define native_to_map_pos(pmap_x, pmap_y, nat_x, nat_y)                     \
-  (topo_has_flag(TF_ISO)                                                    \
+  ((topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX))                         \
    ? (*(pmap_x) = ((nat_y) + ((nat_y) & 1)) / 2 + (nat_x),                  \
       *(pmap_y) = (nat_y) - *(pmap_x) + map.xsize)                          \
    : (*(pmap_x) = (nat_x), *(pmap_y) = (nat_y)))
 
 #define map_to_native_pos(pnat_x, pnat_y, map_x, map_y)                     \
-  (topo_has_flag(TF_ISO)                                                    \
+  ((topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX))                        \
    ? (*(pnat_y) = (map_x) + (map_y) - map.xsize,                            \
       *(pnat_x) = (2 * (map_x) - *(pnat_y) - (*(pnat_y) & 1)) / 2)          \
    : (*(pnat_x) = (map_x), *(pnat_y) = (map_y)))
@@ -581,9 +582,23 @@
 
 /* is the direction "cardinal"?  Cardinal directions
  * (also called cartesian) are the four main ones */
-#define DIR_IS_CARDINAL(dir)                           \
-  ((dir) == DIR8_NORTH || (dir) == DIR8_EAST ||        \
-   (dir) == DIR8_WEST || (dir) == DIR8_SOUTH)
+static inline bool DIR_IS_CARDINAL(enum direction8 dir)
+{
+  switch (dir) {
+  case DIR8_NORTH:
+  case DIR8_SOUTH:
+  case DIR8_EAST:
+  case DIR8_WEST:
+    return TRUE;
+  case DIR8_SOUTHEAST:
+  case DIR8_NORTHWEST:
+    return !(topo_has_flag(TF_HEX) && !topo_has_flag(TF_ISO));
+  case DIR8_NORTHEAST:
+  case DIR8_SOUTHWEST:
+    return !(topo_has_flag(TF_HEX) && topo_has_flag(TF_ISO));
+  }
+  return FALSE;
+}
 
 enum direction8 dir_cw(enum direction8 dir);
 enum direction8 dir_ccw(enum direction8 dir);
@@ -616,7 +631,7 @@
 #define MAP_ORIGINAL_TOPO        TF_WRAPX
 #define MAP_DEFAULT_TOPO         TF_WRAPX
 #define MAP_MIN_TOPO             0
-#define MAP_MAX_TOPO             7
+#define MAP_MAX_TOPO             15
 
 #define MAP_DEFAULT_SEED         0
 #define MAP_MIN_SEED             0
@@ -697,7 +712,9 @@
     /* HACK: An iso-map compresses the value in the X direction but not in
      * the Y direction.  Hence (x+1,y) is 1 tile away while (x,y+2) is also
      * one tile away. */
-    int xdist = dist, ydist = topo_has_flag(TF_ISO) ? (2 * dist) : dist;
+    int xdist = dist;
+    int ydist = ((topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX))
+                ? (2 * dist) : dist);
 
     return (nat_x < xdist 
            || nat_y < ydist
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.329
diff -u -r1.329 stdinhand.c
--- server/stdinhand.c  20 Jul 2004 11:51:33 -0000      1.329
+++ server/stdinhand.c  23 Jul 2004 03:52:57 -0000
@@ -274,7 +274,15 @@
             "  4 Flat Earth (isometric)\n"
             "  5 Earth (isometric)\n"
             "  6 Uranus (isometric)\n"
-            "  7 Donut World (isometric)"
+            "  7 Donut World (isometric)\n"
+            "  8 Flat Earth (hexagonal)\n"
+            "  9 Earth (hexagonal)\n"
+            " 10 Uranus (hexagonal)\n"
+            " 11 Donut World (hexagonal)\n"
+            " 12 Flat Earth (iso-hex)\n"
+            " 13 Earth (iso-hex)\n"
+            " 14 Uranus (iso-hex)\n"
+            " 15 Donut World (iso-hex)"
           ), NULL, 
          MAP_MIN_TOPO, MAP_MAX_TOPO, MAP_DEFAULT_TOPO)
 

[Prev in Thread] Current Thread [Next in Thread]