OpenTTD Source  14.0-beta1
order_backup.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "stdafx.h"
11 #include "command_func.h"
12 #include "core/pool_func.hpp"
13 #include "network/network.h"
14 #include "network/network_func.h"
15 #include "order_backup.h"
16 #include "vehicle_base.h"
17 #include "window_func.h"
18 #include "station_map.h"
19 #include "order_cmd.h"
20 #include "group_cmd.h"
21 #include "vehicle_func.h"
22 
23 #include "safeguards.h"
24 
25 OrderBackupPool _order_backup_pool("BackupOrder");
27 
28 
30 {
31  if (CleaningPool()) return;
32 
33  Order *o = this->orders;
34  while (o != nullptr) {
35  Order *next = o->next;
36  delete o;
37  o = next;
38  }
39 }
40 
46 OrderBackup::OrderBackup(const Vehicle *v, uint32_t user)
47 {
48  this->user = user;
49  this->tile = v->tile;
50  this->group = v->group_id;
51 
53 
54  /* If we have shared orders, store the vehicle we share the order with. */
55  if (v->IsOrderListShared()) {
56  this->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
57  } else {
58  /* Else copy the orders */
59  Order **tail = &this->orders;
60 
61  /* Count the number of orders */
62  for (const Order *order : v->Orders()) {
63  Order *copy = new Order();
64  copy->AssignOrder(*order);
65  *tail = copy;
66  tail = &copy->next;
67  }
68  }
69 }
70 
76 {
77  /* If we had shared orders, recover that */
78  if (this->clone != nullptr) {
79  Command<CMD_CLONE_ORDER>::Do(DC_EXEC, CO_SHARE, v->index, this->clone->index);
80  } else if (this->orders != nullptr && OrderList::CanAllocateItem()) {
81  v->orders = new OrderList(this->orders, v);
82  this->orders = nullptr;
83  /* Make sure buoys/oil rigs are updated in the station list. */
85  }
86 
87  /* Remove backed up name if it's no longer unique. */
88  if (!IsUniqueVehicleName(this->name)) this->name.clear();
89 
91 
92  /* Make sure orders are in range */
95 
96  /* Restore vehicle group */
98 }
99 
106 /* static */ void OrderBackup::Backup(const Vehicle *v, uint32_t user)
107 {
108  /* Don't use reset as that broadcasts over the network to reset the variable,
109  * which is what we are doing at the moment. */
110  for (OrderBackup *ob : OrderBackup::Iterate()) {
111  if (ob->user == user) delete ob;
112  }
114  new OrderBackup(v, user);
115  }
116 }
117 
124 /* static */ void OrderBackup::Restore(Vehicle *v, uint32_t user)
125 {
126  for (OrderBackup *ob : OrderBackup::Iterate()) {
127  if (v->tile != ob->tile || ob->user != user) continue;
128 
129  ob->DoRestore(v);
130  delete ob;
131  }
132 }
133 
140 /* static */ void OrderBackup::ResetOfUser(TileIndex tile, uint32_t user)
141 {
142  for (OrderBackup *ob : OrderBackup::Iterate()) {
143  if (ob->user == user && (ob->tile == tile || tile == INVALID_TILE)) delete ob;
144  }
145 }
146 
155 {
156  /* No need to check anything. If the tile or user don't exist we just ignore it. */
157  if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, user_id);
158 
159  return CommandCost();
160 }
161 
168 /* static */ void OrderBackup::ResetUser(uint32_t user)
169 {
170  assert(_network_server);
171 
172  for (OrderBackup *ob : OrderBackup::Iterate()) {
173  /* If it's not a backup of us, ignore it. */
174  if (ob->user != user) continue;
175 
177  return;
178  }
179 }
180 
187 /* static */ void OrderBackup::Reset(TileIndex t, bool from_gui)
188 {
189  /* The user has CLIENT_ID_SERVER as default when network play is not active,
190  * but compiled it. A network client has its own variable for the unique
191  * client/user identifier. Finally if networking isn't compiled in the
192  * default is just plain and simple: 0. */
194 
195  for (OrderBackup *ob : OrderBackup::Iterate()) {
196  /* If this is a GUI action, and it's not a backup of us, ignore it. */
197  if (from_gui && ob->user != user) continue;
198  /* If it's not for our chosen tile either, ignore it. */
199  if (t != INVALID_TILE && t != ob->tile) continue;
200 
201  if (from_gui) {
202  /* We need to circumvent the "prevention" from this command being executed
203  * while the game is paused, so use the internal method. Nor do we want
204  * this command to get its cost estimated when shift is pressed. */
205  Command<CMD_CLEAR_ORDER_BACKUP>::Unsafe<CommandCallback>(STR_NULL, nullptr, true, false, ob->tile, CommandTraits<CMD_CLEAR_ORDER_BACKUP>::Args{ ob->tile, static_cast<ClientID>(user) });
206  } else {
207  /* The command came from the game logic, i.e. the clearing of a tile.
208  * In that case we have no need to actually sync this, just do it. */
209  delete ob;
210  }
211  }
212 }
213 
218 /* static */ void OrderBackup::ClearGroup(GroupID group)
219 {
220  for (OrderBackup *ob : OrderBackup::Iterate()) {
221  if (ob->group == group) ob->group = DEFAULT_GROUP;
222  }
223 }
224 
232 /* static */ void OrderBackup::ClearVehicle(const Vehicle *v)
233 {
234  assert(v != nullptr);
235  for (OrderBackup *ob : OrderBackup::Iterate()) {
236  if (ob->clone == v) {
237  /* Get another item in the shared list. */
238  ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
239  /* But if that isn't there, remove it. */
240  if (ob->clone == nullptr) delete ob;
241  }
242  }
243 }
244 
253 /* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination, bool hangar)
254 {
255  for (OrderBackup *ob : OrderBackup::Iterate()) {
256  for (Order *order = ob->orders; order != nullptr; order = order->next) {
257  OrderType ot = order->GetType();
258  if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
259  if (ot == OT_GOTO_DEPOT && hangar && !IsHangarTile(ob->tile)) continue; // Not an aircraft? Can't have a hangar order.
260  if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
261  if (ot == type && order->GetDestination() == destination) {
262  /* Remove the order backup! If a station/depot gets removed, we can't/shouldn't restore those broken orders. */
263  delete ob;
264  break;
265  }
266  }
267  }
268 }
BaseConsist::cur_implicit_order_index
VehicleOrderID cur_implicit_order_index
The index to the current implicit order.
Definition: base_consist.h:32
order_cmd.h
command_func.h
VehicleListIdentifier
The information about a vehicle list.
Definition: vehiclelist.h:28
_network_server
bool _network_server
network-server is active
Definition: network.cpp:60
BaseConsist::name
std::string name
Name of vehicle.
Definition: base_consist.h:18
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:234
Vehicle::group_id
GroupID group_id
Index of group Pool array.
Definition: vehicle_base.h:357
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
vehicle_base.h
Order::AssignOrder
void AssignOrder(const Order &other)
Assign data to an order (from another order) This function makes sure that the index is maintained co...
Definition: order_cmd.cpp:273
OrderBackup::clone
const Vehicle * clone
Vehicle this vehicle was a clone of.
Definition: order_backup.h:41
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
OrderBackup::ClearVehicle
static void ClearVehicle(const Vehicle *v)
Clear/update the (clone) vehicle from an order backup.
Definition: order_backup.cpp:232
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:240
_order_backup_pool
OrderBackupPool _order_backup_pool("BackupOrder")
The pool with order backups.
DC_EXEC
@ DC_EXEC
execute the given command
Definition: command_type.h:371
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:369
CommandTraits
Defines the traits of a command.
Definition: command_type.h:448
Vehicle::UpdateRealOrderIndex
void UpdateRealOrderIndex()
Skip implicit orders until cur_real_order_index is a non-implicit order.
Definition: vehicle_base.h:887
OrderBackup::ResetUser
static void ResetUser(uint32_t user)
Reset an user's OrderBackup if needed.
Definition: order_backup.cpp:168
Vehicle::Orders
IterateWrapper Orders() const
Returns an iterable ensemble of orders of a vehicle.
Definition: vehicle_base.h:1070
CommandCost
Common return value for all commands.
Definition: command_type.h:23
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:260
CmdClearOrderBackup
CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id)
Clear an OrderBackup.
Definition: order_backup.cpp:154
ODATFB_NEAREST_DEPOT
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition: order_type.h:105
safeguards.h
DEFAULT_GROUP
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition: group_type.h:17
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:59
stdafx.h
Vehicle::IsOrderListShared
bool IsOrderListShared() const
Check if we share our orders with another vehicle.
Definition: vehicle_base.h:727
OrderBackup::Reset
static void Reset(TileIndex tile=INVALID_TILE, bool from_gui=true)
Reset the OrderBackups from GUI/game logic.
Definition: order_backup.cpp:187
_network_own_client_id
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:65
group_cmd.h
OrderBackup::DoRestore
void DoRestore(Vehicle *v)
Restore the data of this order to the given vehicle.
Definition: order_backup.cpp:75
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition: base_consist.h:31
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:721
vehicle_func.h
Pool::PoolItem<&_order_backup_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:384
Pool
Base class for all pools.
Definition: pool_type.hpp:80
ClientID
ClientID
'Unique' identifier to be given to clients
Definition: network_type.h:49
InvalidateWindowClassesData
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition: window.cpp:3217
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition: order_base.h:260
OrderBackup::ResetOfUser
static void ResetOfUser(TileIndex tile, uint32_t user)
Reset an OrderBackup given a tile and user.
Definition: order_backup.cpp:140
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition: vehicle_base.h:709
OrderBackup::orders
Order * orders
The actual orders if the vehicle was not a clone.
Definition: order_backup.h:42
OrderBackup::tile
TileIndex tile
Tile of the depot where the order was changed.
Definition: order_backup.h:38
OrderBackup::Restore
static void Restore(Vehicle *v, uint32_t user)
Restore the data of this order to the given vehicle.
Definition: order_backup.cpp:124
Pool::PoolItem<&_orderlist_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:305
OrderBackup::ClearGroup
static void ClearGroup(GroupID group)
Clear the group of all backups having this group ID.
Definition: order_backup.cpp:218
GroupID
uint16_t GroupID
Type for all group identifiers.
Definition: group_type.h:13
OrderBackup::RemoveOrder
static void RemoveOrder(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Definition: order_backup.cpp:253
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition: pool_func.hpp:225
OrderType
OrderType
Order types.
Definition: order_type.h:35
network.h
CommandHelper
Definition: command_func.h:93
station_map.h
window_func.h
OrderBackup::user
uint32_t user
The user that requested the backup.
Definition: order_backup.h:37
OrderBackup::group
GroupID group
The group the vehicle was part of.
Definition: order_backup.h:39
OrderBackup::Backup
static void Backup(const Vehicle *v, uint32_t user)
Create an order backup for the given vehicle.
Definition: order_backup.cpp:106
OrderBackup::OrderBackup
OrderBackup()
Creation for savegame restoration.
Definition: order_backup.h:45
IsUniqueVehicleName
bool IsUniqueVehicleName(const std::string &name)
Test if a name is unique among vehicle names.
Definition: vehicle_cmd.cpp:753
OrderBackup
Data for backing up an order of a vehicle so it can be restored after a vehicle is rebuilt in the sam...
Definition: order_backup.h:33
pool_func.hpp
order_backup.h
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition: vehicle_base.h:733
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition: vehicle_base.h:352
BaseConsist::CopyConsistPropertiesFrom
void CopyConsistPropertiesFrom(const BaseConsist *src)
Copy properties of other BaseConsist.
Definition: base_consist.cpp:22
WC_STATION_LIST
@ WC_STATION_LIST
Station list; Window numbers:
Definition: window_type.h:302
Order::next
Order * next
Pointer to next order. If nullptr, end of list.
Definition: order_base.h:59
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition: network_type.h:51
Order
Definition: order_base.h:36
network_func.h
IsHangarTile
bool IsHangarTile(Tile t)
Is tile t an hangar tile?
Definition: station_map.h:327