diff --git a/src/viewport.cpp b/src/viewport.cpp index 1ca6fa2032..6c61793dae 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1693,13 +1693,26 @@ static inline TileIndex GetLastValidOrderLocation(const Vehicle *veh) static inline Order *GetFinalOrder(const Vehicle *veh, Order *order) { - auto original_order = order; + // Use Floyd's cycle-finding algorithm to prevent endless loop + // due to a cycle formed by confitional orders. + auto cycle_check = order; while (order->IsType(OT_CONDITIONAL)) { order = veh->GetOrder(order->GetConditionSkipToOrder()); - if (original_order == order) return nullptr; + if (cycle_check->IsType(OT_CONDITIONAL)) { + cycle_check = veh->GetOrder(cycle_check->GetConditionSkipToOrder()); + + if (cycle_check->IsType(OT_CONDITIONAL)) { + cycle_check = veh->GetOrder(cycle_check->GetConditionSkipToOrder()); + } + } + + bool cycle_detected = (order->IsType(OT_CONDITIONAL) && (order == cycle_check)); + + if (cycle_detected) return nullptr; } + return order; }