ai.cpp
00001
00002
00003 #include "../stdafx.h"
00004 #include "../openttd.h"
00005 #include "../variables.h"
00006 #include "../command_func.h"
00007 #include "../network/network.h"
00008 #include "../core/alloc_func.hpp"
00009 #include "../player_func.h"
00010 #include "../player_base.h"
00011 #include "ai.h"
00012 #include "default/default.h"
00013 #include "trolly/trolly.h"
00014 #include "../signal_func.h"
00015
00016 AIStruct _ai;
00017 AIPlayer _ai_player[MAX_PLAYERS];
00018
00022 static void AI_DequeueCommands(PlayerID player)
00023 {
00024 AICommand *com, *entry_com;
00025
00026 entry_com = _ai_player[player].queue;
00027
00028
00029
00030
00031
00032
00033
00034 _ai_player[player].queue = NULL;
00035 _ai_player[player].queue_tail = NULL;
00036
00037
00038 while ((com = entry_com) != NULL) {
00039 _current_player = player;
00040
00041 _cmd_text = com->text;
00042 DoCommandP(com->tile, com->p1, com->p2, com->callback, com->procc);
00043
00044
00045 entry_com = com->next;
00046 free(com->text);
00047 free(com);
00048 }
00049 }
00050
00055 static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uint32 p2, uint32 procc, CommandCallback* callback)
00056 {
00057 AICommand *com;
00058
00059 if (_ai_player[player].queue_tail == NULL) {
00060
00061 _ai_player[player].queue = MallocT<AICommand>(1);
00062 _ai_player[player].queue_tail = _ai_player[player].queue;
00063 } else {
00064
00065 _ai_player[player].queue_tail->next = MallocT<AICommand>(1);
00066 _ai_player[player].queue_tail = _ai_player[player].queue_tail->next;
00067 }
00068
00069
00070 com = _ai_player[player].queue_tail;
00071
00072
00073 com->tile = tile;
00074 com->p1 = p1;
00075 com->p2 = p2;
00076 com->procc = procc;
00077 com->callback = callback;
00078 com->next = NULL;
00079 com->text = NULL;
00080
00081
00082 if (_cmd_text != NULL) {
00083 com->text = strdup(_cmd_text);
00084 _cmd_text = NULL;
00085 }
00086 }
00087
00091 CommandCost AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint32 procc, CommandCallback* callback)
00092 {
00093 PlayerID old_lp;
00094 CommandCost res;
00095 const char* tmp_cmdtext;
00096
00097
00098
00099
00100
00101
00102 tmp_cmdtext = _cmd_text;
00103
00104
00105 res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
00106
00107 if (CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
00108 return res;
00109 }
00110
00111
00112 _cmd_text = tmp_cmdtext;
00113
00114
00115
00116 old_lp = _local_player;
00117 _local_player = _current_player;
00118
00119 #ifdef ENABLE_NETWORK
00120
00121 if (_networking) {
00122
00123 NetworkSend_Command(tile, p1, p2, procc, callback);
00124 } else {
00125 #else
00126 {
00127 #endif
00128
00129
00130 AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback);
00131 }
00132
00133
00134 _local_player = old_lp;
00135
00136 return res;
00137 }
00138
00139
00140 CommandCost AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint32 procc)
00141 {
00142 return AI_DoCommandCc(tile, p1, p2, flags, procc, NULL);
00143 }
00144
00145
00149 static void AI_RunTick(PlayerID player)
00150 {
00151 extern void AiNewDoGameLoop(Player *p);
00152
00153 Player *p = GetPlayer(player);
00154 _current_player = player;
00155
00156 if (_patches.ainew_active) {
00157 AiNewDoGameLoop(p);
00158 } else {
00159
00160 _is_old_ai_player = true;
00161 AiDoGameLoop(p);
00162 _is_old_ai_player = false;
00163 }
00164
00165
00166 UpdateSignalsInBuffer();
00167 }
00168
00169
00174 void AI_RunGameLoop()
00175 {
00176
00177 if (!_ai.enabled) return;
00178
00179
00180 if (_networking && (!_network_server || !_patches.ai_in_multiplayer)) return;
00181
00182
00183 _ai.tick++;
00184
00185
00186 assert(_opt.diff.competitor_speed <= 4);
00187 if ((_ai.tick & ((1 << (4 - _opt.diff.competitor_speed)) - 1)) != 0) return;
00188
00189
00190 if (!_networking || _network_server) {
00191
00192 const Player* p;
00193
00194 FOR_ALL_PLAYERS(p) {
00195 if (p->is_active && p->is_ai) {
00196
00197 assert(_ai_player[p->index].active);
00198
00199
00200 AI_DequeueCommands(p->index);
00201 AI_RunTick(p->index);
00202 }
00203 }
00204 }
00205
00206 _current_player = OWNER_NONE;
00207 }
00208
00212 void AI_StartNewAI(PlayerID player)
00213 {
00214 assert(IsValidPlayer(player));
00215
00216
00217 _ai_player[player].active = true;
00218 }
00219
00223 void AI_PlayerDied(PlayerID player)
00224 {
00225
00226 _ai_player[player].active = false;
00227
00228 if (_players_ainew[player].pathfinder == NULL) return;
00229
00230 AyStarMain_Free(_players_ainew[player].pathfinder);
00231 delete _players_ainew[player].pathfinder;
00232 _players_ainew[player].pathfinder = NULL;
00233
00234 }
00235
00239 void AI_Initialize()
00240 {
00241
00242 AI_Uninitialize();
00243
00244 memset(&_ai, 0, sizeof(_ai));
00245 memset(&_ai_player, 0, sizeof(_ai_player));
00246
00247 _ai.enabled = true;
00248 }
00249
00253 void AI_Uninitialize()
00254 {
00255 for (PlayerID p = PLAYER_FIRST; p < MAX_PLAYERS; p++) AI_PlayerDied(p);
00256 }