Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2004:
[Freeciv-Dev] (PR#8944) settler citymap overlays
Home

[Freeciv-Dev] (PR#8944) settler citymap overlays

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#8944) settler citymap overlays
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 29 Jul 2004 09:50:46 -0700
Reply-to: rt@xxxxxxxxxxx

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

Here's an update of the settler-overlay patch.  No GUI changes are
needed now.  I think it is ready for inclusion.  Please test.

jason

Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.138
diff -u -r1.138 control.c
--- client/control.c    20 Jul 2004 10:13:06 -0000      1.138
+++ client/control.c    29 Jul 2004 16:50:06 -0000
@@ -1318,7 +1318,18 @@
   if (punit->transported_by == -1) {
     /* We have to refresh the tile before moving.  This will draw
      * the tile without the unit (because it was unlinked above). */
-    refresh_tile_mapcanvas(x, y, FALSE);
+    if (unit_type_flag(punit->type, F_CITIES)) {
+      int width = get_citydlg_canvas_width();
+      int height = get_citydlg_canvas_height();
+      int canvas_x, canvas_y;
+
+      map_to_canvas_pos(&canvas_x, &canvas_y, x, y);
+      update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
+                       canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
+                       width, height);
+    } else {
+      refresh_tile_mapcanvas(x, y, FALSE);
+    }
 
     if (do_animation) {
       int dx, dy;
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.38
diff -u -r1.38 mapctrl_common.c
--- client/mapctrl_common.c     13 Jul 2004 18:22:33 -0000      1.38
+++ client/mapctrl_common.c     29 Jul 2004 16:50:07 -0000
@@ -314,10 +314,14 @@
 
   if (can_client_change_view()
       && canvas_to_map_pos(&map_x, &map_y, canvas_x, canvas_y)) {
-    struct city *pcity = find_city_near_tile(map_x, map_y);
+    struct unit *punit;
+    struct city *pcity = find_city_or_settler_near_tile(map_x, map_y,
+                                                       &punit);
 
     if (pcity) {
       toggle_city_color(pcity);
+    } else if (punit) {
+      toggle_unit_color(punit);
     }
   }
 }
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.138
diff -u -r1.138 mapview_common.c
--- client/mapview_common.c     26 Jul 2004 04:05:58 -0000      1.138
+++ client/mapview_common.c     29 Jul 2004 16:50:07 -0000
@@ -904,6 +904,25 @@
 }
 
 /****************************************************************************
+  Toggle the unit color.  This cycles through the possible colors for the
+  citymap as shown on the mapview.  These colors are listed in the
+  city_colors array; above.
+****************************************************************************/
+void toggle_unit_color(struct unit *punit)
+{
+  int canvas_x, canvas_y;
+  int width = get_citydlg_canvas_width();
+  int height = get_citydlg_canvas_height();
+
+  punit->client.color = (punit->client.color + 1) % NUM_CITY_COLORS;
+
+  map_to_canvas_pos(&canvas_x, &canvas_y, punit->x, punit->y);
+  update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
+                   canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
+                   width, height);
+}
+
+/****************************************************************************
   Return the vertices of the given edge of the tile.  This will return
   FALSE if the edge doesn't exist (or if it does exist but is part of an
   adjacent tile).
@@ -1536,10 +1555,13 @@
 
   /* Draw citymap overlays on top. */
   gui_rect_iterate(gui_x0, gui_y0, width, height, map_x, map_y) {
-    if (normalize_map_pos(&map_x, &map_y)) {
-      struct city *pcity = find_city_near_tile(map_x, map_y);
+    if (normalize_map_pos(&map_x, &map_y)
+       && tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
+      struct unit *punit;
+      struct city *pcity;
       int city_x, city_y, canvas_x2, canvas_y2;
 
+      pcity = find_city_or_settler_near_tile(map_x, map_y, &punit);
       if (pcity
          && city_colors[pcity->client.color] != COLOR_STD_LAST
          && map_to_city_map(&city_x, &city_y, pcity, map_x, map_y)
@@ -1553,6 +1575,14 @@
          put_city_tile_output(pcity, city_x, city_y,
                               mapview_canvas.store, canvas_x2, canvas_y2);
        }
+      } else if (punit
+                && city_colors[punit->client.color] != COLOR_STD_LAST
+                && map_to_canvas_pos(&canvas_x2, &canvas_y2,
+                                     map_x, map_y)) {
+       /* Draw citymap overlay for settlers. */
+       put_city_worker(mapview_canvas.store,
+                       city_colors[punit->client.color], C_TILE_EMPTY,
+                       canvas_x2, canvas_y2);
       }
     }
   } gui_rect_iterate_end;
@@ -1919,16 +1949,26 @@
 }
 
 /**************************************************************************
-  Find the "best" city to associate with the selected tile.
+  Find the "best" city/settlers to associate with the selected tile.
     a.  If a city is working the tile, return that city.
     b.  If another player's city is working the tile, return NULL.
     c.  If any selected cities are within range, return the closest one.
     d.  If any cities are within range, return the closest one.
-    e.  If nobody can work it, return NULL.
+    e.  If any active (with color) settler could work it if they founded a
+        city, choose the closest one (only if punit != NULL).
+    f.  If any settler could work it if they founded a city, choose the
+        closest one (only if punit != NULL).
+    g.  If nobody can work it, return NULL.
 **************************************************************************/
-struct city *find_city_near_tile(int x, int y)
+struct city *find_city_or_settler_near_tile(int x, int y,
+                                           struct unit **punit)
 {
   struct city *pcity = map_get_tile(x, y)->worked, *closest_city;
+  struct unit *closest_settler = NULL, *best_settler = NULL;
+
+  if (punit) {
+    *punit = NULL;
+  }
 
   if (pcity) {
     if (pcity->owner == game.player_idx) {
@@ -1966,7 +2006,50 @@
   } city_map_checked_iterate_end;
 
   /* rule d */
-  return closest_city;
+  if (closest_city || !punit) {
+    return closest_city;
+  }
+
+  city_map_iterate_outwards(city_x, city_y) {
+    int new_x = x + city_x - CITY_MAP_RADIUS;
+    int new_y = y + city_y - CITY_MAP_RADIUS;
+
+    if (normalize_map_pos(&new_x, &new_y)) {
+      struct tile *ptile = map_get_tile(new_x, new_y);
+
+      unit_list_iterate(ptile->units, psettler) {
+       if (psettler->owner == game.player_idx
+           && unit_flag(psettler, F_CITIES)
+           && city_can_be_built_here(psettler->x, psettler->y, psettler)) {
+         if (!closest_settler) {
+           closest_settler = psettler;
+         }
+         if (!best_settler && psettler->client.color != 0) {
+           best_settler = psettler;
+         }
+       }
+      } unit_list_iterate_end;
+    }
+  } city_map_iterate_outwards_end;
+
+  if (best_settler) {
+    /* Rule e */
+    *punit = best_settler;
+  } else if (closest_settler) {
+    /* Rule f */
+    *punit = closest_settler;
+  }
+
+  /* rule g */
+  return NULL;
+}
+
+/**************************************************************************
+  Find the nearest/best city that owns the tile.
+**************************************************************************/
+struct city *find_city_near_tile(int x, int y)
+{
+  return find_city_or_settler_near_tile(x, y, NULL);
 }
 
 /**************************************************************************
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.72
diff -u -r1.72 mapview_common.h
--- client/mapview_common.h     26 Jul 2004 04:05:58 -0000      1.72
+++ client/mapview_common.h     29 Jul 2004 16:50:07 -0000
@@ -155,6 +155,7 @@
                            struct canvas *pcanvas,
                            int canvas_x, int canvas_y);
 void toggle_city_color(struct city *pcity);
+void toggle_unit_color(struct unit *punit);
 void put_red_frame_tile(struct canvas *pcanvas,
                        int canvas_x, int canvas_y);
 
@@ -182,7 +183,9 @@
                             struct unit *punit1, int hp1);
 void move_unit_map_canvas(struct unit *punit,
                          int map_x, int map_y, int dx, int dy);
-                               
+
+struct city *find_city_or_settler_near_tile(int x, int y,
+                                           struct unit **punit);
 struct city *find_city_near_tile(int x, int y);
 
 void get_city_mapview_production(struct city *pcity,
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.391
diff -u -r1.391 packhand.c
--- client/packhand.c   29 Jul 2004 00:09:26 -0000      1.391
+++ client/packhand.c   29 Jul 2004 16:50:08 -0000
@@ -1231,7 +1231,18 @@
   }
 
   if (repaint_unit) {
-    refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
+    if (unit_type_flag(punit->type, F_CITIES)) {
+      int width = get_citydlg_canvas_width();
+      int height = get_citydlg_canvas_height();
+      int canvas_x, canvas_y;
+
+      map_to_canvas_pos(&canvas_x, &canvas_y, punit->x, punit->y);
+      update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
+                       canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
+                       width, height);
+    } else {
+      refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
+    }
   }
 
   if ((check_focus || get_unit_in_focus() == NULL) &&
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.212
diff -u -r1.212 unit.c
--- common/unit.c       20 Jul 2004 11:05:37 -0000      1.212
+++ common/unit.c       29 Jul 2004 16:50:08 -0000
@@ -1729,6 +1729,7 @@
   punit->ord_city = 0;
   set_unit_activity(punit, ACTIVITY_IDLE);
   punit->occupy = 0;
+  punit->client.color = DEFAULT_CITY_COLOR;
   punit->has_orders = FALSE;
 
   return punit;
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.119
diff -u -r1.119 unit.h
--- common/unit.h       18 Jul 2004 04:08:21 -0000      1.119
+++ common/unit.h       29 Jul 2004 16:50:08 -0000
@@ -172,6 +172,10 @@
 
   int transported_by;
   int occupy; /* number of units that occupy transporter */
+  struct {
+    /* Equivalent to pcity->client.color.  Only for F_CITIES units. */
+    int color;
+  } client;
 
   bool has_orders;
   struct {

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