OpenTTD Source: src/order_backup.cpp Source File

OpenTTD Source 15.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");
26 INSTANTIATE_POOL_METHODS(OrderBackup)
27
28
29 OrderBackup::~OrderBackup()
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
52 this->CopyConsistPropertiesFrom(v);
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
75 void OrderBackup::DoRestore(Vehicle *v)
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. */
84 InvalidateWindowClassesData(WC_STATION_LIST, 0);
85 }
86
87 /* Remove backed up name if it's no longer unique. */
88 if (!IsUniqueVehicleName(this->name)) this->name.clear();
89
90 v->CopyConsistPropertiesFrom(this);
91
92 /* Make sure orders are in range */
93 v->UpdateRealOrderIndex();
94 if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index;
95
96 /* Restore vehicle group */
97 Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, this->group, v->index, false, VehicleListIdentifier{});
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 }
113 if (OrderBackup::CanAllocateItem()) {
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
154 CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id)
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
176 Command<CMD_CLEAR_ORDER_BACKUP>::Post(0, static_cast<ClientID>(user));
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. */
193 uint32_t user = _networking && !_network_server ? _network_own_client_id : CLIENT_ID_SERVER;
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}
CommandCost
Common return value for all commands.
Definition command_type.h:23
command_func.h
Functions related to commands.
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition command_type.h:374
DC_EXEC
@ DC_EXEC
execute the given command
Definition command_type.h:376
group_cmd.h
Command definitions related to engine groups.
GroupID
uint16_t GroupID
Type for all group identifiers.
Definition group_type.h:13
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:65
_network_server
bool _network_server
network-server is active
Definition network.cpp:66
_network_own_client_id
ClientID _network_own_client_id
Our client identifier.
Definition network.cpp:70
network.h
Basic functions/variables used all over the place.
network_func.h
Network functions used by other parts of OpenTTD.
ClientID
ClientID
'Unique' identifier to be given to clients
Definition network_type.h:49
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition network_type.h:51
CmdClearOrderBackup
CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id)
Clear an OrderBackup.
Definition order_backup.cpp:154
order_backup.h
Functions related to order backups.
order_cmd.h
Command definitions related to orders.
ODATFB_NEAREST_DEPOT
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition order_type.h:105
OrderType
OrderType
Order types.
Definition order_type.h:35
pool_func.hpp
Some methods of Pool are placed here in order to reduce compilation time and binary size.
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition pool_func.hpp:237
safeguards.h
A number of safeguards to prevent using unsafe methods.
station_map.h
Maps accessors for stations.
IsHangarTile
bool IsHangarTile(Tile t)
Is tile t an hangar tile?
Definition station_map.h:420
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
BaseConsist::name
std::string name
Name of vehicle.
Definition base_consist.h:18
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition base_consist.h:31
BaseConsist::cur_implicit_order_index
VehicleOrderID cur_implicit_order_index
The index to the current implicit order.
Definition base_consist.h:32
BaseConsist::CopyConsistPropertiesFrom
void CopyConsistPropertiesFrom(const BaseConsist *src)
Copy properties of other BaseConsist.
Definition base_consist.cpp:22
CommandHelper
Definition command_func.h:83
CommandTraits
Defines the traits of a command.
Definition command_type.h:453
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
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
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
OrderBackup::DoRestore
void DoRestore(Vehicle *v)
Restore the data of this order to the given vehicle.
Definition order_backup.cpp:75
OrderBackup::orders
Order * orders
The actual orders if the vehicle was not a clone.
Definition order_backup.h:42
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::ClearVehicle
static void ClearVehicle(const Vehicle *v)
Clear/update the (clone) vehicle from an order backup.
Definition order_backup.cpp:232
OrderBackup::clone
const Vehicle * clone
Vehicle this vehicle was a clone of.
Definition order_backup.h:41
OrderBackup::tile
TileIndex tile
Tile of the depot where the order was changed.
Definition order_backup.h:38
OrderBackup::user
uint32_t user
The user that requested the backup.
Definition order_backup.h:37
OrderBackup::ClearGroup
static void ClearGroup(GroupID group)
Clear the group of all backups having this group ID.
Definition order_backup.cpp:218
OrderBackup::group
GroupID group
The group the vehicle was part of.
Definition order_backup.h:39
OrderBackup::OrderBackup
OrderBackup()
Creation for savegame restoration.
Definition order_backup.h:45
OrderBackup::ResetOfUser
static void ResetOfUser(TileIndex tile, uint32_t user)
Reset an OrderBackup given a tile and user.
Definition order_backup.cpp:140
OrderBackup::ResetUser
static void ResetUser(uint32_t user)
Reset an user's OrderBackup if needed.
Definition order_backup.cpp:168
OrderBackup::RemoveOrder
static void RemoveOrder(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Definition order_backup.cpp:253
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition order_base.h:259
Order
Definition order_base.h:36
Order::next
Order * next
Pointer to next order. If nullptr, end of list.
Definition order_base.h:59
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:257
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:238
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:388
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:309
Pool
Base class for all pools.
Definition pool_type.hpp:80
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
VehicleListIdentifier
The information about a vehicle list.
Definition vehiclelist.h:28
Vehicle
Vehicle data structure.
Definition vehicle_base.h:244
Vehicle::IsOrderListShared
bool IsOrderListShared() const
Check if we share our orders with another vehicle.
Definition vehicle_base.h:732
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition vehicle_base.h:738
Vehicle::group_id
GroupID group_id
Index of group Pool array.
Definition vehicle_base.h:366
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition vehicle_base.h:359
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition vehicle_base.h:714
Vehicle::Orders
IterateWrapper Orders() const
Returns an iterable ensemble of orders of a vehicle.
Definition vehicle_base.h:1084
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:726
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:264
Vehicle::UpdateRealOrderIndex
void UpdateRealOrderIndex()
Skip implicit orders until cur_real_order_index is a non-implicit order.
Definition vehicle_base.h:901
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
vehicle_base.h
Base class for all vehicles.
IsUniqueVehicleName
bool IsUniqueVehicleName(const std::string &name)
Test if a name is unique among vehicle names.
Definition vehicle_cmd.cpp:753
vehicle_func.h
Functions related to vehicles.
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:3236
window_func.h
Window functions not directly related to making/drawing windows.
WC_STATION_LIST
@ WC_STATION_LIST
Station list; Window numbers:
Definition window_type.h:302