Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2005:
[Freeciv-Dev] (PR#12437) Some city.c changes
Home

[Freeciv-Dev] (PR#12437) Some city.c changes

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12437) Some city.c changes
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Sat, 5 Mar 2005 14:48:41 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12437 >

CHANGED:
 - Allow for more calls in the city refresh code that do not actually
change city state. This should be helpful for AI and CM stuff.
 - Subtle change in rules: A 'make happy' effect will never change a
citizen from unhappy to content, but may make unhappy to happy if there is
enough points in this effect. I feel this is correct, to properly
differentiate between 'make happy' and 'make content' effects.
 - Should be a tiny bit quicker (aborts earlier in one case).

  - Per

Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.315
diff -u -r1.315 city.c
--- common/city.c       26 Feb 2005 01:05:55 -0000      1.315
+++ common/city.c       5 Mar 2005 22:45:47 -0000
@@ -1787,7 +1787,8 @@
 /**************************************************************************
   Create content, unhappy and angry citizens.
 **************************************************************************/
-static void citizen_happy_size(struct city *pcity)
+static void citizen_base_mood(struct city *pcity, int *happy, int *content,
+                              int *unhappy, int *angry)
 {
   /* Number of specialists in city */
   int specialists = city_specialists(pcity);
@@ -1795,29 +1796,26 @@
   /* This is the number of citizens that may start out content, depending
    * on empire size and game's city unhappysize. This may be bigger than
    * the size of the city, since this is a potential. */
-  int content = content_citizens(city_owner(pcity));
+  int base_content = content_citizens(city_owner(pcity));
 
   /* Create content citizens. Take specialists from their ranks. */
-  pcity->ppl_content[0] = MAX(0, MIN(pcity->size, content) - specialists);
+  *content = MAX(0, MIN(pcity->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.angrycitizen == FALSE) {
-    pcity->ppl_angry[0] = 0;
+    *angry = 0;
   } else {
-    pcity->ppl_angry[0] = MIN(MAX(0, -content), pcity->size - specialists);
+    *angry = MIN(MAX(0, -base_content), pcity->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. */
-  pcity->ppl_unhappy[0] = (pcity->size 
-                           - specialists 
-                           - pcity->ppl_content[0] 
-                           - pcity->ppl_angry[0]);
+  *unhappy = (pcity->size - specialists - *content - *angry);
 
   /* No one is born happy. */
-  pcity->ppl_happy[0] = 0;
+  *happy = 0;
 }
 
 /**************************************************************************
@@ -1873,23 +1871,21 @@
 /**************************************************************************
   Make citizens content due to city improvements.
 **************************************************************************/
-static inline void citizen_content_buildings(struct city *pcity)
+static inline void citizen_content_buildings(struct city *pcity, int *content,
+                                             int *unhappy, int *angry)
 {
-  int faces = 0;
-  happy_copy(pcity, 1);
-
-  faces += get_city_bonus(pcity, EFT_MAKE_CONTENT);
+  int faces = get_city_bonus(pcity, EFT_MAKE_CONTENT);
 
   /* make people content (but not happy):
      get rid of angry first, then make unhappy content. */
-  while (faces > 0 && pcity->ppl_angry[2] > 0) {
-    pcity->ppl_angry[2]--;
-    pcity->ppl_unhappy[2]++;
+  while (faces > 0 && *angry > 0) {
+    (*angry)--;
+    (*unhappy)++;
     faces--;
   }
-  while (faces > 0 && pcity->ppl_unhappy[2] > 0) {
-    pcity->ppl_unhappy[2]--;
-    pcity->ppl_content[2]++;
+  while (faces > 0 && *unhappy > 0) {
+    (*unhappy)--;
+    (*content)++;
     faces--;
   }
 }
@@ -1900,80 +1896,96 @@
   This function requires that pcity->martial_law and
   pcity->unit_happy_cost have already been set in city_support.
 **************************************************************************/
-static inline void citizen_happy_units(struct city *pcity)
+static inline void citizen_happy_units(struct city *pcity, int *happy,
+                                       int *content, int *unhappy,
+                                       int *angry)
 {
-  int amt;
-
-  happy_copy(pcity, 2);
+  int amt = pcity->martial_law;
 
   /* Pacify discontent citizens through martial law.  First convert
    * angry->unhappy and then unhappy->content. */
-  amt = pcity->martial_law;
-  amt -= make_citizens_happy(&pcity->ppl_angry[3], &pcity->ppl_unhappy[3],
-                            amt);
-  amt -= make_citizens_happy(&pcity->ppl_unhappy[3], &pcity->ppl_content[3],
-                            amt);
-  /* Any remaining martial law is unused. */
+  while (amt > 0 && *angry > 0) {
+    (*angry)--;
+    (*unhappy)++;
+    amt--;
+  }
+  while (amt > 0 && *unhappy > 0) {
+    (*unhappy)--;
+    (*content)++;
+    amt--;
+  }
 
   /* Now make citizens unhappier because of military units away from home.
    * First make content people unhappy, then happy people unhappy,
    * then happy people content. */
   amt = pcity->unit_happy_upkeep;
-  amt -= make_citizens_happy(&pcity->ppl_content[3], &pcity->ppl_unhappy[3],
-                            amt);
-  amt -= 2 * make_citizens_happy(&pcity->ppl_happy[3], &pcity->ppl_unhappy[3],
-                                amt / 2);
-  amt -= make_citizens_happy(&pcity->ppl_happy[3], &pcity->ppl_content[3],
-                            amt);
+  while (amt > 0 && *content > 0) {
+    (*content)--;
+    (*unhappy)++;
+    amt--;
+  }
+  while (amt > 1 && *happy > 0) {
+    (*happy)--;
+    (*unhappy)++;
+    amt -= 2;
+  }
+  while (amt > 0 && *content > 0) {
+    (*content)--;
+    (*unhappy)++;
+    amt--;
+  }
   /* Any remaining unhappiness is lost since angry citizens aren't created
    * here. */
+  /* FIXME: Why not? - Per */
 }
 
 /**************************************************************************
   Make citizens happy due to wonders.
 **************************************************************************/
-static inline void citizen_happy_wonders(struct city *pcity)
-{
-  int bonus = 0, mod;
-
-  happy_copy(pcity, 3);
-
-  if ((mod = get_city_bonus(pcity, EFT_MAKE_HAPPY)) > 0) {
-    bonus += mod;
-
-    while (bonus > 0 && pcity->ppl_content[4] > 0) {
-      pcity->ppl_content[4]--;
-      pcity->ppl_happy[4]++;
-      bonus--;
-      /* well i'm not sure what to do with the rest, 
-         will let it make unhappy content */
-    }
+static inline void citizen_happy_wonders(struct city *pcity, int *happy,
+                                         int *content, int *unhappy, 
+                                         int *angry)
+{
+  int bonus = get_city_bonus(pcity, EFT_MAKE_HAPPY);
+
+  /* First create happy citizens from content then from unhappy
+   * citizens; we cannot help angry citizens here. */
+  while (bonus > 0 && *content > 0) {
+    (*content)--;
+    (*happy)++;
+    bonus--;
+  }
+  while (bonus > 1 && *unhappy > 0) {
+    (*unhappy)--;
+    (*happy)++;
+    bonus -= 2;
+  }
+  /* Remaining is wasted; allowing it to make content from
+   * unhappy would wash away the distinction between make
+   * happy and make content, which is the very reason we
+   * do not just pool it all into luxuries. */
+
+  if (get_city_bonus(pcity, EFT_NO_UNHAPPY) > 0
+      || government_has_flag(get_gov_pcity(pcity), G_NO_UNHAPPY_CITIZENS)) {
+    *content += *unhappy + *angry;
+    *unhappy = 0;
+    *angry = 0;
+    return;
   }
 
-  bonus += get_city_bonus(pcity, EFT_FORCE_CONTENT);
+  bonus = get_city_bonus(pcity, EFT_FORCE_CONTENT);
 
   /* get rid of angry first, then make unhappy content */
-  while (bonus > 0 && pcity->ppl_angry[4] > 0) {
-    pcity->ppl_angry[4]--;
-    pcity->ppl_unhappy[4]++;
+  while (bonus > 0 && *angry > 0) {
+    (*angry)--;
+    (*unhappy)++;
     bonus--;
   }
-  while (bonus > 0 && pcity->ppl_unhappy[4] > 0) {
-    pcity->ppl_unhappy[4]--;
-    pcity->ppl_content[4]++;
+  while (bonus > 0 && *unhappy > 0) {
+    (*unhappy)--;
+    (*content)++;
     bonus--;
   }
-
-  if (get_city_bonus(pcity, EFT_NO_UNHAPPY) > 0) {
-    pcity->ppl_content[4] += pcity->ppl_unhappy[4] + pcity->ppl_angry[4];
-    pcity->ppl_unhappy[4] = 0;
-    pcity->ppl_angry[4] = 0;
-  }
-  if (government_has_flag(get_gov_pcity(pcity), G_NO_UNHAPPY_CITIZENS)) {
-    pcity->ppl_content[4] += pcity->ppl_unhappy[4] + pcity->ppl_angry[4];
-    pcity->ppl_unhappy[4] = 0;
-    pcity->ppl_angry[4] = 0;
-  }
 }
 
 /**************************************************************************
@@ -2237,12 +2249,23 @@
   }
   get_citizen_output(pcity, pcity->citizen_base); /* Calculate output from 
citizens. */
   set_city_production(pcity);
-  citizen_happy_size(pcity);
+  citizen_base_mood(pcity, &pcity->ppl_happy[0], &pcity->ppl_content[0],
+                    &pcity->ppl_unhappy[0], &pcity->ppl_angry[0]);
   pcity->pollution = city_pollution(pcity, pcity->prod[O_SHIELD]);
   citizen_happy_luxury(pcity); /* with our new found luxuries */
-  citizen_content_buildings(pcity);    /* temple cathedral colosseum */
-  citizen_happy_units(pcity); /* Martial law & unrest from units */
-  citizen_happy_wonders(pcity);        /* happy wonders & fundamentalism */
+  happy_copy(pcity, 1);
+  citizen_content_buildings(pcity, &pcity->ppl_content[2], 
+                            &pcity->ppl_unhappy[2], &pcity->ppl_angry[2]);
+  happy_copy(pcity, 2);
+  /* Martial law & unrest from units */
+  citizen_happy_units(pcity, &pcity->ppl_happy[3],
+                      &pcity->ppl_content[3], &pcity->ppl_unhappy[3], 
+                      &pcity->ppl_angry[3]);
+  happy_copy(pcity, 3);
+  /* Building (including wonder) happiness effects */
+  citizen_happy_wonders(pcity, &pcity->ppl_happy[4],
+                      &pcity->ppl_content[4], &pcity->ppl_unhappy[4],
+                      &pcity->ppl_angry[4]);
   unhappy_city_check(pcity);
   set_surpluses(pcity);
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12437) Some city.c changes, Per I. Mathisen <=