Author: jtn Date: Fri Aug 7 01:04:41 2015 New Revision: 29373 URL: http://svn.gna.org/viewcvs/freeciv?rev=29373&view=rev Log: Ensure angry citizens appear if enabled in ruleset. They were accidentally disabled in 2.4.
See gna bug #23743. Modified: branches/S2_6/common/aicore/cm.c branches/S2_6/common/city.c branches/S2_6/common/city.h branches/S2_6/server/citytools.c Modified: branches/S2_6/common/aicore/cm.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/aicore/cm.c?rev=29373&r1=29372&r2=29373&view=diff ============================================================================== --- branches/S2_6/common/aicore/cm.c (original) +++ branches/S2_6/common/aicore/cm.c Fri Aug 7 01:04:41 2015 @@ -755,8 +755,17 @@ /* if this solution is not content, we have an estimate on min. luxuries */ if (disorder) { - /* we have to consider the influence of specialists making one unhappy - citizen content (because all other citizens are already unhappy) */ + /* We have to consider the influence of each specialist in this + solution possibly 'hiding' a potential unhappy citizen who + could require luxuries. + Since we know the city is in disorder, we can discount most + effects that make citizens content, since they clearly weren't + sufficient. + This may not be sufficient luxury to make the city content (due + to military unhappiness etc), but certainly no less will do. + (Specialists may also be making angry citizens content, requiring + additional luxuries, but we don't try to consider that here; this + just means we might explore some solutions unnecessarily.) */ state->min_luxury = surplus[O_LUXURY] + game.info.happy_cost*MAX( city_specialists(pcity) - player_content_citizens(city_owner(pcity)), 0) + 1; @@ -1619,9 +1628,16 @@ } } output_type_iterate_end; - /* if we don't get the city content, we assume using every idle worker - as specialist and the maximum producible luxury already computed - see also evaluate_solution, where min_luxury is set */ + /* If we don't get the city content, we assume using every idle worker + as specialist and the maximum producible luxury already computed. + If this is less than the amount of luxury we calculated in + evaluate_solution() (where min_luxury is set), when we observed the + city in disorder, then this is clearly not worth pursuing. + (Since we're comparing to evaluate_solution()'s calculation, we + don't need to take effects, angry citizens etc into account here + either.) + FIXME: this heuristic will break in rulesets where specialists can + influence happiness other than by direct production of luxury. */ int max_luxury = production[O_LUXURY] + game.info.happy_cost*MAX( specialists_in_solution(state, &state->current) + state->current.idle - player_content_citizens(city_owner(state->pcity)), 0); Modified: branches/S2_6/common/city.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/city.c?rev=29373&r1=29372&r2=29373&view=diff ============================================================================== --- branches/S2_6/common/city.c (original) +++ branches/S2_6/common/city.c Fri Aug 7 01:04:41 2015 @@ -1882,9 +1882,11 @@ } /**************************************************************************** - Give base number of content citizens in any city owner by pplayer. + Give base happiness in any city owned by pplayer. + A positive number is a number of content citizens. A negative number is + a number of angry citizens (a city never starts with both). ****************************************************************************/ -citizens player_content_citizens(const struct player *pplayer) +static int player_base_citizen_happiness(const struct player *pplayer) { int cities = city_list_size(pplayer->cities); int content = get_player_bonus(pplayer, EFT_CITY_UNHAPPY_SIZE); @@ -1893,7 +1895,7 @@ if (basis + step <= 0) { /* Value of zero means effect is inactive */ - return CLIP(0, content, MAX_CITY_SIZE); + return content; } if (cities > basis) { @@ -1904,7 +1906,33 @@ content -= (cities - basis - 1) / step; } } + return content; +} + +/**************************************************************************** + Give base number of content citizens in any city owned by pplayer. +****************************************************************************/ +citizens player_content_citizens(const struct player *pplayer) +{ + int content = player_base_citizen_happiness(pplayer); + return CLIP(0, content, MAX_CITY_SIZE); +} + +/**************************************************************************** + Give base number of angry citizens in any city owned by pplayer. +****************************************************************************/ +citizens player_angry_citizens(const struct player *pplayer) +{ + if (!game.info.angrycitizen) { + return 0; + } else { + /* Create angry citizens only if we have a negative number of possible + * content citizens. This can happen when empires grow really big. */ + int content = player_base_citizen_happiness(pplayer); + + return CLIP(0, -content, MAX_CITY_SIZE); + } } /************************************************************************** @@ -2143,22 +2171,21 @@ * on empire size and game's city unhappysize. This may be bigger than * the size of the city, since this is a potential. */ citizens base_content = player_content_citizens(pplayer); + /* Similarly, this is the potential number of angry citizens. */ + citizens base_angry = player_angry_citizens(pplayer); /* Create content citizens. Take specialists from their ranks. */ *content = MAX(0, MIN(size, base_content) - specialists); - /* Create angry citizens only if we have a negative number of possible - * content citizens. This happens when empires grow really big. */ - if (game.info.angrycitizen == FALSE) { - *angry = 0; - } else { - *angry = MIN(MAX(0, -base_content), size - specialists); - } + /* Create angry citizens. Specialists never become angry. */ + fc_assert_action(base_content == 0 || base_angry == 0, *content = 0); + *angry = MIN(base_angry, size - specialists); /* Create unhappy citizens. In the beginning, all who are not content, * specialists or angry are unhappy. This is changed by luxuries and * buildings later. */ *unhappy = (size - specialists - *content - *angry); + fc_assert_action(*unhappy >= 0, *unhappy = 0); /* No one is born happy. */ *happy = 0; Modified: branches/S2_6/common/city.h URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/city.h?rev=29373&r1=29372&r2=29373&view=diff ============================================================================== --- branches/S2_6/common/city.h (original) +++ branches/S2_6/common/city.h Fri Aug 7 01:04:41 2015 @@ -529,6 +529,7 @@ citizens city_specialists(const struct city *pcity); citizens player_content_citizens(const struct player *pplayer); +citizens player_angry_citizens(const struct player *pplayer); int city_population(const struct city *pcity); int city_total_impr_gold_upkeep(const struct city *pcity); Modified: branches/S2_6/server/citytools.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_6/server/citytools.c?rev=29373&r1=29372&r2=29373&view=diff ============================================================================== --- branches/S2_6/server/citytools.c (original) +++ branches/S2_6/server/citytools.c Fri Aug 7 01:04:41 2015 @@ -1012,6 +1012,8 @@ bool had_great_wonders = FALSE; const citizens old_taker_content_citizens = player_content_citizens(ptaker); const citizens old_giver_content_citizens = player_content_citizens(pgiver); + const citizens old_taker_angry_citizens = player_angry_citizens(ptaker); + const citizens old_giver_angry_citizens = player_angry_citizens(pgiver); bool taker_had_no_cities = (city_list_size(ptaker->cities) == 0); bool new_extras; const int units_num = unit_list_size(pcenter->units); @@ -1287,10 +1289,12 @@ /* We may cross the EFT_EMPIRE_SIZE_* effects, then we will have to * refresh all cities for the player. */ - if (old_taker_content_citizens != player_content_citizens(ptaker)) { + if (old_taker_content_citizens != player_content_citizens(ptaker) + || old_taker_angry_citizens != player_angry_citizens(ptaker)) { city_refresh_for_player(ptaker); } - if (old_giver_content_citizens != player_content_citizens(pgiver)) { + if (old_giver_content_citizens != player_content_citizens(pgiver) + || old_giver_angry_citizens != player_angry_citizens(pgiver)) { city_refresh_for_player(pgiver); } @@ -1393,6 +1397,7 @@ struct city *pwork = tile_worked(ptile); struct city *pcity; const citizens old_content_citizens = player_content_citizens(pplayer); + const citizens old_angry_citizens = player_angry_citizens(pplayer); log_debug("create_city() %s", name); @@ -1492,7 +1497,8 @@ update_tile_knowledge(ptile); - if (old_content_citizens != player_content_citizens(pplayer)) { + if (old_content_citizens != player_content_citizens(pplayer) + || old_angry_citizens != player_angry_citizens(pplayer)) { /* We crossed the EFT_EMPIRE_SIZE_* effects, we have to refresh all * cities for the player. */ city_refresh_for_player(pplayer); @@ -1546,6 +1552,7 @@ int id = pcity->id; /* We need this even after memory has been freed */ bool had_great_wonders = FALSE; const citizens old_content_citizens = player_content_citizens(powner); + const citizens old_angry_citizens = player_angry_citizens(powner); struct dbv tile_processed; struct tile_list *process_queue; @@ -1753,7 +1760,8 @@ send_player_info_c(powner, NULL); } - if (old_content_citizens != player_content_citizens(powner)) { + if (old_content_citizens != player_content_citizens(powner) + || old_angry_citizens != player_angry_citizens(powner)) { /* We crossed the EFT_EMPIRE_SIZE_* effects, we have to refresh all * cities for the player. */ city_refresh_for_player(powner); _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits