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

> [book - Mi 11. Feb 2009, 22:41:35]:
> > 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:
> > 
> > [ ... ]
> > 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)
> 
> Try O_LAST instead of O_COUNT.

I changed that. Furthermore, there was an closing tag missing 
(output_type_iterate_end). I corrected that and now I can compile the 
patch. I did not had the time to try a game ...

unit_upkeep.patch.diff

* save the unit upkeep within the unit struct
* define a function there it is calculated each turn, so that it can 
be adapted depending on the government / research
* based on the gold upkeep patch

Thanks for your great work with all the patches!

> 
> 
> -----------------------------------------------------------------------
> はいどうぞ、迷路の地図です。
> 

diff -ur freeciv-2.1.99svn15584.gold//common/unit.c freeciv-2.1.99svn15584.unit_upkeep//common/unit.c
--- freeciv-2.1.99svn15584.gold//common/unit.c	2009-03-21 12:19:14.972947854 +0100
+++ freeciv-2.1.99svn15584.unit_upkeep//common/unit.c	2009-03-23 20:51:14.000000000 +0100
@@ -34,7 +34,6 @@
 #include "unit.h"
 #include "unitlist.h"
 
-
 /**************************************************************************
 bribe unit
 investigate
@@ -1373,6 +1372,8 @@
     punit->tile = NULL;
     punit->homecity = IDENTITY_NUMBER_ZERO;
   }
+  /* upkeep will be set each turn within the cityturn loop */
+  memset(punit->upkeep, 0, O_LAST * sizeof(*punit->upkeep));
   punit->goto_tile = NULL;
   punit->veteran = veteran_level;
   /* A unit new and fresh ... */
diff -ur freeciv-2.1.99svn15584.gold//common/unit.h freeciv-2.1.99svn15584.unit_upkeep//common/unit.h
--- freeciv-2.1.99svn15584.gold//common/unit.h	2009-01-05 11:54:25.000000000 +0100
+++ freeciv-2.1.99svn15584.unit_upkeep//common/unit.h	2009-03-23 20:51:14.000000000 +0100
@@ -142,6 +142,7 @@
   struct player *owner; /* Cannot be NULL. */
   int id;
   int homecity;
+  int upkeep[O_LAST]; /* unit upkeep with regards to the homecity */
 
   int moves_left;
   int hp;
diff -ur freeciv-2.1.99svn15584.gold//server/cityturn.c freeciv-2.1.99svn15584.unit_upkeep//server/cityturn.c
--- freeciv-2.1.99svn15584.gold//server/cityturn.c	2009-03-23 20:47:57.764704419 +0100
+++ freeciv-2.1.99svn15584.unit_upkeep//server/cityturn.c	2009-03-23 22:27:10.288704035 +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);
 
 static float city_migration_score(const struct city *pcity);
 static bool do_city_migration(struct city *pcity_from,
@@ -461,6 +461,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
@@ -501,6 +502,39 @@
 }
 
 /**************************************************************************
+  Update upkeep needed for all units supported by the city
+**************************************************************************/
+static void calc_city_units_upkeep(const struct city *pcity)
+{
+  int free[O_LAST], upkeep[O_LAST];
+
+  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, get_output_type(o),
+                                    EFT_UNIT_UPKEEP_FREE_PER_CITY);
+  } output_type_iterate_end;
+
+  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) */
+    output_type_iterate(o) {
+      punit->upkeep[o] = upkeep[o];
+    } output_type_iterate_end;
+  } unit_list_iterate_end;
+}
+
+/**************************************************************************
   Reduce the city specialists by some (positive) value.
   Return the amount of reduction.
 **************************************************************************/
@@ -1649,20 +1683,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;
@@ -1734,7 +1762,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"),
@@ -1759,8 +1787,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;
@@ -1783,17 +1809,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;
@@ -1825,8 +1844,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;
@@ -1850,17 +1867,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