Index: client/climisc.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v retrieving revision 1.55 diff -u -r1.55 climisc.c --- client/climisc.c 2001/08/29 12:01:36 1.55 +++ client/climisc.c 2001/08/31 16:14:13 @@ -484,11 +484,11 @@ **************************************************************************/ enum color_std get_grid_color(int x1, int y1, int x2, int y2) { - enum city_tile_type city_tile_type1, city_tile_type2; - struct city *dummy_pcity; + struct tile *ptile1, *ptile2; int pos1_is_in_city_radius = player_in_city_radius(game.player_ptr, x1, y1); int pos2_is_in_city_radius = 0; + int isyellow1, isyellow2; if (is_real_tile(x2, y2)) { normalize_map_pos(&x2, &y2); @@ -506,14 +506,29 @@ return COLOR_STD_BLACK; } - get_worker_on_map_position(x1, y1, &city_tile_type1, &dummy_pcity); - get_worker_on_map_position(x2, y2, &city_tile_type2, &dummy_pcity); + ptile1 = map.tiles+map_adjust_x(x1)+map_adjust_y(y1)*map.xsize; + ptile2 = map.tiles+map_adjust_x(x2)+map_adjust_y(y2)*map.xsize; - if (city_tile_type1 == C_TILE_WORKER || city_tile_type2 == C_TILE_WORKER) { + isyellow1 = (ptile1->citydialog && (!ptile1->worked || (ptile1->citydialog == ptile1->worked))); + isyellow2 = (ptile2->citydialog && (!ptile2->worked || (ptile2->citydialog == ptile2->worked))); + + if ((isyellow1 || isyellow2) && + !(isyellow1 && isyellow2)){ + return COLOR_STD_YELLOW; + } + + + if ((ptile1->worked || ptile2->worked) && + !(ptile1->worked && ptile2->worked)){ return COLOR_STD_RED; - } else { + } + + if ((pos1_is_in_city_radius || pos2_is_in_city_radius) && + !(pos1_is_in_city_radius && pos2_is_in_city_radius)) { return COLOR_STD_WHITE; } + + return COLOR_STD_BLACK; } /************************************************************************** Index: client/gui-gtk/mapctrl.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.c,v retrieving revision 1.45 diff -u -r1.45 mapctrl.c --- client/gui-gtk/mapctrl.c 2001/08/24 08:22:02 1.45 +++ client/gui-gtk/mapctrl.c 2001/08/31 16:14:13 @@ -275,16 +275,28 @@ return TRUE; } + if((event->button==3)&&(event->state&GDK_SHIFT_MASK)) { + open_global_citydialog(widget, event); + return TRUE; + } + get_map_xy(event->x, event->y, &xtile, &ytile); if(event->button==1) { + if (map.citydialog) { + handle_global_citydialog(widget, event); + return TRUE; + } do_map_click(xtile, ytile); gtk_widget_grab_focus(turn_done_button); + return TRUE; } - else if((event->button==2)||(event->state&GDK_CONTROL_MASK)) + if((event->button==2)||(event->state&GDK_CONTROL_MASK)) { popit(event, xtile, ytile); - else - center_tile_mapcanvas(xtile, ytile); + return TRUE; + } + + center_tile_mapcanvas(xtile, ytile); return TRUE; } @@ -473,4 +485,95 @@ void set_turn_done_button_state(int state) { gtk_widget_set_sensitive(turn_done_button, state); +} + +/************************************************************************** + Opens the "global" citydialog. +**************************************************************************/ +gint open_global_citydialog(GtkWidget *widget, GdkEventButton *ev) +{ + int x,y; + struct tile *ptile; + struct city *pcity; + + if(get_client_state()!=CLIENT_GAME_RUNNING_STATE) + return TRUE; + + gdk_window_get_pointer(map_canvas->window, &x, &y, NULL); + get_map_xy(x, y, &x, &y); + + pcity = find_city_near_tile(x,y); + if(pcity==NULL) return TRUE; + + close_global_citydialog(); + + map_city_radius_iterate(pcity->x,pcity->y,i,j){ + ptile = map.tiles+map_adjust_x(i)+map_adjust_y(j)*map.xsize; + ptile->citydialog=pcity; + }map_city_radius_iterate_end + map.citydialog = pcity; + center_tile_mapcanvas(x, y); + + return TRUE; + +} + +/************************************************************************** + Closes the "global" citydialog. +**************************************************************************/ +gint close_global_citydialog(void) +{ + struct tile *ptile; + + if(!map.citydialog) return TRUE; + + map_city_radius_iterate(map.citydialog->x,map.citydialog->y,i,j){ + ptile=map.tiles+map_adjust_x(i)+map_adjust_y(j)*map.xsize; + ptile->citydialog= NULL; + }map_city_radius_iterate_end + + map.citydialog=NULL; + + return TRUE; +} + +/************************************************************************** + Handles the "global" citydialog. +**************************************************************************/ +gint handle_global_citydialog(GtkWidget *widget, GdkEventButton *ev) +{ + int x,y; + struct tile *ptile; + struct packet_city_request packet; + enum city_tile_type wrk; + + if(get_client_state()!=CLIENT_GAME_RUNNING_STATE) + return TRUE; + + get_map_xy(ev->x, ev->y, &x, &y); + + ptile=map.tiles+x+y*map.xsize; + if (!ptile->citydialog) + return TRUE; + + x = map_to_city_x(map.citydialog, x); + y = map_to_city_y(map.citydialog, y); + + packet.city_id=map.citydialog->id; + packet.worker_x=x; + packet.worker_y=y; + packet.name[0]='\0'; + packet.worklist.name[0] = '\0'; + + wrk = get_worker_city(map.citydialog, x, y); + if(wrk==C_TILE_WORKER) + send_packet_city_request(&aconnection, &packet, + PACKET_CITY_MAKE_SPECIALIST); + else if(wrk==C_TILE_EMPTY) + send_packet_city_request(&aconnection, &packet, + PACKET_CITY_MAKE_WORKER); + + /* When the city info packet is received, update the workers on the map*/ + refresh_tile_mapcanvas(ev->x,ev->y,1); + return TRUE; } Index: client/gui-gtk/mapctrl.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.h,v retrieving revision 1.8 diff -u -r1.8 mapctrl.h --- client/gui-gtk/mapctrl.h 2001/01/29 18:55:28 1.8 +++ client/gui-gtk/mapctrl.h 2001/08/31 16:14:13 @@ -21,6 +21,9 @@ gint key_city_workers(GtkWidget *w, GdkEventKey *ev); gint adjust_workers(GtkWidget *widget, GdkEventButton *ev); +gint open_global_citydialog(GtkWidget *widget, GdkEventButton *ev); +gint close_global_citydialog(void); +gint handle_global_citydialog(GtkWidget *widget, GdkEventButton *ev); gint butt_down_mapcanvas(GtkWidget *w, GdkEventButton *ev); gint butt_down_wakeup(GtkWidget *w, GdkEventButton *ev); Index: client/gui-gtk/mapview.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v retrieving revision 1.94 diff -u -r1.94 mapview.c --- client/gui-gtk/mapview.c 2001/08/29 13:19:26 1.94 +++ client/gui-gtk/mapview.c 2001/08/31 16:14:15 @@ -1593,6 +1593,37 @@ /************************************************************************** ... **************************************************************************/ +void put_city_tile_output_draw(GdkDrawable *pm, int canvas_x, int canvas_y, + int offset_x, int offset_y, + int width, int height, + int food, int shield, int trade) +{ + food = CLIP(0, food, NUM_TILES_DIGITS-1); + trade = CLIP(0, trade, NUM_TILES_DIGITS-1); + shield = CLIP(0, shield, NUM_TILES_DIGITS-1); + + if (is_isometric) { + canvas_x += NORMAL_TILE_WIDTH/3; + canvas_y -= NORMAL_TILE_HEIGHT/3; + } + + pixmap_put_overlay_tile_draw(pm, canvas_x, canvas_y, + sprites.city.tile_foodnum[food], + offset_x, offset_y, + width, height, 0); + pixmap_put_overlay_tile_draw(pm, canvas_x, canvas_y, + sprites.city.tile_shieldnum[shield], + offset_x, offset_y, + width, height, 0); + pixmap_put_overlay_tile_draw(pm, canvas_x, canvas_y, + sprites.city.tile_tradenum[trade], + offset_x, offset_y, + width, height, 0); +} + +/************************************************************************** +... +**************************************************************************/ void put_unit_gpixmap(struct unit *punit, GtkPixcomm *p) { struct Sprite *sprites[40]; @@ -2227,6 +2281,7 @@ struct Sprite *tile_sprs[80]; struct Sprite *coasts[4]; struct Sprite *dither[4]; + struct tile *ptile; struct city *pcity; struct unit *punit, *pfocus; enum tile_special_type special; @@ -2250,11 +2305,12 @@ assert(is_real_tile(x, y)); normalize_map_pos(&x, &y); - fog = tile_is_known(x, y) == TILE_KNOWN_FOGGED && draw_fog_of_war; - pcity = map_get_city(x, y); + ptile = map.tiles+map_adjust_x(x)+map_adjust_y(y)*map.xsize; + fog = ptile->known == TILE_KNOWN_FOGGED && draw_fog_of_war; + pcity = ptile->city; punit = get_drawable_unit(x, y, citymode); pfocus = get_unit_in_focus(); - special = map_get_special(x, y); + special = ptile->special; if (solid_bg) { gdk_gc_set_clip_origin(fill_bg_gc, canvas_x, canvas_y); @@ -2416,7 +2472,7 @@ /*** city size ***/ /* Not fogged as it would be unreadable */ - if (pcity && draw_cities) { + if (pcity != ptile->citydialog && pcity && draw_cities) { if (pcity->size>=10) pixmap_put_overlay_tile_draw(pm, canvas_x, canvas_y-NORMAL_TILE_HEIGHT/2, sprites.city.size_tens[pcity->size/10], @@ -2429,9 +2485,10 @@ width, height_unit, 0); } + /*** Unit ***/ - if (punit && (draw_units || (punit == pfocus && draw_focus_unit))) { - put_unit_pixmap_draw(punit, pm, + if (punit && (draw_units || (punit == pfocus && draw_focus_unit)) && !ptile->citydialog) { + put_unit_pixmap_draw(punit, pm, canvas_x, canvas_y - NORMAL_TILE_HEIGHT/2, offset_x, offset_y_unit, width, height_unit); @@ -2449,4 +2506,15 @@ sprites.tx.fortress, offset_x, offset_y_unit, width, height_unit, fog); + + + if (ptile->worked && ptile->worked == ptile->citydialog) { + put_city_tile_output_draw(pm, + canvas_x, canvas_y, + offset_x, offset_y_unit, + width, height_unit, + city_get_food_tile_global(x, y, ptile->citydialog), + city_get_shields_tile_global(x, y, ptile->citydialog), + city_get_trade_tile_global(x, y, ptile->citydialog) ); + } } Index: common/city.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.c,v retrieving revision 1.116 diff -u -r1.116 city.c --- common/city.c 2001/08/29 12:01:36 1.116 +++ common/city.c 2001/08/31 16:14:16 @@ -503,11 +503,11 @@ /************************************************************************** ... **************************************************************************/ -int city_get_shields_tile(int x, int y, struct city *pcity) +int city_get_shields_tile_global(int x, int y, struct city *pcity) { int s=0; - enum tile_special_type spec_t=map_get_special(pcity->x+x-2, pcity->y+y-2); - enum tile_terrain_type tile_t=map_get_terrain(pcity->x+x-2, pcity->y+y-2); + enum tile_special_type spec_t=map_get_special(x, y); + enum tile_terrain_type tile_t=map_get_terrain(x, y); struct government *g = get_gov_pcity(pcity); int celeb = city_celebrating(pcity); int before_penalty = (celeb ? g->celeb_shields_before_penalty @@ -539,11 +539,19 @@ if (spec_t & S_FALLOUT) s-=(s*terrain_control.fallout_shield_penalty)/100; - if (sx && y==pcity->y) s=game.rgame.min_city_center_shield; return s; } +/************************************************************************** +This is a wrapper for allowing the old access with "local" coordinates. +**************************************************************************/ +int city_get_shields_tile(int x, int y, struct city *pcity) +{ + return city_get_shields_tile_global(pcity->x+x-CITY_MAP_SIZE/2,pcity->y+y-CITY_MAP_SIZE/2, pcity); +} + /************************************************************************** ... @@ -582,10 +590,10 @@ /************************************************************************** ... **************************************************************************/ -int city_get_trade_tile(int x, int y, struct city *pcity) +int city_get_trade_tile_global(int x, int y, struct city *pcity) { - enum tile_special_type spec_t=map_get_special(pcity->x+x-2, pcity->y+y-2); - enum tile_terrain_type tile_t=map_get_terrain(pcity->x+x-2, pcity->y+y-2); + enum tile_special_type spec_t=map_get_special(x, y); + enum tile_terrain_type tile_t=map_get_terrain(x, y); struct government *g = get_gov_pcity(pcity); int t; @@ -629,11 +637,19 @@ t-=(t*terrain_control.fallout_trade_penalty)/100; } - if (tx && y==pcity->y) t=game.rgame.min_city_center_trade; return t; } +/************************************************************************** +This is a wrapper for allowing the old access with "local" coordinates. +**************************************************************************/ +int city_get_trade_tile(int x, int y, struct city *pcity) +{ + return city_get_trade_tile_global(pcity->x+x-CITY_MAP_SIZE/2,pcity->y+y-CITY_MAP_SIZE/2, pcity); +} + /************************************************************************** ... @@ -672,12 +688,13 @@ Here the exact food production should be calculated. That is including ALL modifiers. Center tile acts as irrigated... +now using "global" coordinates. **************************************************************************/ -int city_get_food_tile(int x, int y, struct city *pcity) +int city_get_food_tile_global(int x, int y, struct city *pcity) { int f; - enum tile_special_type spec_t=map_get_special(pcity->x+x-2, pcity->y+y-2); - enum tile_terrain_type tile_t=map_get_terrain(pcity->x+x-2, pcity->y+y-2); + enum tile_special_type spec_t=map_get_special(x, y); + enum tile_terrain_type tile_t=map_get_terrain(x, y); struct tile_type *type; struct government *g = get_gov_pcity(pcity); int celeb = city_celebrating(pcity); @@ -686,7 +703,7 @@ int city_auto_water; type=get_tile_type(tile_t); - city_auto_water = (x==2 && y==2 && tile_t==type->irrigation_result + city_auto_water = (x==pcity->x && y==pcity->y && tile_t==type->irrigation_result && terrain_control.may_irrigate); if (spec_t & S_SPECIAL_1) @@ -722,10 +739,18 @@ if (spec_t & S_FALLOUT) f-=(f*terrain_control.fallout_food_penalty)/100; - if (fx && y==pcity->y) f=game.rgame.min_city_center_food; return f; +} + +/************************************************************************** +This is a wrapper for allowing the old access with "local" coordinates. +**************************************************************************/ +int city_get_food_tile(int x, int y, struct city *pcity) +{ + return city_get_food_tile_global(pcity->x+x-CITY_MAP_SIZE/2,pcity->y+y-CITY_MAP_SIZE/2, pcity); } /************************************************************************** Index: common/city.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.h,v retrieving revision 1.86 diff -u -r1.86 city.h --- common/city.h 2001/08/26 13:10:12 1.86 +++ common/city.h 2001/08/31 16:14:17 @@ -346,6 +346,9 @@ int city_get_shields_tile(int x, int y, struct city *pcity); /* shield on spot */ int city_get_trade_tile(int x, int y, struct city *pcity); /* trade on spot */ int city_get_food_tile(int x, int y, struct city *pcity); /* food on spot */ +int city_get_shields_tile_global(int x, int y, struct city *pcity); /* shield on spot */ +int city_get_trade_tile_global(int x, int y, struct city *pcity); /* trade on spot */ +int city_get_food_tile_global(int x, int y, struct city *pcity); /* food on spot */ void set_worker_city(struct city *pcity, int city_x, int city_y, enum city_tile_type type); enum city_tile_type get_worker_city(struct city *pcity, int city_x, Index: common/map.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.c,v retrieving revision 1.82 diff -u -r1.82 map.c --- common/map.c 2001/08/26 09:28:16 1.82 +++ common/map.c 2001/08/31 16:14:18 @@ -1137,6 +1137,7 @@ ptile->city=NULL; unit_list_init(&ptile->units); ptile->worked = NULL; /* pointer to city working tile */ + ptile->citydialog = NULL; ptile->assigned = 0; /* bitvector */ } Index: common/map.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.h,v retrieving revision 1.87 diff -u -r1.87 map.h --- common/map.h 2001/08/26 09:28:17 1.87 +++ common/map.h 2001/08/31 16:14:18 @@ -50,6 +50,7 @@ Not used on the client side. */ int assigned; /* these can save a lot of CPU usage -- Syela */ struct city *worked; /* city working tile, or NULL if none */ + struct city *citydialog; /* NULL if not affected by a citydialog, else pointing to the city. */ signed short continent; signed char move_cost[8]; /* don't know if this helps! */ }; @@ -164,6 +165,7 @@ int have_huts; int have_rivers_overlay; /* only applies if !have_specials */ int num_continents; + struct city *citydialog; struct tile *tiles; struct map_position start_positions[MAX_NUM_NATIONS]; };