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 14:17:37 -0000 @@ -160,6 +160,7 @@ update_unit_info_label(punit); update_menus(); + if(punit) set_focus_tile(punit->x, punit->y); } /************************************************************************** @@ -238,6 +239,14 @@ candidate = find_best_focus_candidate(FALSE); } +#if 0 + /* We have to do this ourselves, and not rely on set_unit_focus(), + * because above we change punit_focus directly. + */ + if(punit_old_focus && punit_old_focus!=punit_focus) + refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, FALSE); +#endif + /* Accept current focus unit as last resort. */ if (!candidate) { candidate = find_best_focus_candidate(TRUE); 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 14:17:37 -0000 @@ -32,12 +32,15 @@ #include "climap.h" #include "control.h" #include "goto.h" -#include "mapview_common.h" #include "tilespec.h" +#include "mapview_common.h" + struct mapview_canvas mapview_canvas; struct overview overview; +static struct map_position focus_tile = { -1, -1 }; + /* Arbitrary estimated maximums for width and height of a city description * text. Eventually this may be determined dynamically. */ #define MAX_CITY_DESC_WIDTH 128 @@ -52,6 +55,29 @@ static void base_canvas_to_map_pos(int *map_x, int *map_y, int canvas_x, int canvas_y); static void center_tile_overviewcanvas(int map_x, int map_y); + +static void get_mapview_corners(int x[4], int y[4]); + +void set_focus_tile(int x, int y) +{ + struct map_position old = focus_tile; + + assert(is_real_map_pos(x, y)); + focus_tile.x = x; + focus_tile.y = y; + + if (is_real_map_pos(old.x, old.x)) { + refresh_tile_mapcanvas(old.x, old.y, TRUE); + } + refresh_tile_mapcanvas(focus_tile.x, focus_tile.y, TRUE); +} + +void get_focus_tile(int *x, int *y) +{ + *x=focus_tile.x; + *y=focus_tile.y; +} + static void get_mapview_corners(int x[4], int y[4]); static void redraw_overview(void); static void dirty_overview(void); @@ -787,6 +813,53 @@ } } +void put_terrain(int x, int y, struct canvas *pcanvas, + int canvas_x, int canvas_y) +{ + struct drawn_sprite drawn_sprites[40]; + int count = fill_terrain_sprite_array(drawn_sprites, x, y); + int i; + int unit_width = UNIT_TILE_WIDTH; + int unit_height = UNIT_TILE_HEIGHT; + int unit_offset_x = 0; + int unit_offset_y = 0; + + for (i = 0; i < count; i++) { + if (drawn_sprites[i].sprite) { + int ox = drawn_sprites[i].offset_x, oy = drawn_sprites[i].offset_y; + + canvas_put_sprite(pcanvas, canvas_x + ox, canvas_y + oy, + drawn_sprites[i].sprite, + unit_offset_x - ox, unit_offset_y - oy, + unit_width - ox, unit_height - oy); + } + } +} + +void put_city(struct city *pcity, struct canvas *pcanvas, + int canvas_x, int canvas_y) +{ + struct drawn_sprite drawn_sprites[40]; + bool solid_bg; + int count = fill_city_sprite_array(drawn_sprites, pcity, &solid_bg); + int i; + int unit_width = UNIT_TILE_WIDTH; + int unit_height = UNIT_TILE_HEIGHT; + int unit_offset_x = 0; + int unit_offset_y = 0; + + for (i = 0; i < count; i++) { + if (drawn_sprites[i].sprite) { + int ox = drawn_sprites[i].offset_x, oy = drawn_sprites[i].offset_y; + + canvas_put_sprite(pcanvas, canvas_x + ox, canvas_y + oy, + drawn_sprites[i].sprite, + unit_offset_x - ox, unit_offset_y - oy, + unit_width - ox, unit_height - oy); + } + } +} + /************************************************************************** Draw the given unit onto the canvas store at the given location. **************************************************************************/ @@ -1361,6 +1434,43 @@ } } +#ifdef NEVER +static void tile_draw_focus(struct canvas *pcanvas, + int map_x, int map_y, + int canvas_x, int canvas_y, + bool citymode) +{ + const int inset = (is_isometric ? 0 : 1); + enum direction8 dir; + + if (citymode) { + return; + } + + for (dir = 0; dir < 8; dir++) { + int start_x, start_y, end_x, end_y, adjc_x, adjc_y; + + /* In non-iso view we draw the rectangle with an inset of 1. This makes + * it easy to distinguish from the map grid. + * + * In iso-view the inset doesn't work perfectly (see comments about + * this elsewhere) so we draw without an inset. This may cover up the + * map grid if it is drawn. */ + if (get_tile_boundaries(dir, inset, 1, &start_x, &start_y, + &end_x, &end_y)) { + + /** Focus tile **/ + if ((map_x == focus_tile.x && map_y == focus_tile.y) + || (is_isometric && MAPSTEP(adjc_x, adjc_y, map_x, map_y, dir) + && (map_x == focus_tile.x && map_y == focus_tile.y))) { + canvas_put_line(pcanvas, COLOR_STD_RED, LINE_NORMAL, + canvas_x + start_x, canvas_y + start_y, + end_x - start_x, end_y - start_y); + } + } + } +} +#endif /**************************************************************************** Draw the grid lines of the given map tile at the given canvas position @@ -1619,6 +1729,11 @@ { const int dx = max_desc_width - NORMAL_TILE_WIDTH, dy = max_desc_height; + canvas_x = 0; + canvas_y = 0; + width = mapview_canvas.width; + height = mapview_canvas.height; + if (!draw_city_names && !draw_city_productions) { return; } 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 14:17:37 -0000 @@ -22,8 +22,9 @@ #include "tilespec.h" struct unit; +struct city; -struct canvas_store; /* opaque type, real type is gui-dep */ +struct canvas; /* opaque type, real type is gui-dep */ struct mapview_canvas { int gui_x0, gui_y0; @@ -147,6 +148,10 @@ int unit_width, int unit_height); void put_unit_full(struct unit *punit, struct canvas *pcanvas, int canvas_x, int canvas_y); +void put_terrain(int x, int y, struct canvas *pcanvas, + int canvas_x, int canvas_y); +void put_city(struct city *pcity, struct canvas *pcanvas, + int canvas_x, int canvas_y); void put_city_tile_output(struct city *pcity, int city_x, int city_y, struct canvas *pcanvas, @@ -201,7 +206,8 @@ int map_x, int map_y); void overview_to_map_pos(int *map_x, int *map_y, int overview_x, int overview_y); - +void set_focus_tile(int x, int y); +void get_focus_tile(int *x, int *y); void refresh_overview_canvas(void); void overview_update_tile(int x, int y); void set_overview_dimensions(int width, int height); 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 14:17:38 -0000 @@ -1522,6 +1522,7 @@ char msg[MAX_LEN_MSG]; struct player *pplayer = &game.players[pinfo->playerno]; + freelog(LOG_NORMAL,"player_info id=%d name=%s",pinfo->playerno,pinfo->name); sz_strlcpy(pplayer->name, pinfo->name); pplayer->nation=pinfo->nation; @@ -1648,7 +1649,7 @@ { struct connection *pconn = find_conn_by_id(pinfo->id); - freelog(LOG_DEBUG, "conn_info id%d used%d est%d plr%d obs%d acc%d", + freelog(LOG_NORMAL, "conn_info id%d used%d est%d plr%d obs%d acc%d", pinfo->id, pinfo->used, pinfo->established, pinfo->player_num, pinfo->observer, (int)pinfo->access_level); freelog(LOG_DEBUG, "conn_info \"%s\" \"%s\" \"%s\"", Index: client/text.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/text.c,v retrieving revision 1.7 diff -u -r1.7 text.c --- client/text.c 16 Jul 2004 19:37:57 -0000 1.7 +++ client/text.c 29 Jul 2004 14:17:38 -0000 @@ -130,7 +130,7 @@ ****************************************************************************/ const char *popup_info_text(int map_x, int map_y) { - const char *activity_text; + const char *activity_text = concat_tile_activity_text(map_x, map_y); struct city *pcity = map_get_city(map_x, map_y); struct tile *ptile = map_get_tile(map_x, map_y); struct unit *punit = find_visible_unit(ptile); @@ -233,7 +233,6 @@ add_line(_("Infrastructure: %s"), map_get_infrastructure_text(ptile->special)); } - activity_text = concat_tile_activity_text(map_x, map_y); if (strlen(activity_text) > 0) { add_line(_("Activity: %s"), activity_text); } @@ -706,6 +705,395 @@ } /**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_terrain_tooltip_text(int x, int y) +{ + int infrastructure = get_tile_infrastructure_set(map_get_tile(x, y)); + INIT; + + add_line(_("Location: (%d, %d) [%d]"), + x, y, map_get_tile(x, y)->continent); + add_line("%s", map_get_tile_info_text(x, y)); + if (infrastructure) { + add_line("%s", + map_get_infrastructure_text(infrastructure)); + } + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +static void calc_effect(enum unit_activity activity, int x, int y, int diff[3]) +{ + struct tile backup; + int stats_before[3], stats_after[3]; + + stats_before[0] = get_food_tile(x,y); + stats_before[1] = get_shields_tile(x,y); + stats_before[2] = get_trade_tile(x,y); + + /* BEWARE UGLY HACK AHEAD */ + + memcpy(&backup, map_get_tile(x, y), sizeof(backup)); + + switch (activity) { + case ACTIVITY_ROAD: + map_set_special(x, y, S_ROAD); + break; + case ACTIVITY_RAILROAD: + map_set_special(x, y, S_RAILROAD); + break; + case ACTIVITY_MINE: + map_mine_tile(x, y); + break; + + case ACTIVITY_IRRIGATE: + map_irrigate_tile(x, y); + break; + + case ACTIVITY_TRANSFORM: + map_transform_tile(x, y); + break; + default: + assert(0); + } + + stats_after[0] = get_food_tile(x,y); + stats_after[1] = get_shields_tile(x,y); + stats_after[2] = get_trade_tile(x,y); + + memcpy(map_get_tile(x, y), &backup, sizeof(backup)); + + /* hopefully everything is now back in place */ + + diff[0] = stats_after[0] - stats_before[0]; + diff[1] = stats_after[1] - stats_before[1]; + diff[2] = stats_after[2] - stats_before[2]; +} + +/**************************************************************************** + ... +****************************************************************************/ +static const char *format_effect(enum unit_activity activity, + struct unit *punit) +{ + char parts[3][25]; + int diff[3]; + int n = 0; + INIT; + + calc_effect(activity, punit->x, punit->y, diff); + + if (diff[0] != 0) { + my_snprintf(parts[n], sizeof(parts[n]), _("%+d food"), diff[0]); + n++; + } + + if (diff[1] != 0) { + my_snprintf(parts[n], sizeof(parts[n]), _("%+d shield"), diff[1]); + n++; + } + + if (diff[2] != 0) { + my_snprintf(parts[n], sizeof(parts[n]), _("%+d trade"), diff[2]); + n++; + } + if (n == 0) { + add(_("none")); + } else if (n == 1) { + add("%s", parts[0]); + } else if (n == 2) { + add("%s %s", parts[0], parts[1]); + } else if (n == 3) { + add("%s %s %s", parts[0], parts[1], parts[2]); + } else { + assert(0); + } + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_unit_action_tooltip(struct unit *punit, + const char *action, + const char *shortcut_) +{ + char shortcut[256]; + INIT; + + if (shortcut_) { + my_snprintf(shortcut, sizeof(shortcut), " (%s)", shortcut_); + } else { + my_snprintf(shortcut, sizeof(shortcut), "%s", ""); + } + + if (strcmp(action, "unit_fortifying") == 0) { + add_line(_("Fortify%s"),shortcut); + add_line(_("Time: 1 turn, then till changed")); + add_line(_("Effect: +50%% defense bonus")); + } else if (strcmp(action, "unit_disband") == 0) { + add_line(_("Disband%s"),shortcut); + add_line(_("Time: instantly, unit is destroyed")); + } else if (strcmp(action, "unit_return_nearest") == 0) { + add_line(_("Return to nearest city%s"),shortcut); + add_line(_("Time: unknown")); + } else if (strcmp(action, "unit_sentry") == 0) { + add_line(_("Sentry%s"),shortcut); + add_line(_("Time: instantly, till changed")); + add_line(_("Effect: Unit wakes up if enemy is near")); + } else if (strcmp(action, "unit_add_to_city") == 0) { + add_line(_("Add to city%s"),shortcut); + add_line(_("Time: instantly, unit is destroyed")); + add_line(_("Effect: city size +1")); + } else if (strcmp(action, "unit_build_city") == 0) { + add_line(_("Build city%s"),shortcut); + add_line(_("Time: instantly, unit is destroyed")); + add_line(_("Effect: create a city of size 1")); + } else if (strcmp(action, "unit_road") == 0) { + add_line(_("Build road%s"),shortcut); + add_line(_("Time: %d turns"), + map_get_turns_for_activity(ACTIVITY_ROAD, punit)); + add_line(_("Effect: %s"), + format_effect(ACTIVITY_ROAD, punit)); + } else if (strcmp(action, "unit_irrigate") == 0) { + add_line(_("Build irrigation%s"),shortcut); + add_line(_("Time: %d turns"), + map_get_turns_for_activity(ACTIVITY_IRRIGATE, punit)); + add_line(_("Effect: %s"), + format_effect(ACTIVITY_IRRIGATE, punit)); + } else if (strcmp(action, "unit_mine") == 0) { + add_line(_("Build mine%s"),shortcut); + add_line(_("Time: %d turns"), + map_get_turns_for_activity(ACTIVITY_MINE, punit)); + add_line(_("Effect: %s"), + format_effect(ACTIVITY_MINE, punit)); + } else if (strcmp(action, "unit_auto_settler") == 0) { + add_line(_("Auto-Settle%s"),shortcut); + add_line(_("Time: unknown")); + add_line(_("Effect: the computer performs settler activities")); + } else { +#if 0 + ttype = map_get_tile(punit->x, punit->y)->terrain; + tinfo = get_tile_type(ttype); + if ((tinfo->irrigation_result != T_LAST) + && (tinfo->irrigation_result != ttype)) { + my_snprintf(irrtext, sizeof(irrtext), irrfmt, + (get_tile_type(tinfo->irrigation_result))->terrain_name); + } else if (map_has_special(punit->x, punit->y, S_IRRIGATION) + && player_knows_techs_with_flag(game.player_ptr, TF_FARMLAND)) { + sz_strlcpy(irrtext, _("Bu_ild Farmland")); + } + if ((tinfo->mining_result != T_LAST) && (tinfo->mining_result != ttype)) { + my_snprintf(mintext, sizeof(mintext), minfmt, + (get_tile_type(tinfo->mining_result))->terrain_name); + } + if ((tinfo->transform_result != T_LAST) + && (tinfo->transform_result != ttype)) { + my_snprintf(transtext, sizeof(transtext), transfmt, + (get_tile_type(tinfo->transform_result))->terrain_name); + } + + menus_rename("
/_Orders/Build _Irrigation", irrtext); + menus_rename("
/_Orders/Build _Mine", mintext); + menus_rename("
/_Orders/Transf_orm Terrain", transtext); +#endif + add_line("tooltip for action %s isn't written yet", + action); + freelog(LOG_NORMAL, "warning: get_unit_action_tooltip: unknown action %s", + action); + } + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_city_action_tooltip(struct city *pcity, + const char *action, + const char *shortcut_) +{ + INIT; + + if (strcmp(action, "city_buy") == 0) { + const char *name; + + if (pcity->is_building_unit) { + name = get_unit_type(pcity->currently_building)->name; + } else { + name = get_impr_name_ex(pcity, pcity->currently_building); + } + + add_line(_("Buy production")); + add_line(_("Cost: %d (%d in treasury)"), + city_buy_cost(pcity), game.player_ptr->economic.gold); + add_line(_("Producting: %s (%d turns)"), name, + city_turns_to_build(pcity, pcity->currently_building, + pcity->is_building_unit, TRUE)); + } else { + add_line("tooltip for action %s isn't written yet", action); + freelog(LOG_NORMAL, + "warning: get_city_action_tooltip: unknown action %s", action); + } + RETURN; +} + +/************************************************************************ + Text to popup on middle-click +************************************************************************/ +const char *mapview_get_terrain_info_text(int map_x, int map_y) +{ + const char *activity_text = concat_tile_activity_text(map_x, map_y); + struct tile *ptile = map_get_tile(map_x, map_y); + const char *diplo_nation_plural_adjectives[DS_LAST] = + {Q_("?nation:Neutral"), Q_("?nation:Hostile"), + "" /* unused, DS_CEASEFIRE*/, + Q_("?nation:Peaceful"), Q_("?nation:Friendly"), + Q_("?nation:Mysterious")}; + INIT; + + add_line(_("Terrain: %s"), + map_get_tile_info_text(map_x, map_y)); + add_line(_("Food/Prod/Trade: %s"), + map_get_tile_fpt_text(map_x, map_y)); + if (tile_has_special(ptile, S_HUT)) { + add_line(_("Minor Tribe Village")); + } + if (game.borders > 0) { + struct player *owner = map_get_owner(map_x, map_y); + struct player_diplstate *ds = game.player_ptr->diplstates; + + if (owner == game.player_ptr){ + add_line(_("Our Territory")); + } else if (owner) { + if (ds[owner->player_no].type == DS_CEASEFIRE) { + int turns = ds[owner->player_no].turns_left; + + add_line(PL_("%s territory (%d turn ceasefire)", + "%s territory (%d turn ceasefire)", + turns), + get_nation_name(owner->nation), turns); + } else { + add_line(_("Territory of the %s %s"), + diplo_nation_plural_adjectives[ds[owner->player_no].type], + get_nation_name_plural(owner->nation)); + } + } else { + add_line(_("Unclaimed territory")); + } + } + if (get_tile_infrastructure_set(ptile)) { + add_line(_("Infrastructure: %s"), + map_get_infrastructure_text(ptile->special)); + } + if (strlen(activity_text)) { + add_line(_("Activity: %s"), activity_text); + } + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_city_tooltip_text(struct city *pcity) +{ + struct player *owner = city_owner(pcity); + INIT; + + add_line("%s", pcity->name); + add_line("%s", owner->name); + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_city_info_text(struct city *pcity) +{ + struct player *owner = city_owner(pcity); + INIT; + + add_line(_("City: %s (%s)"), pcity->name, + get_nation_name(owner->nation)); + if (city_got_citywalls(pcity)) { + add(_(" with City Walls")); + } + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_unit_tooltip_text(struct unit *punit) +{ + struct unit_type *ptype = unit_type(punit); + struct city *pcity = + player_find_city_by_id(game.player_ptr, punit->homecity); + INIT; + + add("%s", ptype->name); + if (ptype->veteran[punit->veteran].name[0] != '\0') { + add(" (%s)", ptype->veteran[punit->veteran].name); + } + add("\n"); + add_line("%s", unit_activity_text(punit)); + if (pcity) { + add_line("%s", pcity->name); + } + RETURN; +} + +/**************************************************************************** + ... +****************************************************************************/ +const char *mapview_get_unit_info_text(struct unit *punit) +{ + int map_x = punit->x; + int map_y = punit->y; + const char *activity_text = concat_tile_activity_text(map_x, map_y); + INIT; + + if (strlen(activity_text)) { + add_line(_("Activity: %s"), activity_text); + } + if (punit) { + char tmp[64] = { 0 }; + struct unit_type *ptype = unit_type(punit); + + if (punit->owner == game.player_idx) { + struct city *pcity = + player_find_city_by_id(game.player_ptr, punit->homecity); + + if (pcity){ + my_snprintf(tmp, sizeof(tmp), "/%s", pcity->name); + } + } + add_line(_("Unit: %s(%s%s)"), ptype->name, + get_nation_name(unit_owner(punit)->nation), tmp); + if (punit->owner != game.player_idx) { + struct unit *apunit = get_unit_in_focus(); + + if (apunit) { + /* chance to win when active unit is attacking the selected unit */ + int att_chance = unit_win_chance(apunit, punit) * 100; + + /* chance to win when selected unit is attacking the active unit */ + int def_chance = (1.0 - unit_win_chance(punit, apunit)) * 100; + + add_line(_("Chance to win: A:%d%% D:%d%%"), att_chance, def_chance); + } + } + add_line(_("A:%d D:%d FP:%d HP:%d/%d%s"), + ptype->attack_strength, + ptype->defense_strength, ptype->firepower, punit->hp, + ptype->hp, punit->veteran ? _(" V") : ""); + } + RETURN; +} + +/**************************************************************************** Get the text describing buildings that affect happiness. ****************************************************************************/ const char *get_happiness_buildings(const struct city *pcity) Index: client/text.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/text.h,v retrieving revision 1.4 diff -u -r1.4 text.h --- client/text.h 16 Jul 2004 19:37:57 -0000 1.4 +++ client/text.h 29 Jul 2004 14:17:38 -0000 @@ -42,4 +42,17 @@ const char *get_happiness_buildings(const struct city *pcity); const char *get_happiness_wonders(const struct city *pcity); +const char *mapview_get_terrain_tooltip_text(int x, int y); +const char *mapview_get_unit_action_tooltip(struct unit *punit, + const char *action, + const char *shortcut_); +const char *mapview_get_city_action_tooltip(struct city *pcity, + const char *action, + const char *shortcut_); +const char *mapview_get_terrain_info_text(int map_x, int map_y); +const char *mapview_get_city_tooltip_text(struct city *pcity); +const char *mapview_get_city_info_text(struct city *pcity); +const char *mapview_get_unit_tooltip_text(struct unit *punit); +const char *mapview_get_unit_info_text(struct unit *punit); + #endif /* FC__TEXT_H */ Index: client/tilespec.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v retrieving revision 1.192 diff -u -r1.192 tilespec.c --- client/tilespec.c 28 Jul 2004 16:45:03 -0000 1.192 +++ client/tilespec.c 29 Jul 2004 14:17:39 -0000 @@ -1882,6 +1882,62 @@ #define ADD_SPRITE_SIMPLE(s) ADD_SPRITE(s, DRAW_NORMAL, TRUE, 0, 0) #define ADD_SPRITE_FULL(s) ADD_SPRITE(s, DRAW_FULL, TRUE, 0, 0) +/********************************************************************** + Fill in the sprite array for the city +***********************************************************************/ +int fill_city_sprite_array(struct drawn_sprite *sprs, + struct city *pcity, bool *solid_bg) +{ + struct drawn_sprite *save_sprs = sprs; + + *solid_bg = FALSE; + + if (!solid_color_behind_units) { + ADD_SPRITE(get_city_nation_flag_sprite(pcity), DRAW_FULL, TRUE, + flag_offset_x, flag_offset_y); + } else { + *solid_bg = TRUE; + } + + if (pcity->client.occupied) { + ADD_SPRITE_SIMPLE(get_city_occupied_sprite(pcity)); + } + + ADD_SPRITE_SIMPLE(get_city_sprite(pcity)); + + if (city_got_citywalls(pcity)) { + ADD_SPRITE_SIMPLE(get_city_wall_sprite(pcity)); + } + + if (map_has_special(pcity->x, pcity->y, S_POLLUTION)) { + ADD_SPRITE_SIMPLE(sprites.tx.pollution); + } + if (map_has_special(pcity->x, pcity->y, S_FALLOUT)) { + ADD_SPRITE_SIMPLE(sprites.tx.fallout); + } + + if (pcity->client.unhappy) { + ADD_SPRITE_SIMPLE(sprites.city.disorder); + } + + if (tile_get_known(pcity->x, pcity->y) == TILE_KNOWN_FOGGED + && draw_fog_of_war) { + ADD_SPRITE_SIMPLE(sprites.tx.fog); + } + + /* Put the size sprites last, so that they are not obscured + * (and because they can be hard to read if fogged). + */ + if (pcity->size >= 10) { + assert(pcity->size < 100); + ADD_SPRITE_SIMPLE(sprites.city.size_tens[pcity->size / 10]); + } + + ADD_SPRITE_SIMPLE(sprites.city.size[pcity->size % 10]); + + return sprs - save_sprs; +} + /************************************************************************** Assemble some data that is used in building the tile sprite arrays. (map_x, map_y) : the (normalized) map position @@ -2427,7 +2483,7 @@ Add sprites for the base terrain to the sprite list. This doesn't include specials or rivers. ****************************************************************************/ -static int fill_terrain_sprite_array(struct drawn_sprite *sprs, +static int fill_terrain_sprite_array0(struct drawn_sprite *sprs, int map_x, int map_y, enum tile_terrain_type *ttype_near) { @@ -2640,15 +2696,12 @@ build_tile_data(map_x, map_y, &ttype, &tspecial, ttype_near, tspecial_near); - /* Terrain and specials. */ - if (!unit_only && !city_only) { - sprs += fill_terrain_sprite_array(sprs, map_x, map_y, ttype_near); + sprs += fill_terrain_sprite_array0(sprs, map_x, map_y, ttype_near); - if (is_ocean(ttype) && draw_terrain) { - for (dir = 0; dir < 4; dir++) { - if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) { - ADD_SPRITE_SIMPLE(sprites.tx.river_outlet[dir]); - } + if (is_ocean(ttype) && draw_terrain) { + for (dir = 0; dir < 4; dir++) { + if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) { + ADD_SPRITE_SIMPLE(sprites.tx.river_outlet[dir]); } } @@ -2751,13 +2804,103 @@ FALSE, 0, 0); } - if (punit && !city_only - && (draw_units || (punit == pfocus && draw_focus_unit))) { + if (punit && (draw_units || (punit == pfocus && draw_focus_unit))) { bool stacked = (unit_list_size(&map_get_tile(map_x, map_y)->units) > 1); - bool backdrop = !pcity && !unit_only; - bool dummy; + bool backdrop = !pcity; + + sprs += fill_unit_sprite_array(sprs, punit, solid_bg, stacked, backdrop); + } + + if (draw_fortress_airbase && contains_special(tspecial, S_FORTRESS)) { + ADD_SPRITE_FULL(sprites.tx.fortress); + } + + return sprs - save_sprs; +} + +int fill_terrain_sprite_array(struct drawn_sprite *sprs, int x, int y) +{ + enum tile_terrain_type ttype, ttype_near[8]; + enum tile_special_type tspecial, tspecial_near[8]; + struct drawn_sprite *save_sprs = sprs; + + if (tile_get_known(x, y) == TILE_UNKNOWN) + return -1; + + build_tile_data(x, y, &ttype, &tspecial, ttype_near, tspecial_near); + + sprs += fill_terrain_sprite_array0(sprs, x, y, ttype_near); + return sprs - save_sprs; +} + +/********************************************************************** + Fill in the sprite array for the tile at position (abs_x0,abs_y0) + +The sprites are drawn in the following order: + 1) basic terrain type + 2) river + 3) irritation + 4) road/railroad + 5) specials + 6) mine + 7) hut + 8) fortress + 9) airbase +10) pollution +11) fallout +12) FoW +***********************************************************************/ +#if 0 +int fill_tile_sprite_array(struct drawn_sprite *sprs, int abs_x0, int abs_y0, + bool citymode, bool *solid_bg, + enum color_std *bg_color) +{ + enum tile_terrain_type ttype, ttype_near[8]; + enum tile_special_type tspecial, tspecial_near[8]; + int dir, tileno; + struct tile *ptile; + struct city *pcity; + struct unit *pfocus; + struct unit *punit; + struct drawn_sprite *save_sprs = sprs; + + *solid_bg = FALSE; + *bg_color = COLOR_STD_BACKGROUND; + + ptile=map_get_tile(abs_x0, abs_y0); + + if (tile_get_known(abs_x0, abs_y0) == TILE_UNKNOWN) { + return 0; + } + + pcity=map_get_city(abs_x0, abs_y0); + pfocus=get_unit_in_focus(); - sprs += fill_unit_sprite_array(sprs, punit, &dummy, stacked, backdrop); + if (solid_color_behind_units) { + punit = get_drawable_unit(abs_x0, abs_y0, citymode); + if (punit && (draw_units || (draw_focus_unit && pfocus == punit))) { + bool stacked = (unit_list_size(&ptile->units) > 1); + + sprs += fill_unit_sprite_array(sprs, punit, solid_bg, + stacked, TRUE); + + *bg_color = player_color(unit_owner(punit)); + return sprs - save_sprs; + } + + if (pcity && draw_cities) { + sprs += fill_city_sprite_array(sprs, pcity, solid_bg); + *bg_color = player_color(city_owner(pcity)); + return sprs - save_sprs; + } + } + build_tile_data(abs_x0, abs_y0, + &ttype, &tspecial, ttype_near, tspecial_near); + + sprs += fill_terrain_sprite_array0(sprs, abs_x0, abs_y0, ttype_near); + + if (!draw_terrain) { + *solid_bg = TRUE; } if (!unit_only && !city_only) { @@ -2777,6 +2920,7 @@ return sprs - save_sprs; } +#endif /********************************************************************** Set city tiles sprite values; should only happen after Index: client/tilespec.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v retrieving revision 1.82 diff -u -r1.82 tilespec.h --- client/tilespec.h 28 Jul 2004 16:45:03 -0000 1.82 +++ client/tilespec.h 29 Jul 2004 14:17:39 -0000 @@ -72,6 +72,12 @@ int map_x, int map_y, bool citymode); int fill_unit_sprite_array(struct drawn_sprite *sprs, struct unit *punit, bool *solid_bg, bool stack, bool backdrop); +int fill_city_sprite_array_iso(struct drawn_sprite *sprs, + struct city *pcity); +int fill_terrain_sprite_array(struct drawn_sprite *sprs, int abs_x0, + int abs_y0); +int fill_city_sprite_array(struct drawn_sprite *sprs, + struct city *pcity, bool *solid_bg); enum color_std player_color(struct player *pplayer); enum color_std overview_tile_color(int x, int y); Index: client/include/mapview_g.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/include/mapview_g.h,v retrieving revision 1.56 diff -u -r1.56 mapview_g.h --- client/include/mapview_g.h 26 Jul 2004 04:05:59 -0000 1.56 +++ client/include/mapview_g.h 29 Jul 2004 14:17:39 -0000 @@ -81,4 +81,7 @@ void draw_selection_rectangle(int canvas_x, int canvas_y, int w, int h); void tileset_changed(void); +void popup_mapcanvas(void); +void popdown_mapcanvas(void); + #endif /* FC__MAPVIEW_G_H */ Index: common/map.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.c,v retrieving revision 1.184 diff -u -r1.184 map.c --- common/map.c 28 Jul 2004 15:24:43 -0000 1.184 +++ common/map.c 29 Jul 2004 14:17:39 -0000 @@ -965,6 +965,19 @@ /*************************************************************** ... ***************************************************************/ +int map_get_turns_for_activity(enum unit_activity activity, + struct unit *punit) +{ + int mr = get_unit_type(punit->type)->move_rate; + int au = (mr > 0) ? mr / SINGLE_MOVE : 1; + int time = map_activity_time(activity, punit->x, punit->y) / 10; + + return (time - 1) / au + 1; +} + +/*************************************************************** +... +***************************************************************/ static void clear_infrastructure(int x, int y) { map_clear_special(x, y, S_INFRASTRUCTURE_MASK); Index: common/map.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.h,v retrieving revision 1.202 diff -u -r1.202 map.h --- common/map.h 28 Jul 2004 15:24:43 -0000 1.202 +++ common/map.h 29 Jul 2004 14:17:39 -0000 @@ -406,6 +406,8 @@ int map_clean_pollution_time(int x, int y); int map_clean_fallout_time(int x, int y); int map_activity_time(enum unit_activity activity, int x, int y); +int map_get_turns_for_activity(enum unit_activity activity, + struct unit *punit); bool can_channel_land(int x, int y); bool can_reclaim_ocean(int x, int y);