<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39413 >
Of course I did two errors in the last patch that I caught just after
sending it. Fixed to use textyear (of course) as well.
And: I don't think there should be any rounding in game_next_year(),
but I included it for you to see since I coded it.
Ulrik
Index: doc/README.effects
===================================================================
--- doc/README.effects (revision 13023)
+++ 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,23 @@
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 >= 6 the timeline
+will be 1 year/turn; with value <= 0 the timeline is unaffected.
+ amount years/turn
+ >= 6 1
+ 5 2
+ 4 5
+ 3 10
+ 2 20
+ 1 25
+ default 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: server/settings.c
===================================================================
--- server/settings.c (revision 13023)
+++ 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 13023)
+++ server/report.c (arbetskopia)
@@ -936,7 +936,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/cityturn.c
===================================================================
--- server/cityturn.c (revision 13023)
+++ server/cityturn.c (arbetskopia)
@@ -883,6 +883,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: server/maphand.c
===================================================================
--- server/maphand.c (revision 13023)
+++ 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: data/default/effects.ruleset
===================================================================
--- data/default/effects.ruleset (revision 13023)
+++ data/default/effects.ruleset (arbetskopia)
@@ -19,6 +19,54 @@
; Cheating AI effects are in separate file
*include "default/ai_effects.ruleset"
+[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 = 1
+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"
+ }
+
[effect_unhappysize]
name = "City_Unhappy_Size"
value = 4
@@ -1453,7 +1501,7 @@
}
[effect_plastics_slowdown]
-name = "Slow_Down_Timeline"
+name = "Slow_Down_Timeline_2"
value = 1
reqs =
{ "type", "name", "range"
@@ -1461,7 +1509,7 @@
}
[effect_superconductor_slowdown]
-name = "Slow_Down_Timeline"
+name = "Slow_Down_Timeline_2"
value = 1
reqs =
{ "type", "name", "range"
@@ -1469,7 +1517,7 @@
}
[effect_spaceflight_slowdown]
-name = "Slow_Down_Timeline"
+name = "Slow_Down_Timeline_2"
value = 1
reqs =
{ "type", "name", "range"
Index: common/effects.c
===================================================================
--- common/effects.c (revision 13023)
+++ 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 13023)
+++ 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 13023)
+++ common/game.c (arbetskopia)
@@ -222,7 +222,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;
@@ -424,8 +424,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, round = 1;
if (year == 1) /* hacked it to get rid of year 0 */
year = 0;
@@ -443,23 +445,43 @@
* 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 >= 6 || space_slowdown >= 3 ) { /*1900*/
+ if (year == 0) /* year 0 hack */
+ inc = 2;
+ else
+ inc = 1;
+ } else if (calendar_slowdown >= 5 || space_slowdown >= 2) { /* >= 1750 */
+ inc = 2;
+ } else if (calendar_slowdown >= 4 || space_slowdown >= 1) { /* >= 1500 */
+ inc = 5;
+ } else if( calendar_slowdown >= 3 ) { /* >= 1000 */
+ inc = 10;
+ round = 5;
+ } else if( calendar_slowdown >= 2 ) { /* >= 0 */
+ inc = 20;
+ round = 5;
+ } else if( calendar_slowdown >= 1 ) { /* >= -1000 */
+ inc = 25;
+ round = 5;
+ } else {
+ inc = 50;
+ round = 10;
+ }
+
+ year += inc;
+
+ /* Round years, but always positive */
+ if( year % round != 0 ) {
+ int mod = year % round;
+ if (mod < 0)
+ year -= mod;
+ else
+ year += (round - mod);
+ }
+
if (year == 0)
year = 1;
Index: common/game.h
===================================================================
--- common/game.h (revision 13023)
+++ common/game.h (arbetskopia)
@@ -179,9 +179,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
@@ -328,10 +328,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
@@ -362,6 +362,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: common/requirements.c
===================================================================
--- common/requirements.c (revision 13023)
+++ 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;
@@ -929,6 +948,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;
@@ -1009,6 +1031,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;
}
@@ -1057,6 +1081,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;
}
@@ -1124,6 +1150,11 @@
cat_snprintf(buf, bufsz, _("%s terrain"),
terrain_class_name(psource->value.terrainclass));
break;
+ case REQ_MINYEAR:
+ cat_snprintf(buf, bufsz, _("Earliest year %s"),
+ textyear(psource->value.minyear));
+
+ break;
case REQ_LAST:
assert(0);
break;
Index: common/requirements.h
===================================================================
--- common/requirements.h (revision 13023)
+++ 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 13023)
+++ 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 13023)
+++ client/helpdata.c (arbetskopia)
@@ -218,6 +218,15 @@
cat_snprintf(buf, bufsz, _("Requires %s terrain.\n\n"),
terrain_class_name(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);
}
_______________________________________________
Freeciv-dev mailing list
[email protected]
https://mail.gna.org/listinfo/freeciv-dev