src/ai/api/ai_order.cpp
branchnoai
changeset 9500 d67653613da4
child 9534 72cd7f3a32d9
equal deleted inserted replaced
9499:c02cf5bf4f7a 9500:d67653613da4
       
     1 /* $Id$ */
       
     2 
       
     3 /** @file ai_order.cpp handles the functions of the AIOrder class */
       
     4 
       
     5 #include "ai_order.hpp"
       
     6 #include "ai_map.hpp"
       
     7 #include "ai_vehicle.hpp"
       
     8 #include "../../command.h"
       
     9 #include "../../order.h"
       
    10 
       
    11 #include "../../depot.h"
       
    12 #include "../../rail_map.h"
       
    13 #include "../../road_map.h"
       
    14 #include "../../station_map.h"
       
    15 #include "../../water_map.h"
       
    16 #include "../../waypoint.h"
       
    17 
       
    18 /**
       
    19  * Gets the order type given a tile
       
    20  * @param t the tile to get the order from
       
    21  * @return the order type, or OT_END when there is no order
       
    22  */
       
    23 static OrderType GetOrderTypeByTile(TileIndex t)
       
    24 {
       
    25 	if (!::IsValidTile(t)) return OT_END;
       
    26 
       
    27 	switch (::GetTileType(t)) {
       
    28 		default: break;
       
    29 		case MP_STATION: return OT_GOTO_STATION; break;
       
    30 		case MP_WATER:   if (::IsShipDepot(t)) return OT_GOTO_DEPOT; break;
       
    31 		case MP_STREET:  if (::GetRoadTileType(t) == ROAD_TILE_DEPOT) return OT_GOTO_DEPOT; break;
       
    32 		case MP_RAILWAY:
       
    33 			switch (::GetRailTileType(t)) {
       
    34 				case RAIL_TILE_DEPOT:    return OT_GOTO_DEPOT;
       
    35 				case RAIL_TILE_WAYPOINT: return OT_GOTO_WAYPOINT;
       
    36 				default: break;
       
    37 			}
       
    38 			break;
       
    39 	}
       
    40 
       
    41 	return OT_END;
       
    42 }
       
    43 
       
    44 /* static */ bool AIOrder::IsValidVehicleOrder(VehicleID vehicle_id, uint32 order_id)
       
    45 {
       
    46 	return AIVehicle::IsValidVehicle(vehicle_id) && order_id < ::GetVehicle(vehicle_id)->num_orders;
       
    47 }
       
    48 
       
    49 /* static */ bool AIOrder::AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags)
       
    50 {
       
    51 	switch (::GetOrderTypeByTile(destination)) {
       
    52 		case OT_GOTO_DEPOT:    return (order_flags & ~(AIOF_NON_STOP | AIOF_SERVICE_IF_NEEDED)) == 0;
       
    53 		case OT_GOTO_STATION:  return (order_flags & ~(AIOF_NON_STOP | AIOF_TRANSFER | AIOF_UNLOAD | AIOF_FULL_LOAD)) == 0;
       
    54 		case OT_GOTO_WAYPOINT: return (order_flags & ~(AIOF_NON_STOP)) == 0;
       
    55 		default:               return false;
       
    56 	}
       
    57 }
       
    58 
       
    59 int32 AIOrder::GetNumberOfOrders(VehicleID vehicle_id)
       
    60 {
       
    61 	return AIVehicle::IsValidVehicle(vehicle_id) ? ::GetVehicle(vehicle_id)->num_orders : -1;
       
    62 }
       
    63 
       
    64 TileIndex AIOrder::GetOrderDestination(VehicleID vehicle_id, uint32 order_id)
       
    65 {
       
    66 	if (!AIOrder::IsValidVehicleOrder(vehicle_id, order_id)) return INVALID_TILE;
       
    67 
       
    68 	Order *order = ::GetVehicle(vehicle_id)->orders;
       
    69 	for (uint i = 0; i < order_id; i++) order = order->next;
       
    70 
       
    71 	switch (order->type) {
       
    72 		case OT_GOTO_DEPOT:    return ::GetDepot(order->dest)->xy;
       
    73 		case OT_GOTO_STATION:  return ::GetStation(order->dest)->xy;
       
    74 		case OT_GOTO_WAYPOINT: return ::GetWaypoint(order->dest)->xy;
       
    75 		default:               return INVALID_TILE;
       
    76 	}
       
    77 }
       
    78 
       
    79 AIOrder::AIOrderFlags AIOrder::GetOrderFlags(VehicleID vehicle_id, uint32 order_id)
       
    80 {
       
    81 	if (!AIOrder::IsValidVehicleOrder(vehicle_id, order_id)) return AIOF_INVALID;
       
    82 
       
    83 	Order *order = ::GetVehicle(vehicle_id)->orders;
       
    84 	for (uint i = 0; i < order_id; i++) order = order->next;
       
    85 
       
    86 	return (AIOrder::AIOrderFlags)order->flags;
       
    87 }
       
    88 
       
    89 bool AIOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags)
       
    90 {
       
    91 	if (!AIVehicle::IsValidVehicle(vehicle_id)) return false;
       
    92 	return this->InsertOrder(vehicle_id, GetVehicle(vehicle_id)->num_orders, destination, order_flags);
       
    93 }
       
    94 
       
    95 bool AIOrder::InsertOrder(VehicleID vehicle_id, uint32 order_id, TileIndex destination, AIOrder::AIOrderFlags order_flags)
       
    96 {
       
    97 	if (!IsValidVehicleOrder(vehicle_id, order_id) ||
       
    98 		!this->AreOrderFlagsValid(destination, order_flags)) return false;
       
    99 
       
   100 	Order order;
       
   101 	order.type  = ::GetOrderTypeByTile(destination);
       
   102 	order.flags = order_flags;
       
   103 	switch (order.type) {
       
   104 		case OT_GOTO_DEPOT:    order.dest = ::GetDepotByTile(destination)->index;
       
   105 		case OT_GOTO_STATION:  order.dest = ::GetStationIndex(destination);
       
   106 		case OT_GOTO_WAYPOINT: order.dest = ::GetWaypointIndex(destination);
       
   107 		default: NOT_REACHED(); return false;
       
   108 	}
       
   109 
       
   110 	return this->DoCommand(0, vehicle_id | (order_id << 16), PackOrder(&order), CMD_INSERT_ORDER);
       
   111 }
       
   112 
       
   113 bool AIOrder::RemoveOrder(VehicleID vehicle_id, uint32 order_id)
       
   114 {
       
   115 	if (!IsValidVehicleOrder(vehicle_id, order_id)) return false;
       
   116 
       
   117 	return this->DoCommand(0, vehicle_id, order_id, CMD_DELETE_ORDER);
       
   118 }
       
   119 
       
   120 bool AIOrder::ChangeOrder(VehicleID vehicle_id, uint32 order_id, AIOrder::AIOrderFlags order_flags)
       
   121 {
       
   122 	if (!IsValidVehicleOrder(vehicle_id, order_id) ||
       
   123 		!this->AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_id), order_flags)) return false;
       
   124 
       
   125 	return this->DoCommand(0, vehicle_id | (order_id << 16), order_flags, CMD_MODIFY_ORDER);
       
   126 }
       
   127 
       
   128 bool AIOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
       
   129 {
       
   130 	if (!AIVehicle::IsValidVehicle(vehicle_id) || !AIVehicle::IsValidVehicle(main_vehicle_id)) return false;
       
   131 
       
   132 	return this->DoCommand(0, vehicle_id | (main_vehicle_id << 16), CO_COPY, CMD_CLONE_ORDER);
       
   133 }
       
   134 
       
   135 bool AIOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
       
   136 {
       
   137 	if (!AIVehicle::IsValidVehicle(vehicle_id) || !AIVehicle::IsValidVehicle(main_vehicle_id)) return false;
       
   138 
       
   139 	return this->DoCommand(0, vehicle_id | (main_vehicle_id << 16), CO_SHARE, CMD_CLONE_ORDER);
       
   140 }
       
   141 
       
   142 bool AIOrder::UnshareOrders(VehicleID vehicle_id)
       
   143 {
       
   144 	if (!AIVehicle::IsValidVehicle(vehicle_id)) return false;
       
   145 
       
   146 	return this->DoCommand(0, vehicle_id, CO_UNSHARE, CMD_CLONE_ORDER);
       
   147 }