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

> [book - Mi 11. Feb 2009, 00:32:07]:
> 
> It might be better to do this with effects, but it would
> probably further complicate the functions that calculate
> unit upkeep (maybe the upkeep values should only be calculated
> once at the start of each turn and stored with the unit?).

I tried to implement this:

- calculate upkeep for all units at the beginning of the turn
- save the upkeep values in the unit struct
- use the saved value

At the moment the patch does not compile. I don't find the reason for 
the following error:

[ ... ]
Making all in aicore
make[4]: Entering directory 
`/home/matthias/data/freeciv/freeciv-2.1.99svn15470-unit_upkeep/common/aicore'
/bin/sh ../../libtool --preserve-dup-deps --tag=CC   --mode=compile 
gcc -DHAVE_CONFIG_H -I. -I../..  -I../../utility -I.. -I../../common 
-DLOCALEDIR="\"/usr/local/share/locale\"" 
-DDEFAULT_DATA_PATH="\".:data:~/.freeciv:/usr/local/share/freeciv\""  -Wall 
-Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -g -O2 
-MTaisupport.lo -MD -MP -MF .deps/aisupport.Tpo -c -o 
aisupport.lo aisupport.c
libtool: compile:  
gcc -DHAVE_CONFIG_H -I. -I../.. -I../../utility -I.. -I../../common 
-DLOCALEDIR=\"/usr/local/share/locale\" 
"-DDEFAULT_DATA_PATH=\".:data:~/.freeciv:/usr/local/share/freeciv\"" -Wall 
-Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -g -O2 
-MT 
aisupport.lo -MD -MP -MF .deps/aisupport.Tpo -c aisupport.c -o 
aisupport.o
In file included from ../unitlist.h:18,
                 from ../city.h:19,
                 from aisupport.c:18:
../unit.h:146: error: ‘num_output_types’ undeclared here (not in a 
function)
make[4]: *** [aisupport.lo] Error 1
make[4]: Leaving directory 
`/home/matthias/data/freeciv/freeciv-2.1.99svn15470-unit_upkeep/common/aicore'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory 
`/home/matthias/data/freeciv/freeciv-2.1.99svn15470-unit_upkeep/common'
make[2]: *** [all] Error 2
make[2]: Leaving directory 
`/home/matthias/data/freeciv/freeciv-2.1.99svn15470-unit_upkeep/common'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory 
`/home/matthias/data/freeciv/freeciv-2.1.99svn15470-unit_upkeep'
make: *** [all] Error 2

I tried to add 

#include "city.h"              /* O_COUNT */

to unit.h and unit.c but it does not help :-(
 
> I would also note that gold and shield upkeep behaviour is
> not as symmetric as it might seem. For example, it doesn't
> make sense for shield upkeep to be paid by the nation as
> a whole (i.e. there is no "shield treasury"), and the
> current way gold_upkeep_style=0 is handled doesn't really
> make sense either (i.e. why do individual cities get
> penalized for the global treasury being negative? They
> should have their own "city treasuries" I suppose...). I
> wonder if this last behaviour was present in civ2 as well,
> or if it is just due to the implementation in freeciv.
> 
> 
> -----------------------------------------------------------------------
> 国庫を略奪するつもりだ。
> 

diff -ur freeciv-2.1.99svn15470-gold_upkeep//common/unit.c freeciv-2.1.99svn15470-unit_upkeep//common/unit.c
--- freeciv-2.1.99svn15470-gold_upkeep//common/unit.c	2009-01-23 18:28:24.000000000 +0100
+++ freeciv-2.1.99svn15470-unit_upkeep//common/unit.c	2009-02-11 22:11:41.000000000 +0100
@@ -33,6 +33,7 @@
 #include "tech.h"
 #include "unit.h"
 #include "unitlist.h"
+#include "city.h"		/* O_COUNT */
 
 
 /**************************************************************************
@@ -1369,9 +1370,12 @@
   if (pcity) {
     punit->tile = pcity->tile;
     punit->homecity = pcity->id;
+    punit->upkeep = punittype->upkeep;
   } else {
     punit->tile = NULL;
     punit->homecity = IDENTITY_NUMBER_ZERO;
+    /* no upkeep */
+    memset(punit->upkeep, 0, O_COUNT * sizeof(*punit->upkeep));
   }
   punit->goto_tile = NULL;
   punit->veteran = veteran_level;
diff -ur freeciv-2.1.99svn15470-gold_upkeep//common/unit.h freeciv-2.1.99svn15470-unit_upkeep//common/unit.h
--- freeciv-2.1.99svn15470-gold_upkeep//common/unit.h	2009-01-05 11:54:25.000000000 +0100
+++ freeciv-2.1.99svn15470-unit_upkeep//common/unit.h	2009-02-11 22:06:26.000000000 +0100
@@ -18,6 +18,7 @@
 #include "terrain.h"		/* enum tile_special_type */
 #include "unittype.h"
 #include "vision.h"
+#include "city.h"		/* O_COUNT */
 
 #define BARBARIAN_LIFE    5
 
@@ -142,6 +143,7 @@
   struct player *owner; /* Cannot be NULL. */
   int id;
   int homecity;
+  int upkeep[O_COUNT]; /* unit upkeep with regards to the homecity */
 
   int moves_left;
   int hp;
diff -ur freeciv-2.1.99svn15470-gold_upkeep//server/cityturn.c freeciv-2.1.99svn15470-unit_upkeep//server/cityturn.c
--- freeciv-2.1.99svn15470-gold_upkeep//server/cityturn.c	2009-02-11 20:53:36.000000000 +0100
+++ freeciv-2.1.99svn15470-unit_upkeep//server/cityturn.c	2009-02-11 21:53:29.000000000 +0100
@@ -93,10 +93,9 @@
 #define SPECVEC_TYPE struct cityimpr
 #include "specvec.h"
 
-/* Helper struct for storing a unit with its gold upkeep. */
+/* Helper struct for storing all units with gold upkeep. */
 struct unitgold {
   struct unit *punit;
-  int gold_upkeep;
 };
 
 #define SPECVEC_TAG unitgold
@@ -117,6 +116,7 @@
 static void define_orig_production_values(struct city *pcity);
 static void update_city_activity(struct city *pcity);
 static void nullify_caravan_and_disband_plus(struct city *pcity);
+static void calc_city_units_upkeep(const struct city *pcity);
 
 /**************************************************************************
 ...
@@ -457,6 +457,7 @@
 
     city_list_iterate(pplayer->cities, pcity) {
       cities[i++] = pcity;
+      calc_city_units_upkeep(pcity);
     } city_list_iterate_end;
 
     /* How gold upkeep is handled depends on the setting
@@ -497,6 +498,37 @@
 }
 
 /**************************************************************************
+  Update upkeep needed for all units supported by the city
+**************************************************************************/
+static void calc_city_units_upkeep(const struct city *pcity)
+{
+  int free[O_COUNT], upkeep[O_COUNT];
+
+  if (!pcity || !pcity->units_supported
+      || unit_list_size(pcity->units_supported) < 1) {
+    return;
+  }
+
+  memset(free, 0, O_COUNT * sizeof(*free));
+  output_type_iterate(o) {
+    free[o] = get_city_output_bonus(pcity, o,
+                                    EFT_UNIT_UPKEEP_FREE_PER_CITY);
+  }
+
+  unit_list_iterate(pcity->units_supported, punit) {
+    city_unit_upkeep(punit, upkeep, free);
+    /* here some function to change the upkeep from shields to gold
+     * depending on science and/or government could be added
+     * example (or within the bonus system? How to do this?):
+     * for 'gold_upkeep_style'=2 or capitalisation researched
+     * upkeep[O_GOLD] += upkeep[O_SHIELD]*price_shield;
+     * upkeep[O_SHIELD] = 0;
+     * with 'price_shield' a ruleset option (default to 1) */
+    punit->upkeep = upkeep;
+  } unit_list_iterate_end;
+}
+
+/**************************************************************************
   Reduce the city specialists by some (positive) value.
   Return the amount of reduction.
 **************************************************************************/
@@ -1645,20 +1677,14 @@
 static int city_total_unit_gold_upkeep(const struct city *pcity)
 {
   int gold_needed = 0;
-  int free[O_COUNT], upkeep[O_COUNT];
 
   if (!pcity || !pcity->units_supported
       || unit_list_size(pcity->units_supported) < 1) {
     return 0;
   }
 
-  memset(free, 0, O_COUNT * sizeof(*free));
-  free[O_GOLD] = get_city_output_bonus(pcity, get_output_type(O_GOLD),
-                                       EFT_UNIT_UPKEEP_FREE_PER_CITY);
-
   unit_list_iterate(pcity->units_supported, punit) {
-    city_unit_upkeep(punit, upkeep, free);
-    gold_needed += upkeep[O_GOLD];
+    gold_needed += punit->upkeep[O_GOLD];
   } unit_list_iterate_end;
 
   return gold_needed;
@@ -1730,7 +1756,7 @@
   while (pplayer->economic.gold < 0 && n > 0) {
     r = myrand(n);
     punit = units->p[r].punit;
-    gold_upkeep = units->p[r].gold_upkeep;
+    gold_upkeep = punit->upkeep[O_GOLD];
 
     notify_player(pplayer, unit_tile(punit), E_UNIT_LOST_MISC,
                   _("Not enough gold. %s disbanded"),
@@ -1755,8 +1781,6 @@
   struct cityimpr_vector imprs;
   struct cityimpr ci;
   struct unitgold_vector units;
-  struct unitgold ug;
-  int free[O_COUNT], upkeep[O_COUNT];
 
   if (!pplayer) {
     return;
@@ -1779,17 +1803,10 @@
     goto CLEANUP;
   }
 
-  memset(free, 0, O_COUNT * sizeof(*free));
-
   city_list_iterate(pplayer->cities, pcity) {
-    free[O_GOLD] = get_city_output_bonus(pcity, get_output_type(O_GOLD),
-                                         EFT_UNIT_UPKEEP_FREE_PER_CITY);
     unit_list_iterate(pcity->units_supported, punit) {
-      city_unit_upkeep(punit, upkeep, free);
-      if (upkeep[O_GOLD] > 0) {
-        ug.punit = punit;
-        ug.gold_upkeep = upkeep[O_GOLD];
-        unitgold_vector_append(&units, &ug);
+      if (punit->upkeep[O_GOLD] > 0) {
+        unitgold_vector_append(&units, &punit);
       }
     } unit_list_iterate_end;
   } city_list_iterate_end;
@@ -1821,8 +1838,6 @@
   struct cityimpr_vector imprs;
   struct cityimpr ci;
   struct unitgold_vector units;
-  struct unitgold ug;
-  int free[O_COUNT], upkeep[O_COUNT];
 
   if (!pcity) {
     return;
@@ -1846,17 +1861,10 @@
     goto CLEANUP;
   }
 
-  memset(free, 0, O_COUNT * sizeof(*free));
-  free[O_GOLD] = get_city_output_bonus(pcity, get_output_type(O_GOLD),
-                                       EFT_UNIT_UPKEEP_FREE_PER_CITY);
-
   /* Create a vector of all supported units with gold upkeep. */
   unit_list_iterate(pcity->units_supported, punit) {
-    city_unit_upkeep(punit, upkeep, free);
-    if (upkeep[O_GOLD] > 0) {
-      ug.punit = punit;
-      ug.gold_upkeep = upkeep[O_GOLD];
-      unitgold_vector_append(&units, &ug);
+    if (punit->upkeep[O_GOLD] > 0) {
+      unitgold_vector_append(&units, &punit);
     }
   } unit_list_iterate_end;
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to