Index: client/packhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v retrieving revision 1.256 diff -u -r1.256 packhand.c --- client/packhand.c 2002/09/23 22:47:09 1.256 +++ client/packhand.c 2002/10/16 20:15:55 @@ -438,6 +438,9 @@ &need_effect_update); } impr_type_iterate_end; + pcity->occupied = + (unit_list_size(&(map_get_tile(pcity->x, pcity->y)->units)) > 0); + popup = (city_is_new && get_client_state()==CLIENT_GAME_RUNNING_STATE && pcity->owner==game.player_idx) || packet->diplomat_investigate; @@ -559,6 +562,7 @@ pcity->size=packet->size; pcity->tile_trade = packet->tile_trade; + pcity->occupied = packet->occupied; if (packet->happy) { pcity->ppl_happy[4] = pcity->size; @@ -916,6 +920,9 @@ return; } if(pcity) { + pcity->occupied = + (unit_list_size(&(map_get_tile(pcity->x, pcity->y)->units)) > 0); + if(pcity->id==punit->homecity) repaint_city = TRUE; else @@ -923,6 +930,7 @@ } if((pcity=map_get_city(punit->x, punit->y))) { + pcity->occupied = TRUE; if(pcity->id == punit->homecity) repaint_city = TRUE; else Index: client/tilespec.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v retrieving revision 1.85 diff -u -r1.85 tilespec.c --- client/tilespec.c 2002/09/28 01:36:20 1.85 +++ client/tilespec.c 2002/10/16 20:15:59 @@ -904,7 +904,6 @@ int *solid_bg) { struct Sprite **save_sprs=sprs; - struct tile *ptile = map_get_tile(pcity->x, pcity->y); *solid_bg = 0; if (!no_backdrop) { @@ -916,8 +915,9 @@ } } - if (genlist_size(&(ptile->units.list)) > 0) + if (pcity->occupied) { *sprs++ = get_city_occupied_sprite(pcity); + } *sprs++ = get_city_sprite(pcity); @@ -953,14 +953,14 @@ int fill_city_sprite_array_iso(struct Sprite **sprs, struct city *pcity) { struct Sprite **save_sprs=sprs; - struct tile *ptile = map_get_tile(pcity->x, pcity->y); if (!no_backdrop) { *sprs++ = get_city_nation_flag_sprite(pcity); } - if (genlist_size(&(ptile->units.list)) > 0) + if (pcity->occupied) { *sprs++ = get_city_occupied_sprite(pcity); + } *sprs++ = get_city_sprite(pcity); Index: common/capstr.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v retrieving revision 1.112 diff -u -r1.112 capstr.c --- common/capstr.c 2002/10/07 17:26:21 1.112 +++ common/capstr.c 2002/10/16 20:16:01 @@ -70,12 +70,15 @@ * are not directly related to the capability strings discussed here.) */ -#define CAPABILITY "+1.14.0 conn_info" +#define CAPABILITY "+1.14.0 conn_info +occupied" /* "+1.14.0" is protocol for 1.14.0 release. "conn_info" is sending the conn_id field. To preserve compatability with old clients trying to connect this should persist across releases. + + "occupied": don't send info about units which are inside enemy + cities but instead use the occupied flag of short_city_info. */ void init_our_capability(void) Index: common/city.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.h,v retrieving revision 1.114 diff -u -r1.114 city.h --- common/city.h 2002/09/06 19:14:14 1.114 +++ common/city.h 2002/10/16 20:16:02 @@ -269,6 +269,10 @@ enum city_tile_type city_map[CITY_MAP_SIZE][CITY_MAP_SIZE]; struct unit_list units_supported; + + /* TRUE iff there units in the town. Only set at the client. */ + bool occupied; + int steal; /* diplomats steal once; for spies, gets harder */ /* turn states */ bool did_buy; Index: common/packets.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v retrieving revision 1.219 diff -u -r1.219 packets.c --- common/packets.c 2002/10/09 13:31:09 1.219 +++ common/packets.c 2002/10/16 20:16:08 @@ -1411,7 +1411,8 @@ dio_put_uint8(&dout, (COND_SET_BIT(req->happy, 0) | COND_SET_BIT(req->capital, 1) | - COND_SET_BIT(req->walls, 2))); + COND_SET_BIT(req->walls, 2) | + COND_SET_BIT(req->occupied, 3))); dio_put_uint16(&dout, req->tile_trade); @@ -1439,6 +1440,7 @@ packet->happy = TEST_BIT(i, 0); packet->capital = TEST_BIT(i, 1); packet->walls = TEST_BIT(i, 2); + packet->occupied = TEST_BIT(i, 3); dio_get_uint16(&din, &packet->tile_trade); Index: common/packets.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v retrieving revision 1.125 diff -u -r1.125 packets.h --- common/packets.h 2002/09/25 00:58:12 1.125 +++ common/packets.h 2002/10/16 20:16:10 @@ -381,6 +381,7 @@ bool happy; /* boolean */ bool capital; /* boolean */ bool walls; /* boolean */ + bool occupied; /* boolean */ int tile_trade; /* same as in packet_city_info */ }; Index: server/citytools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v retrieving revision 1.190 diff -u -r1.190 citytools.c --- server/citytools.c 2002/09/23 15:00:56 1.190 +++ server/citytools.c 2002/10/16 20:16:15 @@ -1384,6 +1384,7 @@ packet->capital = FALSE; packet->walls = pdcity->has_walls; + packet->occupied = pdcity->occupied; if (pcity && player_has_traderoute_with_city(pplayer, pcity)) { packet->tile_trade = pcity->tile_trade; @@ -1670,6 +1671,8 @@ sz_strlcpy(pdcity->name, pcity->name); pdcity->size = pcity->size; pdcity->has_walls = city_got_citywalls(pcity); + pdcity->occupied = + (unit_list_size(&(map_get_tile(pcity->x, pcity->y)->units)) > 0); pdcity->owner = pcity->owner; } Index: server/maphand.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v retrieving revision 1.30 diff -u -r1.30 maphand.h --- server/maphand.h 2002/09/28 01:36:24 1.30 +++ server/maphand.h 2002/10/16 20:16:15 @@ -23,6 +23,7 @@ struct dumb_city{ int id; bool has_walls; + bool occupied; char name[MAX_LEN_NAME]; unsigned short size; unsigned char owner; Index: server/unithand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v retrieving revision 1.234 diff -u -r1.234 unithand.c --- server/unithand.c 2002/09/27 12:32:48 1.234 +++ server/unithand.c 2002/10/16 20:16:18 @@ -632,13 +632,13 @@ **************************************************************************/ static void handle_unit_attack_request(struct unit *punit, struct unit *pdefender) { - int o; struct player *pplayer = unit_owner(punit); struct packet_unit_combat combat; struct unit *plooser, *pwinner; struct unit old_punit = *punit; /* Used for new ship algorithm. -GJW */ struct city *pcity; int def_x = pdefender->x, def_y = pdefender->y; + struct packet_unit_info unit_att_packet, unit_def_packet; freelog(LOG_DEBUG, "Start attack: %s's %s against %s's %s.", pplayer->name, unit_type(punit)->name, @@ -722,14 +722,34 @@ combat.attacker_hp=punit->hp / game.firepower_factor; combat.defender_hp=pdefender->hp / game.firepower_factor; combat.make_winner_veteran=pwinner->veteran?1:0; + + package_unit(punit, &unit_att_packet, FALSE, FALSE, UNIT_INFO_IDENTITY, 0, + FALSE); + package_unit(pdefender, &unit_def_packet, FALSE, FALSE, UNIT_INFO_IDENTITY, + 0, FALSE); - for(o=0; ox, punit->y, get_player(o)) || - map_get_known_and_seen(def_x, def_y, get_player(o))) { - lsend_packet_unit_combat(&game.players[o].connections, &combat); + players_iterate(other_player) { + if (map_get_known_and_seen(punit->x, punit->y, other_player) || + map_get_known_and_seen(def_x, def_y, other_player)) { + + /* + * Special case for attacking/defending: + * + * Normally the player doesn't get the information about the + * units inside a city. However for attacking/defending the + * player has to know the unit of the other side. + */ + + lsend_packet_unit_info(&other_player->connections, &unit_att_packet); + lsend_packet_unit_info(&other_player->connections, &unit_def_packet); + lsend_packet_unit_combat(&other_player->connections, &combat); } + } players_iterate_end; + conn_list_iterate(game.game_connections, pconn) { if (!pconn->player && pconn->observer) { + send_packet_unit_info(pconn, &unit_att_packet); + send_packet_unit_info(pconn, &unit_def_packet); send_packet_unit_combat(pconn, &combat); } } conn_list_iterate_end; Index: server/unittools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v retrieving revision 1.185 diff -u -r1.185 unittools.c --- server/unittools.c 2002/09/28 23:00:51 1.185 +++ server/unittools.c 2002/10/16 20:16:25 @@ -2043,12 +2043,19 @@ conn_list_iterate(*dest, pconn) { struct player *pplayer = pconn->player; - if (!pplayer && !pconn->observer) continue; - if (!pplayer - || ((map_get_known_and_seen(info.x, info.y, pplayer) - || map_get_known_and_seen(x, y, pplayer)) - && (player_can_see_unit(pplayer, punit) - || player_can_see_unit_at_location(pplayer, punit, x, y)))) { + bool can_see_tile = (map_get_known_and_seen(info.x, info.y, pplayer) + || map_get_known_and_seen(x, y, pplayer)); + bool can_see_unit = (player_can_see_unit(pplayer, punit) + || player_can_see_unit_at_location(pplayer, punit, + x, y)); + bool outside_city = + ((pplayer && pplayers_allied(unit_owner(punit), pplayer)) + || (!map_get_city(punit->x, punit->y) && !map_get_city(x, y))); + + if (!pplayer && !pconn->observer) { + continue; + } + if (!pplayer || (can_see_tile && can_see_unit && outside_city)) { send_packet_unit_info(pconn, &info); } }