diff --git a/src/order_base.h b/src/order_base.h index e6a1b3ff51..640b2edf7a 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -597,6 +597,7 @@ public: bool CanLeaveWithCargo(bool has_cargo, CargoID cargo) const; TileIndex GetLocation(const Vehicle *v, bool airport = false) const; + TileIndex GetAuxiliaryLocation(bool secondary = false) const; /** Checks if travel_time and wait_time apply to this order and if they are timetabled. */ inline bool IsCompletelyTimetabled() const diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 35b4407e50..05ea4836c9 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -956,6 +956,30 @@ TileIndex Order::GetLocation(const Vehicle *v, bool airport) const } } +/** + * Returns a tile somewhat representing the order's auxiliary location (not related to vehicle movement). + * @param secondary Whether to return a second auxiliary location, if available. + * @return auxiliary location of order, or INVALID_TILE if none. + */ +TileIndex Order::GetAuxiliaryLocation(bool secondary) const +{ + if (this->IsType(OT_CONDITIONAL)) { + if (secondary && this->GetConditionVariable() == OCV_CARGO_WAITING_AMOUNT && GB(this->GetXData(), 16, 16) != 0) { + const Station *st = Station::GetIfValid(GB(this->GetXData(), 16, 16) - 2); + if (st != nullptr) return st->xy; + } + if (ConditionVariableHasStationID(this->GetConditionVariable())) { + const Station *st = Station::GetIfValid(GB(this->GetXData2(), 0, 16) - 1); + if (st != nullptr) return st->xy; + } + } + if (this->IsType(OT_LABEL) && IsDestinationOrderLabelSubType(this->GetLabelSubType())) { + const BaseStation *st = BaseStation::GetIfValid(this->GetDestination()); + if (st != nullptr) return st->xy; + } + return INVALID_TILE; +} + /** * Get the distance between two orders of a vehicle. Conditional orders are resolved * and the bigger distance of the two order branches is returned. diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 2cf77eea44..8643610f84 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -2811,6 +2811,7 @@ public: if (_ctrl_pressed && sel < this->vehicle->GetNumOrders()) { TileIndex xy = this->vehicle->GetOrder(sel)->GetLocation(this->vehicle); + if (xy == INVALID_TILE) xy = this->vehicle->GetOrder(sel)->GetAuxiliaryLocation(_shift_pressed); if (xy != INVALID_TILE) ScrollMainWindowToTile(xy); return; }