Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2005:
[Freeciv-Dev] (PR#14756) Waste rewrite
Home

[Freeciv-Dev] (PR#14756) Waste rewrite

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#14756) Waste rewrite
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Sat, 3 Dec 2005 09:29:41 -0800
Reply-to: bugs@xxxxxxxxxxx

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

This patch moves control over waste entirely over to effects code. The new
waste algorithm is much simpler, but also allows a much greater
flexibility, such as luxury waste or increased waste from techs or
buildings, for example.

Basically, the old

-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0
-waste_extra_distance       = 0
-waste_max_distance_cap     = 36

setup has been replaced by two new effects

+  "Output_Waste",
+  "Output_Waste_By_Distance"

The first is a simpe % of waste for an output, and the latter is simply
added to the first % for each tile of real map distance from capital. If
there is no capital, but there is an Output_Waste_By_Distance effect in
play, everything goes to waste.

This is in addition to the existing "Output_Waste_Pct" effect
(Courthouse).

I think this new algorithm gives a sufficient approximation for civ1/civ2
rulesets, and plenty of possibilities for default.

  - Per

Index: server/ruleset.c
===================================================================
--- server/ruleset.c    (revision 11296)
+++ server/ruleset.c    (working copy)
@@ -1675,8 +1675,6 @@
   /* easy ones: */
   government_iterate(g) {
     int i = g->index;
-    const char *waste_name[] = {NULL, "waste", "corruption",
-                               NULL, NULL, NULL};
     struct requirement_vector *reqs = lookup_req_list(file, sec[i], "reqs");
 
     if (section_file_lookup(file, "%s.ai_better", sec[i])) {
@@ -1693,27 +1691,6 @@
               secfile_lookup_str(file, "%s.graphic", sec[i]));
     sz_strlcpy(g->graphic_alt,
               secfile_lookup_str(file, "%s.graphic_alt", sec[i]));
-    
-    output_type_iterate(o) {
-      if (waste_name[o]) {
-       g->waste[o].level = secfile_lookup_int(file, "%s.%s_level",
-                                              sec[i], waste_name[o]);
-       g->waste[o].fixed_distance
-         = secfile_lookup_int(file, "%s.%s_fixed_distance",
-                              sec[i], waste_name[o]);
-       g->waste[o].distance_factor
-         = secfile_lookup_int(file, "%s.%s_distance_factor",
-                              sec[i], waste_name[o]);
-       g->waste[o].extra_distance
-         = secfile_lookup_int(file, "%s.%s_extra_distance",
-                              sec[i], waste_name[o]);
-       g->waste[o].max_distance_cap
-         = secfile_lookup_int_default(file, 36, "%s.%s_max_distance_cap",
-                                      sec[i], waste_name[o]); 
-      } else {
-       memset(&g->waste[o], 0, sizeof(g->waste[o]));
-      }
-    } output_type_iterate_end;
 
     output_type_iterate(o) {
       g->output_inc_tile[o]
@@ -2857,12 +2834,6 @@
       gov.celeb_output_before_penalty[o] = g->celeb_output_before_penalty[o];
       gov.output_inc_tile[o] = g->output_inc_tile[o];
       gov.celeb_output_inc_tile[o] = g->celeb_output_inc_tile[o];
-
-      gov.waste_level[o] = g->waste[o].level;
-      gov.fixed_waste_distance[o] = g->waste[o].fixed_distance;
-      gov.waste_distance_factor[o] = g->waste[o].distance_factor;
-      gov.extra_waste_distance[o] = g->waste[o].extra_distance;
-      gov.waste_max_distance_cap[o] = g->waste[o].max_distance_cap;
     } output_type_iterate_end;
         
     gov.num_ruler_titles = g->num_ruler_titles;
Index: data/default/effects.ruleset
===================================================================
--- data/default/effects.ruleset        (revision 11296)
+++ data/default/effects.ruleset        (working copy)
@@ -101,6 +101,87 @@
       "Gov", "Republic", "Player"
     }
 
+[effect_corruption_anarchy0]
+name   = "Output_Waste"
+value  = 25
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Anarchy", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_anarchy1]
+name   = "Output_Waste_By_Distance"
+value  = 2
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Anarchy", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_despotism0]
+name   = "Output_Waste"
+value  = 37
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Despotism", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_despotism1]
+name   = "Output_Waste_By_Distance"
+value  = 4
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Despotism", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_monarchy0]
+name   = "Output_Waste"
+value  = 15
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Monarchy", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_monarchy1]
+name   = "Output_Waste_By_Distance"
+value  = 2
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Monarchy", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_communism0]
+name   = "Output_Waste"
+value  = 20
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Communism", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_republic0]
+name   = "Output_Waste"
+value  = 15
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Republic", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
+[effect_corruption_republic1]
+name   = "Output_Waste_By_Distance"
+value  = 2
+reqs   =
+    { "type", "name", "range"
+      "Gov", "Republic", "Player"
+      "OutputType", "Trade", "Local"
+    }
+
 [effect_base_unit_upkeep]
 name   = "Upkeep_Factor"
 value  = 1
Index: data/default/governments.ruleset
===================================================================
--- data/default/governments.ruleset    (revision 11296)
+++ data/default/governments.ruleset    (working copy)
@@ -39,29 +39,6 @@
 ; ai_better   = AI will not consider this government for use if the
 ;               government listed here is available
 
-; corruption:
- 
-; _level            = percentage factor applied to corruption multiplied 
-;                    by 100; if 0, Courthouse effect changes
-; _fixed_distance   = if non-zero, used instead of actual calculation of 
-;                    distance from Palace; also used for distances in 
-;                    unit and city bribe cost calculations
-; _distance_factor  = multiply distance by this factor for corruption 
-;                    (but not bribe costs)
-; _extra_distance   = add this to distance after applying distance factor
-; _max_distance_cap = cap to the max distance from the capital used in
-;                     corruption calculation
-
-; waste:
-
-; _level             = percentage factor applied to waste multiplied by 100
-; _fixed_distance    = used if not 0 instead of actual calculation of 
-;                            distance from Palace;                  
-; _distance_factor   = multiply distance by this factor for waste
-; _extra_distance    = add this to distance after applying distance factor
-; _max_distance_cap  = cap to the max distance from the capital used in
-;                      waste calculation
-
 ; production_*_bonus   = added to base production for each worked tile;
 ;                       second value is used instead when city is celebrating
 ; production_*_penalty = if non-zero, tile production above this amount is 
@@ -81,18 +58,6 @@
 graphic     = "gov.anarchy"
 graphic_alt = "-"
 
-corruption_level            = 250
-corruption_fixed_distance   = 0
-corruption_distance_factor  = 1 
-corruption_extra_distance   = 0 
-corruption_max_distance_cap = 36
-
-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0 
-waste_extra_distance       = 0 
-waste_max_distance_cap     = 36
-
 production_trade_bonus    = 0, 0
 production_shield_bonus   = 0, 0
 production_food_bonus     = 0, 0
@@ -123,18 +88,6 @@
 graphic_alt = "-"
 ai_better   = "Monarchy"
 
-corruption_level            = 370
-corruption_fixed_distance   = 0
-corruption_distance_factor  = 2 
-corruption_extra_distance   = 3 
-corruption_max_distance_cap = 36
-
-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0 
-waste_extra_distance       = 0 
-waste_max_distance_cap     = 36
-
 production_trade_bonus    = 0, 0
 production_shield_bonus   = 0, 0
 production_food_bonus     = 0, 0
@@ -165,18 +118,6 @@
 graphic_alt = "-"
 ai_better   = "Communism"
 
-corruption_level            = 150
-corruption_fixed_distance   = 0
-corruption_distance_factor  = 1 
-corruption_extra_distance   = 0 
-corruption_max_distance_cap = 36
-
-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0 
-waste_extra_distance       = 0 
-waste_max_distance_cap     = 36
-
 production_trade_bonus    = 0, 1
 production_shield_bonus   = 0, 0
 production_food_bonus     = 0, 0
@@ -206,18 +147,6 @@
 graphic     = "gov.communism"
 graphic_alt = "-"
 
-corruption_level            = 62
-corruption_fixed_distance   = 10
-corruption_distance_factor  = 1 
-corruption_extra_distance   = 0 
-corruption_max_distance_cap = 36
-
-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0 
-waste_extra_distance       = 0
-waste_max_distance_cap     = 36
-
 production_trade_bonus    = 0, 1
 production_shield_bonus   = 0, 0
 production_food_bonus     = 0, 0
@@ -253,18 +182,6 @@
 graphic     = "gov.republic"
 graphic_alt = "-"
 
-corruption_level            = 150
-corruption_fixed_distance   = 0
-corruption_distance_factor  = 1 
-corruption_extra_distance   = 0 
-corruption_max_distance_cap = 36
-
-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0 
-waste_extra_distance       = 0
-waste_max_distance_cap     = 36
-
 production_trade_bonus    = 1, 1
 production_shield_bonus   = 0, 0
 production_food_bonus     = 0, 0
@@ -297,18 +214,6 @@
 graphic     = "gov.democracy"
 graphic_alt = "-"
 
-corruption_level            = 0
-corruption_fixed_distance   = 0
-corruption_distance_factor  = 0 
-corruption_extra_distance   = 0 
-corruption_max_distance_cap = 36
-
-waste_level                = 0
-waste_fixed_distance       = 0
-waste_distance_factor      = 0 
-waste_extra_distance       = 0
-waste_max_distance_cap     = 36
-
 production_trade_bonus    = 1, 1
 production_shield_bonus   = 0, 0
 production_food_bonus     = 0, 0
Index: common/packets.def
===================================================================
--- common/packets.def  (revision 11296)
+++ common/packets.def  (working copy)
@@ -1120,12 +1120,6 @@
   UINT8 output_inc_tile[O_MAX];
   UINT8 celeb_output_inc_tile[O_MAX];
 
-  UINT16 waste_level[O_MAX];
-  UINT8 fixed_waste_distance[O_MAX];
-  UINT8 waste_distance_factor[O_MAX];
-  UINT8 extra_waste_distance[O_MAX];
-  UINT8 waste_max_distance_cap[O_MAX];
-      
   UINT8 num_ruler_titles;
        
   STRING name[MAX_LEN_NAME];
Index: common/city.c
===================================================================
--- common/city.c       (revision 11296)
+++ common/city.c       (working copy)
@@ -2170,11 +2170,13 @@
 **************************************************************************/
 int city_waste(const struct city *pcity, Output_type_id otype, int total)
 {
-  struct government *g = get_gov_pcity(pcity);
-  int dist;
-  unsigned int val;
   int penalty = 0;
-  struct gov_waste *waste = &g->waste[otype];
+  int waste_level = get_city_output_bonus(pcity, get_output_type(otype),
+                                          EFT_OUTPUT_WASTE);
+  int waste_by_dist = get_city_output_bonus(pcity, get_output_type(otype),
+                                            EFT_OUTPUT_WASTE_BY_DISTANCE);
+  int waste_pct = get_city_output_bonus(pcity, get_output_type(otype), 
+                                        EFT_OUTPUT_WASTE_PCT);
 
   if (otype == O_TRADE) {
     /* FIXME: special case for trade: it is affected by notradesize and
@@ -2195,34 +2197,24 @@
     }
   }
 
-  if (waste->level == 0) {
-    return penalty;
-  }
-  if (waste->fixed_distance != 0) {
-    dist = waste->fixed_distance;
-  } else {
+  if (waste_by_dist > 0) {
     const struct city *capital = find_palace(city_owner(pcity));
 
     if (!capital) {
-      dist = waste->max_distance_cap;
+      return total; /* no capital - no income */
     } else {
-      int tmp = real_map_distance(capital->tile, pcity->tile);
-
-      dist = MIN(waste->max_distance_cap, tmp);
+      waste_level += waste_by_dist 
+                     * real_map_distance(capital->tile, pcity->tile);
     }
   }
-  dist = dist * waste->distance_factor + waste->extra_distance;
 
-  /* Now calculate the final waste.  Ordered to reduce integer
-   * roundoff errors. */
-  val = total * MAX(dist, 1) * waste->level;
+  if (waste_level > 0) {
+    penalty += total * waste_level / 100;
+  }
 
-  val -= (val * get_city_output_bonus(pcity, &output_types[otype],
-                                          EFT_OUTPUT_WASTE_PCT)) / 100;
+  penalty -= penalty * waste_pct / 100;
 
-  val /= 100 * 100; /* Level is a % multiplied by 100 */
-  val = CLIP(penalty, val, total);
-  return val;
+  return MIN(MAX(penalty, 0), total);
 }
 
 /**************************************************************************
Index: common/effects.c
===================================================================
--- common/effects.c    (revision 11296)
+++ common/effects.c    (working copy)
@@ -111,7 +111,9 @@
   "Trade_Revenue_Bonus",
   "Unhappy_Factor",
   "Upkeep_Factor",
-  "Unit_Upkeep_Free_Per_City"
+  "Unit_Upkeep_Free_Per_City",
+  "Output_Waste",
+  "Output_Waste_By_Distance"
 };
 
 static bool initialized = FALSE;
Index: common/effects.h
===================================================================
--- common/effects.h    (revision 11296)
+++ common/effects.h    (working copy)
@@ -100,6 +100,8 @@
   EFT_UNHAPPY_FACTOR, /* multiply unhappy upkeep by this effect */
   EFT_UPKEEP_FACTOR,  /* multiply upkeep by this effect */
   EFT_UNIT_UPKEEP_FREE_PER_CITY, /* this many units are free from upkeep */
+  EFT_OUTPUT_WASTE,
+  EFT_OUTPUT_WASTE_BY_DISTANCE,
   EFT_LAST     /* keep this last */
 };
 
Index: ai/aicity.c
===================================================================
--- ai/aicity.c (revision 11296)
+++ ai/aicity.c (working copy)
@@ -343,6 +343,8 @@
       case EFT_OUTPUT_ADD_TILE:
       case EFT_OUTPUT_INC_TILE:
       case EFT_OUTPUT_PER_TILE:
+      case EFT_OUTPUT_WASTE:
+      case EFT_OUTPUT_WASTE_BY_DISTANCE:
       case EFT_OUTPUT_WASTE_PCT:
       case EFT_SPECIALIST_OUTPUT:
       case EFT_NO_DIPLOMACY:
Index: client/packhand.c
===================================================================
--- client/packhand.c   (revision 11296)
+++ client/packhand.c   (working copy)
@@ -2263,12 +2263,6 @@
     gov->celeb_output_before_penalty[o] = p->celeb_output_before_penalty[o];
     gov->output_inc_tile[o] = p->output_inc_tile[o];
     gov->celeb_output_inc_tile[o] = p->celeb_output_inc_tile[o];
-
-    gov->waste[o].level = p->waste_level[o];
-    gov->waste[o].fixed_distance = p->fixed_waste_distance[o];
-    gov->waste[o].distance_factor = p->waste_distance_factor[o];
-    gov->waste[o].extra_distance = p->extra_waste_distance[o];
-    gov->waste[o].max_distance_cap = p->waste_max_distance_cap[o];
   } output_type_iterate_end;
   
   gov->num_ruler_titles    = p->num_ruler_titles;

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#14756) Waste rewrite, Per I. Mathisen <=