<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40760 >
> [matthias.pfaffer...@mapfa.de - Sa 11. Apr 2009, 23:45:40]: > > extend the gold upkeep system: > > 0 - old system > 1 - cities pay for buildings; the nation pays for units > 2 - the nation pays for buildings and units > > depends on ticket 40619, 40759 > > compile tested and also with a short game > the missing patch file ...
diff -ur freeciv-2.1.99svn15584.gold1//common/game.h freeciv-2.1.99svn15584.gold2//common/game.h --- freeciv-2.1.99svn15584.gold1//common/game.h 2009-03-23 20:47:57.000000000 +0100 +++ freeciv-2.1.99svn15584.gold2//common/game.h 2009-04-11 18:40:24.790630188 +0200 @@ -185,7 +185,7 @@ #define GAME_DEFAULT_GOLD_UPKEEP_STYLE 0 #define GAME_MIN_GOLD_UPKEEP_STYLE 0 -#define GAME_MAX_GOLD_UPKEEP_STYLE 1 +#define GAME_MAX_GOLD_UPKEEP_STYLE 2 #define GAME_DEFAULT_FOODBOX 100 #define GAME_MIN_FOODBOX 1 diff -ur freeciv-2.1.99svn15584.gold1//data/default/game.ruleset freeciv-2.1.99svn15584.gold2//data/default/game.ruleset --- freeciv-2.1.99svn15584.gold1//data/default/game.ruleset 2009-04-11 18:04:27.290128240 +0200 +++ freeciv-2.1.99svn15584.gold2//data/default/game.ruleset 2009-04-11 18:11:47.986126143 +0200 @@ -74,7 +74,13 @@ ; is negative, random buildings in the city are sold off. If the gold ; is still negative, then supported units with gold upkeep are ; disbanded. -; 1 - Gold upkeep for all buildings and units is paid in a lump sum after +; 1 - In the first step, the player's total gold must be non-negative after +; paying upkeep for all buildings within a city. If for any city the +; player's gold is negative, random buildings in the city are sold off. +; In the second step, gold upkeep for all units is paid in a lump sum. +; If the player does not have enough gold, random units with gold upkeep +; are disbanded. +; 2 - Gold upkeep for all buildings and units is paid in a lump sum after ; all cities have been processed. If the player does not have enough ; gold, random buildings from random cities are sold. If still more ; gold is needed, then random units with gold upkeep are disbanded. diff -ur freeciv-2.1.99svn15584.gold1//server/cityturn.c freeciv-2.1.99svn15584.gold2//server/cityturn.c --- freeciv-2.1.99svn15584.gold1//server/cityturn.c 2009-04-12 00:48:34.806125540 +0200 +++ freeciv-2.1.99svn15584.gold2//server/cityturn.c 2009-04-12 01:12:40.000000000 +0200 @@ -109,8 +109,10 @@ struct cityimpr_vector *imprs); static bool sell_random_units(struct player *pplayer, struct unitgold_vector *units); -static void city_balance_treasury(struct city *pcity); -static void player_balance_treasury(struct player *pplayer); +static bool city_balance_treasury_buildings(struct city *pcity); +static bool city_balance_treasury_units(struct city *pcity); +static bool player_balance_treasury_buildings(struct player *pplayer); +static bool player_balance_treasury_units(struct player *pplayer); static bool disband_city(struct city *pcity); @@ -468,7 +470,9 @@ * 'game.info.gold_upkeep_style': * 0 - Each city tries to balance its upkeep individually * (this is done in update_city_activity()). - * 1 - The nation as a whole balances the treasury. */ + * 1 - Each city tries to balance its upkeep for buildings individually; + * the upkeep for units is paid by the nation. + * 2 - The nation as a whole balances the treasury. */ /* Iterate over cities in a random order. */ while (i > 0) { @@ -477,8 +481,20 @@ cities[r] = cities[--i]; } - if (game.info.gold_upkeep_style == 1 && pplayer->economic.gold < 0) { - player_balance_treasury(pplayer); + if (pplayer->economic.gold < 0 && game.info.gold_upkeep_style > 0) { + switch (game.info.gold_upkeep_style) { + case 2: + /* nation pays for buildings and units */ + player_balance_treasury_buildings(pplayer); + /* no break */ + case 1: + /* nation pays for units */ + player_balance_treasury_units(pplayer); + break; + default: + /* fallthru */ + break; + } } /* Should not happen. */ @@ -1773,22 +1789,18 @@ } /************************************************************************** - Balance the gold of a nation by selling some random buildings. If this - does not help, then disband some units which need gold upkeep. + Balance the gold of a nation by selling some random buildings. **************************************************************************/ -static void player_balance_treasury(struct player *pplayer) +static bool player_balance_treasury_buildings(struct player *pplayer) { struct cityimpr_vector imprs; struct cityimpr ci; - struct unitgold_vector units; - struct unitgold ug; if (!pplayer) { - return; + return false; } cityimpr_vector_init(&imprs); - unitgold_vector_init(&units); city_list_iterate(pplayer->cities, pcity) { city_built_iterate(pcity, pimprove) { @@ -1800,10 +1812,31 @@ } city_built_iterate_end; } city_list_iterate_end; - if (sell_random_buildings(pplayer, &imprs)) { - goto CLEANUP; + if (!sell_random_buildings(pplayer, &imprs)) { + /* If we get here it means the player has + * negative gold. This should never happen. */ + die("Player cannot have negative gold."); } + cityimpr_vector_free(&imprs); + + return pplayer->economic.gold >= 0; +} + +/************************************************************************** + Balance the gold of a nation by selling some units which need gold upkeep. +**************************************************************************/ +static bool player_balance_treasury_units(struct player *pplayer) +{ + struct unitgold_vector units; + struct unitgold ug; + + if (!pplayer) { + return false; + } + + unitgold_vector_init(&units); + city_list_iterate(pplayer->cities, pcity) { unit_list_iterate(pcity->units_supported, punit) { if (punit->upkeep[O_GOLD] > 0) { @@ -1813,42 +1846,32 @@ } unit_list_iterate_end; } city_list_iterate_end; - if (sell_random_units(pplayer, &units)) { - goto CLEANUP; + if (!sell_random_units(pplayer, &units)) { + /* If we get here it means the player has + * negative gold. This should never happen. */ + die("Player cannot have negative gold."); } - /* If we get here it means the player has - * negative gold. This should never happen. */ - die("Player cannot have negative gold."); - -CLEANUP: - cityimpr_vector_free(&imprs); unitgold_vector_free(&units); + + return pplayer->economic.gold >= 0; } /************************************************************************** - Balance the gold of one city by randomly selling some buildings. If this - does not help, randomly disband some units which need gold upkeep. - - NB: This function adds the gold upkeep of disbanded units back to the - player's gold. Hence it assumes that this gold was previously taken - from the player (i.e. in update_city_activity()). + Balance the gold of one city by randomly selling some buildings. **************************************************************************/ -static void city_balance_treasury(struct city *pcity) +static bool city_balance_treasury_buildings(struct city *pcity) { struct player *pplayer; struct cityimpr_vector imprs; struct cityimpr ci; - struct unitgold_vector units; - struct unitgold ug; if (!pcity) { - return; + return true; } pplayer = city_owner(pcity); cityimpr_vector_init(&imprs); - unitgold_vector_init(&units); /* Create a vector of all buildings that can be sold. */ city_built_iterate(pcity, pimprove) { @@ -1860,10 +1883,37 @@ } city_built_iterate_end; /* Try to sell some buildings. */ - if (sell_random_buildings(pplayer, &imprs)) { - goto CLEANUP; + sell_random_buildings(pplayer, &imprs); + + /* If we get here the player has negative gold, but hopefully + * another city will be able to pay the deficit, so continue. */ + + cityimpr_vector_free(&imprs); + + return pplayer->economic.gold >= 0; +} + +/************************************************************************** + Balance the gold of one city by randomly selling some units which need + gold upkeep. + + NB: This function adds the gold upkeep of disbanded units back to the + player's gold. Hence it assumes that this gold was previously taken + from the player (i.e. in update_city_activity()). +**************************************************************************/ +static bool city_balance_treasury_units(struct city *pcity) +{ + struct player *pplayer; + struct unitgold_vector units; + struct unitgold ug; + + if (!pcity) { + return true; } + pplayer = city_owner(pcity); + unitgold_vector_init(&units); + /* Create a vector of all supported units with gold upkeep. */ unit_list_iterate(pcity->units_supported, punit) { if (punit->upkeep[O_GOLD] > 0) { @@ -1873,16 +1923,14 @@ } unit_list_iterate_end; /* Still not enough gold, so try "selling" some units. */ - if (sell_random_units(pplayer, &units)) { - goto CLEANUP; - } + sell_random_units(pplayer, &units); /* If we get here the player has negative gold, but hopefully * another city will be able to pay the deficit, so continue. */ -CLEANUP: - cityimpr_vector_free(&imprs); unitgold_vector_free(&units); + + return pplayer->economic.gold >= 0; } /************************************************************************** @@ -2096,10 +2144,17 @@ pplayer->economic.gold -= city_total_impr_gold_upkeep(pcity); pplayer->economic.gold -= city_total_unit_gold_upkeep(pcity); - if (game.info.gold_upkeep_style == 0 && pplayer->economic.gold < 0) { + if (pplayer->economic.gold < 0 && game.info.gold_upkeep_style < 2) { /* Not enough gold - we have to sell some buildings, and if that - * is not enough, disband units with gold upkeep. */ - city_balance_treasury(pcity); + * is not enough, disband units with gold upkeep, taking into + * account the setting of 'game.info.gold_upkeep_style': + * 0: cities pay for buildings and units + * 1: cities pay only for buildings; the nation pays for units + * 2: the nation pays for buildings and units */ + if (!city_balance_treasury_buildings(pcity) + && game.info.gold_upkeep_style == 0) { + city_balance_treasury_units(pcity); + } } if (city_unhappy(pcity)) {
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev