Route Line Rendering: Properly prevent endless loop due to conditional orders cycle.
(cherry picked from commit ac1c26f5fe942ef47c664ff71000053d874a6008) See #39
This commit is contained in:

committed by
Jonathan G Rennison

parent
d154debb5e
commit
8df549284f
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user