<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 >
Attached the (hopefully) final version (or the last version for this
year ;-) )
I included the suggestions / changes from your patch. I also hope, that this
version follows the coding style guidelines for freeciv.
Am Tuesday 30 December 2008 23:32:48 schrieb Madeline Book:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 >
>
> > [[email protected] - Tue Dec 30 21:34:34 2008]:
> >
> > here is an updated version of the patch.
>
> Unfortunately I just made adjustements to you previous
> patch today, and was about to post the updated version
> when I noticed you already did. :(
sorry - I hat the time and so I did some work on this patch. Now I want to get
it included ... ;-)
>
> Anyway, please at least read over the code in the file
> migrate_v3.patch and make sure your patch follows the
> same style. Maybe integrate some of the ideas in it,
> such as a setting to control the number of turns
> between migrations (perhaps better than the hard-coded
> 5).
I added an option game.info.migrationturn with default to 0 (off)
>
> In particular:
> - No lines longer than 76 characters + 1 newline.
done
> - Multi-line function arguments lined up to column one
> past the initial '(' and similarly for if-statements.
interesting to know; I did it after my feeling ...
done
> - Use city_tile(pcity) instead of pcity->tile, and similar.
I hope done; if there is something missing, please tell me
> - Use LOG_DEBUG not LOG_NORMAL for debugging messages.
Oh, this was for me to test the patch; all set to debug now
> - Use is_capital(pcity) directly instead of find_palace().
done
> - Use const in function arguments if the function
> does not modify the arguments (e.g. the score function).
done
> - Make the default setting values disable migration.
done
>
> I also wonder if there could arise a situation where
> migration happens from city A to city B, and then back
> again from city B to city A, because A happened to be
> before B in the city list. Perhaps the migration score
> should first be calculated for all possible source
> and destination cities, then the migrations actually
> performed?
if people go from A to B, A has a score lower than B. After the migration the
score of B will be even higher ... but you are right, it could happen. I
hope, that the turn (game.info.migrationturn) option as well as the default
possibilities (50% for game.info.migrationplayer and 10% for
game.info.migrationworld) will prevent this. Also for the score a float is
used, so even small differences will be taken into account.
I get the following error; could it be related to the migration code
(remove_city() in make_city_migration())? I have not found a pattern to
narrow it down if it is the patch or the develop version of freeciv.
civserver: maphand.c:1564: map_claim_ownership: Assertion `((void *)0) ==
playtile->site' failed.
I suspect that after a city is remove something is messed up within the
server; but remove_city() is also used in similar kind in other functions.
Matthias
>
>
> Anyway I'll check it again in at least a few days and
> when I'm sure you are not working on it too. ;)
am finished and will start again if you have some comments; till the 6th of
January I have some free time ...
>
>
> -----------------------------------------------------------------------
> 私の人生は大移住の話から始まります。
--
Matthias Pfafferodt - http://www.mapfa.de
Matthias.Pfafferodt <at> mapfa.de
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/common/game.c freeciv-2.1.99svn.patch/common/game.c
--- freeciv-2.1.99svn15391/common/game.c 2008-12-25 19:45:44.000000000 +0100
+++ freeciv-2.1.99svn.patch/common/game.c 2008-12-31 16:37:12.000000000 +0100
@@ -275,6 +275,10 @@
game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE;
game.info.savepalace = GAME_DEFAULT_SAVEPALACE;
game.info.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES;
+ game.info.migrationturn = GAME_DEFAULT_MIGRATION_TURN;
+ game.info.migrationdist = GAME_DEFAULT_MIGRATION_DIST;
+ game.info.migrationworld = GAME_DEFAULT_MIGRATION_WORLD;
+ game.info.migrationplayer = GAME_DEFAULT_MIGRATION_PLAYER;
game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN;
game.info.foodbox = GAME_DEFAULT_FOODBOX;
game.info.shieldbox = GAME_DEFAULT_SHIELDBOX;
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/common/game.h freeciv-2.1.99svn.patch/common/game.h
--- freeciv-2.1.99svn15391/common/game.h 2008-12-30 23:29:33.000000000 +0100
+++ freeciv-2.1.99svn.patch/common/game.h 2008-12-31 17:39:10.000000000 +0100
@@ -250,6 +250,22 @@
#define GAME_DEFAULT_NATURALCITYNAMES TRUE
+#define GAME_DEFAULT_MIGRATION_TURN 0 /* 0 = no migration */
+#define GAME_MIN_MIGRATION_TURN 0
+#define GAME_MAX_MIGRATION_TURN 100
+
+#define GAME_DEFAULT_MIGRATION_DIST 3
+#define GAME_MIN_MIGRATION_DIST 1
+#define GAME_MAX_MIGRATION_DIST 7
+
+#define GAME_DEFAULT_MIGRATION_PLAYER 50
+#define GAME_MIN_MIGRATION_PLAYER 0
+#define GAME_MAX_MIGRATION_PLAYER 100
+
+#define GAME_DEFAULT_MIGRATION_WORLD 10
+#define GAME_MIN_MIGRATION_WORLD 0
+#define GAME_MAX_MIGRATION_WORLD 100
+
#define GAME_DEFAULT_AQUEDUCTLOSS 0
#define GAME_MIN_AQUEDUCTLOSS 0
#define GAME_MAX_AQUEDUCTLOSS 100
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/common/packets.def freeciv-2.1.99svn.patch/common/packets.def
--- freeciv-2.1.99svn15391/common/packets.def 2008-12-30 23:29:33.000000000 +0100
+++ freeciv-2.1.99svn.patch/common/packets.def 2008-12-31 16:37:16.000000000 +0100
@@ -414,6 +414,10 @@
UINT8 razechance;
BOOL savepalace;
BOOL natural_city_names;
+ UINT8 migrationturn;
+ UINT8 migrationdist;
+ UINT8 migrationplayer;
+ UINT8 migrationworld;
BOOL turnblock;
BOOL fixedlength;
BOOL auto_ai_toggle;
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/server/cityturn.c freeciv-2.1.99svn.patch/server/cityturn.c
--- freeciv-2.1.99svn15391/server/cityturn.c 2008-12-25 19:45:49.000000000 +0100
+++ freeciv-2.1.99svn.patch/server/cityturn.c 2008-12-31 18:45:15.000000000 +0100
@@ -1867,3 +1867,355 @@
remove_city(pcity);
return TRUE;
}
+
+/***************************************************************************
+ Helper function to calculate a score of a city. It indicates the
+ "migration desirability" of the city. The higher the score the more likely
+ citizens will migrate to it.
+
+ The score depends on the city size, the feeling of its citizens and the
+ surplus of trade, luxury and science.
+
+ formula:
+ score = ([city size] + feeling) * factors
+
+ * feeling of the citizens
+ feeling = 1.00 * happy citizens
+ + 0.00 * content citizens
+ - 0.25 * unhappy citizens
+ - 0.50 * unhappy citizens
+
+ * factors
+ * the build costs of all buildings
+ f = (1 + (1 - exp(-[build shield cost]/1000))/5)
+ * the trade of the city
+ f = (1 + (1 - exp(-[city surplus trade]/100))/5)
+ * the luxury within the city
+ f = (1 + (1 - exp(-[city surplus luxury]/100))/5)
+ * the science within the city
+ f = (1 + (1 - exp(-[city surplus science]/100))/5)
+
+ all factors f have values between 1 and 1.2; the overall factor will be
+ between 1.0 (smaller cities) and 2.0 (bigger cities)
+
+ [build shield cost], [city surplus trade], [city surplus luxury] and
+ [city surplus science] _must_ be >= 0!
+
+ * for the capital an additional factor of 1.25 is used
+**************************************************************************/
+static float city_score(const struct city *pcity)
+{
+ float score = 0.0;
+ int build_shield_cost = 0;
+
+ if (!pcity) {
+ return 0;
+ }
+
+ /* feeling of the citizens */
+ score = pcity->size + 1.00 * pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]
+ + 0.00 * pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]
+ - 0.25 * pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]
+ - 0.50 * pcity->feel[CITIZEN_ANGRY][FEELING_FINAL];
+
+ /* take shild costs of all buidings into account */
+ city_built_iterate(pcity, pimprove) {
+ build_shield_cost += impr_build_shield_cost(pimprove);
+ } city_built_iterate_end;
+ score *= (1 + (1 - exp(-(float)build_shield_cost/1000))/5);
+ /* take trade into account */
+ score *= (1 + (1 - exp(-(float)pcity->surplus[O_TRADE]/100))/5);
+ /* take luxury into account */
+ score *= (1 + (1 - exp(-(float)pcity->surplus[O_LUXURY]/100))/5);
+ /* take science into account */
+ score *= (1 + (1 - exp(-(float)pcity->surplus[O_SCIENCE]/100))/5);
+
+ if (is_capital(pcity)) {
+ /* the capital is a magnet for the citizens */
+ score *= 1.25;
+ }
+
+ freelog(LOG_DEBUG, "[M] %s score: %.3f", city_name(pcity), score);
+
+ return score;
+}
+
+/**************************************************************************
+ Do the migrations between the cities that overlap, if the growth of the
+ target city is not blocked due to a missing improvement or missing food.
+**************************************************************************/
+static bool make_city_migration(const struct player *pplayer_from,
+ struct city *pcity_from,
+ const struct player *pplayer_to,
+ struct city *pcity_to)
+{
+ char city_from_name[MAX_LEN_NAME];
+ struct city *rcity = NULL;
+
+ if (pcity_to->surplus[O_FOOD] < 0) {
+ /* insufficiency food in receiver city; no additional citizens */
+ if (pplayer_from == pplayer_to) {
+ /* migration between one nation */
+ notify_player(pplayer_to, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s can't go to %s "
+ "because there is not enough food available! "
+ "You are responsible for her poverty!"),
+ city_name(pcity_from), city_name(pcity_to));
+ } else {
+ /* migration between different nations */
+ notify_player(pplayer_from, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s can't go to %s (%s) "
+ "because there is not enough food available! "
+ "Improve your city to keep your citizens!"),
+ city_name(pcity_from), city_name(pcity_to),
+ player_name(pplayer_to));
+ notify_player(pplayer_to, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s (%s) can't go to %s "
+ "because there is not enough food available! "
+ "You are responsible for her poverty!"),
+ city_name(pcity_from), player_name(pplayer_from),
+ city_name(pcity_to));
+ }
+
+ return FALSE;
+ }
+
+ if (!city_can_grow_to(pcity_to, pcity_to->size + 1)) {
+ /* receiver city can't grow */
+ if (pplayer_from == pplayer_to) {
+ /* migration between one nation */
+ notify_player(pplayer_to, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s can't go to %s "
+ "because it needs an improvement to grow! "
+ "You are responsible for her poverty!"),
+ city_name(pcity_from), city_name(pcity_to));
+ } else {
+ /* migration between different nations */
+ notify_player(pplayer_from, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s can't go to %s of %s "
+ "because it needs an improvement to grow! "
+ "Improve your city to keep your citizens!"),
+ city_name(pcity_from), city_name(pcity_to),
+ player_name(pplayer_to));
+ notify_player(pplayer_to, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s of %s can't go to %s "
+ "because it needs an improvement to grow! "
+ "You are responsible for her poverty!"),
+ city_name(pcity_from), player_name(pplayer_from),
+ city_name(pcity_to));
+ }
+
+ return FALSE;
+ }
+
+ /* we copy the city name, maybe we disband it! */
+ sz_strlcpy(city_from_name, city_name(pcity_from));
+ /* reduce size of giver */
+ if (pcity_from->size == 1) {
+ /* find closest city other of the same player than pcity_from */
+ rcity = find_closest_owned_city(pplayer_from, city_tile(pcity_from),
+ FALSE, pcity_from);
+
+ if (rcity) {
+ /* transfer all units to the closest city */
+ transfer_city_units(pplayer_from, pplayer_from,
+ pcity_from->units_supported, rcity, pcity_from,
+ -1, TRUE);
+ remove_city(pcity_from);
+
+ notify_player(pplayer_from, city_tile(pcity_from), E_CITY_TRANSFER,
+ _("Game: %s was disbanded by its citizens."),
+ city_from_name);
+ } else {
+ /* it's the only city of the nation; stop here */
+ notify_player(pplayer_from, city_tile(pcity_from), E_CITY_TRANSFER,
+ _("Game: Citizen of %s are unhappy and want to "
+ "migrate to %s (%s) in search for a better life."),
+ city_from_name, city_name(pcity_to),
+ player_name(pplayer_to));
+ return FALSE;
+ }
+ } else {
+ city_reduce_size(pcity_from, 1, pplayer_from);
+ city_refresh_vision(pcity_from);
+ city_refresh(pcity_from);
+ }
+ /* raise size of receiver city */
+ city_increase_size(pcity_to);
+ city_refresh_vision(pcity_to);
+ city_refresh(pcity_to);
+
+ if (pplayer_from == pplayer_to) {
+ /* migration between one nation */
+ notify_player(pplayer_from, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s moved to %s in search for a "
+ "better life."), city_from_name, city_name(pcity_to));
+ } else {
+ /* migration between different nations */
+ notify_player(pplayer_from, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s moved to %s (%s) in search "
+ "for a better life."), city_from_name,
+ city_name(pcity_to), player_name(pplayer_to));
+ notify_player(pplayer_to, city_tile(pcity_to), E_CITY_TRANSFER,
+ _("Game: Migrants from %s (%s) moved to %s in search "
+ "for a better life."), city_from_name,
+ player_name(pplayer_from), city_name(pcity_to));
+ }
+
+ freelog(LOG_DEBUG, "[M] T%d migration successful (%s -> %s)",
+ game.info.turn, city_from_name, city_name(pcity_to));
+
+ return TRUE;
+}
+
+/**************************************************************************
+ Check for citizens who want to migrate between the cities that overlap.
+ Migrants go to the city with higher score (saved in city->score), if the
+ growth of the target city is not blocked due to a missing improvement.
+
+ The following setting are used:
+
+ 'game.info.migrationsturns' controls the number of turns between
+ migration checks for one city (counted from the founding). If this
+ setting is zero, or it is the first turn (T0), migration does no occur.
+
+ 'game.info.migrationsdist' is the maximal distance for migration.
+
+ 'game.info.migrationsplayer' gives the chance for migration within one
+ nation.
+
+ 'game.info.migrationsworld' gives the chance for migration between all
+ nations.
+**************************************************************************/
+void check_city_migrations(struct player *pplayer)
+{
+ if (!pplayer || game.info.migrationturn <= 0 || game.info.turn <= 0
+ || (game.info.migrationworld == 0 && game.info.migrationplayer == 0)
+ ) {
+ return;
+ }
+
+ /* check for each city
+ * city_list_iterate_safe_end must be used because we could
+ * remove one city from the list */
+ city_list_iterate_safe(pplayer->cities, pcity) {
+ /* no migration out of the capital */
+ if (is_capital(pcity)) {
+ continue;
+ }
+
+ /* check only each (game.info.migrationturn) turn
+ * (counted from the funding turn) */
+ if (((game.info.turn - pcity->turn_founded)
+ % game.info.migrationturn) > 0) {
+ continue;
+ }
+
+ float best_city_player_score = 0;
+ struct city *best_city_player = NULL;
+
+ float best_city_world_score = 0;
+ struct city *best_city_world = NULL;
+
+ /* score of the actual city
+ * taking into account a persistence factor of 3 */
+ float score_from = city_score(pcity) * 3;
+ float score_tmp = 0;
+
+ freelog(LOG_DEBUG, "[M] T%d check city: %s score: %6.3f (%s)",
+ game.info.turn, city_name(pcity), score_from,
+ player_name(pplayer));
+
+ best_city_player_score = 0;
+ best_city_world_score = 0;
+
+ /* loop over all tiles in a circle of game.info.migrationdist radius
+ * in search for cities which overlap */
+ circle_iterate(city_tile(pcity),(game.info.migrationdist *
+ game.info.migrationdist + 1), ptile) {
+ struct city *acity = tile_city(ptile);
+
+ if (!acity || acity == pcity) {
+ /* no city or the city in the center */
+ continue;
+ }
+
+ /* distance between the two cities */
+ int dist = real_map_distance(city_tile(pcity), city_tile(acity));
+
+ /* score of the second city, weighted by the distance */
+ score_tmp = city_score(acity) * (GAME_MAX_MIGRATION_DIST - dist)
+ / GAME_MAX_MIGRATION_DIST;
+
+ freelog(LOG_DEBUG, "[M] T%d - compare city: %s (%s) dist: %d "
+ "score: %6.3f", game.info.turn, city_name(acity),
+ player_name(city_owner(acity)), dist, score_tmp);
+
+ if (game.info.migrationplayer != 0 && city_owner(acity) == pplayer) {
+ /* inmigrate in cities of the same owner */
+ if ((score_tmp > score_from)
+ && (score_tmp > best_city_player_score)) {
+ /* select the best! */
+ best_city_player_score = score_tmp;
+ best_city_player = acity;
+
+ freelog(LOG_DEBUG, "[M] T%d - best city (player): %s (%s) score: "
+ "%6.3f (> %6.3f)", game.info.turn,
+ city_name(best_city_player), player_name(pplayer),
+ best_city_player_score, score_from);
+ }
+ } else if (game.info.migrationworld != 0
+ && city_owner(acity) != pplayer) {
+ /* inmigrate between cities of different owners */
+ if ((score_tmp > score_from)
+ && (score_tmp > best_city_world_score)) {
+ /* select the best! */
+ best_city_world_score = score_tmp;
+ best_city_world = acity;
+
+ freelog(LOG_DEBUG, "[M] T%d - best city (world): %s (%s) score: "
+ "%6.3f (> %6.3f)", game.info.turn,
+ city_name(best_city_world),
+ player_name(city_owner(best_city_world)),
+ best_city_world_score, score_from);
+ }
+ }
+ } circle_iterate_end;
+
+ if (best_city_player_score > 0) {
+ /* first, do the migration within one nation */
+ if (myrand (100) >= game.info.migrationplayer) {
+ /* no migration */
+ notify_player(pplayer, city_tile(pcity), E_CITY_TRANSFER,
+ _("Game: Citizens of %s are thinking about migration "
+ "to %s in search for a better life."),
+ pcity->name, city_name(best_city_player));
+ } else {
+ make_city_migration(pplayer, pcity, pplayer, best_city_player);
+ }
+
+ /* stop here */
+ continue;
+ }
+
+ if (best_city_world_score > 0) {
+ /* second, do the migration between all nations */
+ if (myrand (100) >= game.info.migrationworld) {
+ /* no migration */
+ notify_player(pplayer, city_tile(pcity), E_CITY_TRANSFER,
+ _("Game: Citizens of %s are thinking about migration "
+ "to %s of %s in search for a better life."),
+ city_name(pcity), city_name(best_city_world),
+ player_name(city_owner(best_city_world)));
+ } else {
+ make_city_migration(pplayer, pcity, city_owner(best_city_world),
+ best_city_world);
+ }
+
+ /* stop here */
+ continue;
+ }
+
+ } city_list_iterate_safe_end;
+
+}
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/server/cityturn.h freeciv-2.1.99svn.patch/server/cityturn.h
--- freeciv-2.1.99svn15391/server/cityturn.h 2008-12-25 19:45:49.000000000 +0100
+++ freeciv-2.1.99svn.patch/server/cityturn.h 2008-12-30 23:31:54.000000000 +0100
@@ -46,4 +46,7 @@
void advisor_choose_build(struct player *pplayer, struct city *pcity);
void nullify_prechange_production(struct city *pcity);
+
+void check_city_migrations(struct player *pplayer);
+
#endif /* FC__CITYTURN_H */
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/server/savegame.c freeciv-2.1.99svn.patch/server/savegame.c
--- freeciv-2.1.99svn15391/server/savegame.c 2008-12-27 17:25:17.000000000 +0100
+++ freeciv-2.1.99svn.patch/server/savegame.c 2008-12-31 16:37:16.000000000 +0100
@@ -4291,6 +4291,18 @@
game.info.allowed_city_names =
secfile_lookup_int_default(file, game.info.allowed_city_names,
"game.allowed_city_names");
+ game.info.migrationturn =
+ secfile_lookup_int_default(file, game.info.migrationturn,
+ "game.migrationturn");
+ game.info.migrationdist =
+ secfile_lookup_int_default(file, game.info.migrationdist,
+ "game.migrationdist");
+ game.info.migrationplayer =
+ secfile_lookup_int_default(file, game.info.migrationplayer,
+ "game.migrationplayer");
+ game.info.migrationworld =
+ secfile_lookup_int_default(file, game.info.migrationworld,
+ "game.migrationworld");
if(civstyle == 1) {
string = "civ1";
@@ -4943,6 +4955,10 @@
secfile_insert_bool(file, game.info.happyborders, "game.happyborders");
secfile_insert_int(file, game.info.diplomacy, "game.diplomacy");
secfile_insert_int(file, game.info.allowed_city_names, "game.allowed_city_names");
+ secfile_insert_int(file, game.info.migrationturn, "game.migrationturn");
+ secfile_insert_int(file, game.info.migrationdist, "game.migrationdist");
+ secfile_insert_int(file, game.info.migrationplayer, "game.migrationplayer");
+ secfile_insert_int(file, game.info.migrationworld, "game.migrationworld");
{
/* Now always save these, so the server options reflect the
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/server/settings.c freeciv-2.1.99svn.patch/server/settings.c
--- freeciv-2.1.99svn15391/server/settings.c 2008-12-25 19:45:49.000000000 +0100
+++ freeciv-2.1.99svn.patch/server/settings.c 2008-12-31 16:47:04.000000000 +0100
@@ -841,6 +841,44 @@
"on the surrounding terrain."),
NULL, GAME_DEFAULT_NATURALCITYNAMES)
+ GEN_INT("migrationturn", game.info.migrationturn,
+ SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
+ N_("Turn count between citizen migrations"),
+ N_("This setting controls the number of turns between the "
+ "automatic transfer of citizens between overlapping cities. "
+ "Citizens will generally move to larger cities with happyer "
+ "people, improvements and a surplus of trade, luxury and "
+ "science. The palace building also greatly increases the "
+ "destination desirability. If this setting is zero, "
+ "migration will be disabled."), NULL, GAME_MIN_MIGRATION_TURN,
+ GAME_MAX_MIGRATION_TURN, GAME_DEFAULT_MIGRATION_TURN)
+
+ GEN_INT("migrationdist", game.info.migrationdist,
+ SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
+ N_("Distance for migration between cities"),
+ N_("If two cities overlap or are close to each over, citizens "
+ "can migrate between both cities. For example, when this "
+ "value is 3, there can be up to two empty fields between "
+ "two cities for citizens to migrate."), NULL,
+ GAME_MIN_MIGRATION_DIST, GAME_MAX_MIGRATION_DIST,
+ GAME_DEFAULT_MIGRATION_DIST)
+
+ GEN_INT("migrationplayer", game.info.migrationplayer,
+ SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
+ N_("Chance for migration within one nation"),
+ N_("Possibility of migration between overlapping cities"
+ "within one nation."),
+ NULL, GAME_MIN_MIGRATION_PLAYER, GAME_MAX_MIGRATION_PLAYER,
+ GAME_DEFAULT_MIGRATION_PLAYER)
+
+ GEN_INT("migrationworld", game.info.migrationworld,
+ SSET_RULES_FLEXIBLE, SSET_SOCIOLOGY, SSET_RARE, SSET_TO_CLIENT,
+ N_("Chance for migration between all cities"),
+ N_("Possibility of migration between overlapping cities"
+ "taking into account cities of all nations."),
+ NULL, GAME_MIN_MIGRATION_WORLD, GAME_MAX_MIGRATION_WORLD,
+ GAME_DEFAULT_MIGRATION_WORLD)
+
/* Meta options: these don't affect the internal rules of the game, but
* do affect players. Also options which only produce extra server
* "output" and don't affect the actual game.
diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/server/srv_main.c freeciv-2.1.99svn.patch/server/srv_main.c
--- freeciv-2.1.99svn15391/server/srv_main.c 2008-12-27 17:25:17.000000000 +0100
+++ freeciv-2.1.99svn.patch/server/srv_main.c 2008-12-31 16:52:02.000000000 +0100
@@ -869,6 +869,13 @@
summon_barbarians(); /* wild guess really, no idea where to put it, but
I want to give them chance to move their units */
+ if (game.info.migrationturn > 0) {
+ freelog(LOG_DEBUG, "Season of migrations");
+ players_iterate(pplayer) {
+ check_city_migrations(pplayer);
+ } players_iterate_end;
+ }
+
update_environmental_upset(S_POLLUTION, &game.info.heating,
&game.info.globalwarming, &game.info.warminglevel,
global_warming);
_______________________________________________
Freeciv-dev mailing list
[email protected]
https://mail.gna.org/listinfo/freeciv-dev