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

New version of the patch; now split up into three parts:
effects_timeline_startyear_v3.diff startyear server option
effects_timeline_doc_ruleset_v3.diff MinYear Req type, Effects and
modifications to game_next_year
effects_timeline_doc_ruleset_v3.diff Modifications to README.effects and
civ1, civ2 and default rulesets

Only changes from previous version: removed rounding in game_next_year.
Added the step 15 years/turn for symmetry; it is not used in any default
ruleset but then we have a symmetric list of year steps: 50, 25, 20, 15,
10, 5, 2, 1

The startyear option discards the year 0. We should really interpret
that as year 1 AD, but setting startyear to 0 is disallowed since that
year is never reached in the regular game otherwise, and there is no
possibility to change the value in the validation callback
startyear_callback in server/settings.c.
Index: server/cityturn.c
===================================================================
--- server/cityturn.c	(revision 13092)
+++ server/cityturn.c	(arbetskopia)
@@ -888,6 +888,20 @@
 				 API_TYPE_CITY, pcity,
 				 API_TYPE_STRING, "need_terrainclass");
 	      break;
+	    case REQ_MINYEAR:
+	      /* FIXME: if negated: we should skip rather than postpone,
+	       * since we'll never be able to meet this req... */
+	      notify_player(pplayer, pcity->tile, E_CITY_CANTBUILD,
+			       _("%s can't build %s from the worklist; "
+				 "Only available from %s.  Postponing..."),
+			       pcity->name,
+			       get_impr_name_ex(pcity, building->index),
+			       textyear(preq->source.value.minyear));
+	      script_signal_emit("building_cant_be_built", 3,
+				 API_TYPE_BUILDING_TYPE, building,
+				 API_TYPE_CITY, pcity,
+				 API_TYPE_STRING, "need_minyear");
+	      break;
 	    case REQ_NONE:
 	    case REQ_LAST:
 	      assert(0);
Index: common/effects.c
===================================================================
--- common/effects.c	(revision 13092)
+++ common/effects.c	(arbetskopia)
@@ -93,6 +93,7 @@
   "No_Incite",
   "Gain_AI_Love",
   "Slow_Down_Timeline",
+  "Slow_Down_Timeline_2",
   "Civil_War_Chance",
   "Empire_Size_Base",
   "Empire_Size_Step",
Index: common/effects.h
===================================================================
--- common/effects.h	(revision 13092)
+++ common/effects.h	(arbetskopia)
@@ -81,6 +81,7 @@
   EFT_NO_INCITE,
   EFT_GAIN_AI_LOVE,
   EFT_SLOW_DOWN_TIMELINE,
+  EFT_SLOW_DOWN_TIMELINE_2, /* Space module tech slowdown */
   EFT_CIVIL_WAR_CHANCE,
   EFT_EMPIRE_SIZE_BASE, /* +1 unhappy when more than this cities */
   EFT_EMPIRE_SIZE_STEP, /* adds additional +1 unhappy steps to above */
Index: common/game.c
===================================================================
--- common/game.c	(revision 13092)
+++ common/game.c	(arbetskopia)
@@ -431,8 +431,10 @@
 ***************************************************************/
 int game_next_year(int year)
 {
-  const int slowdown = (game.info.spacerace
-			? get_world_bonus(EFT_SLOW_DOWN_TIMELINE) : 0);
+  const int calendar_slowdown = get_world_bonus(EFT_SLOW_DOWN_TIMELINE);
+  const int space_slowdown = (game.info.spacerace
+			? get_world_bonus(EFT_SLOW_DOWN_TIMELINE_2) : 0);
+	int inc;
 
   if (year == 1) /* hacked it to get rid of year 0 */
     year = 0;
@@ -450,22 +452,31 @@
    * about 1900 AD
    */
 
-  /* Note the slowdown operates even if Enable_Space is not active.  See
-   * README.effects for specifics. */
-  if (year >= 1900 || (slowdown >= 3 && year > 0)) {
-    year += 1;
-  } else if (year >= 1750 || slowdown >= 2) {
-    year += 2;
-  } else if (year >= 1500 || slowdown >= 1) {
-    year += 5;
-  } else if( year >= 1000 )
-    year += 10;
-  else if( year >= 0 )
-    year += 20;
-  else if( year >= -1000 ) /* used this line for tuning (was -1250) */
-    year += 25;
-  else
-    year += 50; 
+  /* Calendar slowdowns commented with years in the default ruleset
+   * Note the space_slowdown operates even if Enable_Space is not active.  
+   * See README.effects for specifics. */
+  if (calendar_slowdown >= 7 || space_slowdown >= 3 ) { /*1900*/
+    if (year == 0) /* year 0 hack */
+      inc = 2;
+    else
+      inc = 1;
+  } else if (calendar_slowdown >= 6 || space_slowdown >= 2) { /* >=  1750 */
+    inc = 2;
+  } else if (calendar_slowdown >= 5 || space_slowdown >= 1) { /* >=  1500 */
+    inc = 5;
+  } else if( calendar_slowdown >= 4 ) {    /* >=  1000 */
+    inc = 10;
+  } else if( calendar_slowdown >= 3 ) {    /*(not used)*/
+    inc = 15;
+  } else if( calendar_slowdown >= 2 ) {    /* >=     0 */
+    inc = 20;
+  } else if( calendar_slowdown >= 1 ) {    /* >= -1000 */
+    inc = 25;
+  } else {
+    inc = 50;
+  }
+  
+  year += inc;
 
   if (year == 0) 
     year = 1;
Index: common/requirements.c
===================================================================
--- common/requirements.c	(revision 13092)
+++ common/requirements.c	(arbetskopia)
@@ -43,7 +43,8 @@
   "Specialist",
   "MinSize",
   "AI",
-  "TerrainClass"
+  "TerrainClass",
+  "MinYear"
 };
 
 /* Names of requirement ranges. These must correspond to enum req_range in
@@ -188,6 +189,12 @@
       return source;
     }
     break;
+  case REQ_MINYEAR:
+    source.value.minyear = atoi(value);
+    if (source.value.minyear >= GAME_MIN_YEAR) {
+      return source;
+    }
+    break;
   case REQ_LAST:
     break;
   }
@@ -252,6 +259,9 @@
   case REQ_TERRAINCLASS:
     source.value.terrainclass = value;
     return source;
+  case REQ_MINYEAR:
+    source.value.minyear = value;
+    return source;
   case REQ_LAST:
     return source;
   }
@@ -317,6 +327,9 @@
   case REQ_TERRAINCLASS:
     *value = source->value.terrainclass;
     return;
+  case REQ_MINYEAR:
+    *value = source->value.minyear;
+    return;
   case REQ_LAST:
     break;
   }
@@ -369,6 +382,9 @@
     case REQ_AI:
       req.range = REQ_RANGE_PLAYER;
       break;
+    case REQ_MINYEAR:
+      req.range = REQ_RANGE_WORLD;
+      break;
     }
   }
 
@@ -411,6 +427,9 @@
   case REQ_SPECIALIST:
     invalid = (req.range != REQ_RANGE_LOCAL);
     break;
+  case REQ_MINYEAR:
+    invalid = (req.range != REQ_RANGE_WORLD);
+    break;
   case REQ_NONE:
     invalid = FALSE;
     break;
@@ -928,6 +947,9 @@
                                      req->range, req->survives,
                                      req->source.value.terrainclass);
     break;
+  case REQ_MINYEAR:
+    eval = game.info.year >= req->source.value.minyear;
+    break;
   case REQ_LAST:
     assert(0);
     return FALSE;
@@ -1008,6 +1030,8 @@
      * reasons and so that the AI doesn't get confused (since the AI
      * doesn't know how to meet special and terrain requirements). */
     return TRUE;
+  case REQ_MINYEAR: /* Passed if negated */
+    return req->negated; 
   case REQ_LAST:
     break;
   }
@@ -1056,6 +1080,8 @@
     return psource1->value.level == psource2->value.level;
   case REQ_TERRAINCLASS:
     return psource1->value.terrainclass == psource2->value.terrainclass;
+  case REQ_MINYEAR:
+    return psource1->value.minyear == psource2->value.minyear;
   case REQ_LAST:
     break;
   }
@@ -1123,6 +1149,10 @@
      cat_snprintf(buf, bufsz, _("%s terrain"),
                   terrain_class_name_translation(psource->value.terrainclass));
      break;
+  case REQ_MINYEAR:
+    cat_snprintf(buf, bufsz, _("After %s"),
+                 textyear(psource->value.minyear));
+    break;
   case REQ_LAST:
     assert(0);
     break;
Index: common/requirements.h
===================================================================
--- common/requirements.h	(revision 13092)
+++ common/requirements.h	(arbetskopia)
@@ -37,6 +37,7 @@
   REQ_MINSIZE,      /* Minimum size: at city range means city size */
   REQ_AI,           /* AI level of the player */
   REQ_TERRAINCLASS, /* More generic terrain type, currently "Land" or "Ocean" */
+  REQ_MINYEAR,      /* Game year greater than or equal */
   REQ_LAST
 };
 
@@ -71,6 +72,7 @@
     int minsize;                        /* source minsize type */
     enum ai_level level;                /* source AI level */
     enum terrain_class terrainclass;    /* source generic terrain type */
+    int minyear;                        /* source minimum year */
   } value;                              /* source value */
 };
 
Index: ai/aicity.c
===================================================================
--- ai/aicity.c	(revision 13092)
+++ ai/aicity.c	(arbetskopia)
@@ -369,6 +369,7 @@
     break;
 
   case EFT_SLOW_DOWN_TIMELINE:
+  case EFT_SLOW_DOWN_TIMELINE_2:
     /* AI doesn't care about these. */
     break;
 
Index: client/helpdata.c
===================================================================
--- client/helpdata.c	(revision 13092)
+++ client/helpdata.c	(arbetskopia)
@@ -218,6 +218,15 @@
      cat_snprintf(buf, bufsz, _("Requires %s terrain.\n\n"),
                   terrain_class_name_translation(req->source.value.terrainclass));
      return;
+  case REQ_MINYEAR:
+    if (req->negated) {
+      cat_snprintf(buf, bufsz, _("Only available before %s.\n\n"),
+		   textyear(req->source.value.minyear));
+    } else {
+      cat_snprintf(buf, bufsz, _("Only available from %s.\n\n"),
+		   textyear(req->source.value.minyear));
+    }
+    return;
   }
   assert(0);
 }
Index: server/settings.c
===================================================================
--- server/settings.c	(revision 13092)
+++ server/settings.c	(arbetskopia)
@@ -162,6 +162,25 @@
 }
 
 /*************************************************************************
+  Verify that a given startyear is valid.
+*************************************************************************/
+static bool startyear_callback(int value, const char **error_string)
+{
+  if (value > game.info.end_year) {
+    /* Tried to set startyear later than endyear */
+    *error_string = _("Cannot set startyear later than endyear.");
+    return FALSE;
+  }
+  if (value == 0) {
+    /* There is no year 0 in the game
+     * FIXME: automatically set it to 1 AD */
+    *error_string = _("Year 0 is not a valid year.");
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/*************************************************************************
   Verify that a given maxplayers string is valid.
 *************************************************************************/
 static bool maxplayers_callback(int value, const char **error_string)
@@ -483,6 +502,15 @@
              "the ruleset, a big value for techlevel can make the next "
              "techs really expensive."), NULL,
 	  GAME_MIN_TECHLEVEL, GAME_MAX_TECHLEVEL, GAME_DEFAULT_TECHLEVEL)
+	  
+  GEN_INT("startyear", game.info.year,
+	  SSET_GAME_INIT, SSET_SOCIOLOGY, SSET_VITAL, SSET_TO_CLIENT,
+	  N_("Year the game begins"),
+	  N_("The game will begin at the given year. "
+	     "A negative number specifies years BC. Year 0 is not a valid "
+	     "year, use year 1 AD."),
+	  startyear_callback,
+	  GAME_MIN_START_YEAR, GAME_MAX_START_YEAR, GAME_DEFAULT_START_YEAR)
 
   GEN_INT("sciencebox", game.info.sciencebox,
 	  SSET_RULES, SSET_SCIENCE, SSET_SITUATIONAL, SSET_TO_CLIENT,
Index: server/report.c
===================================================================
--- server/report.c	(revision 13092)
+++ server/report.c	(arbetskopia)
@@ -939,7 +939,7 @@
   }
 
   if (!fp) {
-    if (game.info.year == GAME_START_YEAR) {
+    if (game.info.turn == 0) {
       oper = SL_CREATE;
     } else {
       fp = fopen(logname, "r");
Index: server/maphand.c
===================================================================
--- server/maphand.c	(revision 13092)
+++ server/maphand.c	(arbetskopia)
@@ -973,7 +973,7 @@
     }
   }
 
-  plrtile->last_updated = GAME_START_YEAR;
+  plrtile->last_updated = GAME_MIN_YEAR;
   vision_layer_iterate(v) {
     plrtile->own_seen[v] = plrtile->seen_count[v];
   } vision_layer_iterate_end;
Index: common/game.c
===================================================================
--- common/game.c	(revision 13092)
+++ common/game.c	(arbetskopia)
@@ -229,7 +229,7 @@
   game.info.tcptimeout    = GAME_DEFAULT_TCPTIMEOUT;
   game.info.netwait       = GAME_DEFAULT_NETWAIT;
   game.info.end_year      = GAME_DEFAULT_END_YEAR;
-  game.info.year          = GAME_START_YEAR;
+  game.info.year          = GAME_DEFAULT_START_YEAR;
   game.info.turn          = 0;
   game.info.min_players   = GAME_DEFAULT_MIN_PLAYERS;
   game.info.max_players   = GAME_DEFAULT_MAX_PLAYERS;
Index: common/game.h
===================================================================
--- common/game.h	(revision 13092)
+++ common/game.h	(arbetskopia)
@@ -177,9 +177,9 @@
 
 #define GAME_DEFAULT_ANGRYCITIZEN TRUE
 
-#define GAME_DEFAULT_END_YEAR    5000
-#define GAME_MIN_END_YEAR        GAME_START_YEAR
-#define GAME_MAX_END_YEAR        5000
+#define GAME_DEFAULT_END_YEAR    GAME_MAX_YEAR
+#define GAME_MIN_END_YEAR        GAME_MIN_YEAR
+#define GAME_MAX_END_YEAR        GAME_MAX_YEAR
 
 #define GAME_DEFAULT_MIN_PLAYERS     1
 #define GAME_MIN_MIN_PLAYERS         1
@@ -326,10 +326,10 @@
 #define GAME_MIN_BARBARIANRATE       0
 #define GAME_MAX_BARBARIANRATE       4
 
-#define GAME_DEFAULT_ONSETBARBARIAN  (GAME_START_YEAR+ \
-				      ((GAME_DEFAULT_END_YEAR-(GAME_START_YEAR))/3))
-#define GAME_MIN_ONSETBARBARIAN      GAME_START_YEAR
-#define GAME_MAX_ONSETBARBARIAN      GAME_MAX_END_YEAR
+#define GAME_DEFAULT_ONSETBARBARIAN  (GAME_DEFAULT_START_YEAR+ \
+				      ((GAME_DEFAULT_END_YEAR-(GAME_DEFAULT_START_YEAR))/3))
+#define GAME_MIN_ONSETBARBARIAN      GAME_MIN_YEAR
+#define GAME_MAX_ONSETBARBARIAN      GAME_MAX_YEAR
 
 #define GAME_DEFAULT_OCCUPYCHANCE    0
 #define GAME_MIN_OCCUPYCHANCE        0
@@ -360,6 +360,11 @@
 #define GAME_MIN_REVOLUTION_LENGTH 0
 #define GAME_MAX_REVOLUTION_LENGTH 10
 
-#define GAME_START_YEAR -4000
+#define GAME_DEFAULT_START_YEAR GAME_MIN_YEAR
+#define GAME_MIN_START_YEAR GAME_MIN_YEAR
+#define GAME_MAX_START_YEAR GAME_MAX_YEAR
 
+#define GAME_MIN_YEAR -4000
+#define GAME_MAX_YEAR 5000
+
 #endif  /* FC__GAME_H */
Index: doc/README.effects
===================================================================
--- doc/README.effects	(revision 13092)
+++ doc/README.effects	(arbetskopia)
@@ -40,9 +40,9 @@
 
 A requirement type is the type of the requirement and can be one of "None" 
 (default), "Tech", "Gov", "Building", "Special", "Terrain", "UnitType", 
-"UnitFlag", "UnitClass", "Nation", "OutputType", "MinSize", "AI" and
-"TerrainClass". MinSize is the minimum size of a city required. AI is ai
-player difficulty level. TerrainClass is either "Land" or "Oceanic".
+"UnitFlag", "UnitClass", "Nation", "OutputType", "MinSize", "AI",
+"TerrainClass" and "MinYear". MinSize is the minimum size of a city required. AI is ai
+player difficulty level. TerrainClass is either "Land" or "Oceanic". MinYear is a qualifier for the game year (Year greater than or equal the given year)
 
 Effect types 
 ============
@@ -207,10 +207,26 @@
     Gain amount points of "AI love" with AI(s).
 
 Slow_Down_Timeline
-    Slow down the timeline based on the AMOUNT. If AMOUNT >= 3 the timeline 
-will be 1 year/turn; with AMOUNT == 2 it is 2 years/turn; with AMOUNT == 1 it 
-is 5 years/turn; with AMOUNT <= 0 the timeline is unaffected. The effect will 
-be ignored if game.spacerace isn't set.
+    Slow down the timeline based on the amount. If amount >= 7 the 
+    timeline will be 1 year/turn; with value <= 0 the timeline 
+    is unaffected.
+    amount    years/turn
+    >= 7      1
+    6         2
+    5         5
+    4         10
+    3         15
+    2         20
+    1         25
+    0         50
+    
+Slow_Down_Timeline_2
+    Override effect for Space Modules to slow down the timeline based on 
+    the amount. This overrides Slow_Down_Timeline.
+    If amount >= 3 the timeline will be 1 year/turn; with amount == 2 
+    it is 2 years/turn; with amount == 1 it is 5 years/turn; with 
+    amount <= 0 it has no effect. 
+    This effect will be ignored if game.spacerace isn't set.
 
 Civil_War_Chance
     Chance of player splitting due to civil war when capital captured is 
Index: data/civ1/effects.ruleset
===================================================================
--- data/civ1/effects.ruleset	(revision 13092)
+++ data/civ1/effects.ruleset	(arbetskopia)
@@ -1188,3 +1188,52 @@
     { "type", "name", "range"
       "Tech", "Railroad", "Player"
     }    
+
+; Timeline
+[effect_calendar_1]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "-1000", "World"
+    }
+
+[effect_calendar_2]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "0", "World"
+    }
+
+[effect_calendar_3]
+name    = "Slow_Down_Timeline"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1000", "World"
+    }
+
+[effect_calendar_4]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1500", "World"
+    }
+
+[effect_calendar_5]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1750", "World"
+    }
+    
+[effect_calendar_6]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1900", "World"
+    }
Index: data/civ2/effects.ruleset
===================================================================
--- data/civ2/effects.ruleset	(revision 13092)
+++ data/civ2/effects.ruleset	(arbetskopia)
@@ -1949,3 +1949,52 @@
     { "type", "name", "range"
       "Tech", "Railroad", "Player"
     }    
+
+; Timeline
+[effect_calendar_1]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "-1000", "World"
+    }
+
+[effect_calendar_2]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "0", "World"
+    }
+
+[effect_calendar_3]
+name    = "Slow_Down_Timeline"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1000", "World"
+    }
+
+[effect_calendar_4]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1500", "World"
+    }
+
+[effect_calendar_5]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1750", "World"
+    }
+    
+[effect_calendar_6]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1900", "World"
+    }
Index: data/default/effects.ruleset
===================================================================
--- data/default/effects.ruleset	(revision 13092)
+++ data/default/effects.ruleset	(arbetskopia)
@@ -1453,7 +1453,7 @@
     }
 
 [effect_plastics_slowdown]
-name    = "Slow_Down_Timeline"
+name    = "Slow_Down_Timeline_2"
 value   = 1
 reqs    =
     { "type", "name", "range"
@@ -1461,7 +1461,7 @@
     }
 
 [effect_superconductor_slowdown]
-name    = "Slow_Down_Timeline"
+name    = "Slow_Down_Timeline_2"
 value   = 1
 reqs    =
     { "type", "name", "range"
@@ -1469,7 +1469,7 @@
     }
 
 [effect_spaceflight_slowdown]
-name    = "Slow_Down_Timeline"
+name    = "Slow_Down_Timeline_2"
 value   = 1
 reqs    =
     { "type", "name", "range"
@@ -1935,3 +1935,52 @@
     { "type", "name", "range"
       "Tech", "Railroad", "Player"
     }    
+
+; Timeline
+[effect_calendar_1]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "-1000", "World"
+    }
+
+[effect_calendar_2]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "0", "World"
+    }
+
+[effect_calendar_3]
+name    = "Slow_Down_Timeline"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1000", "World"
+    }
+
+[effect_calendar_4]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1500", "World"
+    }
+
+[effect_calendar_5]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1750", "World"
+    }
+    
+[effect_calendar_6]
+name    = "Slow_Down_Timeline"
+value   = 1
+reqs    =
+    { "type", "name", "range"
+      "MinYear", "1900", "World"
+    }
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to