diff --git a/ai/tex/texaiplayer.c b/ai/tex/texaiplayer.c index cc1c14d973..18662c1588 100644 --- a/ai/tex/texaiplayer.c +++ b/ai/tex/texaiplayer.c @@ -25,6 +25,9 @@ #include "map.h" #include "unit.h" +/* server */ +#include "srv_main.h" + /* server/advisors */ #include "advchoice.h" #include "infracache.h" diff --git a/doc/README.AI_modules b/doc/README.AI_modules index d1d90b18b8..58a4956b2f 100644 --- a/doc/README.AI_modules +++ b/doc/README.AI_modules @@ -157,3 +157,60 @@ New in Freeciv 2.6: - Added want_to_explore, called for AI type of the unit owner, when it is about to autoexplore - Added currently unused 'reserved' pointers that we can populate with optional callbacks without need to change the mandatory capability of the modules + +7. AI callbacks on startup +----------------------------------- + +In a new game +------------- + +- server_state() is S_S_INITIAL +- gained_control() +- map_alloc() +- the map is created +- map_ready() +- server_state() is set to S_S_RUNNING +- tile_info() for each visible tile +- initial units and cities (if any) are created +- unit_created(), unit_got() are called for each starting unit +- city_created(), city_got() are called for each starting city (if any) +- game_start() + + + +When a savegame is being loaded +------------------------------- + +The game loading sequence is: + +- server_state() is S_S_INITIAL +- map_alloc() +- map loaded +- players loaded, calling player_load(), player_load_relations() +- cities and units loaded, calling city_load() and unit_load() +- gained_control() +- map_ready() +- server_state() goes to S_S_RUNNING + +Note that gained_control(), player_load(), player_load_relations(), +city_load() and unit_load() are called while the savefile is being +loaded - they allow the AI module to gather extra information from the +savefile, but the game is not yet in a consistent state (i.e. cities +and units are not all loaded) + +When a player is switched to AI or to away mode during game +----------------------------------------------------------- + +- server_state() is S_S_RUNNING +- gained_control() +- restart_phase() + +In this case, gained_control() will have to gather all the necessary +information from the globals, it won't receive direct updates about +units, cities or anything. + +When a player is switched to AI or to away mode before game +----------------------------------------------------------- + +- server_state() is S_S_INITIAL +- gained_control() diff --git a/server/plrhand.c b/server/plrhand.c index 1f39f920de..305c2975a9 100644 --- a/server/plrhand.c +++ b/server/plrhand.c @@ -3234,11 +3234,12 @@ void player_set_to_ai_mode(struct player *pplayer, enum ai_level skill_level) set_ai_level_directer(pplayer, skill_level); cancel_all_meetings(pplayer); CALL_PLR_AI_FUNC(gained_control, pplayer, pplayer); - if (is_player_phase(pplayer, game.info.phase)) { - CALL_PLR_AI_FUNC(restart_phase, pplayer, pplayer); - } if (S_S_RUNNING == server_state()) { + if (is_player_phase(pplayer, game.info.phase)) { + CALL_PLR_AI_FUNC(restart_phase, pplayer, pplayer); + } + /* In case this was last player who has not pressed turn done. */ check_for_full_turn_done(); } diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c index 3079a79f41..fb512307b7 100644 --- a/server/savegame/savegame3.c +++ b/server/savegame/savegame3.c @@ -3721,7 +3721,6 @@ static void sg_load_players(struct loaddata *loading) city_list_iterate(plr->cities, pcity) { city_refresh(pcity); sanity_check_city(pcity); - CALL_PLR_AI_FUNC(city_got, plr, plr, pcity); } city_list_iterate_end; } players_iterate_end; @@ -4037,11 +4036,6 @@ static void sg_load_player_main(struct loaddata *loading, server.nbarbarians++; } - if (is_ai(plr)) { - set_ai_level_directer(plr, plr->ai_common.skill_level); - CALL_PLR_AI_FUNC(gained_control, plr, plr); - } - /* Load nation style. */ { struct nation_style *style; diff --git a/server/savegame/savemain.c b/server/savegame/savemain.c index 570aa5de51..3b4f756981 100644 --- a/server/savegame/savemain.c +++ b/server/savegame/savemain.c @@ -28,6 +28,7 @@ /* server */ #include "console.h" #include "notify.h" +#include "difficulty.h" /* server/savegame */ #include "savegame2.h" @@ -72,15 +73,10 @@ void savegame_load(struct section_file *sfile) } players_iterate(pplayer) { - unit_list_iterate(pplayer->units, punit) { - CALL_FUNC_EACH_AI(unit_created, punit); - CALL_PLR_AI_FUNC(unit_got, pplayer, punit); - } unit_list_iterate_end; - - city_list_iterate(pplayer->cities, pcity) { - CALL_FUNC_EACH_AI(city_created, pcity); - CALL_PLR_AI_FUNC(city_got, pplayer, pplayer, pcity); - } city_list_iterate_end; + if (is_ai(pplayer)) { + set_ai_level_directer(pplayer, pplayer->ai_common.skill_level); + CALL_PLR_AI_FUNC(gained_control, pplayer, pplayer); + } } players_iterate_end; #ifdef DEBUG_TIMERS diff --git a/server/unittools.c b/server/unittools.c index ada9e1299c..a9f946e552 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1614,7 +1614,7 @@ void unit_get_goods(struct unit *punit) } /**********************************************************************//** - Creates a unit, and set it's initial values, and put it into the right + Creates a unit, and set its initial values, and put it into the right lists. If moves_left is less than zero, unit will get max moves. **************************************************************************/