00001
00002
00003 #include "../../stdafx.h"
00004 #include "../../openttd.h"
00005 #include "../../debug.h"
00006 #include "../../road_map.h"
00007 #include "../../command_func.h"
00008 #include "trolly.h"
00009 #include "../../engine.h"
00010 #include "../../station.h"
00011 #include "../../variables.h"
00012 #include "../../bridge.h"
00013 #include "../../vehicle_func.h"
00014 #include "../../vehicle_base.h"
00015 #include "../../player_base.h"
00016 #include "../../player_func.h"
00017 #include "../ai.h"
00018 #include "../../tunnelbridge.h"
00019
00020
00021
00022
00023
00024 bool AiNew_Build_CompanyHQ(Player *p, TileIndex tile)
00025 {
00026 if (CmdFailed(AI_DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ)))
00027 return false;
00028 AI_DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_COMPANY_HQ);
00029 return true;
00030 }
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 CommandCost AiNew_Build_Station(Player *p, byte type, TileIndex tile, byte length, byte numtracks, byte direction, byte flag)
00042 {
00043 if (type == AI_TRAIN)
00044 return AI_DoCommand(tile, direction + (numtracks << 8) + (length << 16), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_RAILROAD_STATION);
00045
00046 if (type == AI_BUS)
00047 return AI_DoCommand(tile, direction, ROADTYPES_ROAD << 2 | RoadStop::BUS, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
00048
00049 return AI_DoCommand(tile, direction, ROADTYPES_ROAD << 2 | RoadStop::TRUCK, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
00050 }
00051
00052
00053
00054
00055
00056
00057
00058 CommandCost AiNew_Build_Bridge(Player *p, TileIndex tile_a, TileIndex tile_b, byte flag)
00059 {
00060 int bridge_type, bridge_len, type, type2;
00061
00062
00063 bridge_len = GetTunnelBridgeLength(tile_a, tile_b);
00064 type = type2 = 0;
00065 for (bridge_type = MAX_BRIDGES-1; bridge_type >= 0; bridge_type--) {
00066 if (CheckBridge_Stuff(bridge_type, bridge_len)) {
00067 type2 = type;
00068 type = bridge_type;
00069
00070 if (type2 != 0) break;
00071 }
00072 }
00073
00074 if (type2 == 0 && type != 0) type2 = type;
00075
00076
00077 if (_players_ainew[p->index].tbt == AI_TRAIN) {
00078 return AI_DoCommand(tile_a, tile_b, (0x00 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
00079 } else {
00080 return AI_DoCommand(tile_a, tile_b, ((0x80 | ROADTYPES_ROAD) << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
00081 }
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag)
00096 {
00097 int part = PathFinderInfo->position;
00098 byte *route_extra = PathFinderInfo->route_extra;
00099 TileIndex *route = PathFinderInfo->route;
00100 int dir;
00101 int old_dir = -1;
00102 CommandCost cost;
00103 CommandCost res;
00104
00105
00106 if (part < 1) part = 1;
00107
00108 if (part >= PathFinderInfo->route_length - 1) {
00109 PathFinderInfo->position = -2;
00110 return CommandCost();
00111 }
00112
00113
00114 if (PathFinderInfo->rail_or_road) {
00115
00116 if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
00117 cost.AddCost(AI_DoCommand(route[part], 0, 0, flag, CMD_BUILD_TUNNEL));
00118 PathFinderInfo->position++;
00119
00120 if (CmdFailed(cost)) {
00121 DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
00122 return CommandCost();
00123 }
00124 return cost;
00125 }
00126
00127 if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
00128 cost.AddCost(AiNew_Build_Bridge(p, route[part], route[part - 1], flag));
00129 PathFinderInfo->position++;
00130
00131 if (CmdFailed(cost)) {
00132 DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part - 1]);
00133 return CommandCost();
00134 }
00135 return cost;
00136 }
00137
00138
00139
00140 if (route_extra[part - 1] == 0 && route_extra[part] == 0) {
00141 while (route_extra[part] == 0) {
00142
00143 dir = AiNew_GetRailDirection(route[part-1], route[part], route[part+1]);
00144
00145 if (old_dir != -1 && old_dir != dir) break;
00146 old_dir = dir;
00147
00148 res = AI_DoCommand(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
00149 if (CmdFailed(res)) {
00150
00151 _players_ainew[p->index].state = AI_STATE_NOTHING;
00152 return CommandCost();
00153 }
00154 cost.AddCost(res);
00155
00156 part++;
00157
00158 if (part >= PathFinderInfo->route_length - 1) break;
00159 }
00160 part--;
00161 }
00162
00163 PathFinderInfo->position = part;
00164 } else {
00165
00166 if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
00167 cost.AddCost(AI_DoCommand(route[part], 0x200 | ROADTYPES_ROAD, 0, flag, CMD_BUILD_TUNNEL));
00168 PathFinderInfo->position++;
00169
00170 if (CmdFailed(cost)) {
00171 DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
00172 return CommandCost();
00173 }
00174 return cost;
00175 }
00176
00177 if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
00178 cost.AddCost(AiNew_Build_Bridge(p, route[part], route[part + 1], flag));
00179 PathFinderInfo->position++;
00180
00181 if (CmdFailed(cost)) {
00182 DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part + 1]);
00183 return CommandCost();
00184 }
00185 return cost;
00186 }
00187
00188
00189
00190
00191
00192 if (route_extra[part-1] == 0 && route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicleOnGround(route[part]))) {
00193 while (route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicleOnGround(route[part]))) {
00194
00195 dir = AiNew_GetRoadDirection(route[part-1], route[part], route[part+1]);
00196
00197 if (old_dir != -1 && old_dir != dir) break;
00198 old_dir = dir;
00199
00200 if (!IsTileType(route[part], MP_TUNNELBRIDGE)) {
00201
00202 res = AI_DoCommand(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
00203
00204 if (CmdFailed(res) && flag == DC_EXEC && !IsTileType(route[part], MP_ROAD) && !EnsureNoVehicleOnGround(route[part])) {
00205
00206 DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]);
00207 _players_ainew[p->index].state = AI_STATE_NOTHING;
00208 return CommandCost();
00209 }
00210
00211 if (CmdSucceeded(res)) cost.AddCost(res);
00212 }
00213
00214 part++;
00215
00216 if (part >= PathFinderInfo->route_length - 1) break;
00217 }
00218 part--;
00219
00220 }
00221 if (!EnsureNoVehicleOnGround(route[part]) && flag == DC_EXEC) part--;
00222 PathFinderInfo->position = part;
00223 }
00224
00225 return cost;
00226 }
00227
00228
00229
00230
00231 EngineID AiNew_PickVehicle(Player *p)
00232 {
00233 if (_players_ainew[p->index].tbt == AI_TRAIN) {
00234
00235 return INVALID_ENGINE;
00236 } else {
00237 EngineID best_veh_index = INVALID_ENGINE;
00238 int32 best_veh_rating = 0;
00239 EngineID i;
00240
00241
00242 FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_ROAD) {
00243 const RoadVehicleInfo *rvi = RoadVehInfo(i);
00244 const Engine* e = GetEngine(i);
00245
00246
00247 if (rvi->cargo_type != _players_ainew[p->index].cargo && !CanRefitTo(i, _players_ainew[p->index].cargo)) continue;
00248
00249
00250 if (HasBit(EngInfo(i)->misc_flags, EF_ROAD_TRAM)) continue;
00251
00252
00253
00254 if (!HasBit(e->player_avail, _current_player) || e->reliability * 100 < AI_VEHICLE_MIN_RELIABILTY << 16) continue;
00255
00256
00257 int rating = rvi->max_speed * rvi->capacity;
00258 if (rating <= best_veh_rating) continue;
00259
00260
00261 CommandCost ret = AI_DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_ROAD_VEH);
00262 if (CmdFailed(ret)) continue;
00263
00264 best_veh_rating = rating;
00265 best_veh_index = i;
00266 }
00267
00268 return best_veh_index;
00269 }
00270 }
00271
00272
00273 void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2)
00274 {
00275 Player* p = GetPlayer(_current_player);
00276
00277 if (success) {
00278 _players_ainew[p->index].state = AI_STATE_GIVE_ORDERS;
00279 _players_ainew[p->index].veh_id = _new_vehicle_id;
00280
00281 if (GetVehicle(_players_ainew[p->index].veh_id)->cargo_type != _players_ainew[p->index].cargo) {
00282
00283 if (CmdFailed(DoCommand(tile, _players_ainew[p->index].veh_id, _players_ainew[p->index].cargo, DC_EXEC, CMD_REFIT_ROAD_VEH))) {
00284
00285 DoCommand(tile, _players_ainew[p->index].veh_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
00286 _players_ainew[p->index].state = AI_STATE_NOTHING;
00287 }
00288 }
00289 } else {
00290
00291 _players_ainew[p->index].state = AI_STATE_NOTHING;
00292 }
00293 }
00294
00295
00296
00297 CommandCost AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
00298 {
00299 EngineID i = AiNew_PickVehicle(p);
00300
00301 if (i == INVALID_ENGINE) return CMD_ERROR;
00302 if (_players_ainew[p->index].tbt == AI_TRAIN) return CMD_ERROR;
00303
00304 if (flag & DC_EXEC) {
00305 return AI_DoCommandCc(tile, i, 0, flag, CMD_BUILD_ROAD_VEH, CcAI);
00306 } else {
00307 return AI_DoCommand(tile, i, 0, flag, CMD_BUILD_ROAD_VEH);
00308 }
00309 }
00310
00311 CommandCost AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag)
00312 {
00313 CommandCost ret, ret2;
00314 if (_players_ainew[p->index].tbt == AI_TRAIN) {
00315 return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
00316 } else {
00317 ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
00318 if (CmdFailed(ret2)) return ret;
00319
00320 ret2 = AI_DoCommand(tile + TileOffsByDiagDir(direction), DiagDirToRoadBits(ReverseDiagDir(direction)), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
00321
00322 if (CmdFailed(ret2)) return ret;
00323 ret.AddCost(ret2);
00324 return ret;
00325 }
00326 }