# station_sl.cpp

Go to the documentation of this file.

    00001 /* $Id: station_sl.cpp 16355 2009-05-18 20:17:28Z rubidium $ */
    00002
    00005 #include "../stdafx.h"
    00006 #include "../station_base.h"
    00007 #include "../core/bitmath_func.hpp"
    00008 #include "../core/alloc_func.hpp"
    00009 #include "../variables.h"
    00010 #include "../newgrf_station.h"
    00011
    00012 #include "saveload.h"
    00013
    00014
    00015 void AfterLoadStations()
    00016 {
    00017   /* Update the speclists of all stations to point to the currently loaded custom stations. */
    00018   Station *st;
    00019   FOR_ALL_STATIONS(st) {
    00020     for (uint i = 0; i < st->num_specs; i++) {
    00021       if (st->speclist[i].grfid == 0) continue;
    00022
    00023       st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx, NULL);
    00024     }
    00025
    00026     for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
    00027
    00028     StationUpdateAnimTriggers(st);
    00029   }
    00030 }
    00031
    00032 static const SaveLoad _roadstop_desc[] = {
    00033   SLE_VAR(RoadStop, xy,           SLE_UINT32),
    00034   SLE_CONDNULL(1, 0, 44),
    00035   SLE_VAR(RoadStop, status,       SLE_UINT8),
    00036   /* Index was saved in some versions, but this is not needed */
    00037   SLE_CONDNULL(4, 0, 8),
    00038   SLE_CONDNULL(2, 0, 44),
    00039   SLE_CONDNULL(1, 0, 25),
    00040
    00041   SLE_REF(RoadStop, next,         REF_ROADSTOPS),
    00042   SLE_CONDNULL(2, 0, 44),
    00043
    00044   SLE_CONDNULL(4, 0, 24),
    00045   SLE_CONDNULL(1, 25, 25),
    00046
    00047   SLE_END()
    00048 };
    00049
    00050 static const SaveLoad _station_desc[] = {
    00051   SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
    00052   SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
    00053   SLE_CONDNULL(4, 0, 5),
    00054   SLE_CONDVAR(Station, train_tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
    00055   SLE_CONDVAR(Station, train_tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
    00056   SLE_CONDVAR(Station, airport_tile,               SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
    00057   SLE_CONDVAR(Station, airport_tile,               SLE_UINT32,                  6, SL_MAX_VERSION),
    00058   SLE_CONDVAR(Station, dock_tile,                  SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
    00059   SLE_CONDVAR(Station, dock_tile,                  SLE_UINT32,                  6, SL_MAX_VERSION),
    00060       SLE_REF(Station, town,                       REF_TOWN),
    00061       SLE_VAR(Station, trainst_w,                  SLE_UINT8),
    00062   SLE_CONDVAR(Station, trainst_h,                  SLE_UINT8,                   2, SL_MAX_VERSION),
    00063
    00064   SLE_CONDNULL(1, 0, 3),
    00065
    00066       SLE_VAR(Station, string_id,                  SLE_STRINGID),
    00067   SLE_CONDSTR(Station, name,                       SLE_STR, 0,                 84, SL_MAX_VERSION),
    00068   SLE_CONDVAR(Station, indtype,                    SLE_UINT8,                 103, SL_MAX_VERSION),
    00069       SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT16),
    00070
    00071       SLE_VAR(Station, time_since_load,            SLE_UINT8),
    00072       SLE_VAR(Station, time_since_unload,          SLE_UINT8),
    00073       SLE_VAR(Station, delete_ctr,                 SLE_UINT8),
    00074       SLE_VAR(Station, owner,                      SLE_UINT8),
    00075       SLE_VAR(Station, facilities,                 SLE_UINT8),
    00076       SLE_VAR(Station, airport_type,               SLE_UINT8),
    00077
    00078   SLE_CONDNULL(2, 0, 5),
    00079   SLE_CONDNULL(1, 0, 4),
    00080
    00081   SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U16,  0,  2),
    00082   SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U32,  3, 45),
    00083   SLE_CONDVAR(Station, airport_flags,              SLE_UINT64,                 46, SL_MAX_VERSION),
    00084
    00085   SLE_CONDNULL(2, 0, 25),
    00086   SLE_CONDVAR(Station, last_vehicle_type,          SLE_UINT8,                  26, SL_MAX_VERSION),
    00087
    00088   SLE_CONDNULL(2, 3, 25),
    00089   SLE_CONDVAR(Station, build_date,                 SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
    00090   SLE_CONDVAR(Station, build_date,                 SLE_INT32,                  31, SL_MAX_VERSION),
    00091
    00092   SLE_CONDREF(Station, bus_stops,                  REF_ROADSTOPS,               6, SL_MAX_VERSION),
    00093   SLE_CONDREF(Station, truck_stops,                REF_ROADSTOPS,               6, SL_MAX_VERSION),
    00094
    00095   /* Used by newstations for graphic variations */
    00096   SLE_CONDVAR(Station, random_bits,                SLE_UINT16,                 27, SL_MAX_VERSION),
    00097   SLE_CONDVAR(Station, waiting_triggers,           SLE_UINT8,                  27, SL_MAX_VERSION),
    00098   SLE_CONDVAR(Station, num_specs,                  SLE_UINT8,                  27, SL_MAX_VERSION),
    00099
    00100   SLE_CONDLST(Station, loading_vehicles,           REF_VEHICLE,                57, SL_MAX_VERSION),
    00101
    00102   /* reserve extra space in savegame here. (currently 32 bytes) */
    00103   SLE_CONDNULL(32, 2, SL_MAX_VERSION),
    00104
    00105   SLE_END()
    00106 };
    00107
    00108 static uint16 _waiting_acceptance;
    00109 static uint16 _cargo_source;
    00110 static uint32 _cargo_source_xy;
    00111 static uint16 _cargo_days;
    00112 static Money  _cargo_feeder_share;
    00113
    00114 static const SaveLoad _station_speclist_desc[] = {
    00115   SLE_CONDVAR(StationSpecList, grfid,    SLE_UINT32, 27, SL_MAX_VERSION),
    00116   SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8,  27, SL_MAX_VERSION),
    00117
    00118   SLE_END()
    00119 };
    00120
    00121
    00122 void SaveLoad_STNS(Station *st)
    00123 {
    00124   static const SaveLoad _goods_desc[] = {
    00125     SLEG_CONDVAR(            _waiting_acceptance, SLE_UINT16,                  0, 67),
    00126      SLE_CONDVAR(GoodsEntry, acceptance_pickup,   SLE_UINT8,                  68, SL_MAX_VERSION),
    00127     SLE_CONDNULL(2,                                                           51, 67),
    00128          SLE_VAR(GoodsEntry, days_since_pickup,   SLE_UINT8),
    00129          SLE_VAR(GoodsEntry, rating,              SLE_UINT8),
    00130     SLEG_CONDVAR(            _cargo_source,       SLE_FILE_U8 | SLE_VAR_U16,   0, 6),
    00131     SLEG_CONDVAR(            _cargo_source,       SLE_UINT16,                  7, 67),
    00132     SLEG_CONDVAR(            _cargo_source_xy,    SLE_UINT32,                 44, 67),
    00133     SLEG_CONDVAR(            _cargo_days,         SLE_UINT8,                   0, 67),
    00134          SLE_VAR(GoodsEntry, last_speed,          SLE_UINT8),
    00135          SLE_VAR(GoodsEntry, last_age,            SLE_UINT8),
    00136     SLEG_CONDVAR(            _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
    00137     SLEG_CONDVAR(            _cargo_feeder_share, SLE_INT64,                  65, 67),
    00138      SLE_CONDLST(GoodsEntry, cargo.packets,       REF_CARGO_PACKET,           68, SL_MAX_VERSION),
    00139
    00140     SLE_END()
    00141   };
    00142
    00143
    00144   SlObject(st, _station_desc);
    00145
    00146   _waiting_acceptance = 0;
    00147
    00148   uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
    00149   for (CargoID i = 0; i < num_cargo; i++) {
    00150     GoodsEntry *ge = &st->goods[i];
    00151     SlObject(ge, _goods_desc);
    00152     if (CheckSavegameVersion(68)) {
    00153       SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
    00154       if (GB(_waiting_acceptance, 0, 12) != 0) {
    00155         /* Don't construct the packet with station here, because that'll fail with old savegames */
    00156         CargoPacket *cp = new CargoPacket();
    00157         /* In old versions, enroute_from used 0xFF as INVALID_STATION */
    00158         cp->source          = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
    00159         cp->count           = GB(_waiting_acceptance, 0, 12);
    00160         cp->days_in_transit = _cargo_days;
    00161         cp->feeder_share    = _cargo_feeder_share;
    00162         cp->source_xy       = _cargo_source_xy;
    00163         cp->days_in_transit = _cargo_days;
    00164         cp->feeder_share    = _cargo_feeder_share;
    00165         SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
    00166         ge->cargo.Append(cp);
    00167       }
    00168     }
    00169   }
    00170
    00171   if (st->num_specs != 0) {
    00172     /* Allocate speclist memory when loading a game */
    00173     if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
    00174     for (uint i = 0; i < st->num_specs; i++) {
    00175       SlObject(&st->speclist[i], _station_speclist_desc);
    00176     }
    00177   }
    00178 }
    00179
    00180 static void Save_STNS()
    00181 {
    00182   Station *st;
    00183   /* Write the stations */
    00184   FOR_ALL_STATIONS(st) {
    00185     SlSetArrayIndex(st->index);
    00186     SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
    00187   }
    00188 }
    00189
    00190 static void Load_STNS()
    00191 {
    00192   int index;
    00193   while ((index = SlIterateArray()) != -1) {
    00194     Station *st = new (index) Station();
    00195
    00196     SaveLoad_STNS(st);
    00197   }
    00198 }
    00199
    00200 static void Save_ROADSTOP()
    00201 {
    00202   RoadStop *rs;
    00203
    00204   FOR_ALL_ROADSTOPS(rs) {
    00205     SlSetArrayIndex(rs->index);
    00206     SlObject(rs, _roadstop_desc);
    00207   }
    00208 }
    00209
    00210 static void Load_ROADSTOP()
    00211 {
    00212   int index;
    00213
    00214   while ((index = SlIterateArray()) != -1) {
    00215     RoadStop *rs = new (index) RoadStop(INVALID_TILE);
    00216
    00217     SlObject(rs, _roadstop_desc);
    00218   }
    00219 }
    00220
    00221 extern const ChunkHandler _station_chunk_handlers[] = {
    00222   { 'STNS', Save_STNS,      Load_STNS,      CH_ARRAY },
    00223   { 'ROAD', Save_ROADSTOP,  Load_ROADSTOP,  CH_ARRAY | CH_LAST},
    00224 };