diff -Nur -Xpatches/no.freeciv freeciv/common/city.h my_freeciv/common/city.h --- freeciv/common/city.h Thu May 17 22:58:03 2001 +++ my_freeciv/common/city.h Fri May 18 13:24:42 2001 @@ -185,6 +185,10 @@ /* the people */ int size; + /* index indicating the order in which the city is founded/aquired by + the current owner, used for (un)happiness calculations. */ + int id_by_owner; + /* How the citizens feel: ppl_*[0] is distribution before any of the modifiers below. ppl_*[1] is distribution after luxury. diff -Nur -Xpatches/no.freeciv freeciv/server/citytools.c my_freeciv/server/citytools.c --- freeciv/server/citytools.c Wed May 16 18:19:15 2001 +++ my_freeciv/server/citytools.c Fri May 18 14:06:37 2001 @@ -140,19 +140,29 @@ } /************************************************************************** -v 1.0j code was too rash, only first penalty now! +Unhappiness due to civ size is no longer applied across the board, +but instead on a city by city basis. Only cities that are above the +penalty threshold are affected, according to the order in which they +are founded/aquired. Since currently this is taken as the order in +which they are inserted into a player's city list, a lost city retaken +will be treated as a new city for this particular purpose. A newly +founded or conquered city will have the correct index at that time +(see create_city() and transfer_city()), but changes due to cities +lost are not reflected until the start of next turn (see cityturn.c : +update_city_activities()). Suggestions for a better implementation +are welcome. -- Jing **************************************************************************/ -int content_citizens(struct player *pplayer) +int content_citizens(struct city *pcity) { - int cities = city_list_size(&pplayer->cities); + int id = pcity->id_by_owner; int content = game.unhappysize; - int basis = game.cityfactor + get_gov_pplayer(pplayer)->empire_size_mod; - int step = get_gov_pplayer(pplayer)->empire_size_inc; + int basis = game.cityfactor + get_gov_pcity(pcity)->empire_size_mod; + int step = get_gov_pcity(pcity)->empire_size_inc; - if (cities > basis) { + if (id > basis) { content--; if (step) - content -= (cities - basis - 1) / step; + content -= (id - basis - 1) / step; /* the first penalty is at (basis + 1) cities; the next is at (basis + step + 1), _not_ (basis + step) */ } @@ -869,6 +879,9 @@ pcity->owner = ptaker->player_no; city_list_insert(&ptaker->cities, pcity); + /* update city index for the taker */ + pcity->id_by_owner=city_list_size(&ptaker->cities); + give_citymap_from_player_to_player(pcity, pgiver, ptaker); map_unfog_city_area(pcity); @@ -982,6 +995,8 @@ pcity->y=y; sz_strlcpy(pcity->name, name); pcity->size=1; + /* this one is not yet in the list */ + pcity->id_by_owner=city_list_size(&pplayer->cities)+1; pcity->ppl_elvis=1; pcity->ppl_scientist=pcity->ppl_taxman=0; pcity->ppl_happy[4]=0; diff -Nur -Xpatches/no.freeciv freeciv/server/citytools.h my_freeciv/server/citytools.h --- freeciv/server/citytools.h Wed May 16 18:19:15 2001 +++ my_freeciv/server/citytools.h Thu May 17 23:15:16 2001 @@ -32,7 +32,7 @@ int can_sell_building(struct city *pcity, int id); struct city *find_city_wonder(Impr_Type_id id); int city_specialists(struct city *pcity); /* elv+tax+scie */ -int content_citizens(struct player *pplayer); +int content_citizens(struct city *pcity); int get_temple_power(struct city *pcity); int get_cathedral_power(struct city *pcity); int get_colosseum_power(struct city *pcity); diff -Nur -Xpatches/no.freeciv freeciv/server/cityturn.c my_freeciv/server/cityturn.c --- freeciv/server/cityturn.c Thu May 17 22:58:03 2001 +++ my_freeciv/server/cityturn.c Fri May 18 01:38:15 2001 @@ -167,7 +167,7 @@ int workers, tmp; workers = pcity->size - city_specialists(pcity); - tmp = content_citizens(&game.players[pcity->owner]); + tmp = content_citizens(pcity); /* leftover unhappiness is no longer discarded, but saved in ppl_residue[i] instead. */ pcity->ppl_residue[0] = MAX(0, -tmp); @@ -866,10 +866,13 @@ void update_city_activities(struct player *pplayer) { int gold; + int id; + id=city_list_size(&pplayer->cities); gold=pplayer->economic.gold; pplayer->got_tech=0; city_list_iterate(pplayer->cities, pcity) update_city_activity(pplayer, pcity); + pcity->id_by_owner = id--; city_list_iterate_end; pplayer->ai.prev_gold = gold; if (gold-(gold-pplayer->economic.gold)*3<0) {