1 /* 2 * This file is part of OpenTTD. 3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. 4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. 6 */ 7 8 /** @file script_order.hpp Everything to query and build orders. */ 9 10 #ifndef SCRIPT_ORDER_HPP 11 #define SCRIPT_ORDER_HPP 12 13 #include "script_vehicle.hpp" 14 #include "../../order_type.h" 15 16 /** 17 * Class that handles all order related functions. 18 * @api ai game 19 */ 20 class ScriptOrder : public ScriptObject { 21 public: 22 /** 23 * All order related error messages. 24 */ 25 enum ErrorMessages { 26 /** Base for all order related errors */ 27 ERR_ORDER_BASE = ScriptError::ERR_CAT_ORDER << ScriptError::ERR_CAT_BIT_SIZE, 28 29 /** No more space for orders */ 30 ERR_ORDER_TOO_MANY, // [STR_ERROR_NO_MORE_SPACE_FOR_ORDERS] 31 32 /** Destination of new order is too far away from the previous order */ 33 ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION, // [STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION] 34 35 /** Aircraft has not enough range to copy/share orders. */ 36 ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE, // [STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE] 37 }; 38 39 /** 40 * Flags that can be used to modify the behaviour of orders. 41 */ 42 enum ScriptOrderFlags { 43 /** Just go to the station/depot, stop unload if possible and load if needed. */ 44 OF_NONE = 0, 45 46 /** Do not stop at the stations that are passed when going to the destination. Only for trains and road vehicles. */ 47 OF_NON_STOP_INTERMEDIATE = 1 << 0, 48 /** Do not stop at the destination station. Only for trains and road vehicles. */ 49 OF_NON_STOP_DESTINATION = 1 << 1, 50 51 /** Always unload the vehicle; only for stations. Cannot be set when OF_TRANSFER or OF_NO_UNLOAD is set. */ 52 OF_UNLOAD = 1 << 2, 53 /** Transfer instead of deliver the goods; only for stations. Cannot be set when OF_UNLOAD or OF_NO_UNLOAD is set. */ 54 OF_TRANSFER = 1 << 3, 55 /** Never unload the vehicle; only for stations. Cannot be set when OF_UNLOAD, OF_TRANSFER or OF_NO_LOAD is set. */ 56 OF_NO_UNLOAD = 1 << 4, 57 58 /** Wt till the vehicle is fully loaded; only for stations. Cannot be set when OF_NO_LOAD is set. */ 59 OF_FULL_LOAD = 2 << 5, 60 /** Wt till at least one cargo of the vehicle is fully loaded; only for stations. Cannot be set when OF_NO_LOAD is set. */ 61 OF_FULL_LOAD_ANY = 3 << 5, 62 /** Do not load any cargo; only for stations. Cannot be set when OF_NO_UNLOAD, OF_FULL_LOAD or OF_FULL_LOAD_ANY is set. */ 63 OF_NO_LOAD = 1 << 7, 64 65 /** Service the vehicle when needed, otherwise skip this order; only for depots. */ 66 OF_SERVICE_IF_NEEDED = 1 << 2, 67 /** Stop in the depot instead of only go there for servicing; only for depots. */ 68 OF_STOP_IN_DEPOT = 1 << 3, 69 /** Go to nearest depot. */ 70 OF_GOTO_NEAREST_DEPOT = 1 << 8, 71 72 /** All flags related to non-stop settings. */ 73 OF_NON_STOP_FLAGS = OF_NON_STOP_INTERMEDIATE | OF_NON_STOP_DESTINATION, 74 /** All flags related to unloading. */ 75 OF_UNLOAD_FLAGS = OF_TRANSFER | OF_UNLOAD | OF_NO_UNLOAD, 76 /** All flags related to loading. */ 77 OF_LOAD_FLAGS = OF_FULL_LOAD | OF_FULL_LOAD_ANY | OF_NO_LOAD, 78 /** All flags related to depots. */ 79 OF_DEPOT_FLAGS = OF_SERVICE_IF_NEEDED | OF_STOP_IN_DEPOT | OF_GOTO_NEAREST_DEPOT, 80 81 /** For marking invalid order flags */ 82 OF_INVALID = 0xFFFF, 83 }; 84 85 /** 86 * All conditions a conditional order can depend on. 87 */ 88 enum OrderCondition { 89 /* Note: these values represent part of the in-game OrderConditionVariable enum */ 90 OC_LOAD_PERCENTAGE = ::OCV_LOAD_PERCENTAGE, ///< Skip based on the amount of load, value is in tons. 91 OC_RELIABILITY = ::OCV_RELIABILITY, ///< Skip based on the reliability, value is percent (0..100). 92 OC_MAX_RELIABILITY = ::OCV_MAX_RELIABILITY, ///< Skip based on the maximum reliability. Value in percent 93 OC_MAX_SPEED = ::OCV_MAX_SPEED, ///< Skip based on the maximum speed, value is in OpenTTD's internal speed unit, see ScriptEngine::GetMaxSpeed. 94 OC_AGE = ::OCV_AGE, ///< Skip based on the age, value is in years. 95 OC_REQUIRES_SERVICE = ::OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service, no value. 96 OC_UNCONDITIONALLY = ::OCV_UNCONDITIONALLY, ///< Always skip, no compare function, no value. 97 OC_REMAINING_LIFETIME = ::OCV_REMAINING_LIFETIME, ///< Skip based on the remaining lifetime 98 99 /* Custom added value, only valid for this API */ 100 OC_INVALID = -1, ///< An invalid condition, do not use. 101 }; 102 103 /** 104 * Comparators for conditional orders. 105 */ 106 enum CompareFunction { 107 /* Note: these values represent part of the in-game OrderConditionComparator enum */ 108 CF_EQUALS = ::OCC_EQUALS, ///< Skip if both values are equal 109 CF_NOT_EQUALS = ::OCC_NOT_EQUALS, ///< Skip if both values are not equal 110 CF_LESS_THAN = ::OCC_LESS_THAN, ///< Skip if the value is less than the limit 111 CF_LESS_EQUALS = ::OCC_LESS_EQUALS, ///< Skip if the value is less or equal to the limit 112 CF_MORE_THAN = ::OCC_MORE_THAN, ///< Skip if the value is more than the limit 113 CF_MORE_EQUALS = ::OCC_MORE_EQUALS, ///< Skip if the value is more or equal to the limit 114 CF_IS_TRUE = ::OCC_IS_TRUE, ///< Skip if the variable is true 115 CF_IS_FALSE = ::OCC_IS_FALSE, ///< Skip if the variable is false 116 117 /* Custom added value, only valid for this API */ 118 CF_INVALID = -1, ///< Invalid compare function, do not use. 119 }; 120 121 /** 122 * Index in the list of orders for a vehicle. The first order has index 0, the second 123 * order index 1, etc. The current order can be queried by using ORDER_CURRENT. Do not 124 * use ORDER_INVALID yourself, it's used as return value by for example ResolveOrderPosition. 125 * @note Automatic orders are hidden from scripts, so OrderPosition 0 will always be the first 126 * manual order. 127 */ 128 enum OrderPosition { 129 ORDER_CURRENT = 0xFF, ///< Constant that gets resolved to the current order. 130 ORDER_INVALID = -1, ///< An invalid order. 131 }; 132 133 /** Where to stop trains in a station that's longer than the train */ 134 enum StopLocation { 135 STOPLOCATION_NEAR, ///< Stop the train as soon as it's completely in the station 136 STOPLOCATION_MIDDLE, ///< Stop the train in the middle of the station 137 STOPLOCATION_FAR, ///< Stop the train at the far end of the station 138 STOPLOCATION_INVALID = -1, ///< An invalid stop location 139 }; 140 141 /** 142 * Checks whether the given order id is valid for the given vehicle. 143 * @param vehicle_id The vehicle to check the order index for. 144 * @param order_position The order index to check. 145 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 146 * @return True if and only if the order_position is valid for the given vehicle. 147 */ 148 static bool IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position); 149 150 /** 151 * Checks whether the given order is a goto-station order. 152 * @param vehicle_id The vehicle to check. 153 * @param order_position The order index to check. 154 * @pre IsValidVehicleOrder(vehicle_id, order_position). 155 * @return True if and only if the order is a goto-station order. 156 */ 157 static bool IsGotoStationOrder(VehicleID vehicle_id, OrderPosition order_position); 158 159 /** 160 * Checks whether the given order is a goto-depot order. 161 * @param vehicle_id The vehicle to check. 162 * @param order_position The order index to check. 163 * @pre IsValidVehicleOrder(vehicle_id, order_position). 164 * @return True if and only if the order is a goto-depot order. 165 */ 166 static bool IsGotoDepotOrder(VehicleID vehicle_id, OrderPosition order_position); 167 168 /** 169 * Checks whether the given order is a goto-waypoint order. 170 * @param vehicle_id The vehicle to check. 171 * @param order_position The order index to check. 172 * @pre IsValidVehicleOrder(vehicle_id, order_position). 173 * @return True if and only if the order is a goto-waypoint order. 174 */ 175 static bool IsGotoWaypointOrder(VehicleID vehicle_id, OrderPosition order_position); 176 177 /** 178 * Checks whether the given order is a conditional order. 179 * @param vehicle_id The vehicle to check. 180 * @param order_position The order index to check. 181 * @pre order_position != ORDER_CURRENT && IsValidVehicleOrder(vehicle_id, order_position). 182 * @return True if and only if the order is a conditional order. 183 */ 184 static bool IsConditionalOrder(VehicleID vehicle_id, OrderPosition order_position); 185 186 /** 187 * Checks whether the given order is a void order. 188 * A void order is an order that used to be a goto station, depot or waypoint order but 189 * its destination got removed. In OpenTTD these orders as shown as "(Invalid Order)" 190 * in the order list of a vehicle. 191 * @param vehicle_id The vehicle to check. 192 * @param order_position The order index to check. 193 * @pre order_position != ORDER_CURRENT && IsValidVehicleOrder(vehicle_id, order_position). 194 * @return True if and only if the order is a void order. 195 */ 196 static bool IsVoidOrder(VehicleID vehicle_id, OrderPosition order_position); 197 198 /** 199 * Checks whether the given order has a valid refit cargo. 200 * @param vehicle_id The vehicle to check. 201 * @param order_position The order index to check. 202 * @pre order_position != ORDER_CURRENT && IsValidVehicleOrder(vehicle_id, order_position). 203 * @return True if and only if the order is has a valid refit cargo. 204 */ 205 static bool IsRefitOrder(VehicleID vehicle_id, OrderPosition order_position); 206 207 /** 208 * Checks whether the current order is part of the orderlist. 209 * @param vehicle_id The vehicle to check. 210 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 211 * @return True if and only if the current order is part of the order list. 212 * @note If the order is a non-'non-stop' order, and the vehicle is currently 213 * (un)loading at a station that is not the final destination, this function 214 * will still return true. 215 */ 216 static bool IsCurrentOrderPartOfOrderList(VehicleID vehicle_id); 217 218 /** 219 * Resolves the given order index to the correct index for the given vehicle. 220 * If the order index was ORDER_CURRENT it will be resolved to the index of 221 * the current order (as shown in the order list). If the order with the 222 * given index does not exist it will return ORDER_INVALID. 223 * @param vehicle_id The vehicle to check the order index for. 224 * @param order_position The order index to resolve. 225 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 226 * @return The resolved order index. 227 */ 228 static OrderPosition ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position); 229 230 /** 231 * Checks whether the given order flags are valid for the given destination. 232 * @param destination The destination of the order. 233 * @param order_flags The flags given to the order. 234 * @return True if and only if the order_flags are valid for the given location. 235 */ 236 static bool AreOrderFlagsValid(TileIndex destination, ScriptOrderFlags order_flags); 237 238 /** 239 * Checks whether the given combination of condition and compare function is valid. 240 * @param condition The condition to check. 241 * @param compare The compare function to check. 242 * @return True if and only if the combination of condition and compare function is valid. 243 */ 244 static bool IsValidConditionalOrder(OrderCondition condition, CompareFunction compare); 245 246 /** 247 * Returns the number of orders for the given vehicle. 248 * @param vehicle_id The vehicle to get the order count of. 249 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 250 * @return The number of orders for the given vehicle or a negative 251 * value when the vehicle does not exist. 252 */ 253 static int32 GetOrderCount(VehicleID vehicle_id); 254 255 /** 256 * Gets the destination of the given order for the given vehicle. 257 * @param vehicle_id The vehicle to get the destination for. 258 * @param order_position The order to get the destination for. 259 * @pre IsValidVehicleOrder(vehicle_id, order_position). 260 * @pre order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position). 261 * @note Giving ORDER_CURRENT as order_position will give the order that is 262 * currently being executed by the vehicle. This is not necessarily the 263 * current order as given by ResolveOrderPosition (the current index in the 264 * order list) as manual or autoservicing depot orders do not show up 265 * in the orderlist, but they can be the current order of a vehicle. 266 * @return The destination tile of the order. 267 */ 268 static TileIndex GetOrderDestination(VehicleID vehicle_id, OrderPosition order_position); 269 270 /** 271 * Gets the ScriptOrderFlags of the given order for the given vehicle. 272 * @param vehicle_id The vehicle to get the destination for. 273 * @param order_position The order to get the destination for. 274 * @pre IsValidVehicleOrder(vehicle_id, order_position). 275 * @pre order_position == ORDER_CURRENT || (!IsConditionalOrder(vehicle_id, order_position) && !IsVoidOrder(vehicle_id, order_position)). 276 * @note Giving ORDER_CURRENT as order_position will give the order that is 277 * currently being executed by the vehicle. This is not necessarily the 278 * current order as given by ResolveOrderPosition (the current index in the 279 * order list) as manual or autoservicing depot orders do not show up 280 * in the orderlist, but they can be the current order of a vehicle. 281 * @return The ScriptOrderFlags of the order. 282 */ 283 static ScriptOrderFlags GetOrderFlags(VehicleID vehicle_id, OrderPosition order_position); 284 285 /** 286 * Gets the OrderPosition to jump to if the check succeeds of the given order for the given vehicle. 287 * @param vehicle_id The vehicle to get the OrderPosition for. 288 * @param order_position The order to get the OrderPosition for. 289 * @pre IsValidVehicleOrder(vehicle_id, order_position). 290 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 291 * @return The target of the conditional jump. 292 */ 293 static OrderPosition GetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position); 294 295 /** 296 * Gets the OrderCondition of the given order for the given vehicle. 297 * @param vehicle_id The vehicle to get the condition type for. 298 * @param order_position The order to get the condition type for. 299 * @pre IsValidVehicleOrder(vehicle_id, order_position). 300 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 301 * @return The OrderCondition of the order. 302 */ 303 static OrderCondition GetOrderCondition(VehicleID vehicle_id, OrderPosition order_position); 304 305 /** 306 * Gets the CompareFunction of the given order for the given vehicle. 307 * @param vehicle_id The vehicle to get the compare function for. 308 * @param order_position The order to get the compare function for. 309 * @pre IsValidVehicleOrder(vehicle_id, order_position). 310 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 311 * @return The CompareFunction of the order. 312 */ 313 static CompareFunction GetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position); 314 315 /** 316 * Gets the value to compare against of the given order for the given vehicle. 317 * @param vehicle_id The vehicle to get the value for. 318 * @param order_position The order to get the value for. 319 * @pre IsValidVehicleOrder(vehicle_id, order_position). 320 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 321 * @return The value to compare against of the order. 322 */ 323 static int32 GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position); 324 325 /** 326 * Gets the stoplocation of the given order for the given train. 327 * @param vehicle_id The vehicle to get the value for. 328 * @param order_position The order to get the value for. 329 * @pre IsValidVehicleOrder(vehicle_id, order_position). 330 * @pre ScriptVehicle::GetVehicleType(vehicle_id) == ScriptVehicle::VT_RAIL. 331 * @pre IsGotoStationOrder(vehicle_id, order_position). 332 * @return The relative position where the train will stop inside a station. 333 */ 334 static StopLocation GetStopLocation(VehicleID vehicle_id, OrderPosition order_position); 335 336 /** 337 * Gets the refit cargo type of the given order for the given vehicle. 338 * @param vehicle_id The vehicle to get the refit cargo for. 339 * @param order_position The order to get the refit cargo for. 340 * @pre IsValidVehicleOrder(vehicle_id, order_position). 341 * @pre order_position == ORDER_CURRENT || IsGotoStationOrder(vehicle_id, order_position) || IsGotoDepotOrder(vehicle_id, order_position). 342 * @note Giving ORDER_CURRENT as order_position will give the order that is 343 * currently being executed by the vehicle. This is not necessarily the 344 * current order as given by ResolveOrderPosition (the current index in the 345 * order list) as manual or autoservicing depot orders do not show up 346 * in the orderlist, but they can be the current order of a vehicle. 347 * @return The refit cargo of the order or CT_NO_REFIT if no refit is set. 348 */ 349 static CargoID GetOrderRefit(VehicleID vehicle_id, OrderPosition order_position); 350 351 /** 352 * Sets the OrderPosition to jump to if the check succeeds of the given order for the given vehicle. 353 * @param vehicle_id The vehicle to set the OrderPosition for. 354 * @param order_position The order to set the OrderPosition for. 355 * @param jump_to The order to jump to if the check succeeds. 356 * @pre IsValidVehicleOrder(vehicle_id, order_position). 357 * @pre IsValidVehicleOrder(vehicle_id, jump_to). 358 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 359 * @return Whether the order has been/can be changed. 360 * @api -game 361 */ 362 static bool SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to); 363 364 /** 365 * Sets the OrderCondition of the given order for the given vehicle. 366 * @param vehicle_id The vehicle to set the condition type for. 367 * @param order_position The order to set the condition type for. 368 * @param condition The condition to compare on. 369 * @pre IsValidVehicleOrder(vehicle_id, order_position). 370 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 371 * @pre condition >= OC_LOAD_PERCENTAGE && condition <= OC_UNCONDITIONALLY. 372 * @return Whether the order has been/can be changed. 373 * @api -game 374 */ 375 static bool SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition); 376 377 /** 378 * Sets the CompareFunction of the given order for the given vehicle. 379 * @param vehicle_id The vehicle to set the compare function for. 380 * @param order_position The order to set the compare function for. 381 * @param compare The new compare function of the order. 382 * @pre IsValidVehicleOrder(vehicle_id, order_position). 383 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 384 * @pre compare >= CF_EQUALS && compare <= CF_IS_FALSE. 385 * @return Whether the order has been/can be changed. 386 * @api -game 387 */ 388 static bool SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare); 389 390 /** 391 * Sets the value to compare against of the given order for the given vehicle. 392 * @param vehicle_id The vehicle to set the value for. 393 * @param order_position The order to set the value for. 394 * @param value The value to compare against. 395 * @pre IsValidVehicleOrder(vehicle_id, order_position). 396 * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). 397 * @pre value >= 0 && value < 2048. 398 * @return Whether the order has been/can be changed. 399 * @api -game 400 */ 401 static bool SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value); 402 403 /** 404 * Sets the stoplocation of the given order for the given train. 405 * @param vehicle_id The vehicle to get the value for. 406 * @param order_position The order to get the value for. 407 * @param stop_location The relative position where a train will stop inside a station. 408 * @pre IsValidVehicleOrder(vehicle_id, order_position). 409 * @pre ScriptVehicle::GetVehicleType(vehicle_id) == ScriptVehicle::VT_RAIL. 410 * @pre IsGotoStationOrder(vehicle_id, order_position). 411 * @pre stop_location >= STOPLOCATION_NEAR && stop_location <= STOPLOCATION_FAR 412 * @return Whether the order has been/can be changed. 413 * @api -game 414 */ 415 static bool SetStopLocation(VehicleID vehicle_id, OrderPosition order_position, StopLocation stop_location); 416 417 /** 418 * Sets the refit cargo type of the given order for the given vehicle. 419 * @param vehicle_id The vehicle to set the refit cargo for. 420 * @param order_position The order to set the refit cargo for. 421 * @param refit_cargo The cargo to refit to. The refit can be cleared by passing CT_NO_REFIT. 422 * @pre IsValidVehicleOrder(vehicle_id, order_position). 423 * @pre IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT). 424 * @pre ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT 425 * @return Whether the order has been/can be changed. 426 * @api -game 427 */ 428 static bool SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo); 429 430 /** 431 * Appends an order to the end of the vehicle's order list. 432 * @param vehicle_id The vehicle to append the order to. 433 * @param destination The destination of the order. 434 * @param order_flags The flags given to the order. 435 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 436 * @pre AreOrderFlagsValid(destination, order_flags). 437 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 438 * @exception ScriptOrder::ERR_ORDER_TOO_MANY 439 * @exception ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION 440 * @return True if and only if the order was appended. 441 * @api -game 442 */ 443 static bool AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags); 444 445 /** 446 * Appends a conditional order to the end of the vehicle's order list. 447 * @param vehicle_id The vehicle to append the order to. 448 * @param jump_to The OrderPosition to jump to if the condition is true. 449 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 450 * @pre IsValidVehicleOrder(vehicle_id, jump_to). 451 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 452 * @exception ScriptOrder::ERR_ORDER_TOO_MANY 453 * @return True if and only if the order was appended. 454 * @api -game 455 */ 456 static bool AppendConditionalOrder(VehicleID vehicle_id, OrderPosition jump_to); 457 458 /** 459 * Inserts an order before the given order_position into the vehicle's order list. 460 * @param vehicle_id The vehicle to add the order to. 461 * @param order_position The order to place the new order before. 462 * @param destination The destination of the order. 463 * @param order_flags The flags given to the order. 464 * @pre IsValidVehicleOrder(vehicle_id, order_position). 465 * @pre AreOrderFlagsValid(destination, order_flags). 466 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 467 * @exception ScriptOrder::ERR_ORDER_TOO_MANY 468 * @exception ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION 469 * @return True if and only if the order was inserted. 470 * @api -game 471 */ 472 static bool InsertOrder(VehicleID vehicle_id, OrderPosition order_position, TileIndex destination, ScriptOrderFlags order_flags); 473 474 /** 475 * Appends a conditional order before the given order_position into the vehicle's order list. 476 * @param vehicle_id The vehicle to add the order to. 477 * @param order_position The order to place the new order before. 478 * @param jump_to The OrderPosition to jump to if the condition is true. 479 * @pre IsValidVehicleOrder(vehicle_id, order_position). 480 * @pre IsValidVehicleOrder(vehicle_id, jump_to). 481 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 482 * @exception ScriptOrder::ERR_ORDER_TOO_MANY 483 * @return True if and only if the order was inserted. 484 * @api -game 485 */ 486 static bool InsertConditionalOrder(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to); 487 488 /** 489 * Removes an order from the vehicle's order list. 490 * @param vehicle_id The vehicle to remove the order from. 491 * @param order_position The order to remove from the order list. 492 * @pre IsValidVehicleOrder(vehicle_id, order_position). 493 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 494 * @return True if and only if the order was removed. 495 * @api -game 496 */ 497 static bool RemoveOrder(VehicleID vehicle_id, OrderPosition order_position); 498 499 /** 500 * Internal function to help SetOrderFlags. 501 * @api -all 502 */ 503 static bool _SetOrderFlags(); 504 505 /** 506 * Changes the order flags of the given order. 507 * @param vehicle_id The vehicle to change the order of. 508 * @param order_position The order to change. 509 * @param order_flags The new flags given to the order. 510 * @pre IsValidVehicleOrder(vehicle_id, order_position). 511 * @pre AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags). 512 * @pre (order_flags & OF_GOTO_NEAREST_DEPOT) == (GetOrderFlags(vehicle_id, order_position) & OF_GOTO_NEAREST_DEPOT). 513 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 514 * @return True if and only if the order was changed. 515 * @api -game 516 */ 517 static bool SetOrderFlags(VehicleID vehicle_id, OrderPosition order_position, ScriptOrderFlags order_flags); 518 519 /** 520 * Move an order inside the orderlist 521 * @param vehicle_id The vehicle to move the orders. 522 * @param order_position_move The order to move. 523 * @param order_position_target The target order 524 * @pre IsValidVehicleOrder(vehicle_id, order_position_move). 525 * @pre IsValidVehicleOrder(vehicle_id, order_position_target). 526 * @pre order_position_move != order_position_target. 527 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 528 * @return True if and only if the order was moved. 529 * @note If the order is moved to a lower place (e.g. from 7 to 2) 530 * the target order is moved upwards (e.g. 3). If the order is moved 531 * to a higher place (e.g. from 7 to 9) the target will be moved 532 * downwards (e.g. 8). 533 * @api -game 534 */ 535 static bool MoveOrder(VehicleID vehicle_id, OrderPosition order_position_move, OrderPosition order_position_target); 536 537 /** 538 * Make a vehicle execute next_order instead of its current order. 539 * @param vehicle_id The vehicle that should skip some orders. 540 * @param next_order The order the vehicle should skip to. 541 * @pre IsValidVehicleOrder(vehicle_id, next_order). 542 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 543 * @return True if and only the current order was changed. 544 * @api -game 545 */ 546 static bool SkipToOrder(VehicleID vehicle_id, OrderPosition next_order); 547 548 /** 549 * Copies the orders from another vehicle. The orders of the main vehicle 550 * are going to be the orders of the changed vehicle. 551 * @param vehicle_id The vehicle to copy the orders to. 552 * @param main_vehicle_id The vehicle to copy the orders from. 553 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 554 * @pre ScriptVehicle::IsValidVehicle(main_vehicle_id). 555 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 556 * @exception ScriptOrder::ERR_ORDER_TOO_MANY 557 * @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE 558 * @return True if and only if the copying succeeded. 559 * @api -game 560 */ 561 static bool CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id); 562 563 /** 564 * Shares the orders between two vehicles. The orders of the main 565 * vehicle are going to be the orders of the changed vehicle. 566 * @param vehicle_id The vehicle to add to the shared order list. 567 * @param main_vehicle_id The vehicle to share the orders with. 568 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 569 * @pre ScriptVehicle::IsValidVehicle(main_vehicle_id). 570 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY 571 * @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE 572 * @return True if and only if the sharing succeeded. 573 * @api -game 574 */ 575 static bool ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id); 576 577 /** 578 * Removes the given vehicle from a shared orders list. 579 * After unsharing orders, the orders list of the vehicle is empty. 580 * @param vehicle_id The vehicle to remove from the shared order list. 581 * @pre ScriptVehicle::IsValidVehicle(vehicle_id). 582 * @return True if and only if the unsharing succeeded. 583 * @api -game 584 */ 585 static bool UnshareOrders(VehicleID vehicle_id); 586 587 /** 588 * Get the distance between two points for a vehicle type. 589 * Use this function to compute the distance between two tiles wrt. a vehicle type. 590 * These vehicle-type specific distances are independent from other map distances, you may 591 * use the result of this function to compare it with the result of 592 * ScriptEngine::GetMaximumOrderDistance or ScriptVehicle::GetMaximumOrderDistance. 593 * @param vehicle_type The vehicle type to get the distance for. 594 * @param origin_tile Origin, can be any tile or a tile of a specific station. 595 * @param dest_tile Destination, can be any tile or a tile of a specific station. 596 * @return The distance between the origin and the destination for a 597 * vehicle of the given vehicle type. 598 * @note The unit of the order distances is unspecified and should 599 * not be compared with map distances 600 * @see ScriptEngine::GetMaximumOrderDistance and ScriptVehicle::GetMaximumOrderDistance 601 */ 602 static uint GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile); 603 }; 604 DECLARE_ENUM_AS_BIT_SET(ScriptOrder::ScriptOrderFlags) 605 606 #endif /* SCRIPT_ORDER_HPP */ 607