[Freeciv-Dev] (PR#8944) settler citymap overlays
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8944 >
People have often requested a citymap overlay for settlers, so you can
see their city range.
This patch implements that. The settler overlay works just like the
city overlay. (It also fixes a bad drawing bug in packhand.c, which
should be fixed separately.)
This is just a demo at this point. Only gui-gtk-2.0 is supported.
jason
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.136
diff -u -r1.136 control.c
--- client/control.c 28 May 2004 19:13:07 -0000 1.136
+++ client/control.c 10 Jun 2004 02:56:13 -0000
@@ -1319,7 +1319,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/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.123
diff -u -r1.123 mapview_common.c
--- client/mapview_common.c 10 Jun 2004 01:04:52 -0000 1.123
+++ client/mapview_common.c 10 Jun 2004 02:56:14 -0000
@@ -842,6 +842,20 @@
width, height);
}
+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
@@ -1467,8 +1481,11 @@
/* Draw citymap overlays on top. */
gui_rect_iterate(gui_x0, gui_y0, width, height, map_x, map_y, draw) {
if (((draw & D_B) || (draw & D_M))
- && normalize_map_pos(&map_x, &map_y)) {
- struct city *pcity = find_city_near_tile(map_x, map_y);
+ && normalize_map_pos(&map_x, &map_y)
+ && tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
+ struct unit *punit;
+ struct city *pcity = find_city_or_settler_near_tile(map_x, map_y,
+ &punit);
int city_x, city_y, canvas_x2, canvas_y2;
if (pcity
@@ -1484,6 +1501,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;
@@ -1941,7 +1966,7 @@
}
/**************************************************************************
- Find the "best" city to associate with the selected tile.
+ Find the "best" city or settlers to associate with the selected tile.
a. A city working the tile is the best
b. If another player is working the tile, return NULL.
c. If no city is working the tile, choose a city that could work
@@ -1949,12 +1974,20 @@
d. If multiple cities could work it, choose the most recently
"looked at".
e. If none of the cities were looked at last, choose "randomly".
- f. If no cities can work it, return NULL.
+ f. If any settlers could work it if they founded a city, choose the
+ closest settler (only if punit != NULL).
+ g. If no cities or settlers 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, *pcity2;
static struct city *last_pcity = NULL;
+ struct unit *closest_settler = NULL, *best_settler = NULL;
+
+ if (punit) {
+ *punit = NULL;
+ }
if (pcity) {
if (pcity->owner == game.player_idx) {
@@ -1990,7 +2023,52 @@
/* rule e */
last_pcity = pcity2;
- return pcity2;
+ if (pcity2 || !punit) {
+ return pcity2;
+ }
+
+ /* rule f */
+ 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_type_flag(psettler->type, F_CITIES)
+ && psettler->transported_by == -1) {
+ if (!closest_settler) {
+ /* The closest settler is the one nearest to the position. */
+ closest_settler = psettler;
+ }
+ if (city_colors[psettler->client.color] != COLOR_STD_LAST
+ && !best_settler) {
+ /* The best settler is the nearest one to the position that
+ * is "active". */
+ best_settler = psettler;
+ }
+ }
+ } unit_list_iterate_end;
+ }
+ } city_map_iterate_outwards_end;
+
+ if (best_settler) {
+ *punit = best_settler;
+ } else {
+ *punit = closest_settler;
+ }
+
+ 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.66
diff -u -r1.66 mapview_common.h
--- client/mapview_common.h 10 Jun 2004 01:04:52 -0000 1.66
+++ client/mapview_common.h 10 Jun 2004 02:56:14 -0000
@@ -258,6 +258,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);
@@ -284,7 +285,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.378
diff -u -r1.378 packhand.c
--- client/packhand.c 10 Jun 2004 01:04:52 -0000 1.378
+++ client/packhand.c 10 Jun 2004 02:56:14 -0000
@@ -1093,7 +1093,7 @@
/* Show where the unit is going. */
do_move_unit(punit, packet_unit);
- if (punit->transported_by != -1) {
+ if (punit->transported_by == -1) {
repaint_unit = TRUE;
}
@@ -1222,7 +1222,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: client/gui-gtk-2.0/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapctrl.c,v
retrieving revision 1.40
diff -u -r1.40 mapctrl.c
--- client/gui-gtk-2.0/mapctrl.c 10 Jun 2004 01:04:53 -0000 1.40
+++ client/gui-gtk-2.0/mapctrl.c 10 Jun 2004 02:56:14 -0000
@@ -375,6 +375,7 @@
{
int x,y;
struct city *pcity;
+ struct unit *punit;
if (!can_client_change_view()) {
return;
@@ -385,13 +386,13 @@
nearest_real_pos(&x, &y);
}
- pcity = find_city_near_tile(x, y);
- if (!pcity) {
- return;
+ pcity = find_city_or_settler_near_tile(x, y, &punit);
+ if (pcity) {
+ /* Shade tiles on usage */
+ toggle_city_color(pcity);
+ } else if (punit) {
+ toggle_unit_color(punit);
}
-
- /* Shade tiles on usage */
- toggle_city_color(pcity);
}
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.210
diff -u -r1.210 unit.c
--- common/unit.c 19 May 2004 00:49:31 -0000 1.210
+++ common/unit.c 10 Jun 2004 02:56:15 -0000
@@ -1724,6 +1724,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.118
diff -u -r1.118 unit.h
--- common/unit.h 19 May 2004 00:49:31 -0000 1.118
+++ common/unit.h 10 Jun 2004 02:56:15 -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] |
- [Freeciv-Dev] (PR#8944) settler citymap overlays,
Jason Short <=
|
|