From 8df549284f6923d3edbb43c87aa0100c30ac202c Mon Sep 17 00:00:00 2001 From: keldorkatarn Date: Thu, 19 Apr 2018 01:43:33 +0200 Subject: [PATCH] Route Line Rendering: Properly prevent endless loop due to conditional orders cycle. (cherry picked from commit ac1c26f5fe942ef47c664ff71000053d874a6008) See #39 --- src/viewport.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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; }