src/aircraft_cmd.cpp
branchnoai
changeset 9724 b39bc69bb2f2
parent 9723 eee46cb39750
child 9732 f8eb3e208514
equal deleted inserted replaced
9723:eee46cb39750 9724:b39bc69bb2f2
     7 #include "openttd.h"
     7 #include "openttd.h"
     8 #include "aircraft.h"
     8 #include "aircraft.h"
     9 #include "debug.h"
     9 #include "debug.h"
    10 #include "landscape.h"
    10 #include "landscape.h"
    11 #include "station_map.h"
    11 #include "station_map.h"
    12 #include "table/strings.h"
       
    13 #include "timetable.h"
    12 #include "timetable.h"
    14 #include "depot.h"
    13 #include "depot.h"
    15 #include "engine.h"
    14 #include "engine.h"
    16 #include "station.h"
    15 #include "station.h"
    17 #include "news.h"
    16 #include "news.h"
    18 #include "player.h"
       
    19 #include "aircraft.h"
    17 #include "aircraft.h"
    20 #include "airport.h"
    18 #include "airport.h"
    21 #include "vehicle_gui.h"
    19 #include "vehicle_gui.h"
    22 #include "table/sprites.h"
       
    23 #include "newgrf_engine.h"
    20 #include "newgrf_engine.h"
    24 #include "newgrf_callbacks.h"
    21 #include "newgrf_callbacks.h"
    25 #include "newgrf_text.h"
    22 #include "newgrf_text.h"
    26 #include "newgrf_sound.h"
    23 #include "newgrf_sound.h"
    27 #include "spritecache.h"
    24 #include "spritecache.h"
    36 #include "variables.h"
    33 #include "variables.h"
    37 #include "autoreplace_func.h"
    34 #include "autoreplace_func.h"
    38 #include "autoreplace_gui.h"
    35 #include "autoreplace_gui.h"
    39 #include "gfx_func.h"
    36 #include "gfx_func.h"
    40 #include "ai/ai.h"
    37 #include "ai/ai.h"
       
    38 #include "player_func.h"
       
    39 #include "settings_type.h"
       
    40 
       
    41 #include "table/strings.h"
       
    42 #include "table/sprites.h"
    41 
    43 
    42 void Aircraft::UpdateDeltaXY(Direction direction)
    44 void Aircraft::UpdateDeltaXY(Direction direction)
    43 {
    45 {
    44 	uint32 x;
    46 	uint32 x;
    45 #define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
    47 #define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
   334 		v->cargo_type = CT_PASSENGERS;
   336 		v->cargo_type = CT_PASSENGERS;
   335 		u->cargo_type = CT_MAIL;
   337 		u->cargo_type = CT_MAIL;
   336 
   338 
   337 		v->cargo_subtype = 0;
   339 		v->cargo_subtype = 0;
   338 
   340 
   339 		v->string_id = STR_SV_AIRCRAFT_NAME;
   341 		v->name = NULL;
   340 //		v->next_order_param = v->next_order = 0;
   342 //		v->next_order_param = v->next_order = 0;
   341 
   343 
   342 //		v->load_unload_time_rem = 0;
   344 //		v->load_unload_time_rem = 0;
   343 //		v->progress = 0;
   345 //		v->progress = 0;
   344 		v->last_station_visited = INVALID_STATION;
   346 		v->last_station_visited = INVALID_STATION;
   534 			DeleteVehicleNews(p1, STR_A014_AIRCRAFT_IS_WAITING_IN);
   536 			DeleteVehicleNews(p1, STR_A014_AIRCRAFT_IS_WAITING_IN);
   535 		}
   537 		}
   536 
   538 
   537 		v->vehstatus ^= VS_STOPPED;
   539 		v->vehstatus ^= VS_STOPPED;
   538 		v->cur_speed = 0;
   540 		v->cur_speed = 0;
   539 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   541 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   540 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   542 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   541 		InvalidateWindowClasses(WC_AIRCRAFT_LIST);
   543 		InvalidateWindowClasses(WC_AIRCRAFT_LIST);
   542 	}
   544 	}
   543 
   545 
   544 	return CommandCost();
   546 	return CommandCost();
   566 	Vehicle *v = GetVehicle(p1);
   568 	Vehicle *v = GetVehicle(p1);
   567 
   569 
   568 	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR;
   570 	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR;
   569 
   571 
   570 	if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
   572 	if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
   571 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
   573 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
   572 			/* We called with a different DEPOT_SERVICE setting.
   574 			/* We called with a different DEPOT_SERVICE setting.
   573 			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
   575 			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
   574 			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
   576 			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
   575 			if (flags & DC_EXEC) {
   577 			if (flags & DC_EXEC) {
   576 				ClrBit(v->current_order.flags, OFB_PART_OF_ORDERS);
   578 				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
   577 				ToggleBit(v->current_order.flags, OFB_HALT_IN_DEPOT);
   579 				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
   578 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   580 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   579 			}
   581 			}
   580 			return CommandCost();
   582 			return CommandCost();
   581 		}
   583 		}
   582 
   584 
   583 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
   585 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
   584 		if (flags & DC_EXEC) {
   586 		if (flags & DC_EXEC) {
   585 			if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
   587 			if (v->current_order.flags & OFB_UNLOAD) v->cur_order_index++;
   586 			v->current_order.type = OT_DUMMY;
   588 			v->current_order.type = OT_DUMMY;
   587 			v->current_order.flags = 0;
   589 			v->current_order.flags = 0;
   588 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   590 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   589 		}
   591 		}
   590 	} else {
   592 	} else {
   591 		bool next_airport_has_hangar = true;
   593 		bool next_airport_has_hangar = true;
   592 		StationID next_airport_index = v->u.air.targetairport;
   594 		StationID next_airport_index = v->u.air.targetairport;
   593 		const Station *st = GetStation(next_airport_index);
   595 		const Station *st = GetStation(next_airport_index);
   603 
   605 
   604 		if (flags & DC_EXEC) {
   606 		if (flags & DC_EXEC) {
   605 			if (v->current_order.type == OT_LOADING) v->LeaveStation();
   607 			if (v->current_order.type == OT_LOADING) v->LeaveStation();
   606 
   608 
   607 			v->current_order.type = OT_GOTO_DEPOT;
   609 			v->current_order.type = OT_GOTO_DEPOT;
   608 			v->current_order.flags = OF_NON_STOP;
   610 			v->current_order.flags = OFB_NON_STOP;
   609 			if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OFB_HALT_IN_DEPOT);
   611 			if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
   610 			v->current_order.refit_cargo = CT_INVALID;
   612 			v->current_order.refit_cargo = CT_INVALID;
   611 			v->current_order.dest = next_airport_index;
   613 			v->current_order.dest = next_airport_index;
   612 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   614 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   613 			if (v->u.air.state == FLYING && !next_airport_has_hangar) {
   615 			if (v->u.air.state == FLYING && !next_airport_has_hangar) {
   614 				/* The aircraft is now heading for a different hangar than the next in the orders */
   616 				/* The aircraft is now heading for a different hangar than the next in the orders */
   615 				AircraftNextAirportPos_and_Order(v);
   617 				AircraftNextAirportPos_and_Order(v);
   616 			}
   618 			}
   617 		}
   619 		}
   711 	/* only goto depot if the target airport has terminals (eg. it is airport) */
   713 	/* only goto depot if the target airport has terminals (eg. it is airport) */
   712 	if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) {
   714 	if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) {
   713 //		printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
   715 //		printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
   714 //		v->u.air.targetairport = st->index;
   716 //		v->u.air.targetairport = st->index;
   715 		v->current_order.type = OT_GOTO_DEPOT;
   717 		v->current_order.type = OT_GOTO_DEPOT;
   716 		v->current_order.flags = OF_NON_STOP;
   718 		v->current_order.flags = OFB_NON_STOP;
   717 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   719 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   718 	} else if (v->current_order.type == OT_GOTO_DEPOT) {
   720 	} else if (v->current_order.type == OT_GOTO_DEPOT) {
   719 		v->current_order.type = OT_DUMMY;
   721 		v->current_order.type = OT_DUMMY;
   720 		v->current_order.flags = 0;
   722 		v->current_order.flags = 0;
   721 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   723 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   722 	}
   724 	}
   723 }
   725 }
   724 
   726 
   725 void OnNewDay_Aircraft(Vehicle *v)
   727 void Aircraft::OnNewDay()
   726 {
   728 {
   727 	if (!IsNormalAircraft(v)) return;
   729 	if (!IsNormalAircraft(this)) return;
   728 
   730 
   729 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
   731 	if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
   730 
   732 
   731 	CheckOrders(v);
   733 	CheckOrders(this);
   732 
   734 
   733 	CheckVehicleBreakdown(v);
   735 	CheckVehicleBreakdown(this);
   734 	AgeVehicle(v);
   736 	AgeVehicle(this);
   735 	CheckIfAircraftNeedsService(v);
   737 	CheckIfAircraftNeedsService(this);
   736 
   738 
   737 	if (v->vehstatus & VS_STOPPED) return;
   739 	if (this->vehstatus & VS_STOPPED) return;
   738 
   740 
   739 	CommandCost cost = CommandCost(EXPENSES_AIRCRAFT_RUN, GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364);
   741 	CommandCost cost = CommandCost(EXPENSES_AIRCRAFT_RUN, GetVehicleProperty(this, 0x0E, AircraftVehInfo(this->engine_type)->running_cost) * _price.aircraft_running / 364);
   740 
   742 
   741 	v->profit_this_year -= cost.GetCost() >> 8;
   743 	this->profit_this_year -= cost.GetCost() >> 8;
   742 
   744 
   743 	SubtractMoneyFromPlayerFract(v->owner, cost);
   745 	SubtractMoneyFromPlayerFract(this->owner, cost);
   744 
   746 
   745 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   747 	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
   746 	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
   748 	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
   747 }
   749 }
   748 
   750 
   749 void AircraftYearlyLoop()
   751 void AircraftYearlyLoop()
   750 {
   752 {
   938 
   940 
   939 	/* updates statusbar only if speed have changed to save CPU time */
   941 	/* updates statusbar only if speed have changed to save CPU time */
   940 	if (spd != v->cur_speed) {
   942 	if (spd != v->cur_speed) {
   941 		v->cur_speed = spd;
   943 		v->cur_speed = spd;
   942 		if (_patches.vehicle_speed)
   944 		if (_patches.vehicle_speed)
   943 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   945 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   944 	}
   946 	}
   945 
   947 
   946 	if (!(v->direction & 1)) spd = spd * 3 / 4;
   948 	if (!(v->direction & 1)) spd = spd * 3 / 4;
   947 
   949 
   948 	spd += v->progress;
   950 	spd += v->progress;
  1285 		 * but they all share the same number */
  1287 		 * but they all share the same number */
  1286 		CLRBITS(st->airport_flags, RUNWAY_IN_block);
  1288 		CLRBITS(st->airport_flags, RUNWAY_IN_block);
  1287 		CLRBITS(st->airport_flags, RUNWAY_IN_OUT_block); // commuter airport
  1289 		CLRBITS(st->airport_flags, RUNWAY_IN_OUT_block); // commuter airport
  1288 		CLRBITS(st->airport_flags, RUNWAY_IN2_block);    // intercontinental
  1290 		CLRBITS(st->airport_flags, RUNWAY_IN2_block);    // intercontinental
  1289 
  1291 
  1290 		BeginVehicleMove(v);
  1292 		MarkSingleVehicleDirty(v);
  1291 		EndVehicleMove(v);
       
  1292 
  1293 
  1293 		DoDeleteAircraft(v);
  1294 		DoDeleteAircraft(v);
  1294 	}
  1295 	}
  1295 }
  1296 }
  1296 
  1297 
  1344 
  1345 
  1345 static void ProcessAircraftOrder(Vehicle *v)
  1346 static void ProcessAircraftOrder(Vehicle *v)
  1346 {
  1347 {
  1347 	switch (v->current_order.type) {
  1348 	switch (v->current_order.type) {
  1348 		case OT_GOTO_DEPOT:
  1349 		case OT_GOTO_DEPOT:
  1349 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
  1350 			if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return;
  1350 			if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
  1351 			if (v->current_order.flags & OFB_SERVICE_IF_NEEDED &&
  1351 					!VehicleNeedsService(v)) {
  1352 					!VehicleNeedsService(v)) {
  1352 				UpdateVehicleTimetable(v, true);
  1353 				UpdateVehicleTimetable(v, true);
  1353 				v->cur_order_index++;
  1354 				v->cur_order_index++;
  1354 			}
  1355 			}
  1355 			break;
  1356 			break;
  1414 
  1415 
  1415 void Aircraft::MarkDirty()
  1416 void Aircraft::MarkDirty()
  1416 {
  1417 {
  1417 		this->cur_image = this->GetImage(this->direction);
  1418 		this->cur_image = this->GetImage(this->direction);
  1418 		if (this->subtype == AIR_HELICOPTER) this->Next()->Next()->cur_image = GetRotorImage(this);
  1419 		if (this->subtype == AIR_HELICOPTER) this->Next()->Next()->cur_image = GetRotorImage(this);
  1419 		MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1);
  1420 		MarkSingleVehicleDirty(this);
  1420 }
  1421 }
  1421 
  1422 
  1422 static void CrashAirplane(Vehicle *v)
  1423 static void CrashAirplane(Vehicle *v)
  1423 {
  1424 {
  1424 	v->vehstatus |= VS_CRASHED;
  1425 	v->vehstatus |= VS_CRASHED;
  1548 	SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
  1549 	SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
  1549 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1550 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1550 	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
  1551 	InvalidateWindowClasses(WC_AIRCRAFT_LIST);
  1551 }
  1552 }
  1552 
  1553 
       
  1554 /** Checks if an aircraft should head towards a hangar because it needs replacement
       
  1555  * @param *v the vehicle to test
       
  1556  * @return true if the aircraft should head towards a hangar
       
  1557  */
       
  1558 static inline bool CheckSendAircraftToHangarForReplacement(const Vehicle *v)
       
  1559 {
       
  1560 	EngineID new_engine;
       
  1561 	Player *p = GetPlayer(v->owner);
       
  1562 
       
  1563 	if (VehicleHasDepotOrders(v)) return false; // The aircraft will end up in the hangar eventually on it's own
       
  1564 
       
  1565 	new_engine = EngineReplacementForPlayer(p, v->engine_type, v->group_id);
       
  1566 
       
  1567 	if (new_engine == INVALID_ENGINE) {
       
  1568 		/* There is no autoreplace assigned to this EngineID so we will set it to renew to the same type if needed */
       
  1569 		new_engine = v->engine_type;
       
  1570 
       
  1571 		if(!p->engine_renew || (v->age - v->max_age) < p->engine_renew_months * 30) {
       
  1572 			/* No need to replace the aircraft */
       
  1573 			return false;
       
  1574 		}
       
  1575 	}
       
  1576 
       
  1577 	if (!HasBit(GetEngine(new_engine)->player_avail, v->owner)) {
       
  1578 		/* Engine is not buildable anymore */
       
  1579 		return false;
       
  1580 	}
       
  1581 
       
  1582 	if (p->player_money < (p->engine_renew_money + (2 * DoCommand(0, new_engine, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT).GetCost()))) {
       
  1583 		/* We lack enough money to request the replacement right away.
       
  1584 		 * We want 2*(the price of the new vehicle) and not looking at the value of the vehicle we are going to sell.
       
  1585 		 * The reason is that we don't want to send a whole lot of vehicles to the hangars when we only have enough money to replace a single one.
       
  1586 		 * Remember this happens in the background so the user can't stop this. */
       
  1587 		return false;
       
  1588 	}
       
  1589 
       
  1590 	/* We found no reason NOT to send the aircraft to a hangar so we will send it there at once */
       
  1591 	return true;
       
  1592 }
  1553 
  1593 
  1554 ////////////////////////////////////////////////////////////////////////////////
  1594 ////////////////////////////////////////////////////////////////////////////////
  1555 ///////////////////   AIRCRAFT MOVEMENT SCHEME  ////////////////////////////////
  1595 ///////////////////   AIRCRAFT MOVEMENT SCHEME  ////////////////////////////////
  1556 ////////////////////////////////////////////////////////////////////////////////
  1596 ////////////////////////////////////////////////////////////////////////////////
  1557 static void AircraftEventHandler_EnterTerminal(Vehicle *v, const AirportFTAClass *apc)
  1597 static void AircraftEventHandler_EnterTerminal(Vehicle *v, const AirportFTAClass *apc)
  1676 	AircraftNextAirportPos_and_Order(v);
  1716 	AircraftNextAirportPos_and_Order(v);
  1677 }
  1717 }
  1678 
  1718 
  1679 static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *apc)
  1719 static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *apc)
  1680 {
  1720 {
  1681 	const Player* p = GetPlayer(v->owner);
       
  1682 	v->u.air.state = FLYING;
  1721 	v->u.air.state = FLYING;
  1683 	v->UpdateDeltaXY(INVALID_DIR);
  1722 	v->UpdateDeltaXY(INVALID_DIR);
  1684 
  1723 
  1685 	/* get the next position to go to, differs per airport */
  1724 	/* get the next position to go to, differs per airport */
  1686 	AircraftNextAirportPos_and_Order(v);
  1725 	AircraftNextAirportPos_and_Order(v);
  1687 
  1726 
  1688 	/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed
  1727 	/* Send the helicopter to a hangar if needed for replacement */
  1689 	 * unless it is due for renewal but the engine is no longer available */
  1728 	if (CheckSendAircraftToHangarForReplacement(v)) {
  1690 	if (v->owner == _local_player && (
  1729 		_current_player = v->owner;
  1691 				EngineHasReplacementForPlayer(p, v->engine_type, v->group_id) ||
  1730 		DoCommand(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
  1692 				((p->engine_renew && v->age - v->max_age > p->engine_renew_months * 30) &&
       
  1693 				HasBit(GetEngine(v->engine_type)->player_avail, _local_player))
       
  1694 			)) {
       
  1695 		_current_player = _local_player;
       
  1696 		DoCommandP(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
       
  1697 		_current_player = OWNER_NONE;
  1731 		_current_player = OWNER_NONE;
  1698 	}
  1732 	}
  1699 }
  1733 }
  1700 
  1734 
  1701 static void AircraftEventHandler_Flying(Vehicle *v, const AirportFTAClass *apc)
  1735 static void AircraftEventHandler_Flying(Vehicle *v, const AirportFTAClass *apc)
  1741 {
  1775 {
  1742 	v->u.air.state = ENDLANDING;
  1776 	v->u.air.state = ENDLANDING;
  1743 	AircraftLandAirplane(v);  // maybe crash airplane
  1777 	AircraftLandAirplane(v);  // maybe crash airplane
  1744 
  1778 
  1745 	/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
  1779 	/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
  1746 	if (v->current_order.type != OT_GOTO_DEPOT && v->owner == _local_player) {
  1780 	if (CheckSendAircraftToHangarForReplacement(v)) {
  1747 		/* only the vehicle owner needs to calculate the rest (locally) */
  1781 		_current_player = v->owner;
  1748 		const Player* p = GetPlayer(v->owner);
  1782 		DoCommand(v->tile, v->index, DEPOT_SERVICE, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
  1749 		if (EngineHasReplacementForPlayer(p, v->engine_type, v->group_id) ||
  1783 		_current_player = OWNER_NONE;
  1750 			(p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) {
       
  1751 			/* send the aircraft to the hangar at next airport */
       
  1752 			_current_player = _local_player;
       
  1753 			DoCommandP(v->tile, v->index, DEPOT_SERVICE, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
       
  1754 			_current_player = OWNER_NONE;
       
  1755 		}
       
  1756 	}
  1784 	}
  1757 }
  1785 }
  1758 
  1786 
  1759 static void AircraftEventHandler_HeliLanding(Vehicle *v, const AirportFTAClass *apc)
  1787 static void AircraftEventHandler_HeliLanding(Vehicle *v, const AirportFTAClass *apc)
  1760 {
  1788 {