Files
@ r26799:826b1c52a903
Branch filter:
Location: cpp/openttd-patchpack/source/src/order_backup.cpp - annotation
r26799:826b1c52a903
8.9 KiB
text/x-c
Fix: no ScriptEvent sub class should export constructors to scripts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15855:2be9e0211a54 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r18353:55e21e815cc4 r18607:7724313c61c6 r26094:7572e88decb3 r26102:502baaa2877d r15847:4a3cf48b2f40 r21383:942c32fb8b0e r21383:942c32fb8b0e r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r23607:36c15679007d r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r19519:a08cec92f7c7 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15849:33fd4f65439e r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r24513:ba5551156e4e r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r23607:36c15679007d r26109:9d7a08d936b2 r23607:36c15679007d r26178:733038a553ce r23607:36c15679007d r18353:55e21e815cc4 r18353:55e21e815cc4 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r19519:a08cec92f7c7 r19519:a08cec92f7c7 r19519:a08cec92f7c7 r19519:a08cec92f7c7 r19521:9abf5bbcc05a r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r26115:02430a86c873 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15853:61b6cb670877 r15855:2be9e0211a54 r15855:2be9e0211a54 r23965:e71e85950eb1 r15855:2be9e0211a54 r15855:2be9e0211a54 r17297:4740a882c430 r17297:4740a882c430 r17297:4740a882c430 r15853:61b6cb670877 r15853:61b6cb670877 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r23965:e71e85950eb1 r15855:2be9e0211a54 r15853:61b6cb670877 r15853:61b6cb670877 r15853:61b6cb670877 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15847:4a3cf48b2f40 r23965:e71e85950eb1 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r26095:00c14d52e378 r15855:2be9e0211a54 r26107:59139eb8d51a r15855:2be9e0211a54 r15855:2be9e0211a54 r26107:59139eb8d51a r15855:2be9e0211a54 r15855:2be9e0211a54 r26107:59139eb8d51a r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r23965:e71e85950eb1 r23965:e71e85950eb1 r15855:2be9e0211a54 r15855:2be9e0211a54 r26107:59139eb8d51a r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r17099:f140f6165f35 r17099:f140f6165f35 r17629:21e9dfd343cd r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r23965:e71e85950eb1 r26130:b35f21dabdee r26130:b35f21dabdee r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r16682:c4afe0af8523 r16682:c4afe0af8523 r16682:c4afe0af8523 r26121:f66f65c35c74 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15855:2be9e0211a54 r15853:61b6cb670877 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r23965:e71e85950eb1 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r15847:4a3cf48b2f40 r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r23607:36c15679007d r17099:f140f6165f35 r17099:f140f6165f35 r17099:f140f6165f35 r15849:33fd4f65439e r15849:33fd4f65439e r23607:36c15679007d r23965:e71e85950eb1 r15849:33fd4f65439e r15849:33fd4f65439e r15849:33fd4f65439e r15849:33fd4f65439e r23607:36c15679007d r15849:33fd4f65439e r15849:33fd4f65439e r15849:33fd4f65439e r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r23367:7aa5d2e62188 r23367:7aa5d2e62188 r23367:7aa5d2e62188 r18607:7724313c61c6 r23367:7aa5d2e62188 r18607:7724313c61c6 r23965:e71e85950eb1 r23607:36c15679007d r18607:7724313c61c6 r18607:7724313c61c6 r23490:269ca3d32272 r23367:7aa5d2e62188 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 r18607:7724313c61c6 | /*
* 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_backup.cpp Handling of order backups. */
#include "stdafx.h"
#include "command_func.h"
#include "core/pool_func.hpp"
#include "network/network.h"
#include "network/network_func.h"
#include "order_backup.h"
#include "vehicle_base.h"
#include "window_func.h"
#include "station_map.h"
#include "order_cmd.h"
#include "group_cmd.h"
#include "safeguards.h"
OrderBackupPool _order_backup_pool("BackupOrder");
INSTANTIATE_POOL_METHODS(OrderBackup)
/** Free everything that is allocated. */
OrderBackup::~OrderBackup()
{
if (CleaningPool()) return;
Order *o = this->orders;
while (o != nullptr) {
Order *next = o->next;
delete o;
o = next;
}
}
/**
* Create an order backup for the given vehicle.
* @param v The vehicle to make a backup of.
* @param user The user that is requesting the backup.
*/
OrderBackup::OrderBackup(const Vehicle *v, uint32 user)
{
this->user = user;
this->tile = v->tile;
this->group = v->group_id;
this->CopyConsistPropertiesFrom(v);
/* If we have shared orders, store the vehicle we share the order with. */
if (v->IsOrderListShared()) {
this->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
} else {
/* Else copy the orders */
Order **tail = &this->orders;
/* Count the number of orders */
for (const Order *order : v->Orders()) {
Order *copy = new Order();
copy->AssignOrder(*order);
*tail = copy;
tail = ©->next;
}
}
}
/**
* Restore the data of this order to the given vehicle.
* @param v The vehicle to restore to.
*/
void OrderBackup::DoRestore(Vehicle *v)
{
/* If we had shared orders, recover that */
if (this->clone != nullptr) {
Command<CMD_CLONE_ORDER>::Do(DC_EXEC, CO_SHARE, v->index, this->clone->index);
} else if (this->orders != nullptr && OrderList::CanAllocateItem()) {
v->orders = new OrderList(this->orders, v);
this->orders = nullptr;
/* Make sure buoys/oil rigs are updated in the station list. */
InvalidateWindowClassesData(WC_STATION_LIST, 0);
}
v->CopyConsistPropertiesFrom(this);
/* Make sure orders are in range */
v->UpdateRealOrderIndex();
if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index;
/* Restore vehicle group */
Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, this->group, v->index, false);
}
/**
* Create an order backup for the given vehicle.
* @param v The vehicle to make a backup of.
* @param user The user that is requesting the backup.
* @note Will automatically remove any previous backups of this user.
*/
/* static */ void OrderBackup::Backup(const Vehicle *v, uint32 user)
{
/* Don't use reset as that broadcasts over the network to reset the variable,
* which is what we are doing at the moment. */
for (OrderBackup *ob : OrderBackup::Iterate()) {
if (ob->user == user) delete ob;
}
if (OrderBackup::CanAllocateItem()) {
new OrderBackup(v, user);
}
}
/**
* Restore the data of this order to the given vehicle.
* @param v The vehicle to restore to.
* @param user The user that built the vehicle, thus wants to restore.
* @note After restoration the backup will automatically be removed.
*/
/* static */ void OrderBackup::Restore(Vehicle *v, uint32 user)
{
for (OrderBackup *ob : OrderBackup::Iterate()) {
if (v->tile != ob->tile || ob->user != user) continue;
ob->DoRestore(v);
delete ob;
}
}
/**
* Reset an OrderBackup given a tile and user.
* @param tile The tile associated with the OrderBackup.
* @param user The user associated with the OrderBackup.
* @note Must not be used from the GUI!
*/
/* static */ void OrderBackup::ResetOfUser(TileIndex tile, uint32 user)
{
for (OrderBackup *ob : OrderBackup::Iterate()) {
if (ob->user == user && (ob->tile == tile || tile == INVALID_TILE)) delete ob;
}
}
/**
* Clear an OrderBackup
* @param flags For command.
* @param tile Tile related to the to-be-cleared OrderBackup.
* @param user_id User that had the OrderBackup.
* @return The cost of this operation or an error.
*/
CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id)
{
/* No need to check anything. If the tile or user don't exist we just ignore it. */
if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, user_id);
return CommandCost();
}
/**
* Reset an user's OrderBackup if needed.
* @param user The user associated with the OrderBackup.
* @pre _network_server.
* @note Must not be used from a command.
*/
/* static */ void OrderBackup::ResetUser(uint32 user)
{
assert(_network_server);
for (OrderBackup *ob : OrderBackup::Iterate()) {
/* If it's not a backup of us, ignore it. */
if (ob->user != user) continue;
Command<CMD_CLEAR_ORDER_BACKUP>::Post(0, static_cast<ClientID>(user));
return;
}
}
/**
* Reset the OrderBackups from GUI/game logic.
* @param t The tile of the order backup.
* @param from_gui Whether the call came from the GUI, i.e. whether
* it must be synced over the network.
*/
/* static */ void OrderBackup::Reset(TileIndex t, bool from_gui)
{
/* The user has CLIENT_ID_SERVER as default when network play is not active,
* but compiled it. A network client has its own variable for the unique
* client/user identifier. Finally if networking isn't compiled in the
* default is just plain and simple: 0. */
uint32 user = _networking && !_network_server ? _network_own_client_id : CLIENT_ID_SERVER;
for (OrderBackup *ob : OrderBackup::Iterate()) {
/* If this is a GUI action, and it's not a backup of us, ignore it. */
if (from_gui && ob->user != user) continue;
/* If it's not for our chosen tile either, ignore it. */
if (t != INVALID_TILE && t != ob->tile) continue;
if (from_gui) {
/* We need to circumvent the "prevention" from this command being executed
* while the game is paused, so use the internal method. Nor do we want
* this command to get its cost estimated when shift is pressed. */
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) });
} else {
/* The command came from the game logic, i.e. the clearing of a tile.
* In that case we have no need to actually sync this, just do it. */
delete ob;
}
}
}
/**
* Clear the group of all backups having this group ID.
* @param group The group to clear.
*/
/* static */ void OrderBackup::ClearGroup(GroupID group)
{
for (OrderBackup *ob : OrderBackup::Iterate()) {
if (ob->group == group) ob->group = DEFAULT_GROUP;
}
}
/**
* Clear/update the (clone) vehicle from an order backup.
* @param v The vehicle to clear.
* @pre v != nullptr
* @note If it is not possible to set another vehicle as clone
* "example", then this backed up order will be removed.
*/
/* static */ void OrderBackup::ClearVehicle(const Vehicle *v)
{
assert(v != nullptr);
for (OrderBackup *ob : OrderBackup::Iterate()) {
if (ob->clone == v) {
/* Get another item in the shared list. */
ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
/* But if that isn't there, remove it. */
if (ob->clone == nullptr) delete ob;
}
}
}
/**
* Removes an order from all vehicles. Triggers when, say, a station is removed.
* @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]).
* @param destination The destination. Can be a StationID, DepotID or WaypointID.
* @param hangar Only used for airports in the destination.
* When false, remove airport and hangar orders.
* When true, remove either airport or hangar order.
*/
/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination, bool hangar)
{
for (OrderBackup *ob : OrderBackup::Iterate()) {
for (Order *order = ob->orders; order != nullptr; order = order->next) {
OrderType ot = order->GetType();
if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
if (ot == OT_GOTO_DEPOT && hangar && !IsHangarTile(ob->tile)) continue; // Not an aircraft? Can't have a hangar order.
if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
if (ot == type && order->GetDestination() == destination) {
/* Remove the order backup! If a station/depot gets removed, we can't/shouldn't restore those broken orders. */
delete ob;
break;
}
}
}
}
|