<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39895 >
> I think you attached the wrong patch. > Sigh, that's what happens with too many branch windows open at the same time.... (Sorry, that was the patch I was committing in S2_1.)
Index: server/citytools.c =================================================================== --- server/citytools.c (revision 14015) +++ server/citytools.c (working copy) @@ -838,6 +838,7 @@ city_list_unlink(pgiver->cities, pcity); pcity->owner = ptaker; map_claim_ownership(pcity->tile, ptaker, pcity->tile); + map_claim_border(pcity->tile, ptaker); city_list_prepend(ptaker->cities, pcity); transfer_city_units(ptaker, pgiver, old_city_units, @@ -946,31 +947,13 @@ void create_city(struct player *pplayer, struct tile *ptile, const char *name) { - struct city *pcity; int x_itr, y_itr; struct nation_type *nation = nation_of_player(pplayer); - struct base_type *pbase; + struct base_type *pbase = tile_get_base(ptile); + struct city *pcity = create_city_virtual(pplayer, ptile, name); freelog(LOG_DEBUG, "Creating city %s", name); - /* Ensure that we claim the ground we stand on */ - map_claim_ownership(ptile, pplayer, ptile); - - if (terrain_control.may_road) { - tile_set_special(ptile, S_ROAD); - if (player_knows_techs_with_flag(pplayer, TF_RAILROAD)) { - tile_set_special(ptile, S_RAILROAD); - update_tile_knowledge(ptile); - } - } - - /* It is possible that update_tile_knowledge() already sent tile information - * to some players, but we don't want to make any special handling for - * those cases. The network code may prevent asecond packet from being - * sent anyway. */ - send_tile_info(NULL, ptile, FALSE); - - pcity = create_city_virtual(pplayer, ptile, name); pcity->ai.trade_want = TRADE_WEIGHTING; pcity->id = get_next_id_number(); idex_register_city(pcity); @@ -1007,9 +990,26 @@ city_refresh_vision(pcity); tile_set_city(ptile, pcity); - city_list_prepend(pplayer->cities, pcity); + /* Claim the ground we stand on */ + map_claim_ownership(ptile, pplayer, ptile); + map_claim_border(ptile, pplayer); + + if (terrain_control.may_road) { + tile_set_special(ptile, S_ROAD); + if (player_knows_techs_with_flag(pplayer, TF_RAILROAD)) { + tile_set_special(ptile, S_RAILROAD); + update_tile_knowledge(ptile); + } + } + + /* It is possible that update_tile_knowledge() already sent tile information + * to some players, but we don't want to make any special handling for + * those cases. The network code may prevent a second packet from being + * sent anyway. */ + send_tile_info(NULL, ptile, FALSE); + /* it is possible to build a city on a tile that is already worked * this will displace the worker on the newly-built city's tile -- Syela */ for (y_itr = 0; y_itr < CITY_MAP_SIZE; y_itr++) { @@ -1041,8 +1041,7 @@ city_refresh(pcity); auto_arrange_workers(pcity); - /* Put vision back to normal, if base acted as a watchtower */ - pbase = tile_get_base(ptile); + /* If base acted as a watchtower, put vision back to normal */ if (pbase) { tile_remove_base(ptile); unit_list_refresh_vision(ptile->units); @@ -1709,7 +1708,6 @@ bool update_dumb_city(struct player *pplayer, struct city *pcity) { bv_imprs improvements; - struct player_tile *plrtile = map_get_player_tile(pcity->tile, pplayer); struct vision_site *pdcity = map_get_player_city(pcity->tile, pplayer); /* pcity->occupied isn't used at the server, so we go straight to the * unit list to check the occupied status. */ @@ -1726,37 +1724,31 @@ } } improvement_iterate_end; - if (pdcity - && pdcity->identity == pcity->id - && strcmp(pdcity->name, pcity->name) == 0 - && pdcity->size == pcity->size - && pdcity->occupied == occupied - && pdcity->walls == walls - && pdcity->happy == happy - && pdcity->unhappy == unhappy - && vision_owner(pdcity) == city_owner(pcity) - && BV_ARE_EQUAL(pdcity->improvements, improvements)) { + if (NULL == pdcity) { + pdcity = create_vision_site_from_city(pcity); + map_get_player_tile(pcity->tile, pplayer)->site = pdcity; + } else if (pdcity->identity == pcity->id + && vision_owner(pdcity) == city_owner(pcity) + && pdcity->size == pcity->size + && 0 == strcmp(pdcity->name, pcity->name) + && pdcity->occupied == occupied + && pdcity->walls == walls + && pdcity->happy == happy + && pdcity->unhappy == unhappy + && BV_ARE_EQUAL(pdcity->improvements, improvements)) { return FALSE; } - if (NULL == pdcity) { - pdcity = plrtile->site = fc_calloc(1, sizeof(*pdcity)); - pdcity->identity = pcity->id; - } if (pdcity->identity != pcity->id) { freelog(LOG_ERROR, "Trying to update old city (wrong ID)" " at %i,%i for player %s", - pcity->tile->x, pcity->tile->y, pplayer->name); + TILE_XY(pcity->tile), pplayer->name); pdcity->identity = pcity->id; /* ?? */ } - sz_strlcpy(pdcity->name, pcity->name); - pdcity->size = pcity->size; pdcity->occupied = occupied; pdcity->walls = walls; pdcity->happy = happy; pdcity->unhappy = unhappy; - pdcity->owner = city_owner(pcity); - pdcity->location = pcity->tile; pdcity->improvements = improvements; return TRUE; Index: server/maphand.c =================================================================== --- server/maphand.c (revision 14015) +++ server/maphand.c (working copy) @@ -58,6 +58,10 @@ static Continent_id *lake_surrounders; static int *continent_sizes, *ocean_sizes; +/* Suppress send_tile_info() during game_load() */ +static bool send_tile_suppressed = FALSE; + + /************************************************************************** Number this tile and nearby tiles (recursively) with the specified continent number nr, using a flood-fill algorithm. @@ -598,6 +602,17 @@ } /************************************************************************** + Suppress send_tile_info() during game_load() +**************************************************************************/ +bool send_tile_suppression(bool now) +{ + bool formerly = send_tile_suppressed; + + send_tile_suppressed = now; + return formerly; +} + +/************************************************************************** Send tile information to all the clients in dest which know and see the tile. If dest is NULL, sends to all clients (game.est_connections) which know and see tile. @@ -610,6 +625,10 @@ { struct packet_tile_info info; + if (send_tile_suppressed) { + return; + } + if (!dest) { dest = game.est_connections; } @@ -1095,6 +1114,7 @@ { pplayer->private_map = fc_malloc(MAP_INDEX_SIZE * sizeof(*pplayer->private_map)); + whole_map_iterate(ptile) { player_tile_init(ptile, pplayer); } whole_map_iterate_end; @@ -1109,11 +1129,20 @@ return; } + /* removing borders */ whole_map_iterate(ptile) { - struct player_tile *plrtile = map_get_player_tile(ptile, pplayer); + struct player_tile *playtile = map_get_player_tile(ptile, pplayer); - if (plrtile->site) { - free(plrtile->site); + /* cleverly uses return that is NULL for non-site tile */ + playtile->site = map_get_player_base(ptile, pplayer); + } whole_map_iterate_end; + + /* only after removing borders! */ + whole_map_iterate(ptile) { + struct vision_site *psite = map_get_player_base(ptile, pplayer); + + if (NULL != psite) { + free_vision_site(psite); } } whole_map_iterate_end; @@ -1137,7 +1166,8 @@ vision_layer_iterate(v) { plrtile->seen_count[v] = 0; BV_CLR(ptile->tile_seen[v], player_index(pplayer)); - } vision_layer_iterate_end + } vision_layer_iterate_end; + if (!game.fogofwar_old) { plrtile->seen_count[V_MAIN] = 1; if (map_is_known(ptile, pplayer)) { @@ -1293,8 +1323,8 @@ /* update and send city knowledge */ /* remove outdated cities */ - if (dest_tile->site) { - if (!from_tile->site) { + if (dest_tile->site && dest_tile->site->location == ptile) { + if (!from_tile->site || from_tile->site->location != ptile) { /* As the city was gone on the newer from_tile it will be removed by this function */ reality_check_city(pdest, ptile); @@ -1306,8 +1336,8 @@ reality_check_city(pdest, ptile); } /* Set and send new city info */ - if (from_tile->site) { - if (!dest_tile->site) { + if (from_tile->site && from_tile->site->location == ptile) { + if (!dest_tile->site || dest_tile->site->location != ptile) { dest_tile->site = fc_calloc(1, sizeof(*dest_tile->site)); } /* struct assignment copy */ @@ -1675,23 +1705,8 @@ } } +#ifdef OWNER_SOURCE /************************************************************************* - Update tile worker states for all cities that have the given map tile - within their radius. Does not sync with client. - - This function is inefficient and so should only be called when the - owner actually changes. -*************************************************************************/ -static void tile_update_owner(struct tile *ptile) -{ - /* This implementation is horribly inefficient, but this doesn't cause - * problems since it's not called often. */ - cities_iterate(pcity) { - update_city_tile_status_map(pcity, ptile); - } cities_iterate_end; -} - -/************************************************************************* Add any unique home city not found in list but found on tile to the list. *************************************************************************/ @@ -1717,36 +1732,141 @@ } city_list_iterate_end; } unit_list_iterate_end; } +#endif /************************************************************************* - Claim ownership of a single tile. This does no checks. + Claim ownership of a single tile. *************************************************************************/ -void map_claim_ownership(struct tile *ptile, struct player *owner, - struct tile *source) +void map_claim_ownership(struct tile *ptile, struct player *powner, + struct tile *psource) { - ptile->owner_source = source; - tile_set_owner(ptile, owner); + struct player *ploser = tile_owner(ptile); + + if (NULL != ploser) { + struct player_tile *playtile = map_get_player_tile(ptile, ploser); + + /* cleverly uses return that is NULL for non-site tile */ + playtile->site = map_get_player_base(ptile, ploser); + + if (NULL != playtile->site && ptile == psource) { + /* has new owner */ + playtile->site->owner = powner; + } + } + + if (NULL != powner /* assume && NULL != psource */) { + struct city *pcity = tile_city(ptile); + struct player_tile *playtile = map_get_player_tile(psource, powner); + + if (NULL != playtile->site) { + if (ptile != psource) { + map_get_player_tile(ptile, powner)->site = playtile->site; + } else if (NULL != pcity) { + playtile->site = update_vision_site_from_city(playtile->site, pcity); + } else { + /* has new owner */ + playtile->site->owner = powner; + } + } else { + assert(ptile == psource); + if (NULL != pcity) { + playtile->site = create_vision_site_from_city(pcity); + } else { + playtile->site = create_vision_site(-1/*FIXME*/, psource, powner); + } + } + } + + tile_set_owner(ptile, powner); send_tile_info(NULL, ptile, FALSE); - tile_update_owner(ptile); + + /* This implementation is somewhat inefficient. By design, it's not + * called often. Does not send updates to client. + */ + if (NULL != ploser && ploser != powner) { + city_list_iterate(ploser->cities, pcity) { + update_city_tile_status_map(pcity, ptile); + } city_list_iterate_end; + } + if (NULL != powner && ploser != powner) { + city_list_iterate(powner->cities, pcity) { + update_city_tile_status_map(pcity, ptile); + } city_list_iterate_end; + } } /************************************************************************* - Establish range of a border source. + Update borders for this source. Call this for each new source. *************************************************************************/ -static int map_border_range(struct tile *ptile) +void map_claim_border(struct tile *ptile, struct player *powner) { - int range; - struct city *pcity = tile_city(ptile); + struct vision_site *psite = map_get_player_site(ptile, powner); + int range = game.info.borders; - if (NULL != pcity) { - range = MIN(pcity->size + 1, game.info.borders); - if (pcity->size > game.info.borders) { - range += (pcity->size - game.info.borders) / 2; + if (0 == range) { + /* no borders */ + return; + } + if (VISION_SITE_RUIN == psite->identity) { + /* should never be called! */ + freelog(LOG_VERBOSE, "Warning: border source (%d,%d) is ruin!", + TILE_XY(ptile)); + return; + } + if (VISION_SITE_RUIN < psite->identity) { + /* city expansion */ + range = MIN(psite->size + 1, game.info.borders); + if (psite->size > game.info.borders) { + range += (psite->size - game.info.borders) / 2; } - } else { - range = game.info.borders; } - return range; + range *= range; /* due to sq dist */ + + freelog(LOG_VERBOSE, "border source (%d,%d) range %d", + TILE_XY(ptile), range); + + circle_dxyr_iterate(ptile, range, dtile, dx, dy, dr) { + struct player *downer = tile_owner(dtile); + + if (!map_is_known(dtile, powner)) { + /* border tile never seen */ + continue; + } + if (NULL != downer && downer != powner) { + struct vision_site *dsite = map_get_player_site(dtile, downer); + int r = sq_map_distance(dsite->location, dtile); + + /* border tile claimed by another */ + if (VISION_SITE_RUIN == dsite->identity) { + /* ruins don't keep their borders */ + dsite->owner = powner; + tile_set_owner(dtile, powner); + continue; + } else if (r < dr) { + /* nearest shall prevail */ + continue; + } else if (r == dr) { + if (dsite->identity < psite->identity) { + /* lower shall prevail: airport/fortress/city */ + continue; + } else if (dsite->identity == psite->identity) { + /* neither shall prevail */ + map_claim_ownership(dtile, NULL, NULL); + continue; + } + } + } + + if (is_ocean_tile(dtile)) { + if (is_claimable_ocean(dtile, ptile)) { + map_claim_ownership(dtile, powner, ptile); + } + } else { + if (tile_continent(dtile) == tile_continent(ptile)) { + map_claim_ownership(dtile, powner, ptile); + } + } + } circle_dxyr_iterate_end; } /************************************************************************* @@ -1768,6 +1888,16 @@ cities_to_refresh = city_list_new(); } + /* base sites are done first, as they may be thorn in city side. */ + sites_iterate(psite) { + map_claim_border(psite->location, vision_owner(psite)); + } sites_iterate_end; + + cities_iterate(pcity) { + map_claim_border(pcity->tile, city_owner(pcity)); + } cities_iterate_end; + +#ifdef OWNER_SOURCE /* First transfer ownership for sources that have changed hands. */ whole_map_iterate(ptile) { if (tile_owner(ptile) @@ -1880,6 +2010,7 @@ } circle_dxyr_iterate_end; } } whole_map_iterate_end; +#endif /* Update happiness in all homecities we have collected */ if (game.info.happyborders > 0) { Index: server/maphand.h =================================================================== --- server/maphand.h (revision 14015) +++ server/maphand.h (working copy) @@ -46,14 +46,18 @@ void global_warming(int effect); void nuclear_winter(int effect); +void upgrade_city_rails(struct player *pplayer, bool discovery); + void give_map_from_player_to_player(struct player *pfrom, struct player *pdest); void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest); void give_citymap_from_player_to_player(struct city *pcity, struct player *pfrom, struct player *pdest); void send_all_known_tiles(struct conn_list *dest); + +bool send_tile_suppression(bool now); void send_tile_info(struct conn_list *dest, struct tile *ptile, bool send_unknown); -void upgrade_city_rails(struct player *pplayer, bool discovery); + void send_map_info(struct conn_list *dest); void map_show_tile(struct player *pplayer, struct tile *ptile); @@ -93,8 +97,9 @@ void disable_fog_of_war(void); void map_calculate_borders(void); -void map_claim_ownership(struct tile *ptile, struct player *owner, - struct tile *place); +void map_claim_border(struct tile *ptile, struct player *powner); +void map_claim_ownership(struct tile *ptile, struct player *powner, + struct tile *psource); void check_terrain_change(struct tile *ptile, struct terrain *oldter); int get_continent_size(Continent_id id); Index: server/unittools.c =================================================================== --- server/unittools.c (revision 14015) +++ server/unittools.c (working copy) @@ -744,6 +744,7 @@ /* Claim base if it has "ClaimTerritory" flag */ if (tile_has_base_flag(ptile, BF_CLAIM_TERRITORY)) { map_claim_ownership(ptile, unit_owner(punit), ptile); + map_claim_border(ptile, unit_owner(punit)); } unit_activity_done = TRUE; @@ -2727,6 +2728,7 @@ BF_CLAIM_TERRITORY) && (!tile_owner(pdesttile) || pplayers_at_war(tile_owner(pdesttile), pplayer))) { map_claim_ownership(pdesttile, pplayer, pdesttile); + map_claim_border(pdesttile, pplayer); } unit_list_unlink(psrctile->units, punit); Index: server/sanitycheck.c =================================================================== --- server/sanitycheck.c (revision 14015) +++ server/sanitycheck.c (working copy) @@ -167,7 +167,7 @@ SANITY_TILE(ptile, tile_owner(ptile) != NULL); } if (tile_owner(ptile) != NULL) { - SANITY_TILE(ptile, ptile->owner_source != NULL); + SANITY_TILE(ptile, map_get_player_site(ptile, tile_owner(ptile)) != NULL); } index_to_map_pos(&x, &y, tile_index(ptile)); Index: server/savegame.c =================================================================== --- server/savegame.c (revision 14015) +++ server/savegame.c (working copy) @@ -883,6 +883,7 @@ } } whole_map_iterate_end; +#ifdef OWNER_SOURCE /* Owner and ownership source are stored as plain numbers */ if (has_capability("new_owner_map", savefile_options)) { int x, y; @@ -946,6 +947,7 @@ } } } +#endif if (secfile_lookup_bool_default(file, TRUE, "game.save_known")) { int known[MAP_INDEX_SIZE]; @@ -1075,6 +1077,7 @@ get_savegame_special(ptile->special, mod)); } special_halfbyte_iterate_end; +#ifdef OWNER_SOURCE /* Store owner and ownership source as plain numbers */ { int x, y; @@ -1120,6 +1123,7 @@ secfile_insert_str(file, line, "map.source%03d", y); } } +#endif secfile_insert_bool(file, game.save_options.save_known, "game.save_known"); if (game.save_options.save_known) { @@ -1745,6 +1749,15 @@ unit_list_append(plr->units, punit); unit_list_prepend(punit->tile->units, punit); + + /* Claim ownership of fortress? */ + if (tile_has_base_flag_for_unit(punit->tile, unit_type(punit), + BF_CLAIM_TERRITORY) + && (!tile_owner(punit->tile) + || pplayers_at_war(tile_owner(punit->tile), plr))) { + map_claim_ownership(punit->tile, plr, punit->tile); + map_claim_border(punit->tile, plr); + } } } @@ -1835,7 +1848,7 @@ if ((is_sea_barbarian(plr) && nat_barb_type != SEA_BARBARIAN) || (is_land_barbarian(plr) && nat_barb_type != LAND_BARBARIAN)) { - freelog(LOG_ERROR, "Reassigning barbarian nation for %s", plr->name); + freelog(LOG_VERBOSE, "Reassigning barbarian nation for %s", plr->name); plr->nation = NO_NATION_SELECTED; } else { player_set_nation(plr, pnation); @@ -2532,9 +2545,13 @@ (pcity->ai.founder_want < 0), "player%d.c%d.ai.founder_boat", plrno, i); - /* do after all the set_worker_city() are done. */ + /* After all the set_worker_city() are done. */ tile_set_city(pcity->tile, pcity); city_list_append(plr->cities, pcity); + + /* After all the set_worker_city() are done. */ + map_claim_ownership(ptile, plr, ptile); + map_claim_border(ptile, plr); } load_player_units(plr, plrno, file); @@ -3324,7 +3341,8 @@ i = 0; whole_map_iterate(ptile) { - if (NULL != (pdcity = map_get_player_city(ptile, plr))) { + if (NULL != (pdcity = map_get_player_city(ptile, plr)) + && plr != vision_owner(pdcity)) { secfile_insert_int(file, pdcity->identity, "player%d.dc%d.id", plrno, i); secfile_insert_int(file, ptile->nat_x, @@ -3550,6 +3568,7 @@ enum tile_special_type *special_order = NULL; int technology_order_size = 0; int civstyle = 0; + bool was_send_tile_suppressed = send_tile_suppression(TRUE); /* [savefile] */ savefile_options = secfile_lookup_str(file, "savefile.options"); @@ -4201,6 +4220,8 @@ if (!game.info.is_new_game) { set_myrand_state(rstate); } + + send_tile_suppression(was_send_tile_suppressed); } /*************************************************************** Index: common/city.c =================================================================== --- common/city.c (revision 14015) +++ common/city.c (working copy) @@ -446,6 +446,7 @@ **************************************************************************/ struct player *city_owner(const struct city *pcity) { + assert(NULL != pcity->owner); return pcity->owner; } Index: common/tile.c =================================================================== --- common/tile.c (revision 14015) +++ common/tile.c (working copy) @@ -53,7 +53,12 @@ ****************************************************************************/ struct city *tile_city(const struct tile *ptile) { - return ptile->city; + struct city *pcity = ptile->worked; + + if (NULL != pcity && ptile == pcity->tile) { + return pcity; + } + return NULL; } /**************************************************************************** @@ -61,7 +66,7 @@ ****************************************************************************/ void tile_set_city(struct tile *ptile, struct city *pcity) { - ptile->city = pcity; + ptile->worked = pcity; /* probably duplicate effort */ } #ifndef tile_terrain Index: common/tile.h =================================================================== --- common/tile.h (revision 14015) +++ common/tile.h (working copy) @@ -41,11 +41,9 @@ bv_special special; struct resource *resource; /* NULL for no resource */ struct terrain *terrain; /* NULL for unknown tiles */ - struct city *city; /* city standing on the tile, NULL if none */ struct unit_list *units; - struct city *worked; /* city working tile, or NULL if none */ - struct player *owner; /* Player owning this tile, or NULL. */ - struct tile *owner_source; /* what makes it owned by owner */ + struct player *owner; /* NULL for not owned */ + struct city *worked; /* NULL for not worked */ char *spec_sprite; }; Index: common/terrain.c =================================================================== --- common/terrain.c (revision 14015) +++ common/terrain.c (working copy) @@ -766,11 +766,8 @@ case TC_LAND: adjc_iterate(ptile, adjc_tile) { struct terrain* pterrain = tile_terrain(adjc_tile); - - if (T_UNKNOWN == pterrain) { - continue; - } - if (!terrain_has_flag(pterrain, TER_OCEANIC)) { + if (T_UNKNOWN != pterrain + && !terrain_has_flag(pterrain, TER_OCEANIC)) { return TRUE; } } adjc_iterate_end; Index: common/player.c =================================================================== --- common/player.c (revision 14015) +++ common/player.c (working copy) @@ -188,13 +188,18 @@ plr->nation = NO_NATION_SELECTED; plr->team = NULL; plr->is_ready = FALSE; + plr->revolution_finishes = -1; plr->capital = FALSE; + plr->city_style=0; /* should be first basic style */ + plr->cities = city_list_new(); + plr->sites = site_list_new(); plr->units = unit_list_new(); - plr->cities = city_list_new(); + plr->connections = conn_list_new(); plr->current_conn = NULL; plr->is_connected = FALSE; + plr->was_created = FALSE; plr->is_alive=TRUE; plr->is_dying = FALSE; @@ -205,7 +210,6 @@ plr->diplstates[i].has_reason_to_cancel = 0; plr->diplstates[i].contact_turns_left = 0; } - plr->city_style=0; /* should be first basic style */ plr->ai.control=FALSE; plr->ai.handicap = 0; plr->ai.skill_level = 0; Index: common/player.h =================================================================== --- common/player.h (revision 14015) +++ common/player.h (working copy) @@ -178,8 +178,9 @@ bv_player embassy; struct player_diplstate diplstates[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS]; int city_style; + struct city_list *cities; + struct site_list *sites; struct unit_list *units; - struct city_list *cities; struct player_score score; struct player_economic economic; Index: common/vision.c =================================================================== --- common/vision.c (revision 14015) +++ common/vision.c (working copy) @@ -71,3 +71,51 @@ { return vision->radius_sq[vlayer]; } + +/**************************************************************************** + ... +****************************************************************************/ +void free_vision_site(struct vision_site *psite) +{ + free(psite); +} + +/**************************************************************************** + Returns the basic structure. +****************************************************************************/ +struct vision_site *create_vision_site(int identity, struct tile *location, + struct player *owner) +{ + struct vision_site *psite = fc_calloc(1, sizeof(*psite)); + + psite->identity = identity; + psite->location = location; + psite->owner = owner; + return psite; +} + +/**************************************************************************** + Returns the basic structure filled with initial elements. +****************************************************************************/ +struct vision_site *create_vision_site_from_city(const struct city *pcity) +{ + struct vision_site *psite = create_vision_site(pcity->id, pcity->tile, + city_owner(pcity)); + + psite->size = pcity->size; + sz_strlcpy(psite->name, pcity->name); + return psite; +} + +/**************************************************************************** + Returns the basic structure filled with current elements. +****************************************************************************/ +struct vision_site *update_vision_site_from_city(struct vision_site *psite, + const struct city *pcity) +{ + psite->identity = pcity->id; + psite->owner = pcity->owner; + psite->size = pcity->size; + sz_strlcpy(psite->name, pcity->name); + return psite; +} Index: common/vision.h =================================================================== --- common/vision.h (revision 14015) +++ common/vision.h (working copy) @@ -126,6 +126,12 @@ }; #define vision_owner(v) ((v)->owner) +void free_vision_site(struct vision_site *psite); +struct vision_site *create_vision_site(int identity, struct tile *location, + struct player *owner); +struct vision_site *create_vision_site_from_city(const struct city *pcity); +struct vision_site *update_vision_site_from_city(struct vision_site *psite, + const struct city *pcity); /* get 'struct site_list' and related functions: */ #define SPECLIST_TAG site Index: common/map.c =================================================================== --- common/map.c (revision 14015) +++ common/map.c (working copy) @@ -277,11 +277,9 @@ tile_clear_all_specials (ptile); ptile->resource = NULL; ptile->terrain = T_UNKNOWN; - ptile->city = NULL; ptile->units = unit_list_new(); - ptile->worked = NULL; /* pointer to city working tile */ - ptile->owner = NULL; /* Tile not claimed by any nation. */ - ptile->owner_source = NULL; + ptile->owner = NULL; /* Not claimed by any player. */ + ptile->worked = NULL; /* No city working here. */ ptile->spec_sprite = NULL; } @@ -582,9 +580,15 @@ } cardinal_adjc_iterate(ptile, tile1) { + struct terrain* pterrain1 = tile_terrain(tile1); + + if (T_UNKNOWN == pterrain1) { + continue; + } + if (tile_has_special(tile1, S_RIVER) || tile_has_special(tile1, S_IRRIGATION) - || is_ocean_tile(tile1)) { + || terrain_has_flag(pterrain1, TER_OCEANIC)) { return TRUE; } } cardinal_adjc_iterate_end; Index: client/packhand.c =================================================================== --- client/packhand.c (revision 14015) +++ client/packhand.c (working copy) @@ -655,12 +655,14 @@ static void handle_city_packet_common(struct city *pcity, bool is_new, bool popup, bool investigate) { - if(is_new) { + if (is_new) { pcity->units_supported = unit_list_new(); pcity->info_units_supported = unit_list_new(); pcity->info_units_present = unit_list_new(); + + tile_set_city(pcity->tile, pcity); city_list_prepend(city_owner(pcity)->cities, pcity); - tile_set_city(pcity->tile, pcity); + if (city_owner(pcity) == game.player_ptr) { city_report_dialog_update(); } @@ -677,7 +679,6 @@ } } - if (can_client_change_view()) { refresh_city_mapcanvas(pcity, pcity->tile, FALSE, FALSE); } @@ -2019,14 +2020,21 @@ **************************************************************************/ void handle_tile_info(struct packet_tile_info *packet) { + enum known_type old_known; + bool known_changed = FALSE; bool tile_changed = FALSE; - bool known_changed = FALSE; struct terrain *pterrain = terrain_by_number(packet->type); struct tile *ptile = map_pos_to_tile(packet->x, packet->y); - enum known_type old_known = client_tile_get_known(ptile); + + if (NULL == ptile) { + freelog(LOG_ERROR, + "handle_tile_info() invalid tile (%d,%d).", + TILE_XY(packet)); + return; + } + old_known = client_tile_get_known(ptile); - if (NULL == tile_terrain(ptile) - || terrain_number(tile_terrain(ptile)) != packet->type) { + if (NULL == tile_terrain(ptile) || pterrain != tile_terrain(ptile)) { tile_changed = TRUE; switch (old_known) { case TILE_UNKNOWN: @@ -2034,14 +2042,13 @@ break; case TILE_KNOWN_FOGGED: case TILE_KNOWN: - if (pterrain || TILE_UNKNOWN == packet->known) { + if (NULL != pterrain || TILE_UNKNOWN == packet->known) { tile_set_terrain(ptile, pterrain); } else { tile_changed = FALSE; freelog(LOG_ERROR, "handle_tile_info() unknown terrain (%d,%d).", - packet->x, - packet->y); + TILE_XY(packet)); } break; };
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev