<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40667 >
> [book - Mon Jan 19 03:31:45 2009]: > > Attached patch implements traderoute line drawing on the main > map view. [...] Version 2 uses cyan (i.e. the goto line color) instead of green for improved visibility. ----------------------------------------------------------------------- まだ誘惑に負けないか。
diff --git a/client/mapview_common.c b/client/mapview_common.c index 518b6fd..11f9402 100644 --- a/client/mapview_common.c +++ b/client/mapview_common.c @@ -25,6 +25,7 @@ #include "timing.h" /* common */ +#include "game.h" #include "map.h" #include "unitlist.h" @@ -72,6 +73,15 @@ static void queue_mapview_update(enum update_type update); static void queue_mapview_tile_update(struct tile *ptile, enum tile_update_type type); +/* Helper struct for drawing traderoutes. */ +struct traderoute_line { + int x, y, width, height; +}; + +/* A traderoute line might need to be drawn in two parts. */ +static const int MAX_TRADEROUTE_DRAW_LINES = 2; + + /************************************************************************** Refreshes a single tile on the map canvas. **************************************************************************/ @@ -1078,6 +1088,129 @@ static void put_one_tile(struct canvas *pcanvas, enum mapview_layer layer, } /************************************************************************** + Depending on where ptile1 and ptile2 are on the map canvas, a traderoute + line may need to be drawn as two disjointed line segments. This function + fills the given line array 'lines' with the necessary line segments. + + The return value is the number of line segments that need to be drawn. + + NB: It is assumed ptile1 and ptile2 are already consistently ordered. + NB: 'lines' must be able to hold least MAX_TRADEROUTE_DRAW_LINES + elements. +**************************************************************************/ +static int traderoute_to_canvas_lines(const struct tile *ptile1, + const struct tile *ptile2, + struct traderoute_line *lines) +{ + int dx, dy; + + if (!ptile1 || !ptile2 || !lines) { + return 0; + } + + base_map_distance_vector(&dx, &dy, TILE_XY(ptile1), TILE_XY(ptile2)); + map_to_gui_pos(tileset, &lines[0].width, &lines[0].height, dx, dy); + + /* FIXME: Remove these casts. */ + tile_to_canvas_pos(&lines[0].x, &lines[0].y, (struct tile *)ptile1); + tile_to_canvas_pos(&lines[1].x, &lines[1].y, (struct tile *)ptile2); + + if (lines[1].x - lines[0].x == lines[0].width + && lines[1].y - lines[0].y == lines[0].height) { + return 1; + } + + lines[1].width = -lines[0].width; + lines[1].height = -lines[0].height; + return 2; +} + +/************************************************************************** + Draw a colored traderoute line from one tile to another. +**************************************************************************/ +static void draw_traderoute_line(const struct tile *ptile1, + const struct tile *ptile2, + enum color_std color) +{ + struct traderoute_line lines[MAX_TRADEROUTE_DRAW_LINES]; + int line_count, i; + struct color *pcolor; + + if (!ptile1 || !ptile2) { + return; + } + + pcolor = get_color(tileset, color); + if (!pcolor) { + return; + } + + /* Order the source and destination tiles consistently + * so that if a line is drawn twice it does not produce + * ugly effects due to dashes not lining up. */ + if (tile_index(ptile2) > tile_index(ptile1)) { + const struct tile *tmp; + tmp = ptile1; + ptile1 = ptile2; + ptile2 = tmp; + } + + line_count = traderoute_to_canvas_lines(ptile1, ptile2, lines); + for (i = 0; i < line_count; i++) { + canvas_put_line(mapview.store, pcolor, LINE_BORDER, + lines[i].x + tileset_tile_width(tileset) / 2, + lines[i].y + tileset_tile_height(tileset) / 2, + lines[i].width, lines[i].height); + } +} + +/************************************************************************** + Draw all traderoutes for the given city. +**************************************************************************/ +static void draw_traderoutes_for_city(const struct city *pcity_src) +{ + int i; + const struct city *pcity_dest; + + if (!pcity_src) { + return; + } + + for (i = 0; i < NUM_TRADEROUTES; i++) { + pcity_dest = game_find_city_by_number(pcity_src->trade[i]); + if (!pcity_dest) { + continue; + } + draw_traderoute_line(city_tile(pcity_src), city_tile(pcity_dest), + COLOR_MAPVIEW_GOTO); /* Cyan. */ + } +} + +/************************************************************************** + Draw traderoutes between cities as lines on the main map canvas. +**************************************************************************/ +static void draw_traderoutes(void) +{ + if (!draw_city_traderoutes) { + return; + } + + if (client_is_global_observer()) { + cities_iterate(pcity) { + draw_traderoutes_for_city(pcity); + } cities_iterate_end; + } else { + struct player *pplayer = client_player(); + if (!pplayer) { + return; + } + city_list_iterate(pplayer->cities, pcity) { + draw_traderoutes_for_city(pcity); + } city_list_iterate_end; + } +} + +/************************************************************************** Update (refresh) the map canvas starting at the given tile (in map coordinates) and with the given dimensions (also in map coordinates). @@ -1159,6 +1292,8 @@ void update_map_canvas(int canvas_x, int canvas_y, int width, int height) } gui_rect_iterate_end; } mapview_layer_iterate_end; + draw_traderoutes(); + /* Draw the goto lines on top of the whole thing. This is done last as * we want it completely on top. *
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev