Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "command_func.h"
00014 #include "core/pool_func.hpp"
00015 #include "network/network.h"
00016 #include "network/network_func.h"
00017 #include "order_backup.h"
00018 #include "vehicle_base.h"
00019 #include "window_func.h"
00020 #include "station_map.h"
00021
00022 OrderBackupPool _order_backup_pool("BackupOrder");
00023 INSTANTIATE_POOL_METHODS(OrderBackup)
00024
00025
00026 OrderBackup::~OrderBackup()
00027 {
00028 free(this->name);
00029
00030 if (CleaningPool()) return;
00031
00032 Order *o = this->orders;
00033 while (o != NULL) {
00034 Order *next = o->next;
00035 delete o;
00036 o = next;
00037 }
00038 }
00039
00045 OrderBackup::OrderBackup(const Vehicle *v, uint32 user)
00046 {
00047 this->user = user;
00048 this->tile = v->tile;
00049 this->orderindex = v->cur_implicit_order_index;
00050 this->group = v->group_id;
00051 this->service_interval = v->service_interval;
00052
00053 if (v->name != NULL) this->name = strdup(v->name);
00054
00055
00056 if (v->IsOrderListShared()) {
00057 this->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
00058 } else {
00059
00060 Order **tail = &this->orders;
00061
00062
00063 const Order *order;
00064 FOR_VEHICLE_ORDERS(v, order) {
00065 Order *copy = new Order();
00066 copy->AssignOrder(*order);
00067 *tail = copy;
00068 tail = ©->next;
00069 }
00070 }
00071 }
00072
00077 void OrderBackup::DoRestore(Vehicle *v)
00078 {
00079
00080 v->name = this->name;
00081 this->name = NULL;
00082
00083
00084 if (this->clone != NULL) {
00085 DoCommand(0, v->index | CO_SHARE << 30, this->clone->index, DC_EXEC, CMD_CLONE_ORDER);
00086 } else if (this->orders != NULL && OrderList::CanAllocateItem()) {
00087 v->orders.list = new OrderList(this->orders, v);
00088 this->orders = NULL;
00089
00090 InvalidateWindowClassesData(WC_STATION_LIST, 0);
00091 }
00092
00093 uint num_orders = v->GetNumOrders();
00094 if (num_orders != 0) {
00095 v->cur_real_order_index = v->cur_implicit_order_index = this->orderindex % num_orders;
00096 v->UpdateRealOrderIndex();
00097 }
00098 v->service_interval = this->service_interval;
00099
00100
00101 DoCommand(0, this->group, v->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP);
00102 }
00103
00110 void OrderBackup::Backup(const Vehicle *v, uint32 user)
00111 {
00112
00113
00114 OrderBackup *ob;
00115 FOR_ALL_ORDER_BACKUPS(ob) {
00116 if (ob->user == user) delete ob;
00117 }
00118 if (OrderBackup::CanAllocateItem()) {
00119 new OrderBackup(v, user);
00120 }
00121 }
00122
00129 void OrderBackup::Restore(Vehicle *v, uint32 user)
00130 {
00131 OrderBackup *ob;
00132 FOR_ALL_ORDER_BACKUPS(ob) {
00133 if (v->tile != ob->tile || ob->user != user) continue;
00134
00135 ob->DoRestore(v);
00136 delete ob;
00137 }
00138 }
00139
00146 void OrderBackup::ResetOfUser(TileIndex tile, uint32 user)
00147 {
00148 OrderBackup *ob;
00149 FOR_ALL_ORDER_BACKUPS(ob) {
00150 if (ob->user == user && (ob->tile == tile || tile == INVALID_TILE)) delete ob;
00151 }
00152 }
00153
00163 CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00164 {
00165
00166 if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, p2);
00167
00168 return CommandCost();
00169 }
00170
00177 void OrderBackup::ResetUser(uint32 user)
00178 {
00179 assert(_network_server);
00180
00181 OrderBackup *ob;
00182 FOR_ALL_ORDER_BACKUPS(ob) {
00183
00184 if (ob->user != user) continue;
00185
00186 DoCommandP(0, 0, user, CMD_CLEAR_ORDER_BACKUP);
00187 return;
00188 }
00189 }
00190
00197 void OrderBackup::Reset(TileIndex t, bool from_gui)
00198 {
00199
00200
00201
00202
00203 #ifdef ENABLE_NETWORK
00204 uint32 user = _networking && !_network_server ? _network_own_client_id : CLIENT_ID_SERVER;
00205 #else
00206 uint32 user = 0;
00207 #endif
00208
00209 OrderBackup *ob;
00210 FOR_ALL_ORDER_BACKUPS(ob) {
00211
00212 if (ob->user != user) continue;
00213
00214 if (t != INVALID_TILE && t != ob->tile) continue;
00215
00216 if (from_gui) {
00217
00218
00219
00220 DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, NULL, NULL, true, false);
00221 } else {
00222
00223
00224 delete ob;
00225 }
00226 }
00227 }
00228
00233 void OrderBackup::ClearGroup(GroupID group)
00234 {
00235 OrderBackup *ob;
00236 FOR_ALL_ORDER_BACKUPS(ob) {
00237 if (ob->group == group) ob->group = DEFAULT_GROUP;
00238 }
00239 }
00240
00248 void OrderBackup::ClearVehicle(const Vehicle *v)
00249 {
00250 assert(v != NULL);
00251 OrderBackup *ob;
00252 FOR_ALL_ORDER_BACKUPS(ob) {
00253 if (ob->clone == v) {
00254
00255 ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
00256
00257 if (ob->clone == NULL) delete ob;
00258 }
00259 }
00260 }
00261
00262 void InitializeOrderBackups()
00263 {
00264 _order_backup_pool.CleanPool();
00265 }
00266
00272 void OrderBackup::RemoveOrder(OrderType type, DestinationID destination)
00273 {
00274 OrderBackup *ob;
00275 FOR_ALL_ORDER_BACKUPS(ob) {
00276 for (Order *order = ob->orders; order != NULL; order = order->next) {
00277 OrderType ot = order->GetType();
00278 if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
00279 if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION;
00280 if (ot == type && order->GetDestination() == destination) {
00281
00282 delete ob;
00283 break;
00284 }
00285 }
00286 }
00287 }