OpenTTD Source: src/order_backup.cpp Source File

OpenTTD Source 15.3

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
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 "table/strings.h"
24
25#include "safeguards.h"
26
27 OrderBackupPool _order_backup_pool("BackupOrder");
28 INSTANTIATE_POOL_METHODS(OrderBackup)
29
30OrderBackup::~OrderBackup() = default;
31
37 OrderBackup::OrderBackup(const Vehicle *v, uint32_t user) : user(user), tile(v->tile), group(v->group_id)
38{
39 this->CopyConsistPropertiesFrom(v);
40
41 /* If we have shared orders, store the vehicle we share the order with. */
42 if (v->IsOrderListShared()) {
43 this->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
44 } else {
45 /* Else copy the orders */
46 this->orders.assign(std::begin(v->Orders()), std::end(v->Orders()));
47 }
48}
49
54 void OrderBackup::DoRestore(Vehicle *v)
55{
56 /* If we had shared orders, recover that */
57 if (this->clone != nullptr) {
58 Command<CMD_CLONE_ORDER>::Do(DoCommandFlag::Execute, CO_SHARE, v->index, this->clone->index);
59 } else if (!this->orders.empty() && OrderList::CanAllocateItem()) {
60 v->orders = new OrderList(std::move(this->orders), v);
61 /* Make sure buoys/oil rigs are updated in the station list. */
62 InvalidateWindowClassesData(WC_STATION_LIST, 0);
63 }
64
65 /* Remove backed up name if it's no longer unique. */
66 if (!IsUniqueVehicleName(this->name)) this->name.clear();
67
68 v->CopyConsistPropertiesFrom(this);
69
70 /* Make sure orders are in range */
71 v->UpdateRealOrderIndex();
72 if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index;
73
74 /* Restore vehicle group */
75 Command<CMD_ADD_VEHICLE_GROUP>::Do(DoCommandFlag::Execute, this->group, v->index, false, VehicleListIdentifier{});
76}
77
84/* static */ void OrderBackup::Backup(const Vehicle *v, uint32_t user)
85{
86 /* Don't use reset as that broadcasts over the network to reset the variable,
87 * which is what we are doing at the moment. */
88 for (OrderBackup *ob : OrderBackup::Iterate()) {
89 if (ob->user == user) delete ob;
90 }
91 if (OrderBackup::CanAllocateItem()) {
92 new OrderBackup(v, user);
93 }
94}
95
102/* static */ void OrderBackup::Restore(Vehicle *v, uint32_t user)
103{
104 for (OrderBackup *ob : OrderBackup::Iterate()) {
105 if (v->tile != ob->tile || ob->user != user) continue;
106
107 ob->DoRestore(v);
108 delete ob;
109 }
110}
111
118/* static */ void OrderBackup::ResetOfUser(TileIndex tile, uint32_t user)
119{
120 for (OrderBackup *ob : OrderBackup::Iterate()) {
121 if (ob->user == user && (ob->tile == tile || tile == INVALID_TILE)) delete ob;
122 }
123}
124
132 CommandCost CmdClearOrderBackup(DoCommandFlags flags, TileIndex tile, ClientID user_id)
133{
134 /* No need to check anything. If the tile or user don't exist we just ignore it. */
135 if (flags.Test(DoCommandFlag::Execute)) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, user_id);
136
137 return CommandCost();
138}
139
146/* static */ void OrderBackup::ResetUser(uint32_t user)
147{
148 assert(_network_server);
149
150 for (OrderBackup *ob : OrderBackup::Iterate()) {
151 /* If it's not a backup of us, ignore it. */
152 if (ob->user != user) continue;
153
154 Command<CMD_CLEAR_ORDER_BACKUP>::Post(TileIndex{}, static_cast<ClientID>(user));
155 return;
156 }
157}
158
165/* static */ void OrderBackup::Reset(TileIndex t, bool from_gui)
166{
167 /* The user has CLIENT_ID_SERVER as default when network play is not active,
168 * but compiled it. A network client has its own variable for the unique
169 * client/user identifier. Finally if networking isn't compiled in the
170 * default is just plain and simple: 0. */
171 uint32_t user = _networking && !_network_server ? _network_own_client_id : CLIENT_ID_SERVER;
172
173 for (OrderBackup *ob : OrderBackup::Iterate()) {
174 /* If this is a GUI action, and it's not a backup of us, ignore it. */
175 if (from_gui && ob->user != user) continue;
176 /* If it's not for our chosen tile either, ignore it. */
177 if (t != INVALID_TILE && t != ob->tile) continue;
178
179 if (from_gui) {
180 /* We need to circumvent the "prevention" from this command being executed
181 * while the game is paused, so use the internal method. Nor do we want
182 * this command to get its cost estimated when shift is pressed. */
183 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) });
184 } else {
185 /* The command came from the game logic, i.e. the clearing of a tile.
186 * In that case we have no need to actually sync this, just do it. */
187 delete ob;
188 }
189 }
190}
191
196/* static */ void OrderBackup::ClearGroup(GroupID group)
197{
198 for (OrderBackup *ob : OrderBackup::Iterate()) {
199 if (ob->group == group) ob->group = DEFAULT_GROUP;
200 }
201}
202
210/* static */ void OrderBackup::ClearVehicle(const Vehicle *v)
211{
212 assert(v != nullptr);
213 for (OrderBackup *ob : OrderBackup::Iterate()) {
214 if (ob->clone == v) {
215 /* Get another item in the shared list. */
216 ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
217 /* But if that isn't there, remove it. */
218 if (ob->clone == nullptr) delete ob;
219 }
220 }
221}
222
231/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination, bool hangar)
232{
233 for (OrderBackup *ob : OrderBackup::Iterate()) {
234 for (Order &order : ob->orders) {
235 OrderType ot = order.GetType();
236 if (ot == OT_GOTO_DEPOT && order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) continue;
237 if (ot == OT_GOTO_DEPOT && hangar && !IsHangarTile(ob->tile)) continue; // Not an aircraft? Can't have a hangar order.
238 if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
239 if (ot == type && order.GetDestination() == destination) {
240 /* Remove the order backup! If a station/depot gets removed, we can't/shouldn't restore those broken orders. */
241 delete ob;
242 break;
243 }
244 }
245 }
246}
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
CommandCost
Common return value for all commands.
Definition command_type.h:24
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
command_func.h
Functions related to commands.
DoCommandFlag::Execute
@ Execute
execute the given command
group_cmd.h
Command definitions related to engine groups.
DEFAULT_GROUP
static constexpr GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition group_type.h:18
_networking
bool _networking
are we in networking mode?
Definition network.cpp:67
_network_server
bool _network_server
network-server is active
Definition network.cpp:68
_network_own_client_id
ClientID _network_own_client_id
Our client identifier.
Definition network.cpp:72
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:43
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition network_type.h:45
CmdClearOrderBackup
CommandCost CmdClearOrderBackup(DoCommandFlags flags, TileIndex tile, ClientID user_id)
Clear an OrderBackup.
Definition order_backup.cpp:132
order_backup.h
Functions related to order backups.
order_cmd.h
Command definitions related to orders.
OrderDepotActionFlag::NearestDepot
@ NearestDepot
Send the vehicle to the nearest depot.
OrderType
OrderType
Order types.
Definition order_type.h:50
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:210
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:34
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition base_consist.h:47
BaseConsist::cur_implicit_order_index
VehicleOrderID cur_implicit_order_index
The index to the current implicit order.
Definition base_consist.h:48
BaseConsist::CopyConsistPropertiesFrom
void CopyConsistPropertiesFrom(const BaseConsist *src)
Copy properties of other BaseConsist.
Definition base_consist.cpp:22
CommandHelper
Definition command_func.h:84
CommandTraits
Defines the traits of a command.
Definition command_type.h:464
DestinationID
Definition order_type.h:21
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:165
OrderBackup::Restore
static void Restore(Vehicle *v, uint32_t user)
Restore the data of this order to the given vehicle.
Definition order_backup.cpp:102
OrderBackup::DoRestore
void DoRestore(Vehicle *v)
Restore the data of this order to the given vehicle.
Definition order_backup.cpp:54
OrderBackup::Backup
static void Backup(const Vehicle *v, uint32_t user)
Create an order backup for the given vehicle.
Definition order_backup.cpp:84
OrderBackup::ClearVehicle
static void ClearVehicle(const Vehicle *v)
Clear/update the (clone) vehicle from an order backup.
Definition order_backup.cpp:210
OrderBackup::clone
const Vehicle * clone
Vehicle this vehicle was a clone of.
Definition order_backup.h:44
OrderBackup::tile
TileIndex tile
Tile of the depot where the order was changed.
Definition order_backup.h:41
OrderBackup::user
uint32_t user
The user that requested the backup.
Definition order_backup.h:40
OrderBackup::ClearGroup
static void ClearGroup(GroupID group)
Clear the group of all backups having this group ID.
Definition order_backup.cpp:196
OrderBackup::group
GroupID group
The group the vehicle was part of.
Definition order_backup.h:42
OrderBackup::OrderBackup
OrderBackup()=default
Creation for savegame restoration.
OrderBackup::ResetOfUser
static void ResetOfUser(TileIndex tile, uint32_t user)
Reset an OrderBackup given a tile and user.
Definition order_backup.cpp:118
OrderBackup::ResetUser
static void ResetUser(uint32_t user)
Reset an user's OrderBackup if needed.
Definition order_backup.cpp:146
OrderBackup::orders
std::vector< Order > orders
The actual orders if the vehicle was not a clone.
Definition order_backup.h:45
OrderBackup::RemoveOrder
static void RemoveOrder(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Definition order_backup.cpp:231
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition order_base.h:274
Order
Definition order_base.h:33
PoolID< uint16_t, struct GroupIDTag, 64000, 0xFFFF >
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:436
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
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:357
Pool
Base class for all pools.
Definition pool_type.hpp:133
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:32
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Vehicle::IsOrderListShared
bool IsOrderListShared() const
Check if we share our orders with another vehicle.
Definition vehicle_base.h:699
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition vehicle_base.h:705
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition vehicle_base.h:314
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition vehicle_base.h:681
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:693
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:225
Vehicle::UpdateRealOrderIndex
void UpdateRealOrderIndex()
Skip implicit orders until cur_real_order_index is a non-implicit order.
Definition vehicle_base.h:869
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:761
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:3314
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:307