Author: jtn
Date: Fri Aug  7 00:54:31 2015
New Revision: 29371

URL: http://svn.gna.org/viewcvs/freeciv?rev=29371&view=rev
Log:
Ensure angry citizens appear if enabled in ruleset.
They were accidentally disabled in 2.4.

See gna bug #23743.

Modified:
    trunk/common/aicore/cm.c
    trunk/common/city.c
    trunk/common/city.h
    trunk/server/citytools.c

Modified: trunk/common/aicore/cm.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/aicore/cm.c?rev=29371&r1=29370&r2=29371&view=diff
==============================================================================
--- trunk/common/aicore/cm.c    (original)
+++ trunk/common/aicore/cm.c    Fri Aug  7 00:54:31 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: trunk/common/city.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/city.c?rev=29371&r1=29370&r2=29371&view=diff
==============================================================================
--- trunk/common/city.c (original)
+++ trunk/common/city.c Fri Aug  7 00:54:31 2015
@@ -1887,9 +1887,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);
@@ -1898,7 +1900,7 @@
 
   if (basis + step <= 0) {
     /* Value of zero means effect is inactive */
-    return CLIP(0, content, MAX_CITY_SIZE);
+    return content;
   }
 
   if (cities > basis) {
@@ -1909,7 +1911,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);
+  }
 }
 
 /**************************************************************************
@@ -2148,22 +2176,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: trunk/common/city.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/city.h?rev=29371&r1=29370&r2=29371&view=diff
==============================================================================
--- trunk/common/city.h (original)
+++ trunk/common/city.h Fri Aug  7 00:54:31 2015
@@ -530,6 +530,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: trunk/server/citytools.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/citytools.c?rev=29371&r1=29370&r2=29371&view=diff
==============================================================================
--- trunk/server/citytools.c    (original)
+++ trunk/server/citytools.c    Fri Aug  7 00:54:31 2015
@@ -1018,6 +1018,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);
@@ -1293,10 +1295,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);
   }
 
@@ -1399,6 +1403,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);
 
@@ -1498,7 +1503,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);
@@ -1552,6 +1558,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;
 
@@ -1759,7 +1766,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

Reply via email to