diff client/packhand.c client/packhand.c --- client/packhand.c Mon Oct 16 10:38:31 2000 +++ client/packhand.c Tue Oct 17 10:55:42 2000 @@ -235,15 +235,15 @@ pcity=find_city_by_id(packet->id); if (pcity && (pcity->owner != packet->owner)) { - /* With current server, this shouldn't happen: when city changes - * owner it is re-created with a new id. Unclear what to do here; - * try to cope... - */ + /* If we receive full city packet because we own this city, city of + old owner should be already removed. If we are just investigating + city, we should have already received packet_short_city with new + owner. */ freelog(LOG_ERROR, - "Got existing city id (%d %s) with wrong owner (%d %s, old %d %s)", - packet->id, pcity->name, packet->owner, - get_player(packet->owner)->name, pcity->owner, - get_player(pcity->owner)->name); + "Got existing city id (%d %s) with old owner (%d %s, old %d %s)", + packet->id, pcity->name, packet->owner, + get_player(packet->owner)->name, pcity->owner, + get_player(pcity->owner)->name); client_remove_city(pcity); pcity = 0; } @@ -446,15 +446,6 @@ pcity=find_city_by_id(packet->id); if (pcity && (pcity->owner != packet->owner)) { - /* With current server, this shouldn't happen: when city changes - * owner it is re-created with a new id. Unclear what to do here; - * try to cope... - */ - freelog(LOG_ERROR, - "Got existing city id (%d %s) with wrong owner (%d %s, old %d %s)", - packet->id, pcity->name, packet->owner, - get_player(packet->owner)->name, pcity->owner, - get_player(pcity->owner)->name); client_remove_city(pcity); pcity = 0; } diff common/city.h common/city.h --- common/city.h Mon Sep 25 17:35:40 2000 +++ common/city.h Mon Oct 16 12:10:18 2000 @@ -152,6 +152,7 @@ struct city { int id; + int orig_id; int owner; int x, y; char name[MAX_LEN_NAME]; diff server/cityhand.c server/cityhand.c --- server/cityhand.c Mon Sep 25 17:35:44 2000 +++ server/cityhand.c Tue Oct 17 11:11:05 2000 @@ -156,6 +156,7 @@ pcity=fc_malloc(sizeof(struct city)); pcity->id=get_next_id_number(); + pcity->orig_id = pcity->id; idex_register_city(pcity); pcity->owner=pplayer->player_no; pcity->x=x; @@ -283,7 +284,7 @@ struct packet_city_request *preq) { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); if(!pcity) return; if(!player_owns_city(pplayer, pcity)) @@ -331,7 +332,7 @@ { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); if(!pcity) return; if (!player_owns_city(pplayer, pcity)) return; @@ -359,7 +360,7 @@ struct packet_city_request *preq) { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); if (preq->worker_x < 0 || preq->worker_x > 4) return; @@ -439,7 +440,7 @@ void handle_city_sell(struct player *pplayer, struct packet_city_request *preq) { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); if (!pcity || !player_owns_city(pplayer, pcity) || preq->build_id>=game.num_impr_types) return; @@ -523,7 +524,7 @@ void handle_city_worklist(struct player *pplayer, struct packet_city_request *preq) { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); copy_worklist(pcity->worklist, &preq->worklist); @@ -536,7 +537,7 @@ void handle_city_buy(struct player *pplayer, struct packet_city_request *preq) { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); really_handle_city_buy(pplayer, pcity); } @@ -546,7 +547,7 @@ void handle_city_refresh(struct player *pplayer, struct packet_generic_integer *preq) { struct city *pcity; - pcity=find_city_by_id(preq->value); + pcity=find_city_by_orig_id(preq->value); if (pcity) { city_refresh(pcity); send_city_info(pplayer, pcity); @@ -630,7 +631,7 @@ struct packet_city_request *preq) { struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); if (!pcity) { freelog(LOG_ERROR, "Pcity null in handle_city_change" " (%s, id = %d)!", pplayer->name, preq->city_id); @@ -664,7 +665,7 @@ char *cp; struct city *pcity; - pcity=find_city_by_id(preq->city_id); + pcity=find_city_by_orig_id(preq->city_id); if(!player_owns_city(pplayer, pcity)) return; @@ -685,7 +686,7 @@ void handle_city_options(struct player *pplayer, struct packet_generic_values *preq) { - struct city *pcity = find_city_by_id(preq->value1); + struct city *pcity = find_city_by_orig_id(preq->value1); if (!pcity || pcity->owner != pplayer->player_no) return; pcity->city_options = preq->value2; /* We don't need to send the full city info, since no other properties @@ -1014,7 +1015,7 @@ { int i, x, y; char *p; - packet->id=pcity->id; + packet->id=pcity->orig_id; packet->owner=pcity->owner; packet->x=pcity->x; packet->y=pcity->y; @@ -1028,7 +1029,7 @@ packet->ppl_scientist=pcity->ppl_scientist; packet->ppl_taxman=pcity->ppl_taxman; for (i=0;i<4;i++) { - packet->trade[i]=pcity->trade[i]; + packet->trade[i]=orig_city_id(pcity->trade[i]); packet->trade_value[i]=pcity->trade_value[i]; } @@ -1105,7 +1106,7 @@ packet->happy=1; } - if ((pcity = map_get_city(x,y)) && pcity->id == pdcity->id && + if ((pcity = map_get_city(x,y)) && pcity->orig_id == pdcity->id && city_got_building(pcity, B_PALACE)) packet->capital=1; else @@ -1126,13 +1127,13 @@ struct dumb_city *pdcity; if (!plrtile->city) { plrtile->city = fc_malloc(sizeof(struct dumb_city)); - plrtile->city->id = pcity->id; + plrtile->city->id = pcity->orig_id; } pdcity = plrtile->city; - if (pdcity->id != pcity->id) { + if (pdcity->id != pcity->orig_id) { freelog(LOG_ERROR, "Trying to update old city (wrong ID)" " at %i,%i for player %s", pcity->x, pcity->y, pplayer->name); - pdcity->id = pcity->id; /* ?? */ + pdcity->id = pcity->orig_id; /* ?? */ } sz_strlcpy(pdcity->name, pcity->name); pdcity->size = pcity->size; @@ -1151,7 +1152,7 @@ if (pdcity) { pcity = map_get_tile(x,y)->city; - if (!pcity || (pcity && pcity->id != pdcity->id)) { + if (!pcity || (pcity && pcity->orig_id != pdcity->id)) { packet.value=pdcity->id; lsend_packet_generic_integer(&pplayer->connections, PACKET_REMOVE_CITY, &packet); diff server/citytools.c server/citytools.c --- server/citytools.c Sat Sep 2 11:22:06 2000 +++ server/citytools.c Mon Oct 16 12:12:14 2000 @@ -1064,6 +1064,7 @@ *pnewcity->worklist = *pcity->worklist; pnewcity->id=get_next_id_number(); + pnewcity->orig_id = pcity->orig_id; idex_register_city(pnewcity); for (i = 0; i < game.num_impr_types; i++) { @@ -1163,3 +1164,43 @@ } } + +int orig_city_id(int id) +{ + if(!id) + return 0; + return find_city_by_id(id)->orig_id; +} + + +struct city *find_city_by_orig_id(int id) +{ + int i; + struct city *pcity; + struct genlist_iterator myiter; + + /* Most of the time cities id == orig_id. */ + pcity = find_city_by_id(id); + if(pcity) + return pcity; + + for(i=0; iorig_id) + return (struct city *)ITERATOR_PTR(myiter); + } + return 0; +} + + +struct city *player_find_city_by_orig_id(struct player *pplayer, int city_id) +{ + struct city *pcity = find_city_by_orig_id(city_id); + + if(pcity && (pcity->owner==pplayer->player_no)) { + return pcity; + } else { + return NULL; + } +} diff server/citytools.h server/citytools.h --- server/citytools.h Tue Jul 25 21:18:35 2000 +++ server/citytools.h Mon Oct 16 12:10:16 2000 @@ -69,4 +69,9 @@ void adjust_city_free_cost(int *num_free, int *this_cost); +int orig_city_id(int id); +struct city *find_city_by_orig_id(int id); +struct city *player_find_city_by_orig_id(struct player *pplayer, int city_id); + + #endif /* FC__CITYTOOLS_H */ diff server/diplhand.c server/diplhand.c --- server/diplhand.c Fri Sep 8 16:42:36 2000 +++ server/diplhand.c Mon Oct 16 12:10:18 2000 @@ -279,6 +279,7 @@ struct Treaty *ptreaty; struct player *plr0, *plr1, *pgiver; int capability; + int real_value; plr0=&game.players[packet->plrno0]; plr1=&game.players[packet->plrno1]; @@ -294,10 +295,13 @@ */ if(packet->clause_type == CLAUSE_CITY){ - struct city *pcity = find_city_by_id(packet->value); + struct city *pcity = find_city_by_orig_id(packet->value); if (pcity && !map_get_known_and_seen(pcity->x, pcity->y, plr1->player_no)) give_citymap_from_player_to_player(pcity, plr0, plr1); + real_value = pcity->id; } + else + real_value = packet->value; capability = 1; conn_list_iterate(plr0->connections, pconn) { @@ -318,7 +322,7 @@ } if((ptreaty=find_treaty(plr0, plr1))) { - if(add_clause(ptreaty, pgiver, packet->clause_type, packet->value)) { + if(add_clause(ptreaty, pgiver, packet->clause_type, real_value)) { lsend_packet_diplomacy_info(&plr0->connections, PACKET_DIPLOMACY_CREATE_CLAUSE, packet); @@ -427,7 +431,10 @@ packet.clause_type = pclause->type; packet.plrno_from = pclause->from->player_no; - packet.value = pclause->value; + if(pclause->type == CLAUSE_CITY) + packet.value = orig_city_id(pclause->value); + else + packet.value = pclause->value; send_packet_diplomacy_info(dest, PACKET_DIPLOMACY_CREATE_CLAUSE, &packet); diff server/savegame.c server/savegame.c --- server/savegame.c Mon Sep 25 17:35:44 2000 +++ server/savegame.c Mon Oct 16 12:10:18 2000 @@ -707,6 +707,9 @@ pcity->id=secfile_lookup_int(file, "player%d.c%d.id", plrno, i); alloc_id(pcity->id); idex_register_city(pcity); + pcity->orig_id= + secfile_lookup_int_default(file, pcity->id, "player%d.c%d.orig_id", + plrno, i); pcity->owner=plrno; pcity->x=secfile_lookup_int(file, "player%d.c%d.x", plrno, i); pcity->y=secfile_lookup_int(file, "player%d.c%d.y", plrno, i); @@ -1289,6 +1292,7 @@ i++; secfile_insert_int(file, pcity->id, "player%d.c%d.id", plrno, i); + secfile_insert_int(file, pcity->orig_id, "player%d.c%d.orig_id", plrno, i); secfile_insert_int(file, pcity->x, "player%d.c%d.x", plrno, i); secfile_insert_int(file, pcity->y, "player%d.c%d.y", plrno, i); secfile_insert_str(file, pcity->name, "player%d.c%d.name", plrno, i); diff server/unithand.c server/unithand.c --- server/unithand.c Mon Oct 16 10:38:32 2000 +++ server/unithand.c Tue Oct 17 11:31:03 2000 @@ -155,7 +155,7 @@ struct city *pcity; if(!(punit=player_find_unit_by_id(pplayer, packet->unit_id))) return; - if(!(pcity=find_city_by_id(packet->city_id))) return; + if(!(pcity=find_city_by_orig_id(packet->city_id))) return; if(punit->x!=pcity->x || punit->y!=pcity->y) { notify_player(pplayer, _("Game: Illegal move, unit not in city!")); @@ -190,7 +190,7 @@ struct packet_generic_integer *packet) { struct player *pplayer = pconn->player; - struct city *pcity=find_city_by_id(packet->value); + struct city *pcity=find_city_by_orig_id(packet->value); struct unit *punit=find_unit_by_id(packet->value); struct packet_generic_values req; @@ -223,7 +223,7 @@ { struct unit *pdiplomat=player_find_unit_by_id(pplayer, packet->diplomat_id); struct unit *pvictim=find_unit_by_id(packet->target_id); - struct city *pcity=find_city_by_id(packet->target_id); + struct city *pcity=find_city_by_orig_id(packet->target_id); if (!pdiplomat) return; if (!unit_flag(pdiplomat->type, F_DIPLOMAT)) @@ -306,20 +306,21 @@ struct unit *punit; if ((punit=player_find_unit_by_id(pplayer, req->unit_id))) { - struct city *pcity; - if ((pcity=player_find_city_by_id(pplayer, req->city_id)) - && pcity->owner == punit->owner) { - unit_list_insert(&pcity->units_supported, punit); - city_refresh(pcity); - send_city_info(pplayer, pcity); + struct city *new_homecity = 0; + struct city *old_homecity = 0; + if ((new_homecity=player_find_city_by_orig_id(pplayer, req->city_id)) + && new_homecity->owner == punit->owner) { + unit_list_insert(&new_homecity->units_supported, punit); + city_refresh(new_homecity); + send_city_info(pplayer, new_homecity); - if((pcity=player_find_city_by_id(pplayer, punit->homecity))) { - unit_list_unlink(&pcity->units_supported, punit); - city_refresh(pcity); - send_city_info(pplayer, pcity); + if((old_homecity=player_find_city_by_id(pplayer, punit->homecity))) { + unit_list_unlink(&old_homecity->units_supported, punit); + city_refresh(old_homecity); + send_city_info(pplayer, old_homecity); } - punit->homecity=req->city_id; + punit->homecity=new_homecity->id; send_unit_info(pplayer, punit); } } @@ -910,7 +911,7 @@ && punit->homecity) { struct packet_unit_request req; req.unit_id = punit->id; - req.city_id = pcity->id; + req.city_id = pcity->orig_id; req.name[0] = '\0'; return handle_unit_establish_trade(pplayer, &req); } @@ -940,7 +941,7 @@ /* if is_diplomat_action_available() then there must be a city or a unit */ if (pcity) { - packet.target_id = pcity->id; + packet.target_id = pcity->orig_id; } else if (pdefender) { packet.target_id = pdefender->id; } else { @@ -1129,7 +1130,7 @@ if (!punit || !unit_flag(punit->type, F_CARAVAN)) return; - pcity_dest = find_city_by_id(req->city_id); + pcity_dest = find_city_by_orig_id(req->city_id); if (!pcity_dest || !unit_can_help_build_wonder(punit, pcity_dest)) return; @@ -1176,7 +1177,7 @@ return 0; pcity_homecity=player_find_city_by_id(pplayer, punit->homecity); - pcity_dest=find_city_by_id(req->city_id); + pcity_dest=find_city_by_orig_id(req->city_id); if(!pcity_homecity || !pcity_dest) return 0; @@ -1489,7 +1490,7 @@ packet->owner = punit->owner; packet->x = punit->x; packet->y = punit->y; - packet->homecity = punit->homecity; + packet->homecity = orig_city_id(punit->homecity); packet->veteran = punit->veteran; packet->type = punit->type; packet->movesleft = punit->moves_left; @@ -1510,6 +1511,6 @@ packet->carried = carried; packet->select_it = select_it; packet->packet_use = packet_use; - packet->info_city_id = info_city_id; + packet->info_city_id = orig_city_id(info_city_id); packet->serial_num = serial_num; }