[Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 [book - Do 22. Jan 2009, 05:15:02]: In anticipation of future use beyond the migration feature, I have made the city migration score a field in the city struct, and added this field to the city info packet sent to clients which can see the city internals. However, since at the moment the score is only updated and used in the check_city_migrations() function, and since there would appear to be no secfile functions for float datatypes, I have neglected to save/load this field in savegames. This can be easily added later if needed. The city score could be multiplied with 100 to get an int value which can be saved ... I used a float because I needed it for the calculation I would appreciate more testing (if you don't mind doing the full re-compile when this patch is applied), especially gameplay with various combinations of the migration settings to determine the best default values. I have updated the freeciv opensuse rpm's including this patch (see http://forum.freeciv.org/viewtopic.php?t=5749 ) ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 I have made some minor changes to the combined v6 patches (the base migration patch v6 and the food patch). The result is the attached patch which could be commited to trunk, if nobody has any objection or problems in the code are found. Migration is a pretty radical game concept and changes the game mechanics substantially. There are similarities between certain aspects of this feature and other civ game rules, for example the city migration score is sort of like a city's culture rating from civ3; the modular nature of the code in this patch will make future generalizations to features like culture possible. The main change from v6 is in the naming of the various migration settings. There is now one master setting 'migration' which controls whether migration is activated in the game. The other settings have no effect if this option is disabled. By default 'migration' is set to 0, i.e. migration is off. The other migration settings are renamed: migrationturn - mgr_turninterval migrationfood - mgr_foodneeded migrationdist - mgr_distance migrationworld - mgr_worldchance migrationplayer - mgr_nationchance This is so that users do not have to type the full migration prefix to get an unambiguous match, yet still can see from the name that the setting is migration related. The patch in 40671 is required to make the set command work with option names containing underscores. In anticipation of future use beyond the migration feature, I have made the city migration score a field in the city struct, and added this field to the city info packet sent to clients which can see the city internals. However, since at the moment the score is only updated and used in the check_city_migrations() function, and since there would appear to be no secfile functions for float datatypes, I have neglected to save/load this field in savegames. This can be easily added later if needed. As for user visible messages, I have changed the migration messages to give the nation of a city rather than the name of the player that owns it. I have also added TRANS (translator) comments to clarify what the %s formats should be interpreted as. Otherwise I have just normalized and simplified the code in a few places. The logic should be same as in v6. I would appreciate more testing (if you don't mind doing the full re-compile when this patch is applied), especially gameplay with various combinations of the migration settings to determine the best default values. --- 旅は長くて苦しかった。たくさん死んじゃった。 common/city.h |1 + common/game.c |6 + common/game.h | 20 +++ common/packets.def |7 + server/citytools.c |7 +- server/citytools.h |8 +- server/cityturn.c | 397 server/cityturn.h |3 + server/savegame.c | 30 server/settings.c | 78 ++ server/srv_main.c |7 + version.in |2 +- 12 files changed, 559 insertions(+), 7 deletions(-) diff --git a/common/city.h b/common/city.h index 6fef23f..f3f36cf 100644 --- a/common/city.h +++ b/common/city.h @@ -330,6 +330,7 @@ struct city { int steal;/* diplomats steal once; for spies, gets harder */ int turn_founded; int turn_last_built; + float migration_score;/* Updated by check_city_migrations. */ int before_change_shields;/* If changed this turn, shields before penalty */ int caravan_shields; /* If caravan has helped city to build wonder. */ diff --git a/common/game.c b/common/game.c index 25e627f..31c7337 100644 --- a/common/game.c +++ b/common/game.c @@ -275,6 +275,12 @@ void game_init(void) game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE; game.info.savepalace= GAME_DEFAULT_SAVEPALACE; game.info.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES; + game.info.migration= GAME_DEFAULT_MIGRATION; + game.info.mgr_turninterval = GAME_DEFAULT_MGR_TURNINTERVAL; + game.info.mgr_foodneeded = GAME_DEFAULT_MGR_FOODNEEDED; + game.info.mgr_distance = GAME_DEFAULT_MGR_DISTANCE; + game.info.mgr_worldchance = GAME_DEFAULT_MGR_WORLDCHANCE; + game.info.mgr_nationchance = GAME_DEFAULT_MGR_NATIONCHANCE; game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN; game.info.foodbox = GAME_DEFAULT_FOODBOX; game.info.shieldbox = GAME_DEFAULT_SHIELDBOX; diff --git a/common/game.h b/common/game.h index f993b36..ce4da03 100644 --- a/common/game.h +++ b/common/game.h @@ -250,6 +250,26 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_DEFAULT_NATURALCITYNAMES TRUE +#define GAME_DEFAULT_MIGRATIONFALSE + +#define GAME_DEFAULT_MGR_TURNINTERVAL 5 +#define GAME_MIN_MGR_TURNINTERVAL 1 +#define GAME_MAX_MGR_TURNINTERVAL 100 + +#define GAME_DEFAULT_MGR_FOODNEEDED TRUE + +#define GAME_DEFAULT_MGR_DISTANCE 3 +#define
Re: [Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 Am Friday 02 January 2009 07:08:22 schrieb Madeline Book: URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 Most of the time I just put in printfs for debugging and remove them later. ;) This is also possible; I think it is the easiest way to get some debugging output ... The attached version 5 of the migration patch has the following changes: * check for wonders (higher score; never disband a city with a wonder) * reduced messages to the player (some text was not usefull at all) * use LOG_VERBOSE Matthias diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/common/game.c freeciv-2.1.99svn.patch_migration/common/game.c --- freeciv-2.1.99svn15391/common/game.c 2008-12-25 19:45:44.0 +0100 +++ freeciv-2.1.99svn.patch_migration/common/game.c 2008-12-31 16:37:12.0 +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_migration/common/game.h --- freeciv-2.1.99svn15391/common/game.h 2008-12-30 23:29:33.0 +0100 +++ freeciv-2.1.99svn.patch_migration/common/game.h 2008-12-31 17:39:10.0 +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_PLAYER0 +#define GAME_MAX_MIGRATION_PLAYER100 + +#define GAME_DEFAULT_MIGRATION_WORLD 10 +#define GAME_MIN_MIGRATION_WORLD 0 +#define GAME_MAX_MIGRATION_WORLD 100 + #define GAME_DEFAULT_AQUEDUCTLOSS0 #define GAME_MIN_AQUEDUCTLOSS0 #define GAME_MAX_AQUEDUCTLOSS100 diff -ur -X./freeciv-2.1.99svn15391/diff_ignore freeciv-2.1.99svn15391/common/packets.def freeciv-2.1.99svn.patch_migration/common/packets.def --- freeciv-2.1.99svn15391/common/packets.def 2008-12-30 23:29:33.0 +0100 +++ freeciv-2.1.99svn.patch_migration/common/packets.def 2008-12-31 16:37:16.0 +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_migration/server/cityturn.c --- freeciv-2.1.99svn15391/server/cityturn.c 2008-12-25 19:45:49.0 +0100 +++ freeciv-2.1.99svn.patch_migration/server/cityturn.c 2009-01-02 03:54:53.0 +0100 @@ -90,6 +90,12 @@ static void update_city_activity(struct player *pplayer, struct city *pcity); static void nullify_caravan_and_disband_plus(struct city *pcity); +static float city_score(const struct city *pcity); +static bool make_city_migration(const struct player *pplayer_from, +struct city *pcity_from, +const struct player *pplayer_to, +struct city *pcity_to); + /** ... **/ @@ -1867,3 +1873,363 @@ 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
[Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 [guest - Thu Jan 01 03:28:31 2009]: [matthias.pfaffer...@mapfa.de - Mi 31. Dez 2008, 18:03:52]: - Use LOG_DEBUG not LOG_NORMAL for debugging messages. Oh, this was for me to test the patch; all set to debug now There is the possibility to activate DEBUG messages for only one file and there only selected lines - how to do this? at the moment I don't understand this part ... :-( I only know of the -d 4:file syntax (see --help). The most annoying thing about that is that you get a load of verbose messages spam due to -d 3 automatically being set for every other file. Helpful in that case is to use the -l logfile option and unique message prefixes (i.e. for grep). Most of the time I just put in printfs for debugging and remove them later. ;) --- いいじゃないか? ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] (PR#40612) Patch: migration
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 [matthias.pfaffer...@mapfa.de - 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.0 +0100 +++ freeciv-2.1.99svn.patch/common/game.c 2008-12-31 16:37:12.0 +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.0 +0100 +++ freeciv-2.1.99svn.patch/common/game.h 2008-12-31 17:39:10.0 +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
[Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 [matthias.pfaffer...@mapfa.de - Wed Dec 31 18:03:52 2008]: 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. Don't worry about that assertion too much; it is due to a known problem in the border code (40589). Sooner or later I will get to hunting it down. ;( --- 余命いくばくもない。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 [matthias.pfaffer...@mapfa.de - 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. :( 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). In particular: - No lines longer than 76 characters + 1 newline. - Multi-line function arguments lined up to column one past the initial '(' and similarly for if-statements. - Use city_tile(pcity) instead of pcity-tile, and similar. - Use LOG_DEBUG not LOG_NORMAL for debugging messages. - Use is_capital(pcity) directly instead of find_palace(). - Use const in function arguments if the function does not modify the arguments (e.g. the score function). - Make the default setting values disable migration. 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? Anyway I'll check it again in at least a few days and when I'm sure you are not working on it too. ;) --- 私の人生は大移住の話から始まります。 common/game.c |1 + common/game.h |4 ++ common/packets.def |1 + server/cityturn.c | 135 server/cityturn.h |3 + server/savegame.c |4 ++ server/settings.c | 13 + server/srv_main.c |7 +++ 8 files changed, 168 insertions(+), 0 deletions(-) diff --git a/common/game.c b/common/game.c index f0d4378..0d5bfab 100644 --- a/common/game.c +++ b/common/game.c @@ -275,6 +275,7 @@ void game_init(void) game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE; game.info.savepalace= GAME_DEFAULT_SAVEPALACE; game.info.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES; + game.info.migration = GAME_DEFAULT_MIGRATION; game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN; game.info.foodbox = GAME_DEFAULT_FOODBOX; game.info.shieldbox = GAME_DEFAULT_SHIELDBOX; diff --git a/common/game.h b/common/game.h index 4e75ece..f593bf2 100644 --- a/common/game.h +++ b/common/game.h @@ -250,6 +250,10 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_DEFAULT_NATURALCITYNAMES TRUE +#define GAME_DEFAULT_MIGRATION 0 +#define GAME_MIN_MIGRATION 0 +#define GAME_MAX_MIGRATION 100 + #define GAME_DEFAULT_AQUEDUCTLOSS0 #define GAME_MIN_AQUEDUCTLOSS0 #define GAME_MAX_AQUEDUCTLOSS100 diff --git a/common/packets.def b/common/packets.def index 8455fda..a00a2c4 100644 --- a/common/packets.def +++ b/common/packets.def @@ -414,6 +414,7 @@ PACKET_GAME_INFO=15; sc UINT8 razechance; BOOL savepalace; BOOL natural_city_names; + UINT8 migration; BOOL turnblock; BOOL fixedlength; BOOL auto_ai_toggle; diff --git a/server/cityturn.c b/server/cityturn.c index b860a5e..412eddc 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -1867,3 +1867,138 @@ static bool disband_city(struct city *pcity) remove_city(pcity); return TRUE; } + +/*** + Helper function to find the migration desirability of a city. The higher + the score the more likely citizens will migrate to it. + + The score depends on the total trade and shield output of the city, its + size, number of ocean squares around it, and the shield cost of all the + improvements in the city. The score is doubled for the player's capital + city (the one containing the palace small wonder). +***/ +static int city_migration_score(const struct city *pcity) +{ + int score = 0; + + if (!pcity) { +return 0; + } + + score = pcity-prod[O_TRADE] + pcity-prod[O_SHIELD]; + score += 10 * pcity-size; + square_iterate(city_tile(pcity), 2, ptile) { +if (is_ocean(tile_terrain(ptile))) { + score += 2; +} + } square_iterate_end; + + city_built_iterate(pcity, pimprove) { +score += impr_build_shield_cost(pimprove) * 2; + } city_built_iterate_end; + + if (find_palace(city_owner(pcity)) == pcity) { +score *= 2; + } + + return score; +} + +/** + Do the migrations between the cities that overlap. Migrants go to the + city with higher city_migration_score(), if the growth of the target + city is not blocked due to a missing improvement. + + The setting
[Freeciv-Dev] (PR#40612) Patch: migration
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40612 The attached patch implements the migration of population between cities that overlap. It has an activation / deactivation option (default: on). The patch original cames from jorneg [1]. I updated it to the svn trunk [2]. [1] http://forum.freeciv.org/viewtopic.php?t=1348 [2] http://forum.freeciv.org/viewtopic.php?t=4095 -- Matthias Pfafferodt - http://www.mapfa.de Matthias.Pfafferodt at mapfa.de diff -ur -X./freeciv-2.1.99svn15387/diff_ignore freeciv-2.1.99svn15387/common/game.c freeciv-2.1.99svn.patch/common/game.c --- freeciv-2.1.99svn15387/common/game.c 2008-12-25 19:45:44.0 +0100 +++ freeciv-2.1.99svn.patch/common/game.c 2008-12-27 18:11:51.0 +0100 @@ -275,6 +275,7 @@ game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE; game.info.savepalace= GAME_DEFAULT_SAVEPALACE; game.info.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES; + game.info.migration = GAME_DEFAULT_MIGRATION; game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN; game.info.foodbox = GAME_DEFAULT_FOODBOX; game.info.shieldbox = GAME_DEFAULT_SHIELDBOX; diff -ur -X./freeciv-2.1.99svn15387/diff_ignore freeciv-2.1.99svn15387/common/game.h freeciv-2.1.99svn.patch/common/game.h --- freeciv-2.1.99svn15387/common/game.h 2008-12-25 19:45:44.0 +0100 +++ freeciv-2.1.99svn.patch/common/game.h 2008-12-27 18:11:26.0 +0100 @@ -248,6 +248,8 @@ #define GAME_DEFAULT_NATURALCITYNAMES TRUE +#define GAME_DEFAULT_MIGRATION TRUE + #define GAME_DEFAULT_AQUEDUCTLOSS0 #define GAME_MIN_AQUEDUCTLOSS0 #define GAME_MAX_AQUEDUCTLOSS100 diff -ur -X./freeciv-2.1.99svn15387/diff_ignore freeciv-2.1.99svn15387/common/packets.def freeciv-2.1.99svn.patch/common/packets.def --- freeciv-2.1.99svn15387/common/packets.def 2008-12-27 17:25:16.0 +0100 +++ freeciv-2.1.99svn.patch/common/packets.def 2008-12-27 19:38:02.0 +0100 @@ -414,6 +414,7 @@ UINT8 razechance; BOOL savepalace; BOOL natural_city_names; + BOOL migration; BOOL turnblock; BOOL fixedlength; BOOL auto_ai_toggle; diff -ur -X./freeciv-2.1.99svn15387/diff_ignore freeciv-2.1.99svn15387/server/cityturn.c freeciv-2.1.99svn.patch/server/cityturn.c --- freeciv-2.1.99svn15387/server/cityturn.c 2008-12-25 19:45:49.0 +0100 +++ freeciv-2.1.99svn.patch/server/cityturn.c 2008-12-27 18:32:19.0 +0100 @@ -1867,3 +1867,121 @@ remove_city(pcity); return TRUE; } + +/** + Helpful function to make a score of a city. + + It computes the trade of the city, the production and the tiles of the city. +**/ +static int city_score(struct city *pcity) +{ + int score = 0; + + score = pcity-prod[O_TRADE] + pcity-prod[O_SHIELD]; + score += 10 * pcity-size; + square_iterate(pcity-tile, 2, ptile) { +if (is_ocean(ptile-terrain)) { + score += 2; +} + } square_iterate_end; + + city_built_iterate(pcity, pimprove) { +score += impr_build_shield_cost(pimprove) * 2; + } city_built_iterate_end; + + if (find_palace(city_owner(pcity)) == pcity) { +score *= 2; + } + + return score; +} + +/** + Make the migrations between the cities that overlap. + + Migrants go to the better city of both involved, the giver and the receiver. +**/ +void make_city_migrations(struct player *pplayer) +{ + char city_name[100]; + + if ((game.info.turn % 5) 0) { +return; + } + + /* first we search for cities that overlap */ + city_list_iterate(pplayer-cities, pcity) { +struct city *best_city = NULL; +int score_1 = city_score(pcity); +int best_score = 0; + +square_iterate(pcity-tile, 2, ptile) { + struct city *acity = tile_city(ptile); + if (acity) { +/* here we have two cities that overlap... */ +int score_2 = city_score(acity); + +/* inmigrate in cities of the same owner */ +if (city_owner(acity) != pplayer) { + continue; +} + +/* inmigrate in cities that can grow */ +if (!city_can_grow_to(acity, acity-size + 1)) { + score_2 /= 4; +} + +if ((score_2 score_1) (score_2 best_score)) { + /* select the best! */ + best_score = score_2; + best_city = acity; +} + } +} square_iterate_end; + +/* do the migration */ +if (best_score 0) { + /* we copy the city name, maybe we disband it! */ + sz_strlcpy(city_name, pcity-name); + if (city_can_grow_to(best_city, best_city-size + 1)) { +/* reduce size of giver */ +if (pcity-size == 1) { + struct city *rcity = NULL; + /* find closest city other than pcity */ + rcity =