order_sl.cpp

Go to the documentation of this file.
00001 /* $Id: order_sl.cpp 15500 2009-02-16 21:43:44Z smatz $ */
00002 
00005 #include "../stdafx.h"
00006 #include "../order_base.h"
00007 #include "../core/alloc_func.hpp"
00008 #include "../settings_type.h"
00009 
00010 #include "saveload.h"
00011 
00012 void Order::ConvertFromOldSavegame()
00013 {
00014   uint8 old_flags = this->flags;
00015   this->flags = 0;
00016 
00017   /* First handle non-stop - use value from savegame if possible, else use value from config file */
00018   if (_settings_client.gui.sg_new_nonstop || (CheckSavegameVersion(22) && _settings_client.gui.new_nonstop)) {
00019     /* OFB_NON_STOP */
00020     this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_ANY_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
00021   } else {
00022     this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
00023   }
00024 
00025   switch (this->GetType()) {
00026     /* Only a few types need the other savegame conversions. */
00027     case OT_GOTO_DEPOT: case OT_GOTO_STATION: case OT_LOADING: break;
00028     default: return;
00029   }
00030 
00031   if (this->GetType() != OT_GOTO_DEPOT) {
00032     /* Then the load flags */
00033     if ((old_flags & 2) != 0) { // OFB_UNLOAD
00034       this->SetLoadType(OLFB_NO_LOAD);
00035     } else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
00036       this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
00037     } else {
00038       /* old OTTD versions stored full_load_any in config file - assume it was enabled when loading */
00039       this->SetLoadType(_settings_client.gui.sg_full_load_any || CheckSavegameVersion(22) ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
00040     }
00041 
00042     /* Finally fix the unload flags */
00043     if ((old_flags & 1) != 0) { // OFB_TRANSFER
00044       this->SetUnloadType(OUFB_TRANSFER);
00045     } else if ((old_flags & 2) != 0) { // OFB_UNLOAD
00046       this->SetUnloadType(OUFB_UNLOAD);
00047     } else {
00048       this->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
00049     }
00050   } else {
00051     /* Then the depot action flags */
00052     this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
00053 
00054     /* Finally fix the depot type flags */
00055     uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
00056     if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
00057     this->SetDepotOrderType((OrderDepotTypeFlags)t);
00058   }
00059 }
00060 
00065 static Order UnpackVersion4Order(uint16 packed)
00066 {
00067   return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4));
00068 }
00069 
00074 Order UnpackOldOrder(uint16 packed)
00075 {
00076   Order order = UnpackVersion4Order(packed);
00077 
00078   /*
00079    * Sanity check
00080    * TTD stores invalid orders as OT_NOTHING with non-zero flags/station
00081    */
00082   if (!order.IsValid() && packed != 0) order.MakeDummy();
00083 
00084   return order;
00085 }
00086 
00087 const SaveLoad *GetOrderDescription()
00088 {
00089   static const SaveLoad _order_desc[] = {
00090          SLE_VAR(Order, type,           SLE_UINT8),
00091          SLE_VAR(Order, flags,          SLE_UINT8),
00092          SLE_VAR(Order, dest,           SLE_UINT16),
00093          SLE_REF(Order, next,           REF_ORDER),
00094      SLE_CONDVAR(Order, refit_cargo,    SLE_UINT8,   36, SL_MAX_VERSION),
00095      SLE_CONDVAR(Order, refit_subtype,  SLE_UINT8,   36, SL_MAX_VERSION),
00096      SLE_CONDVAR(Order, wait_time,      SLE_UINT16,  67, SL_MAX_VERSION),
00097      SLE_CONDVAR(Order, travel_time,    SLE_UINT16,  67, SL_MAX_VERSION),
00098 
00099     /* Leftover from the minor savegame version stuff
00100      * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
00101     SLE_CONDNULL(10,                                  5,  35),
00102          SLE_END()
00103   };
00104 
00105   return _order_desc;
00106 }
00107 
00108 static void Save_ORDR()
00109 {
00110   Order *order;
00111 
00112   FOR_ALL_ORDERS(order) {
00113     SlSetArrayIndex(order->index);
00114     SlObject(order, GetOrderDescription());
00115   }
00116 }
00117 
00118 static void Load_ORDR()
00119 {
00120   if (CheckSavegameVersionOldStyle(5, 2)) {
00121     /* Version older than 5.2 did not have a ->next pointer. Convert them
00122         (in the old days, the orderlist was 5000 items big) */
00123     size_t len = SlGetFieldLength();
00124     uint i;
00125 
00126     if (CheckSavegameVersion(5)) {
00127       /* Pre-version 5 had an other layout for orders
00128           (uint16 instead of uint32) */
00129       len /= sizeof(uint16);
00130       uint16 *orders = MallocT<uint16>(len + 1);
00131 
00132       SlArray(orders, len, SLE_UINT16);
00133 
00134       for (i = 0; i < len; ++i) {
00135         Order *order = new (i) Order();
00136         order->AssignOrder(UnpackVersion4Order(orders[i]));
00137       }
00138 
00139       free(orders);
00140     } else if (CheckSavegameVersionOldStyle(5, 2)) {
00141       len /= sizeof(uint16);
00142       uint16 *orders = MallocT<uint16>(len + 1);
00143 
00144       SlArray(orders, len, SLE_UINT32);
00145 
00146       for (i = 0; i < len; ++i) {
00147         new (i) Order(orders[i]);
00148       }
00149 
00150       free(orders);
00151     }
00152 
00153     /* Update all the next pointer */
00154     for (i = 1; i < len; ++i) {
00155       /* The orders were built like this:
00156        *   While the order is valid, set the previous will get it's next pointer set
00157        *   We start with index 1 because no order will have the first in it's next pointer */
00158       if (GetOrder(i)->IsValid())
00159         GetOrder(i - 1)->next = GetOrder(i);
00160     }
00161   } else {
00162     int index;
00163 
00164     while ((index = SlIterateArray()) != -1) {
00165       Order *order = new (index) Order();
00166       SlObject(order, GetOrderDescription());
00167     }
00168   }
00169 }
00170 
00171 const SaveLoad *GetOrderListDescription()
00172 {
00173   static const SaveLoad _orderlist_desc[] = {
00174     SLE_REF(OrderList, first,              REF_ORDER),
00175     SLE_END()
00176   };
00177 
00178   return _orderlist_desc;
00179 }
00180 
00181 static void Save_ORDL()
00182 {
00183   OrderList *list;
00184 
00185   FOR_ALL_ORDER_LISTS(list) {
00186     SlSetArrayIndex(list->index);
00187     SlObject(list, GetOrderListDescription());
00188   }
00189 }
00190 
00191 static void Load_ORDL()
00192 {
00193   int index;
00194 
00195   while ((index = SlIterateArray()) != -1) {
00196     OrderList *list = new (index) OrderList();
00197     SlObject(list, GetOrderListDescription());
00198   }
00199 }
00200 
00201 extern const ChunkHandler _order_chunk_handlers[] = {
00202   { 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
00203   { 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
00204 };

Generated on Mon Feb 16 23:12:10 2009 for openttd by  doxygen 1.5.6