mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r14096) -Codechange: merge the shared order's vehicle list management to a single location.
This commit is contained in:
parent
ca3f1f6406
commit
abd9f74871
|
@ -263,7 +263,7 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, ui
|
|||
if (v->group_id != id_g) continue;
|
||||
|
||||
/* For each shared vehicles add it to the group */
|
||||
for (Vehicle *v2 = GetFirstVehicleFromSharedList(v); v2 != NULL; v2 = v2->next_shared) {
|
||||
for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) {
|
||||
if (v2->group_id != id_g) CmdAddVehicleGroup(tile, flags, id_g, v2->index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -372,8 +372,7 @@ static void FixOldVehicles()
|
|||
/* If a vehicle has the same orders, add the link to eachother
|
||||
* in both vehicles */
|
||||
if (v->orders == u->orders) {
|
||||
v->next_shared = u;
|
||||
u->prev_shared = v;
|
||||
u->AddToShared(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2272,7 +2272,7 @@ bool AfterLoadGame()
|
|||
if (v->orders != NULL && !v->orders->IsValid()) v->orders = NULL;
|
||||
|
||||
v->current_order.ConvertFromOldSavegame();
|
||||
if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->prev_shared == NULL) {
|
||||
if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->FirstShared() == v) {
|
||||
FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -506,7 +506,6 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
Vehicle *u;
|
||||
Order *new_o = new Order();
|
||||
new_o->AssignOrder(new_order);
|
||||
|
||||
|
@ -537,9 +536,9 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
}
|
||||
|
||||
u = GetFirstVehicleFromSharedList(v);
|
||||
Vehicle *u = v->FirstShared();
|
||||
DeleteOrderWarnings(u);
|
||||
for (; u != NULL; u = u->next_shared) {
|
||||
for (; u != NULL; u = u->NextShared()) {
|
||||
/* Increase amount of orders */
|
||||
u->num_orders++;
|
||||
|
||||
|
@ -601,7 +600,7 @@ static CommandCost DecloneOrder(Vehicle *dst, uint32 flags)
|
|||
* Remove the VehicleList that shows all the vehicles with the same shared
|
||||
* orders.
|
||||
*/
|
||||
static void RemoveSharedOrderVehicleList(Vehicle *v)
|
||||
void RemoveSharedOrderVehicleList(Vehicle *v)
|
||||
{
|
||||
assert(v->orders != NULL);
|
||||
WindowClass window_class = WC_NONE;
|
||||
|
@ -624,7 +623,7 @@ static void RemoveSharedOrderVehicleList(Vehicle *v)
|
|||
*/
|
||||
CommandCost CmdDeleteOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
Vehicle *v, *u;
|
||||
Vehicle *v;
|
||||
VehicleID veh_id = p1;
|
||||
VehicleOrderID sel_ord = p2;
|
||||
Order *order;
|
||||
|
@ -665,9 +664,9 @@ CommandCost CmdDeleteOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
/* Give the item free */
|
||||
order->Free();
|
||||
|
||||
u = GetFirstVehicleFromSharedList(v);
|
||||
Vehicle *u = v->FirstShared();
|
||||
DeleteOrderWarnings(u);
|
||||
for (; u != NULL; u = u->next_shared) {
|
||||
for (; u != NULL; u = u->NextShared()) {
|
||||
u->num_orders--;
|
||||
|
||||
if (sel_ord < u->cur_order_index)
|
||||
|
@ -803,11 +802,11 @@ CommandCost CmdMoveOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
/* Update shared list */
|
||||
Vehicle *u = GetFirstVehicleFromSharedList(v);
|
||||
Vehicle *u = v->FirstShared();
|
||||
|
||||
DeleteOrderWarnings(u);
|
||||
|
||||
for (; u != NULL; u = u->next_shared) {
|
||||
for (; u != NULL; u = u->NextShared()) {
|
||||
/* Update the first order */
|
||||
if (u->orders != v->orders) u->orders = v->orders;
|
||||
|
||||
|
@ -1027,9 +1026,9 @@ CommandCost CmdModifyOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
/* Update the windows and full load flags, also for vehicles that share the same order list */
|
||||
Vehicle *u = GetFirstVehicleFromSharedList(v);
|
||||
Vehicle *u = v->FirstShared();
|
||||
DeleteOrderWarnings(u);
|
||||
for (; u != NULL; u = u->next_shared) {
|
||||
for (; u != NULL; u = u->NextShared()) {
|
||||
/* Toggle u->current_order "Full load" flag if it changed.
|
||||
* However, as the same flag is used for depot orders, check
|
||||
* whether we are not going to a depot as there are three
|
||||
|
@ -1090,13 +1089,7 @@ CommandCost CmdCloneOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
/* Is the vehicle already in the shared list? */
|
||||
{
|
||||
const Vehicle* u;
|
||||
|
||||
for (u = GetFirstVehicleFromSharedList(src); u != NULL; u = u->next_shared) {
|
||||
if (u == dst) return CMD_ERROR;
|
||||
}
|
||||
}
|
||||
if (src->FirstShared() == dst->FirstShared()) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* If the destination vehicle had a OrderList, destroy it */
|
||||
|
@ -1106,10 +1099,7 @@ CommandCost CmdCloneOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
dst->num_orders = src->num_orders;
|
||||
|
||||
/* Link this vehicle in the shared-list */
|
||||
dst->next_shared = src->next_shared;
|
||||
dst->prev_shared = src;
|
||||
if (src->next_shared != NULL) src->next_shared->prev_shared = dst;
|
||||
src->next_shared = dst;
|
||||
dst->AddToShared(src);
|
||||
|
||||
InvalidateVehicleOrder(dst);
|
||||
InvalidateVehicleOrder(src);
|
||||
|
@ -1212,12 +1202,9 @@ CommandCost CmdOrderRefit(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
if (order == NULL) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
Vehicle *u;
|
||||
|
||||
order->SetRefit(cargo, subtype);
|
||||
|
||||
u = GetFirstVehicleFromSharedList(v);
|
||||
for (; u != NULL; u = u->next_shared) {
|
||||
for (Vehicle *u = v->FirstShared(); u != NULL; u = u->NextShared()) {
|
||||
/* Update any possible open window of the vehicle */
|
||||
InvalidateVehicleOrder(u);
|
||||
|
||||
|
@ -1253,7 +1240,7 @@ void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *bak)
|
|||
|
||||
/* If we have shared orders, store it on a special way */
|
||||
if (v->IsOrderListShared()) {
|
||||
const Vehicle *u = (v->next_shared) ? v->next_shared : v->prev_shared;
|
||||
const Vehicle *u = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
|
||||
|
||||
bak->clone = u->index;
|
||||
} else {
|
||||
|
@ -1413,7 +1400,7 @@ void CheckOrders(const Vehicle* v)
|
|||
return;
|
||||
|
||||
/* do nothing we we're not the first vehicle in a share-chain */
|
||||
if (v->next_shared != NULL) return;
|
||||
if (v->FirstShared() != v) return;
|
||||
|
||||
/* Only check every 20 days, so that we don't flood the message log */
|
||||
if (v->owner == _local_player && v->day_counter % 20 == 0) {
|
||||
|
@ -1541,49 +1528,16 @@ void DeleteVehicleOrders(Vehicle *v)
|
|||
{
|
||||
DeleteOrderWarnings(v);
|
||||
|
||||
/* If we have a shared order-list, don't delete the list, but just
|
||||
remove our pointer */
|
||||
if (v->IsOrderListShared()) {
|
||||
Vehicle *u = v;
|
||||
|
||||
v->orders = NULL;
|
||||
v->num_orders = 0;
|
||||
|
||||
/* Unlink ourself */
|
||||
if (v->prev_shared != NULL) {
|
||||
v->prev_shared->next_shared = v->next_shared;
|
||||
u = v->prev_shared;
|
||||
}
|
||||
if (v->next_shared != NULL) {
|
||||
v->next_shared->prev_shared = v->prev_shared;
|
||||
u = v->next_shared;
|
||||
}
|
||||
v->prev_shared = NULL;
|
||||
v->next_shared = NULL;
|
||||
|
||||
/* If we are the only one left in the Shared Order Vehicle List,
|
||||
* remove it, as we are no longer a Shared Order Vehicle */
|
||||
if (u->prev_shared == NULL && u->next_shared == NULL && u->orders != NULL) RemoveSharedOrderVehicleList(u);
|
||||
|
||||
/* We only need to update this-one, because if there is a third
|
||||
* vehicle which shares the same order-list, nothing will change. If
|
||||
* this is the last vehicle, the last line of the order-window
|
||||
* will change from Shared order list, to Order list, so it needs
|
||||
* an update */
|
||||
InvalidateVehicleOrder(u);
|
||||
return;
|
||||
/* Remove ourself from the shared order list. */
|
||||
v->RemoveFromShared();
|
||||
} else if (v->orders != NULL) {
|
||||
/* Remove the orders */
|
||||
v->orders->FreeChain();
|
||||
}
|
||||
|
||||
/* Remove the orders */
|
||||
Order *cur = v->orders;
|
||||
/* Delete the vehicle list of shared orders, if any */
|
||||
if (cur != NULL) RemoveSharedOrderVehicleList(v);
|
||||
v->orders = NULL;
|
||||
v->num_orders = 0;
|
||||
|
||||
if (cur != NULL) {
|
||||
cur->FreeChain(); // Free the orders.
|
||||
}
|
||||
}
|
||||
|
||||
Date GetServiceIntervalClamped(uint index)
|
||||
|
|
|
@ -32,7 +32,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 time
|
|||
}
|
||||
}
|
||||
|
||||
for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
|
||||
for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
|
||||
InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ CommandCost CmdAutofillTimetable(TileIndex tile, uint32 flags, uint32 p1, uint32
|
|||
}
|
||||
}
|
||||
|
||||
for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
|
||||
for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
|
||||
InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
|
|||
|
||||
v->lateness_counter -= (timetabled - time_taken);
|
||||
|
||||
for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
|
||||
for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
|
||||
InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1427,27 +1427,13 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
new_f->cur_order_index = first->cur_order_index;
|
||||
new_f->orders = first->orders;
|
||||
new_f->num_orders = first->num_orders;
|
||||
|
||||
/* Make sure the group counts stay correct. */
|
||||
new_f->group_id = first->group_id;
|
||||
first->group_id = DEFAULT_GROUP;
|
||||
|
||||
if (first->prev_shared != NULL) {
|
||||
first->prev_shared->next_shared = new_f;
|
||||
new_f->prev_shared = first->prev_shared;
|
||||
}
|
||||
|
||||
if (first->next_shared != NULL) {
|
||||
first->next_shared->prev_shared = new_f;
|
||||
new_f->next_shared = first->next_shared;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove all order information from the front train, to
|
||||
* prevent the order and the shared order list to be
|
||||
* destroyed by Destroy/DeleteVehicle.
|
||||
*/
|
||||
first->orders = NULL;
|
||||
first->prev_shared = NULL;
|
||||
first->next_shared = NULL;
|
||||
first->group_id = DEFAULT_GROUP;
|
||||
new_f->AddToShared(first);
|
||||
first->RemoveFromShared();
|
||||
|
||||
/* If we deleted a window then open a new one for the 'new' train */
|
||||
if (IsLocalPlayer() && w != NULL) ShowVehicleViewWindow(new_f);
|
||||
|
|
|
@ -255,6 +255,7 @@ void AfterLoadVehicles(bool clear_te_id)
|
|||
FOR_ALL_VEHICLES(v) {
|
||||
/* Reinstate the previous pointer */
|
||||
if (v->Next() != NULL) v->Next()->previous = v;
|
||||
if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
|
||||
|
||||
v->UpdateDeltaXY(v->direction);
|
||||
|
||||
|
@ -272,6 +273,13 @@ void AfterLoadVehicles(bool clear_te_id)
|
|||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
u->first = v;
|
||||
}
|
||||
|
||||
/* Shared orders are only valid for first vehicles in chains. */
|
||||
if (v->previous_shared == NULL) {
|
||||
for (Vehicle *u = v; u != NULL; u = u->NextShared()) {
|
||||
u->first_shared = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,6 +337,7 @@ Vehicle::Vehicle()
|
|||
this->group_id = DEFAULT_GROUP;
|
||||
this->fill_percent_te_id = INVALID_TE_ID;
|
||||
this->first = this;
|
||||
this->first_shared = this;
|
||||
this->colormap = PAL_NONE;
|
||||
}
|
||||
|
||||
|
@ -2155,7 +2164,8 @@ static const SaveLoad _common_veh_desc[] = {
|
|||
SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
|
||||
SLE_CONDREF(Vehicle, prev_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(2, 2, 68),
|
||||
SLE_CONDNULL(4, 69, 100),
|
||||
|
||||
SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
|
||||
|
||||
|
@ -2390,8 +2400,7 @@ void Load_VEHS()
|
|||
/* If a vehicle has the same orders, add the link to eachother
|
||||
* in both vehicles */
|
||||
if (v->orders == u->orders) {
|
||||
v->next_shared = u;
|
||||
u->prev_shared = v;
|
||||
u->AddToShared(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2574,6 +2583,49 @@ void Vehicle::SetNext(Vehicle *next)
|
|||
}
|
||||
}
|
||||
|
||||
void Vehicle::AddToShared(Vehicle *shared_chain)
|
||||
{
|
||||
assert(!this->IsOrderListShared());
|
||||
|
||||
this->next_shared = shared_chain->next_shared;
|
||||
this->previous_shared = shared_chain;
|
||||
this->first_shared = shared_chain->first_shared;
|
||||
|
||||
shared_chain->next_shared = this;
|
||||
|
||||
if (this->next_shared != NULL) this->next_shared->previous_shared = this;
|
||||
}
|
||||
|
||||
void Vehicle::RemoveFromShared()
|
||||
{
|
||||
Vehicle *new_first;
|
||||
|
||||
if (this->FirstShared() == this) {
|
||||
/* We are the first shared one, so update all the first pointers of our next shared ones. */
|
||||
new_first = this->NextShared();
|
||||
for (Vehicle *u = new_first; u != NULL; u = u->NextShared()) {
|
||||
u->first_shared = new_first;
|
||||
}
|
||||
} else {
|
||||
/* We are not the first shared one, so only relink our previous one. */
|
||||
new_first = this->FirstShared();
|
||||
this->previous_shared->next_shared = this->NextShared();
|
||||
}
|
||||
|
||||
if (this->next_shared != NULL) this->next_shared->previous_shared = this->previous_shared;
|
||||
|
||||
if (new_first->NextShared() == NULL) {
|
||||
/* When there is only one vehicle, remove the shared order list window. */
|
||||
extern void RemoveSharedOrderVehicleList(Vehicle *v);
|
||||
if (new_first->orders != NULL) RemoveSharedOrderVehicleList(new_first);
|
||||
InvalidateVehicleOrder(new_first);
|
||||
}
|
||||
|
||||
this->first_shared = this;
|
||||
this->next_shared = NULL;
|
||||
this->previous_shared = NULL;
|
||||
}
|
||||
|
||||
void StopAllVehicles()
|
||||
{
|
||||
Vehicle *v;
|
||||
|
|
|
@ -202,6 +202,10 @@ private:
|
|||
Vehicle *next; ///< pointer to the next vehicle in the chain
|
||||
Vehicle *previous; ///< NOSAVE: pointer to the previous vehicle in the chain
|
||||
Vehicle *first; ///< NOSAVE: pointer to the first vehicle in the chain
|
||||
|
||||
Vehicle *next_shared; ///< pointer to the next vehicle that shares the order
|
||||
Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain
|
||||
Vehicle *first_shared; ///< NOSAVE: pointer to the first vehicle in the shared order chain
|
||||
public:
|
||||
friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
|
||||
friend void AfterLoadVehicles(bool clear_te_id); ///< So we can set the previous and first pointers while loading
|
||||
|
@ -214,9 +218,6 @@ public:
|
|||
TileIndex tile; ///< Current tile index
|
||||
TileIndex dest_tile; ///< Heading for this tile
|
||||
|
||||
Vehicle *next_shared; ///< If not NULL, this points to the next vehicle that shared the order
|
||||
Vehicle *prev_shared; ///< If not NULL, this points to the prev vehicle that shared the order
|
||||
|
||||
Money profit_this_year; ///< Profit this year << 8, low 8 bits are fract
|
||||
Money profit_last_year; ///< Profit last year << 8, low 8 bits are fract
|
||||
Money value;
|
||||
|
@ -476,12 +477,37 @@ public:
|
|||
*/
|
||||
inline Vehicle *First() const { return this->first; }
|
||||
|
||||
|
||||
/**
|
||||
* Adds this vehicle to a shared vehicle chain.
|
||||
* @param shared_chain a vehicle of the chain with shared vehicles.
|
||||
* @pre !this->IsOrderListShared()
|
||||
*/
|
||||
void AddToShared(Vehicle *shared_chain);
|
||||
|
||||
/**
|
||||
* Removes the vehicle from the shared order list.
|
||||
*/
|
||||
void RemoveFromShared();
|
||||
|
||||
/**
|
||||
* Get the next vehicle of this vehicle.
|
||||
* @note articulated parts are also counted as vehicles.
|
||||
* @return the next vehicle or NULL when there isn't a next vehicle.
|
||||
*/
|
||||
inline Vehicle *NextShared() const { return this->next_shared; }
|
||||
|
||||
/**
|
||||
* Get the first vehicle of this vehicle chain.
|
||||
* @return the first vehicle of the chain.
|
||||
*/
|
||||
inline Vehicle *FirstShared() const { return this->first_shared; }
|
||||
|
||||
/**
|
||||
* Check if we share our orders with another vehicle.
|
||||
* This is done by checking the previous and next pointers in the shared chain.
|
||||
* @return true if there are other vehicles sharing the same order
|
||||
*/
|
||||
inline bool IsOrderListShared() const { return this->next_shared != NULL || this->prev_shared != NULL; };
|
||||
inline bool IsOrderListShared() const { return this->previous_shared != NULL || this->next_shared != NULL; };
|
||||
|
||||
/**
|
||||
* Copy certain configurations and statistics of a vehicle after successful autoreplace/renew
|
||||
|
@ -648,18 +674,6 @@ static inline Order *GetLastVehicleOrder(const Vehicle *v)
|
|||
return order;
|
||||
}
|
||||
|
||||
/** Get the first vehicle of a shared-list, so we only have to walk forwards
|
||||
* @param v Vehicle to query
|
||||
* @return first vehicle of a shared-list
|
||||
*/
|
||||
static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v)
|
||||
{
|
||||
Vehicle *u = (Vehicle *)v;
|
||||
while (u->prev_shared != NULL) u = u->prev_shared;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Trackdir on which the vehicle is currently located.
|
||||
* Works for trains and ships.
|
||||
|
|
|
@ -97,7 +97,7 @@ void GenerateVehicleSortList(VehicleList *list, VehicleType type, PlayerID owner
|
|||
/* Find a vehicle with the order in question */
|
||||
if (v->orders != NULL && v->orders->index == index) {
|
||||
/* Add all vehicles from this vehicle's shared order list */
|
||||
for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
|
||||
for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
|
||||
*list->Append() = v;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue