Index: ai/advdomestic.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/advdomestic.c,v retrieving revision 1.102 diff -u -r1.102 advdomestic.c --- ai/advdomestic.c 4 Apr 2003 15:47:45 -0000 1.102 +++ ai/advdomestic.c 27 Apr 2003 13:36:35 -0000 @@ -987,7 +987,7 @@ unit_type = best_role_unit(pcity, F_CITIES); if (unit_type != U_LAST - && est_food > utype_food_cost(get_unit_type(unit_type), gov)) { + && est_food >= utype_food_cost(get_unit_type(unit_type), gov)) { /* founder_want calculated in settlers.c, called from ai_manage_city(). */ int want = pcity->ai.founder_want; Index: ai/aidata.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v retrieving revision 1.12 diff -u -r1.12 aidata.c --- ai/aidata.c 20 Apr 2003 11:22:59 -0000 1.12 +++ ai/aidata.c 27 Apr 2003 13:36:35 -0000 @@ -32,6 +32,7 @@ #include "advmilitary.h" #include "aicity.h" +#include "aihand.h" #include "aitools.h" #include "aiunit.h" @@ -250,6 +251,9 @@ ai->unhappy_priority = TRADE_WEIGHTING; /* danger */ ai->angry_priority = TRADE_WEIGHTING * 3; /* grave danger */ ai->pollution_priority = POLLUTION_WEIGHTING; + + /* Goals */ + ai_best_government(pplayer); } /************************************************************************** Index: ai/aidata.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aidata.h,v retrieving revision 1.6 diff -u -r1.6 aidata.h --- ai/aidata.h 20 Apr 2003 11:22:59 -0000 1.6 +++ ai/aidata.h 27 Apr 2003 13:36:35 -0000 @@ -74,6 +74,14 @@ int unhappy_priority; int angry_priority; int pollution_priority; + + /* Goals */ + struct { + struct { + int idx, val, req; + } govt; + int revolution; + } goal; }; void ai_data_turn_init(struct player *pplayer); Index: ai/aihand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aihand.c,v retrieving revision 1.78 diff -u -r1.78 aihand.c --- ai/aihand.c 4 Apr 2003 15:47:45 -0000 1.78 +++ ai/aihand.c 27 Apr 2003 13:36:35 -0000 @@ -306,20 +306,22 @@ } /************************************************************************** - Change the government form, if it can and there is a good reason. + Find best government to aim for. **************************************************************************/ -static void ai_manage_government(struct player *pplayer) +void ai_best_government(struct player *pplayer) { #undef ANALYSE struct ai_data *ai = ai_data_get(pplayer); - int best_gov = 0; int best_val = 0; - int really_best_val = 0; - int really_best_req = A_UNSET; int i; int bonus = 0; /* in percentage */ int current_gov = pplayer->government; + ai->goal.govt.idx = pplayer->government; + ai->goal.govt.val = 0; + ai->goal.govt.req = A_UNSET; + ai->goal.revolution = pplayer->government; + if (ai_handicap(pplayer, H_AWAY)) { return; } @@ -370,7 +372,9 @@ #endif } city_list_iterate_end; - /* Bonuses for non-economic abilities */ + /* Bonuses for non-economic abilities. We increase val by + * a very small amount here to choose govt in cases where + * we have no cities yet. */ if (government_has_flag(gov, G_BUILD_VETERAN_DIPLOMAT)) { bonus += 3; /* WAG */ } @@ -385,10 +389,12 @@ } if (government_has_flag(gov, G_RAPTURE_CITY_GROWTH)) { bonus += 5; /* WAG */ + val += 1; } if (government_has_flag(gov, G_FANATIC_TROOPS)) { bonus += 3; /* WAG */ } + val += gov->trade_bonus + gov->shield_bonus + gov->food_bonus; val += (val * bonus) / 100; @@ -396,11 +402,12 @@ val = amortize(val, dist); if (val > best_val && can_change_to_government(pplayer, i)) { best_val = val; - best_gov = i; + ai->goal.revolution = i; } - if (val > really_best_val) { - really_best_val = val; - really_best_req = gov->required_tech; + if (val > ai->goal.govt.val) { + ai->goal.govt.idx = i; + ai->goal.govt.val = val; + ai->goal.govt.req = gov->required_tech; } #ifdef ANALYSE freelog(LOG_NORMAL, "%s govt eval %s (dist %d): %d [f%d|sh%d|l%d|g%d|sc%d|h%d|u%d|a%d|p%d]", @@ -409,20 +416,29 @@ ppl_happy, ppl_unhappy, ppl_angry, pollution); #endif } - if (best_gov != current_gov) { - ai_government_change(pplayer, best_gov); /* change */ - } else { - pplayer->government = current_gov; /* reset */ + pplayer->government = current_gov; /* reset */ + ai->goal.govt.val -= best_val; +} + +/************************************************************************** + Change the government form, if it can and there is a good reason. +**************************************************************************/ +static void ai_manage_government(struct player *pplayer) +{ + struct ai_data *ai = ai_data_get(pplayer); + + if (ai->goal.revolution != pplayer->government) { + ai_government_change(pplayer, ai->goal.revolution); /* change */ } /* Crank up tech want */ - if (get_invention(pplayer, really_best_req) == TECH_KNOWN) { + if (get_invention(pplayer, ai->goal.govt.req) == TECH_KNOWN) { return; /* already got it! */ } - pplayer->ai.tech_want[really_best_req] += (really_best_val - best_val); + pplayer->ai.tech_want[ai->goal.govt.req] += ai->goal.govt.val; freelog(LOG_DEBUG, "%s wants %s with want %d", pplayer->name, - advances[really_best_req].name, - pplayer->ai.tech_want[really_best_req]); + advances[ai->goal.govt.req].name, + pplayer->ai.tech_want[ai->goal.govt.req]); } /************************************************************************** Index: ai/aihand.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aihand.h,v retrieving revision 1.6 diff -u -r1.6 aihand.h --- ai/aihand.h 19 Feb 2002 16:41:14 -0000 1.6 +++ ai/aihand.h 27 Apr 2003 13:36:35 -0000 @@ -22,4 +22,6 @@ bool is_unit_choice_type(enum choice_type type); +void ai_best_government(struct player *pplayer); + #endif /* FC__AIHAND_H */ Index: server/citytools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v retrieving revision 1.215 diff -u -r1.215 citytools.c --- server/citytools.c 17 Apr 2003 20:06:36 -0000 1.215 +++ server/citytools.c 27 Apr 2003 13:36:36 -0000 @@ -969,29 +969,18 @@ } /************************************************************************** -... + Create virtual skeleton for a city **************************************************************************/ -void create_city(struct player *pplayer, const int x, const int y, - const char *name) +struct city *create_city_virtual(struct player *pplayer, const int x, + const int y, const char *name) { - struct city *pcity; - int i, x_itr, y_itr; + int i; - freelog(LOG_DEBUG, "Creating city %s", name); - gamelog(GAMELOG_FOUNDC, _("%s (%i, %i) founded by the %s"), name, x, y, - get_nation_name_plural(pplayer->nation)); - - if (terrain_control.may_road) { - map_set_special(x, y, S_ROAD); - if (player_knows_techs_with_flag(pplayer, TF_RAILROAD)) - map_set_special(x, y, S_RAILROAD); - } - send_tile_info(NULL, x, y); + struct city *pcity; pcity=fc_malloc(sizeof(struct city)); - pcity->id=get_next_id_number(); - idex_register_city(pcity); + pcity->id=-1; pcity->owner=pplayer->player_no; pcity->x=x; pcity->y=y; @@ -1036,10 +1025,6 @@ improvement_status_init(pcity->improvements, ARRAY_SIZE(pcity->improvements)); - if (!pplayer->capital) { - pplayer->capital = TRUE; - city_add_improvement(pcity,B_PALACE); - } pcity->turn_last_built = game.year; pcity->changed_from_id = 0; pcity->changed_from_is_unit = FALSE; @@ -1064,14 +1049,46 @@ pcity->tax_bonus = 100; pcity->science_bonus = 100; + unit_list_init(&pcity->units_supported); + + return pcity; +} + +/************************************************************************** +... +**************************************************************************/ +void create_city(struct player *pplayer, const int x, const int y, + const char *name) +{ + struct city *pcity; + int x_itr, y_itr; + + freelog(LOG_DEBUG, "Creating city %s", name); + gamelog(GAMELOG_FOUNDC, _("%s (%i, %i) founded by the %s"), name, x, y, + get_nation_name_plural(pplayer->nation)); + + if (terrain_control.may_road) { + map_set_special(x, y, S_ROAD); + if (player_knows_techs_with_flag(pplayer, TF_RAILROAD)) + map_set_special(x, y, S_RAILROAD); + } + send_tile_info(NULL, x, y); + + pcity = create_city_virtual(pplayer, x, y, name); + pcity->id = get_next_id_number(); + idex_register_city(pcity); + + if (!pplayer->capital) { + pplayer->capital = TRUE; + city_add_improvement(pcity, B_PALACE); + } + /* Before arranging workers to show unknown land */ map_unfog_pseudo_city_area(pplayer, x, y); map_set_city(x, y, pcity); - unit_list_init(&pcity->units_supported); city_list_insert(&pplayer->cities, pcity); - add_city_to_minimap(x, y); /* it is possible to build a city on a tile that is already worked * this will displace the worker on the newly-built city's tile -- Syela */ @@ -1124,6 +1141,28 @@ if (!can_unit_continue_current_activity(punit)) handle_unit_activity_request(punit, ACTIVITY_IDLE); } unit_list_iterate_end; +} + +/************************************************************************** + Removes the virtual skeleton of a city. Contains lots of duplicate code, + but there is no easy way around that. +**************************************************************************/ +void remove_city_virtual(struct city *pcity) +{ + /* Explicitly remove all improvements, to properly remove any global effects + and to handle the preservation of "destroyed" effects. */ + bool effect_update=FALSE; + + built_impr_iterate(pcity, i) { + effect_update = TRUE; + city_remove_improvement(pcity, i); + } built_impr_iterate_end; + + city_map_checked_iterate(pcity->x, pcity->y, x, y, mx, my) { + set_worker_city(pcity, x, y, C_TILE_EMPTY); + } city_map_checked_iterate_end; + city_list_unlink(&city_owner(pcity)->cities, pcity); + free(pcity); } /************************************************************************** Index: server/citytools.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/citytools.h,v retrieving revision 1.45 diff -u -r1.45 citytools.h --- server/citytools.h 4 Apr 2003 15:47:49 -0000 1.45 +++ server/citytools.h 27 Apr 2003 13:36:36 -0000 @@ -69,6 +69,9 @@ void reality_check_city(struct player *pplayer,int x, int y); void update_dumb_city(struct player *pplayer, struct city *pcity); +struct city *create_city_virtual(struct player *pplayer, const int x, + const int y, const char *name); +void remove_city_virtual(struct city *pcity); void create_city(struct player *pplayer, const int x, const int y, const char *name); void remove_city(struct city *pcity);