src/aircraft_cmd.cpp
branchnoai
changeset 9869 6404afe43575
parent 9837 c9ec4f82e0d0
child 10142 56ee7da4ad56
equal deleted inserted replaced
9868:3998f2e73dda 9869:6404afe43575
    53 				case LANDING:
    53 				case LANDING:
    54 				case HELILANDING:
    54 				case HELILANDING:
    55 				case FLYING:     x = MKIT(24, 24, -1, -1); break;
    55 				case FLYING:     x = MKIT(24, 24, -1, -1); break;
    56 				default:         x = MKIT( 2,  2, -1, -1); break;
    56 				default:         x = MKIT( 2,  2, -1, -1); break;
    57 			}
    57 			}
    58 			this->z_height = 5;
    58 			this->z_extent = 5;
    59 			break;
    59 			break;
    60 		case AIR_SHADOW:     this->z_height = 1; x = MKIT(2,  2,  0,  0); break;
    60 		case AIR_SHADOW:     this->z_extent = 1; x = MKIT(2,  2,  0,  0); break;
    61 		case AIR_ROTOR:      this->z_height = 1; x = MKIT(2,  2, -1, -1); break;
    61 		case AIR_ROTOR:      this->z_extent = 1; x = MKIT(2,  2, -1, -1); break;
    62 	}
    62 	}
    63 #undef MKIT
    63 #undef MKIT
    64 
    64 
    65 	this->x_offs        = GB(x,  0, 8);
    65 	this->x_offs        = GB(x,  0, 8);
    66 	this->y_offs        = GB(x,  8, 8);
    66 	this->y_offs        = GB(x,  8, 8);
    67 	this->sprite_width  = GB(x, 16, 8);
    67 	this->x_extent      = GB(x, 16, 8);
    68 	this->sprite_height = GB(x, 24, 8);
    68 	this->y_extent      = GB(x, 24, 8);
    69 }
    69 }
    70 
    70 
    71 
    71 
    72 /** this maps the terminal to its corresponding state and block flag
    72 /** this maps the terminal to its corresponding state and block flag
    73  *  currently set for 10 terms, 4 helipads */
    73  *  currently set for 10 terms, 4 helipads */
   568 
   568 
   569 	Vehicle *v = GetVehicle(p1);
   569 	Vehicle *v = GetVehicle(p1);
   570 
   570 
   571 	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR;
   571 	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR;
   572 
   572 
   573 	if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
   573 	if (v->current_order.IsType(OT_GOTO_DEPOT) && !(p2 & DEPOT_LOCATE_HANGAR)) {
   574 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
   574 		bool halt_in_depot = HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT);
       
   575 		if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) {
   575 			/* We called with a different DEPOT_SERVICE setting.
   576 			/* We called with a different DEPOT_SERVICE setting.
   576 			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
   577 			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
   577 			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
   578 			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
   578 			if (flags & DC_EXEC) {
   579 			if (flags & DC_EXEC) {
   579 				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
   580 				v->current_order.SetDepotOrderType(OFB_MANUAL_ORDER);
   580 				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
   581 				v->current_order.SetDepotActionType(halt_in_depot ? OFB_NORMAL_ACTION : OFB_HALT_IN_DEPOT);
   581 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   582 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   582 			}
   583 			}
   583 			return CommandCost();
   584 			return CommandCost();
   584 		}
   585 		}
   585 
   586 
   586 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
   587 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
   587 		if (flags & DC_EXEC) {
   588 		if (flags & DC_EXEC) {
   588 			if (v->current_order.flags & OFB_UNLOAD) v->cur_order_index++;
   589 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
   589 			v->current_order.type = OT_DUMMY;
   590 			 * then skip to the next order; effectively cancelling this forced service */
   590 			v->current_order.flags = 0;
   591 			if (v->current_order.GetDepotOrderType() & OFB_PART_OF_ORDERS) v->cur_order_index++;
       
   592 
       
   593 			v->current_order.MakeDummy();
   591 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   594 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   592 		}
   595 		}
   593 	} else {
   596 	} else {
   594 		bool next_airport_has_hangar = true;
   597 		bool next_airport_has_hangar = true;
   595 		StationID next_airport_index = v->u.air.targetairport;
   598 		StationID next_airport_index = v->u.air.targetairport;
   603 			if (station == INVALID_STATION) return CMD_ERROR;
   606 			if (station == INVALID_STATION) return CMD_ERROR;
   604 			next_airport_index = station;
   607 			next_airport_index = station;
   605 		}
   608 		}
   606 
   609 
   607 		if (flags & DC_EXEC) {
   610 		if (flags & DC_EXEC) {
   608 			if (v->current_order.type == OT_LOADING) v->LeaveStation();
   611 			if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
   609 
   612 
   610 			v->current_order.type = OT_GOTO_DEPOT;
   613 			v->current_order.MakeGoToDepot(next_airport_index, false);
   611 			v->current_order.flags = OFB_NON_STOP;
   614 			if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(OFB_HALT_IN_DEPOT);
   612 			if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
       
   613 			v->current_order.refit_cargo = CT_INVALID;
       
   614 			v->current_order.dest = next_airport_index;
       
   615 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   615 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   616 			if (v->u.air.state == FLYING && !next_airport_has_hangar) {
   616 			if (v->u.air.state == FLYING && !next_airport_has_hangar) {
   617 				/* The aircraft is now heading for a different hangar than the next in the orders */
   617 				/* The aircraft is now heading for a different hangar than the next in the orders */
   618 				AircraftNextAirportPos_and_Order(v);
   618 				AircraftNextAirportPos_and_Order(v);
   619 			}
   619 			}
   708 	if (v->IsInDepot()) {
   708 	if (v->IsInDepot()) {
   709 		VehicleServiceInDepot(v);
   709 		VehicleServiceInDepot(v);
   710 		return;
   710 		return;
   711 	}
   711 	}
   712 
   712 
   713 	const Station *st = GetStation(v->current_order.dest);
   713 	const Station *st = GetStation(v->current_order.GetDestination());
   714 	/* only goto depot if the target airport has terminals (eg. it is airport) */
   714 	/* only goto depot if the target airport has terminals (eg. it is airport) */
   715 	if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) {
   715 	if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) {
   716 //		printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
   716 //		printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
   717 //		v->u.air.targetairport = st->index;
   717 //		v->u.air.targetairport = st->index;
   718 		v->current_order.type = OT_GOTO_DEPOT;
   718 		v->current_order.MakeGoToDepot(0, false);
   719 		v->current_order.flags = OFB_NON_STOP;
       
   720 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   719 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   721 	} else if (v->current_order.type == OT_GOTO_DEPOT) {
   720 	} else if (v->current_order.IsType(OT_GOTO_DEPOT)) {
   722 		v->current_order.type = OT_DUMMY;
   721 		v->current_order.MakeDummy();
   723 		v->current_order.flags = 0;
       
   724 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   722 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   725 	}
   723 	}
   726 }
   724 }
   727 
   725 
   728 void Aircraft::OnNewDay()
   726 void Aircraft::OnNewDay()
   779 
   777 
   780 	if (u->vehstatus & VS_HIDDEN) return;
   778 	if (u->vehstatus & VS_HIDDEN) return;
   781 
   779 
   782 	/* if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
   780 	/* if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
   783 	 * loading/unloading at a terminal or stopped */
   781 	 * loading/unloading at a terminal or stopped */
   784 	if (v->current_order.type == OT_LOADING || (v->vehstatus & VS_STOPPED)) {
   782 	if (v->current_order.IsType(OT_LOADING) || (v->vehstatus & VS_STOPPED)) {
   785 		if (u->cur_speed != 0) {
   783 		if (u->cur_speed != 0) {
   786 			u->cur_speed++;
   784 			u->cur_speed++;
   787 			if (u->cur_speed >= 0x80 && u->u.air.state == HRS_ROTOR_MOVING_3) {
   785 			if (u->cur_speed >= 0x80 && u->u.air.state == HRS_ROTOR_MOVING_3) {
   788 				u->cur_speed = 0;
   786 				u->cur_speed = 0;
   789 			}
   787 			}
  1059 		tile = st->xy;
  1057 		tile = st->xy;
  1060 
  1058 
  1061 		/* Jump into our "holding pattern" state machine if possible */
  1059 		/* Jump into our "holding pattern" state machine if possible */
  1062 		if (v->u.air.pos >= afc->nofelements) {
  1060 		if (v->u.air.pos >= afc->nofelements) {
  1063 			v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc);
  1061 			v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc);
  1064 		} else if (v->u.air.targetairport != v->current_order.dest) {
  1062 		} else if (v->u.air.targetairport != v->current_order.GetDestination()) {
  1065 			/* If not possible, just get out of here fast */
  1063 			/* If not possible, just get out of here fast */
  1066 			v->u.air.state = FLYING;
  1064 			v->u.air.state = FLYING;
  1067 			UpdateAircraftCache(v);
  1065 			UpdateAircraftCache(v);
  1068 			AircraftNextAirportPos_and_Order(v);
  1066 			AircraftNextAirportPos_and_Order(v);
  1069 			/* get aircraft back on running altitude */
  1067 			/* get aircraft back on running altitude */
  1360 			EV_SMOKE
  1358 			EV_SMOKE
  1361 		);
  1359 		);
  1362 	}
  1360 	}
  1363 }
  1361 }
  1364 
  1362 
  1365 static void ProcessAircraftOrder(Vehicle *v)
  1363 void HandleMissingAircraftOrders(Vehicle *v)
  1366 {
  1364 {
  1367 	switch (v->current_order.type) {
  1365 	/*
  1368 		case OT_GOTO_DEPOT:
  1366 	 * We do not have an order. This can be divided into two cases:
  1369 			if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return;
  1367 	 * 1) we are heading to an invalid station. In this case we must
  1370 			if (v->current_order.flags & OFB_SERVICE_IF_NEEDED &&
  1368 	 *    find another airport to go to. If there is nowhere to go,
  1371 					!VehicleNeedsService(v)) {
  1369 	 *    we will destroy the aircraft as it otherwise will enter
  1372 				UpdateVehicleTimetable(v, true);
  1370 	 *    the holding pattern for the first airport, which can cause
  1373 				v->cur_order_index++;
  1371 	 *    the plane to go into an undefined state when building an
  1374 			}
  1372 	 *    airport with the same StationID.
  1375 			break;
  1373 	 * 2) we are (still) heading to a (still) valid airport, then we
  1376 
  1374 	 *    can continue going there. This can happen when you are
  1377 		case OT_LOADING: return;
  1375 	 *    changing the aircraft's orders while in-flight or in for
  1378 
  1376 	 *    example a depot. However, when we have a current order to
  1379 		default: break;
  1377 	 *    go to a depot, we have to keep that order so the aircraft
  1380 	}
  1378 	 *    actually stops.
  1381 
  1379 	 */
  1382 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
  1380 	const Station *st = GetStation(v->u.air.targetairport);
  1383 
  1381 	if (!st->IsValid() || st->airport_tile == 0) {
  1384 	const Order *order = GetVehicleOrder(v, v->cur_order_index);
  1382 		CommandCost ret;
  1385 
  1383 		PlayerID old_player = _current_player;
  1386 	if (order == NULL|| (order->type == OT_DUMMY && !CheckForValidOrders(v))) {
  1384 
  1387 		/*
  1385 		_current_player = v->owner;
  1388 		 * We do not have an order. This can be divided into two cases:
  1386 		ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
  1389 		 * 1) we are heading to an invalid station. In this case we must
  1387 		_current_player = old_player;
  1390 		 *    find another airport to go to. If there is nowhere to go,
  1388 
  1391 		 *    we will destroy the aircraft as it otherwise will enter
  1389 		if (CmdFailed(ret)) CrashAirplane(v);
  1392 		 *    the holding pattern for the first airport, which can cause
  1390 	} else if (!v->current_order.IsType(OT_GOTO_DEPOT)) {
  1393 		 *    the plane to go into an undefined state when building an
  1391 		v->current_order.Free();
  1394 		 *    airport with the same StationID.
  1392 	}
  1395 		 * 2) we are (still) heading to a (still) valid airport, then we
  1393 }
  1396 		 *    can continue going there. This can happen when you are
  1394 
  1397 		 *    changing the aircraft's orders while in-flight or in for
  1395 
  1398 		 *    example a depot. However, when we have a current order to
  1396 TileIndex Aircraft::GetOrderStationLocation(StationID station)
  1399 		 *    go to a depot, we have to keep that order so the aircraft
  1397 {
  1400 		 *    actually stops.
  1398 	/* Orders are changed in flight, ensure going to the right station. */
  1401 		 */
  1399 	if (this->u.air.state == FLYING) {
  1402 		const Station *st = GetStation(v->u.air.targetairport);
  1400 		AircraftNextAirportPos_and_Order(this);
  1403 		if (!st->IsValid() || st->airport_tile == 0) {
  1401 	}
  1404 			CommandCost ret;
  1402 
  1405 			PlayerID old_player = _current_player;
  1403 	/* Aircraft do not use dest-tile */
  1406 
  1404 	return 0;
  1407 			_current_player = v->owner;
       
  1408 			ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
       
  1409 			_current_player = old_player;
       
  1410 
       
  1411 			if (CmdFailed(ret)) CrashAirplane(v);
       
  1412 		} else if (v->current_order.type != OT_GOTO_DEPOT) {
       
  1413 			v->current_order.Free();
       
  1414 		}
       
  1415 		return;
       
  1416 	}
       
  1417 
       
  1418 	if (order->type  == v->current_order.type  &&
       
  1419 			order->flags == v->current_order.flags &&
       
  1420 			order->dest  == v->current_order.dest)
       
  1421 		return;
       
  1422 
       
  1423 	v->current_order = *order;
       
  1424 
       
  1425 	/* orders are changed in flight, ensure going to the right station */
       
  1426 	if (order->type == OT_GOTO_STATION && v->u.air.state == FLYING) {
       
  1427 		AircraftNextAirportPos_and_Order(v);
       
  1428 	}
       
  1429 
       
  1430 	InvalidateVehicleOrder(v);
       
  1431 
       
  1432 	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
       
  1433 }
  1405 }
  1434 
  1406 
  1435 void Aircraft::MarkDirty()
  1407 void Aircraft::MarkDirty()
  1436 {
  1408 {
  1437 		this->cur_image = this->GetImage(this->direction);
  1409 		this->cur_image = this->GetImage(this->direction);
  1498 }
  1470 }
  1499 
  1471 
  1500 /** we've landed and just arrived at a terminal */
  1472 /** we've landed and just arrived at a terminal */
  1501 static void AircraftEntersTerminal(Vehicle *v)
  1473 static void AircraftEntersTerminal(Vehicle *v)
  1502 {
  1474 {
  1503 	if (v->current_order.type == OT_GOTO_DEPOT) return;
  1475 	if (v->current_order.IsType(OT_GOTO_DEPOT)) return;
  1504 
  1476 
  1505 	Station *st = GetStation(v->u.air.targetairport);
  1477 	Station *st = GetStation(v->u.air.targetairport);
  1506 	v->last_station_visited = v->u.air.targetairport;
  1478 	v->last_station_visited = v->u.air.targetairport;
  1507 
  1479 
  1508 	/* Check if station was ever visited before */
  1480 	/* Check if station was ever visited before */
  1532 
  1504 
  1533 
  1505 
  1534 /** set the right pos when heading to other airports after takeoff */
  1506 /** set the right pos when heading to other airports after takeoff */
  1535 static void AircraftNextAirportPos_and_Order(Vehicle *v)
  1507 static void AircraftNextAirportPos_and_Order(Vehicle *v)
  1536 {
  1508 {
  1537 	if (v->current_order.type == OT_GOTO_STATION ||
  1509 	if (v->current_order.IsType(OT_GOTO_STATION) ||
  1538 			v->current_order.type == OT_GOTO_DEPOT)
  1510 			v->current_order.IsType(OT_GOTO_DEPOT))
  1539 		v->u.air.targetairport = v->current_order.dest;
  1511 		v->u.air.targetairport = v->current_order.GetDestination();
  1540 
  1512 
  1541 	const AirportFTAClass *apc = GetStation(v->u.air.targetairport)->Airport();
  1513 	const AirportFTAClass *apc = GetStation(v->u.air.targetairport)->Airport();
  1542 	v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc);
  1514 	v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc);
  1543 }
  1515 }
  1544 
  1516 
  1630 		AircraftEventHandler_EnterHangar(v, apc);
  1602 		AircraftEventHandler_EnterHangar(v, apc);
  1631 		return;
  1603 		return;
  1632 	}
  1604 	}
  1633 
  1605 
  1634 	/* if we were sent to the depot, stay there */
  1606 	/* if we were sent to the depot, stay there */
  1635 	if (v->current_order.type == OT_GOTO_DEPOT && (v->vehstatus & VS_STOPPED)) {
  1607 	if (v->current_order.IsType(OT_GOTO_DEPOT) && (v->vehstatus & VS_STOPPED)) {
  1636 		v->current_order.Free();
  1608 		v->current_order.Free();
  1637 		return;
  1609 		return;
  1638 	}
  1610 	}
  1639 
  1611 
  1640 	if (v->current_order.type != OT_GOTO_STATION &&
  1612 	if (!v->current_order.IsType(OT_GOTO_STATION) &&
  1641 			v->current_order.type != OT_GOTO_DEPOT)
  1613 			!v->current_order.IsType(OT_GOTO_DEPOT))
  1642 		return;
  1614 		return;
  1643 
  1615 
  1644 	/* if the block of the next position is busy, stay put */
  1616 	/* if the block of the next position is busy, stay put */
  1645 	if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
  1617 	if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
  1646 
  1618 
  1647 	/* We are already at the target airport, we need to find a terminal */
  1619 	/* We are already at the target airport, we need to find a terminal */
  1648 	if (v->current_order.dest == v->u.air.targetairport) {
  1620 	if (v->current_order.GetDestination() == v->u.air.targetairport) {
  1649 		/* FindFreeTerminal:
  1621 		/* FindFreeTerminal:
  1650 		 * 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal */
  1622 		 * 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal */
  1651 		if (v->subtype == AIR_HELICOPTER) {
  1623 		if (v->subtype == AIR_HELICOPTER) {
  1652 			if (!AirportFindFreeHelipad(v, apc)) return; // helicopter
  1624 			if (!AirportFindFreeHelipad(v, apc)) return; // helicopter
  1653 		} else {
  1625 		} else {
  1687 	if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
  1659 	if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return;
  1688 
  1660 
  1689 	/* airport-road is free. We either have to go to another airport, or to the hangar
  1661 	/* airport-road is free. We either have to go to another airport, or to the hangar
  1690 	 * ---> start moving */
  1662 	 * ---> start moving */
  1691 
  1663 
  1692 	switch (v->current_order.type) {
  1664 	switch (v->current_order.GetType()) {
  1693 		case OT_GOTO_STATION: // ready to fly to another airport
  1665 		case OT_GOTO_STATION: // ready to fly to another airport
  1694 			/* airplane goto state takeoff, helicopter to helitakeoff */
  1666 			/* airplane goto state takeoff, helicopter to helitakeoff */
  1695 			v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF;
  1667 			v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF;
  1696 			break;
  1668 			break;
  1697 		case OT_GOTO_DEPOT:   // visit hangar for serivicing, sale, etc.
  1669 		case OT_GOTO_DEPOT:   // visit hangar for serivicing, sale, etc.
  1698 			if (v->current_order.dest == v->u.air.targetairport) {
  1670 			if (v->current_order.GetDestination() == v->u.air.targetairport) {
  1699 				v->u.air.state = HANGAR;
  1671 				v->u.air.state = HANGAR;
  1700 			} else {
  1672 			} else {
  1701 				v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF;
  1673 				v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF;
  1702 			}
  1674 			}
  1703 			break;
  1675 			break;
  1813 
  1785 
  1814 	/* if going to terminal (OT_GOTO_STATION) choose one
  1786 	/* if going to terminal (OT_GOTO_STATION) choose one
  1815 	 * 1. in case all terminals are busy AirportFindFreeTerminal() returns false or
  1787 	 * 1. in case all terminals are busy AirportFindFreeTerminal() returns false or
  1816 	 * 2. not going for terminal (but depot, no order),
  1788 	 * 2. not going for terminal (but depot, no order),
  1817 	 * --> get out of the way to the hangar. */
  1789 	 * --> get out of the way to the hangar. */
  1818 	if (v->current_order.type == OT_GOTO_STATION) {
  1790 	if (v->current_order.IsType(OT_GOTO_STATION)) {
  1819 		if (AirportFindFreeTerminal(v, apc)) return;
  1791 		if (AirportFindFreeTerminal(v, apc)) return;
  1820 	}
  1792 	}
  1821 	v->u.air.state = HANGAR;
  1793 	v->u.air.state = HANGAR;
  1822 
  1794 
  1823 }
  1795 }
  1832 	 * 2. not going for terminal (but depot, no order),
  1804 	 * 2. not going for terminal (but depot, no order),
  1833 	 * --> get out of the way to the hangar IF there are terminals on the airport.
  1805 	 * --> get out of the way to the hangar IF there are terminals on the airport.
  1834 	 * --> else TAKEOFF
  1806 	 * --> else TAKEOFF
  1835 	 * the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes
  1807 	 * the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes
  1836 	 * must go to a hangar. */
  1808 	 * must go to a hangar. */
  1837 	if (v->current_order.type == OT_GOTO_STATION) {
  1809 	if (v->current_order.IsType(OT_GOTO_STATION)) {
  1838 		if (AirportFindFreeHelipad(v, apc)) return;
  1810 		if (AirportFindFreeHelipad(v, apc)) return;
  1839 	}
  1811 	}
  1840 	v->u.air.state = (apc->nof_depots != 0) ? HANGAR : HELITAKEOFF;
  1812 	v->u.air.state = (apc->nof_depots != 0) ? HANGAR : HELITAKEOFF;
  1841 }
  1813 }
  1842 
  1814 
  2150 			v->breakdown_ctr--;
  2122 			v->breakdown_ctr--;
  2151 		}
  2123 		}
  2152 	}
  2124 	}
  2153 
  2125 
  2154 	HandleAircraftSmoke(v);
  2126 	HandleAircraftSmoke(v);
  2155 	ProcessAircraftOrder(v);
  2127 	ProcessOrders(v);
  2156 	v->HandleLoading(loop != 0);
  2128 	v->HandleLoading(loop != 0);
  2157 
  2129 
  2158 	if (v->current_order.type >= OT_LOADING) return;
  2130 	if (v->current_order.IsType(OT_LOADING) || v->current_order.IsType(OT_LEAVESTATION)) return;
  2159 
  2131 
  2160 	AirportGoToNextPosition(v);
  2132 	AirportGoToNextPosition(v);
  2161 }
  2133 }
  2162 
  2134 
  2163 void Aircraft::Tick()
  2135 void Aircraft::Tick()