--- ./data/civ1.serv.orig Fri Jun 30 20:58:14 2000 +++ ./data/civ1.serv Fri Jun 30 20:58:35 2000 @@ -8,6 +8,7 @@ # # Minor civ1 rules: set civstyle 1 +set keepextrashields 0 # # Rulesets: set terrain civ1 --- ./data/civ2.serv.orig Fri Jun 30 20:58:39 2000 +++ ./data/civ2.serv Fri Jun 30 20:58:45 2000 @@ -8,6 +8,7 @@ # # Minor civ2 rules: set civstyle 2 +set keepextrashields 0 # # Rulesets: set terrain civ2 --- ./common/game.h.orig Fri Jun 30 21:06:23 2000 +++ ./common/game.h Fri Jun 30 20:36:09 2000 @@ -82,6 +82,8 @@ int foodbox; int aqueductloss; int killcitizen; + int keepextrafood; + int keepextrashields; int techpenalty; int razechance; int scorelog; @@ -255,6 +257,14 @@ #define GAME_DEFAULT_KILLCITIZEN 1 #define GAME_MIN_KILLCITIZEN 0 #define GAME_MAX_KILLCITIZEN 15 + +#define GAME_DEFAULT_KEEPEXTRAFOOD 0 +#define GAME_MIN_KEEPEXTRAFOOD -1 +#define GAME_MAX_KEEPEXTRAFOOD 1000 + +#define GAME_DEFAULT_KEEPEXTRASHIELDS -1 +#define GAME_MIN_KEEPEXTRASHIELDS -1 +#define GAME_MAX_KEEPEXTRASHIELDS 1000 #define GAME_DEFAULT_TECHPENALTY 100 #define GAME_MIN_TECHPENALTY 0 --- ./common/game.c.orig Fri Jun 30 20:18:51 2000 +++ ./common/game.c Fri Jun 30 20:13:02 2000 @@ -746,6 +746,8 @@ game.foodbox = GAME_DEFAULT_FOODBOX; game.aqueductloss= GAME_DEFAULT_AQUEDUCTLOSS; game.killcitizen = GAME_DEFAULT_KILLCITIZEN; + game.keepextrafood = GAME_DEFAULT_KEEPEXTRAFOOD; + game.keepextrashields = GAME_DEFAULT_KEEPEXTRASHIELDS; game.scorelog = GAME_DEFAULT_SCORELOG; game.techpenalty = GAME_DEFAULT_TECHPENALTY; game.civstyle = GAME_DEFAULT_CIVSTYLE; --- ./server/gamehand.c.orig Fri Jun 30 20:02:21 2000 +++ ./server/gamehand.c Fri Jun 30 20:05:54 2000 @@ -370,6 +370,10 @@ "game.aqueductloss"); game.killcitizen = secfile_lookup_int_default(file, game.killcitizen, "game.killcitizen"); + game.keepextrafood = secfile_lookup_int_default(file, game.keepextrafood, + "game.keepextrafood"); + game.keepextrashields = secfile_lookup_int_default(file, + game.keepextrashields, "game.keepextrashields"); game.turnblock = secfile_lookup_int_default(file,game.turnblock, "game.turnblock"); game.fixedlength = secfile_lookup_int_default(file,game.fixedlength, @@ -600,6 +604,8 @@ secfile_insert_int(file, game.diplchance, "game.diplchance"); secfile_insert_int(file, game.aqueductloss, "game.aqueductloss"); secfile_insert_int(file, game.killcitizen, "game.killcitizen"); + secfile_insert_int(file, game.keepextrafood, "game.keepextrafood"); + secfile_insert_int(file, game.keepextrashields, "game.keepextrashields"); secfile_insert_int(file, game.turnblock, "game.turnblock"); secfile_insert_int(file, game.fixedlength, "game.fixedlength"); secfile_insert_int(file, game.barbarianrate, "game.barbarians"); --- ./server/stdinhand.c.orig Fri Jun 30 20:06:03 2000 +++ ./server/stdinhand.c Fri Jun 30 20:59:39 2000 @@ -480,6 +480,25 @@ " 4 = heli\n" " 8 = air") }, + { "keepextrafood", &game.keepextrafood, + SSET_RULES, SSET_TO_CLIENT, + GAME_MIN_KEEPEXTRAFOOD, GAME_MAX_KEEPEXTRAFOOD, GAME_DEFAULT_KEEPEXTRAFOOD, + N_("Amount of food to keep when city grows"), + N_("This is the number of extra food units to keep when a city grows. " + "A negative value means keep all the extra food; a value of 0 discards " + "all excess food. This value is not used when a city grows because " + "of celebrations.") }, + + { "keepextrashields", &game.keepextrashields, + SSET_RULES, SSET_TO_CLIENT, + GAME_MIN_KEEPEXTRASHIELDS, GAME_MAX_KEEPEXTRASHIELDS, + GAME_DEFAULT_KEEPEXTRASHIELDS, + N_("Shields to keep after city builds something"), + N_("This is the number of extra production shields to keep when a city " + "finishes building an improvement, unit or wonder. A negative value " + "means keep all the extra shields; a value of 0 discards all excess " + "shields.") }, + /* Flexible rules: these can be changed after the game has started. * * The distinction between "rules" and "flexible rules" is not always --- ./server/cityturn.c.orig Fri Jun 30 20:24:35 2000 +++ ./server/cityturn.c Fri Jun 30 21:00:54 2000 @@ -866,15 +866,22 @@ pcity->size++; /* Do not empty food stock if city is growing by celebrating */ - if (rapture_grow) { - new_food = (pcity->size+1) * game.foodbox; - } else { + if (!rapture_grow) { + + /* We've already added the food to the city's storage (in city_populate()). + * Now subtract the amount needed for growth, and keep the excess (up to + * game.keepextrafood, if it's nonnegative). Note that we don't use + * (pcity->size+1) here -- we need to use the *old* city size. -GJW */ + pcity->food_stock -= (pcity->size * game.foodbox); + if (game.keepextrafood >= 0) + pcity->food_stock = MIN(pcity->food_stock, game.keepextrafood); + + /* Keep the foodbox half full if we have a granary. This is added after + * the keepextrafood check, so that keepextrafood doesn't become + * meaningless when cities have granaries. -GJW */ if (has_granary) - new_food = ((pcity->size+1) * game.foodbox) / 2; - else - new_food = 0; + pcity->food_stock += (pcity->size+1) * game.foodbox / 2; } - pcity->food_stock = MIN(pcity->food_stock, new_food); /* If there is enough food, and the city is big enough, * make new citizens into scientists or taxmen -- Massimo */ @@ -1268,9 +1275,15 @@ space_part = 0; pcity->improvements[pcity->currently_building]=1; } + + /* Depending on ruleset, we may keep none, some or all of the extra + * shields. Keeping extra shields helps reduce micromanagement. -GJW */ pcity->shield_stock-=improvement_value(pcity->currently_building); + if (game.keepextrashields >= 0) { + pcity->shield_stock = MIN(pcity->shield_stock, game.keepextrashields); + } + pcity->turn_last_built = game.year; - /* to eliminate micromanagement */ if(is_wonder(pcity->currently_building)) { game.global_wonders[pcity->currently_building]=pcity->id; notify_player_ex(0, pcity->x, pcity->y, E_WONDER_BUILD,