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
00020 OrderBackupPool _order_backup_pool("BackupOrder");
00021 INSTANTIATE_POOL_METHODS(OrderBackup)
00022
00023
00024 OrderBackup::~OrderBackup()
00025 {
00026 free(this->name);
00027
00028 if (CleaningPool()) return;
00029
00030 Order *o = this->orders;
00031 while (o != NULL) {
00032 Order *next = o->next;
00033 delete o;
00034 o = next;
00035 }
00036 }
00037
00043 OrderBackup::OrderBackup(const Vehicle *v, uint32 user)
00044 {
00045 this->user = user;
00046 this->tile = v->tile;
00047 this->orderindex = v->cur_implicit_order_index;
00048 this->group = v->group_id;
00049 this->service_interval = v->service_interval;
00050
00051 if (v->name != NULL) this->name = strdup(v->name);
00052
00053
00054 if (v->IsOrderListShared()) {
00055 this->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
00056 } else {
00057
00058 Order **tail = &this->orders;
00059
00060
00061 const Order *order;
00062 FOR_VEHICLE_ORDERS(v, order) {
00063 Order *copy = new Order();
00064 copy->AssignOrder(*order);
00065 *tail = copy;
00066 tail = ©->next;
00067 }
00068 }
00069 }
00070
00075 void OrderBackup::DoRestore(Vehicle *v)
00076 {
00077
00078 v->name = this->name;
00079 this->name = NULL;
00080
00081
00082 if (this->clone != NULL) {
00083 DoCommand(0, v->index | CO_SHARE << 30, this->clone->index, DC_EXEC, CMD_CLONE_ORDER);
00084 } else if (this->orders != NULL && OrderList::CanAllocateItem()) {
00085 v->orders.list = new OrderList(this->orders, v);
00086 this->orders = NULL;
00087 }
00088
00089 uint num_orders = v->GetNumOrders();
00090 if (num_orders != 0) {
00091 v->cur_real_order_index = v->cur_implicit_order_index = this->orderindex % num_orders;
00092 v->UpdateRealOrderIndex();
00093 }
00094 v->service_interval = this->service_interval;
00095
00096
00097 DoCommand(0, this->group, v->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP);
00098 }
00099
00106 void OrderBackup::Backup(const Vehicle *v, uint32 user)
00107 {
00108
00109
00110 OrderBackup *ob;
00111 FOR_ALL_ORDER_BACKUPS(ob) {
00112 if (ob->user == user) delete ob;
00113 }
00114 if (OrderBackup::CanAllocateItem()) {
00115 new OrderBackup(v, user);
00116 }
00117 }
00118
00125 void OrderBackup::Restore(Vehicle *v, uint32 user)
00126 {
00127 OrderBackup *ob;
00128 FOR_ALL_ORDER_BACKUPS(ob) {
00129 if (v->tile != ob->tile || ob->user != user) continue;
00130
00131 ob->DoRestore(v);
00132 delete ob;
00133 }
00134 }
00135
00142 void OrderBackup::ResetOfUser(TileIndex tile, uint32 user)
00143 {
00144 OrderBackup *ob;
00145 FOR_ALL_ORDER_BACKUPS(ob) {
00146 if (ob->user == user && (ob->tile == tile || tile == INVALID_TILE)) delete ob;
00147 }
00148 }
00149
00159 CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00160 {
00161
00162 if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, p2);
00163
00164 return CommandCost();
00165 }
00166
00173 void OrderBackup::ResetUser(uint32 user)
00174 {
00175 assert(_network_server);
00176
00177 OrderBackup *ob;
00178 FOR_ALL_ORDER_BACKUPS(ob) {
00179
00180 if (ob->user != user) continue;
00181
00182 DoCommandP(0, 0, user, CMD_CLEAR_ORDER_BACKUP);
00183 return;
00184 }
00185 }
00186
00193 void OrderBackup::Reset(TileIndex t, bool from_gui)
00194 {
00195
00196
00197
00198
00199 #ifdef ENABLE_NETWORK
00200 uint32 user = _networking && !_network_server ? _network_own_client_id : CLIENT_ID_SERVER;
00201 #else
00202 uint32 user = 0;
00203 #endif
00204
00205 OrderBackup *ob;
00206 FOR_ALL_ORDER_BACKUPS(ob) {
00207
00208 if (ob->user != user) continue;
00209
00210 if (t != INVALID_TILE && t != ob->tile) continue;
00211
00212 if (from_gui) {
00213
00214
00215
00216 DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, NULL, NULL, true, false);
00217 } else {
00218
00219
00220 delete ob;
00221 }
00222 }
00223 }
00224
00229 void OrderBackup::ClearGroup(GroupID group)
00230 {
00231 OrderBackup *ob;
00232 FOR_ALL_ORDER_BACKUPS(ob) {
00233 if (ob->group == group) ob->group = DEFAULT_GROUP;
00234 }
00235 }
00236
00244 void OrderBackup::ClearVehicle(const Vehicle *v)
00245 {
00246 assert(v != NULL);
00247 OrderBackup *ob;
00248 FOR_ALL_ORDER_BACKUPS(ob) {
00249 if (ob->clone == v) {
00250
00251 ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared();
00252
00253 if (ob->clone == NULL) delete ob;
00254 }
00255 }
00256 }
00257
00258 void InitializeOrderBackups()
00259 {
00260 _order_backup_pool.CleanPool();
00261 }