Fix order removal due to shared-infra company deletion.

Order totals were not updated correctly, implicit orders not handled
properly, etc.
Create generic function for vehicle order filtering.
Use for station deletion and infra sharing company deletion.
pull/16/head
Jonathan G Rennison 7 years ago
parent 11e4bcee40
commit f3b1059930

@ -556,6 +556,7 @@
<ClInclude Include="..\src\openttd.h" />
<ClInclude Include="..\src\order_backup.h" />
<ClInclude Include="..\src\order_base.h" />
<ClInclude Include="..\src\order_cmd.h" />
<ClInclude Include="..\src\order_func.h" />
<ClInclude Include="..\src\order_type.h" />
<ClInclude Include="..\src\pbs.h" />

@ -897,6 +897,9 @@
<ClInclude Include="..\src\order_base.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\order_cmd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\order_func.h">
<Filter>Header Files</Filter>
</ClInclude>

@ -348,6 +348,7 @@
<ClCompile Include="..\src\ground_vehicle.cpp" />
<ClCompile Include="..\src\heightmap.cpp" />
<ClCompile Include="..\src\highscore.cpp" />
<ClCompile Include="..\src\infrastructure.cpp" />
<ClCompile Include="..\src\hotkeys.cpp" />
<ClCompile Include="..\src\ini.cpp" />
<ClCompile Include="..\src\ini_load.cpp" />
@ -498,6 +499,7 @@
<ClInclude Include="..\src\industry.h" />
<ClInclude Include="..\src\industry_type.h" />
<ClInclude Include="..\src\industrytype.h" />
<ClInclude Include="..\src\infrastructure_func.h" />
<ClInclude Include="..\src\ini_type.h" />
<ClInclude Include="..\src\landscape.h" />
<ClInclude Include="..\src\landscape_type.h" />
@ -571,6 +573,7 @@
<ClInclude Include="..\src\openttd.h" />
<ClInclude Include="..\src\order_backup.h" />
<ClInclude Include="..\src\order_base.h" />
<ClInclude Include="..\src\order_cmd.h" />
<ClInclude Include="..\src\order_func.h" />
<ClInclude Include="..\src\order_type.h" />
<ClInclude Include="..\src\pbs.h" />

@ -222,6 +222,9 @@
<ClCompile Include="..\src\highscore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\infrastructure.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\hotkeys.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -672,6 +675,9 @@
<ClInclude Include="..\src\industrytype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\infrastructure_func.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\ini_type.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -891,6 +897,9 @@
<ClInclude Include="..\src\order_base.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\order_cmd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\order_func.h">
<Filter>Header Files</Filter>
</ClInclude>

@ -1498,6 +1498,10 @@
RelativePath=".\..\src\order_base.h"
>
</File>
<File
RelativePath=".\..\src\order_cmd.h"
>
</File>
<File
RelativePath=".\..\src\order_func.h"
>

@ -1495,6 +1495,10 @@
RelativePath=".\..\src\order_base.h"
>
</File>
<File
RelativePath=".\..\src\order_cmd.h"
>
</File>
<File
RelativePath=".\..\src\order_func.h"
>

@ -295,6 +295,7 @@ object_type.h
openttd.h
order_backup.h
order_base.h
order_cmd.h
order_func.h
order_type.h
pbs.h

@ -23,6 +23,7 @@
#include "gui.h"
#include "pathfinder/yapf/yapf_cache.h"
#include "company_base.h"
#include "order_cmd.h"
#include "table/strings.h"
@ -138,6 +139,7 @@ static bool OrderDestinationIsAllowed(const Order *order, const Vehicle *v, Owne
{
Owner dest_owner;
switch (order->GetType()) {
case OT_IMPLICIT:
case OT_GOTO_STATION:
case OT_GOTO_WAYPOINT: dest_owner = BaseStation::Get(order->GetDestination())->owner; break;
case OT_GOTO_DEPOT: dest_owner = (v->type == VEH_AIRCRAFT) ? Station::Get(order->GetDestination())->owner : GetTileOwner(Depot::Get(order->GetDestination())->xy); break;
@ -294,19 +296,10 @@ void HandleSharingCompanyDeletion(Owner owner)
/* order list */
if (v->FirstShared() != v) continue;
Order *o;
int id = -1;
FOR_VEHICLE_ORDERS(v, o) {
id++;
if (OrderDestinationIsAllowed(o, v, owner)) continue;
o->MakeDummy();
for (const Vehicle *w = v; w != NULL; w = w->NextShared()) {
/* In GUI, simulate by removing the order and adding it back */
InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8));
InvalidateVehicleOrder(w, (id << 8) | INVALID_VEH_ORDER_ID);
}
}
RemoveVehicleOrdersIf(v, [&](const Order *o) {
if (o->GetType() == OT_GOTO_DEPOT && (o->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) return false;
return !OrderDestinationIsAllowed(o, v, owner);
});
}
}

@ -29,6 +29,7 @@
#include "infrastructure_func.h"
#include "order_backup.h"
#include "cheat_type.h"
#include "order_cmd.h"
#include "table/strings.h"
@ -1842,55 +1843,22 @@ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination)
/* Go through all vehicles */
FOR_ALL_VEHICLES(v) {
Order *order;
order = &v->current_order;
Order *order = &v->current_order;
if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type &&
v->current_order.GetDestination() == destination) {
order->MakeDummy();
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
}
/* Clear the order from the order-list */
int id = -1;
FOR_VEHICLE_ORDERS(v, order) {
id++;
restart:
/* order list */
if (v->FirstShared() != v) continue;
OrderType ot = order->GetType();
if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
RemoveVehicleOrdersIf(v, [&](const Order *o) {
OrderType ot = o->GetType();
if (ot == OT_GOTO_DEPOT && (o->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) return false;
if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION;
if (ot == type && order->GetDestination() == destination) {
/* We want to clear implicit orders, but we don't want to make them
* dummy orders. They should just vanish. Also check the actual order
* type as ot is currently OT_GOTO_STATION. */
if (order->IsType(OT_IMPLICIT)) {
order = order->next; // DeleteOrder() invalidates current order
DeleteOrder(v, id);
if (order != NULL) goto restart;
break;
}
/* Clear wait time */
v->orders.list->UpdateTotalDuration(-order->GetWaitTime());
if (order->IsWaitTimetabled()) {
v->orders.list->UpdateTimetableDuration(-order->GetTimetabledWait());
order->SetWaitTimetabled(false);
}
order->SetWaitTime(0);
/* Clear order, preserving travel time */
bool travel_timetabled = order->IsTravelTimetabled();
order->MakeDummy();
order->SetTravelTimetabled(travel_timetabled);
for (const Vehicle *w = v->FirstShared(); w != NULL; w = w->NextShared()) {
/* In GUI, simulate by removing the order and adding it back */
InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8));
InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id);
}
}
}
return (ot == type && o->GetDestination() == destination);
});
}
OrderBackup::RemoveOrder(type, destination);

@ -0,0 +1,66 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file order_cmd.h Functions related to order commands. */
#ifndef ORDER_CMD_H
#define ORDER_CMD_H
#include "order_base.h"
#include "order_func.h"
#include "vehicle_base.h"
/**
* Removes all orders from a vehicle for which order_predicate returns true.
* Handles timetable updating, removing implicit orders correctly, etc.
* @param v The vehicle.
* @param order_predicate Functor with signature: bool (const Order *)
*/
template <typename F> void RemoveVehicleOrdersIf(Vehicle * const v, F order_predicate) {
/* Clear the order from the order-list */
Order *order;
int id = -1;
FOR_VEHICLE_ORDERS(v, order) {
id++;
restart:
if (order_predicate(const_cast<const Order *>(order))) {
/* We want to clear implicit orders, but we don't want to make them
* dummy orders. They should just vanish. Also check the actual order
* type as ot is currently OT_GOTO_STATION. */
if (order->IsType(OT_IMPLICIT)) {
order = order->next; // DeleteOrder() invalidates current order
DeleteOrder(v, id);
if (order != NULL) goto restart;
break;
}
/* Clear wait time */
v->orders.list->UpdateTotalDuration(-order->GetWaitTime());
if (order->IsWaitTimetabled()) {
v->orders.list->UpdateTimetableDuration(-order->GetTimetabledWait());
order->SetWaitTimetabled(false);
}
order->SetWaitTime(0);
/* Clear order, preserving travel time */
bool travel_timetabled = order->IsTravelTimetabled();
order->MakeDummy();
order->SetTravelTimetabled(travel_timetabled);
for (const Vehicle *w = v->FirstShared(); w != NULL; w = w->NextShared()) {
/* In GUI, simulate by removing the order and adding it back */
InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8));
InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id);
}
}
}
}
#endif /* ORDER_CMD_H */
Loading…
Cancel
Save