station_sl.cpp

Go to the documentation of this file.
00001 /* $Id: station_sl.cpp 23636 2011-12-19 21:06:06Z truebrain $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #include "../stdafx.h"
00013 #include "../station_base.h"
00014 #include "../waypoint_base.h"
00015 #include "../roadstop_base.h"
00016 #include "../vehicle_base.h"
00017 #include "../newgrf_station.h"
00018 #include "../newgrf.h"
00019 
00020 #include "saveload.h"
00021 #include "table/strings.h"
00022 
00027 static void UpdateWaypointOrder(Order *o)
00028 {
00029   if (!o->IsType(OT_GOTO_STATION)) return;
00030 
00031   const Station *st = Station::Get(o->GetDestination());
00032   if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) return;
00033 
00034   o->MakeGoToWaypoint(o->GetDestination());
00035 }
00036 
00041 void MoveBuoysToWaypoints()
00042 {
00043   /* Buoy orders become waypoint orders */
00044   OrderList *ol;
00045   FOR_ALL_ORDER_LISTS(ol) {
00046     VehicleType vt = ol->GetFirstSharedVehicle()->type;
00047     if (vt != VEH_SHIP && vt != VEH_TRAIN) continue;
00048 
00049     for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o);
00050   }
00051 
00052   Vehicle *v;
00053   FOR_ALL_VEHICLES(v) {
00054     VehicleType vt = v->type;
00055     if (vt != VEH_SHIP && vt != VEH_TRAIN) continue;
00056 
00057     UpdateWaypointOrder(&v->current_order);
00058   }
00059 
00060   /* Now make the stations waypoints */
00061   Station *st;
00062   FOR_ALL_STATIONS(st) {
00063     if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) continue;
00064 
00065     StationID index    = st->index;
00066     TileIndex xy       = st->xy;
00067     Town *town         = st->town;
00068     StringID string_id = st->string_id;
00069     char *name         = st->name;
00070     st->name           = NULL;
00071     Date build_date    = st->build_date;
00072     /* TTDPatch could use "buoys with rail station" for rail waypoints */
00073     bool train         = st->train_station.tile != INVALID_TILE;
00074     TileArea train_st  = st->train_station;
00075 
00076     /* Delete the station, so we can make it a real waypoint. */
00077     delete st;
00078 
00079     /* Stations and waypoints are in the same pool, so if a station
00080      * is deleted there must be place for a Waypoint. */
00081     assert(Waypoint::CanAllocateItem());
00082     Waypoint *wp   = new (index) Waypoint(xy);
00083     wp->town       = town;
00084     wp->string_id  = train ? STR_SV_STNAME_WAYPOINT : STR_SV_STNAME_BUOY;
00085     wp->name       = name;
00086     wp->delete_ctr = 0; // Just reset delete counter for once.
00087     wp->build_date = build_date;
00088     wp->owner      = train ? GetTileOwner(xy) : OWNER_NONE;
00089 
00090     if (IsInsideBS(string_id, STR_SV_STNAME_BUOY, 9)) wp->town_cn = string_id - STR_SV_STNAME_BUOY;
00091 
00092     if (train) {
00093       /* When we make a rail waypoint of the station, convert the map as well. */
00094       TILE_AREA_LOOP(t, train_st) {
00095         if (!IsTileType(t, MP_STATION) || GetStationIndex(t) != index) continue;
00096 
00097         SB(_m[t].m6, 3, 3, STATION_WAYPOINT);
00098         wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
00099       }
00100 
00101       wp->train_station = train_st;
00102       wp->facilities |= FACIL_TRAIN;
00103     } else if (IsBuoyTile(xy) && GetStationIndex(xy) == index) {
00104       wp->rect.BeforeAddTile(xy, StationRect::ADD_FORCE);
00105       wp->facilities |= FACIL_DOCK;
00106     }
00107   }
00108 }
00109 
00110 void AfterLoadStations()
00111 {
00112   /* Update the speclists of all stations to point to the currently loaded custom stations. */
00113   BaseStation *st;
00114   FOR_ALL_BASE_STATIONS(st) {
00115     for (uint i = 0; i < st->num_specs; i++) {
00116       if (st->speclist[i].grfid == 0) continue;
00117 
00118       st->speclist[i].spec = StationClass::GetByGrf(st->speclist[i].grfid, st->speclist[i].localidx, NULL);
00119     }
00120 
00121     if (Station::IsExpected(st)) {
00122       Station *sta = Station::From(st);
00123       for (const RoadStop *rs = sta->bus_stops; rs != NULL; rs = rs->next) sta->bus_station.Add(rs->xy);
00124       for (const RoadStop *rs = sta->truck_stops; rs != NULL; rs = rs->next) sta->truck_station.Add(rs->xy);
00125     }
00126 
00127     StationUpdateAnimTriggers(st);
00128   }
00129 }
00130 
00134 void AfterLoadRoadStops()
00135 {
00136   /* First construct the drive through entries */
00137   RoadStop *rs;
00138   FOR_ALL_ROADSTOPS(rs) {
00139     if (IsDriveThroughStopTile(rs->xy)) rs->MakeDriveThrough();
00140   }
00141   /* And then rebuild the data in those entries */
00142   FOR_ALL_ROADSTOPS(rs) {
00143     if (!HasBit(rs->status, RoadStop::RSSFB_BASE_ENTRY)) continue;
00144 
00145     rs->GetEntry(DIAGDIR_NE)->Rebuild(rs);
00146     rs->GetEntry(DIAGDIR_NW)->Rebuild(rs);
00147   }
00148 }
00149 
00150 static const SaveLoad _roadstop_desc[] = {
00151   SLE_VAR(RoadStop, xy,           SLE_UINT32),
00152   SLE_CONDNULL(1, 0, 44),
00153   SLE_VAR(RoadStop, status,       SLE_UINT8),
00154   /* Index was saved in some versions, but this is not needed */
00155   SLE_CONDNULL(4, 0, 8),
00156   SLE_CONDNULL(2, 0, 44),
00157   SLE_CONDNULL(1, 0, 25),
00158 
00159   SLE_REF(RoadStop, next,         REF_ROADSTOPS),
00160   SLE_CONDNULL(2, 0, 44),
00161 
00162   SLE_CONDNULL(4, 0, 24),
00163   SLE_CONDNULL(1, 25, 25),
00164 
00165   SLE_END()
00166 };
00167 
00168 static const SaveLoad _old_station_desc[] = {
00169   SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
00170   SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
00171   SLE_CONDNULL(4, 0, 5),  
00172   SLE_CONDVAR(Station, train_station.tile,         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
00173   SLE_CONDVAR(Station, train_station.tile,         SLE_UINT32,                  6, SL_MAX_VERSION),
00174   SLE_CONDVAR(Station, airport.tile,               SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
00175   SLE_CONDVAR(Station, airport.tile,               SLE_UINT32,                  6, SL_MAX_VERSION),
00176   SLE_CONDVAR(Station, dock_tile,                  SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
00177   SLE_CONDVAR(Station, dock_tile,                  SLE_UINT32,                  6, SL_MAX_VERSION),
00178       SLE_REF(Station, town,                       REF_TOWN),
00179       SLE_VAR(Station, train_station.w,            SLE_FILE_U8 | SLE_VAR_U16),
00180   SLE_CONDVAR(Station, train_station.h,            SLE_FILE_U8 | SLE_VAR_U16,   2, SL_MAX_VERSION),
00181 
00182   SLE_CONDNULL(1, 0, 3),  
00183 
00184       SLE_VAR(Station, string_id,                  SLE_STRINGID),
00185   SLE_CONDSTR(Station, name,                       SLE_STR | SLF_ALLOW_CONTROL, 0, 84, SL_MAX_VERSION),
00186   SLE_CONDVAR(Station, indtype,                    SLE_UINT8,                 103, SL_MAX_VERSION),
00187   SLE_CONDVAR(Station, had_vehicle_of_type,        SLE_FILE_U16 | SLE_VAR_U8,   0, 121),
00188   SLE_CONDVAR(Station, had_vehicle_of_type,        SLE_UINT8,                 122, SL_MAX_VERSION),
00189 
00190       SLE_VAR(Station, time_since_load,            SLE_UINT8),
00191       SLE_VAR(Station, time_since_unload,          SLE_UINT8),
00192       SLE_VAR(Station, delete_ctr,                 SLE_UINT8),
00193       SLE_VAR(Station, owner,                      SLE_UINT8),
00194       SLE_VAR(Station, facilities,                 SLE_UINT8),
00195       SLE_VAR(Station, airport.type,               SLE_UINT8),
00196 
00197   SLE_CONDNULL(2, 0, 5),  
00198   SLE_CONDNULL(1, 0, 4),  
00199 
00200   SLE_CONDVAR(Station, airport.flags,              SLE_VAR_U64 | SLE_FILE_U16,  0,  2),
00201   SLE_CONDVAR(Station, airport.flags,              SLE_VAR_U64 | SLE_FILE_U32,  3, 45),
00202   SLE_CONDVAR(Station, airport.flags,              SLE_UINT64,                 46, SL_MAX_VERSION),
00203 
00204   SLE_CONDNULL(2, 0, 25), 
00205   SLE_CONDVAR(Station, last_vehicle_type,          SLE_UINT8,                  26, SL_MAX_VERSION),
00206 
00207   SLE_CONDNULL(2, 3, 25), 
00208   SLE_CONDVAR(Station, build_date,                 SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
00209   SLE_CONDVAR(Station, build_date,                 SLE_INT32,                  31, SL_MAX_VERSION),
00210 
00211   SLE_CONDREF(Station, bus_stops,                  REF_ROADSTOPS,               6, SL_MAX_VERSION),
00212   SLE_CONDREF(Station, truck_stops,                REF_ROADSTOPS,               6, SL_MAX_VERSION),
00213 
00214   /* Used by newstations for graphic variations */
00215   SLE_CONDVAR(Station, random_bits,                SLE_UINT16,                 27, SL_MAX_VERSION),
00216   SLE_CONDVAR(Station, waiting_triggers,           SLE_UINT8,                  27, SL_MAX_VERSION),
00217   SLE_CONDVAR(Station, num_specs,                  SLE_UINT8,                  27, SL_MAX_VERSION),
00218 
00219   SLE_CONDLST(Station, loading_vehicles,           REF_VEHICLE,                57, SL_MAX_VERSION),
00220 
00221   /* reserve extra space in savegame here. (currently 32 bytes) */
00222   SLE_CONDNULL(32, 2, SL_MAX_VERSION),
00223 
00224   SLE_END()
00225 };
00226 
00227 static uint16 _waiting_acceptance;
00228 static uint16 _cargo_source;
00229 static uint32 _cargo_source_xy;
00230 static uint16 _cargo_days;
00231 static Money  _cargo_feeder_share;
00232 
00233 static const SaveLoad _station_speclist_desc[] = {
00234   SLE_CONDVAR(StationSpecList, grfid,    SLE_UINT32, 27, SL_MAX_VERSION),
00235   SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8,  27, SL_MAX_VERSION),
00236 
00237   SLE_END()
00238 };
00239 
00245 const SaveLoad *GetGoodsDesc()
00246 {
00247   static const SaveLoad goods_desc[] = {
00248     SLEG_CONDVAR(            _waiting_acceptance, SLE_UINT16,                  0, 67),
00249      SLE_CONDVAR(GoodsEntry, acceptance_pickup,   SLE_UINT8,                  68, SL_MAX_VERSION),
00250     SLE_CONDNULL(2,                                                           51, 67),
00251          SLE_VAR(GoodsEntry, days_since_pickup,   SLE_UINT8),
00252          SLE_VAR(GoodsEntry, rating,              SLE_UINT8),
00253     SLEG_CONDVAR(            _cargo_source,       SLE_FILE_U8 | SLE_VAR_U16,   0, 6),
00254     SLEG_CONDVAR(            _cargo_source,       SLE_UINT16,                  7, 67),
00255     SLEG_CONDVAR(            _cargo_source_xy,    SLE_UINT32,                 44, 67),
00256     SLEG_CONDVAR(            _cargo_days,         SLE_UINT8,                   0, 67),
00257          SLE_VAR(GoodsEntry, last_speed,          SLE_UINT8),
00258          SLE_VAR(GoodsEntry, last_age,            SLE_UINT8),
00259     SLEG_CONDVAR(            _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
00260     SLEG_CONDVAR(            _cargo_feeder_share, SLE_INT64,                  65, 67),
00261      SLE_CONDVAR(GoodsEntry, amount_fract,        SLE_UINT8,                 150, SL_MAX_VERSION),
00262      SLE_CONDLST(GoodsEntry, cargo.packets,       REF_CARGO_PACKET,           68, SL_MAX_VERSION),
00263 
00264     SLE_END()
00265   };
00266 
00267   return goods_desc;
00268 }
00269 
00270 
00271 static void Load_STNS()
00272 {
00273   int index;
00274   while ((index = SlIterateArray()) != -1) {
00275     Station *st = new (index) Station();
00276 
00277     SlObject(st, _old_station_desc);
00278 
00279     _waiting_acceptance = 0;
00280 
00281     uint num_cargo = IsSavegameVersionBefore(55) ? 12 : NUM_CARGO;
00282     for (CargoID i = 0; i < num_cargo; i++) {
00283       GoodsEntry *ge = &st->goods[i];
00284       SlObject(ge, GetGoodsDesc());
00285       if (IsSavegameVersionBefore(68)) {
00286         SB(ge->acceptance_pickup, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
00287         if (GB(_waiting_acceptance, 0, 12) != 0) {
00288           /* In old versions, enroute_from used 0xFF as INVALID_STATION */
00289           StationID source = (IsSavegameVersionBefore(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
00290 
00291           /* Make sure we can allocate the CargoPacket. This is safe
00292            * as there can only be ~64k stations and 32 cargoes in these
00293            * savegame versions. As the CargoPacketPool has more than
00294            * 16 million entries; it fits by an order of magnitude. */
00295           assert(CargoPacket::CanAllocateItem());
00296           ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, source, _cargo_source_xy, _cargo_source_xy, _cargo_feeder_share));
00297           SB(ge->acceptance_pickup, GoodsEntry::GES_PICKUP, 1, 1);
00298         }
00299       }
00300     }
00301 
00302     if (st->num_specs != 0) {
00303       /* Allocate speclist memory when loading a game */
00304       st->speclist = CallocT<StationSpecList>(st->num_specs);
00305       for (uint i = 0; i < st->num_specs; i++) {
00306         SlObject(&st->speclist[i], _station_speclist_desc);
00307       }
00308     }
00309   }
00310 }
00311 
00312 static void Ptrs_STNS()
00313 {
00314   /* Don't run when savegame version is higher than or equal to 123. */
00315   if (!IsSavegameVersionBefore(123)) return;
00316 
00317   Station *st;
00318   FOR_ALL_STATIONS(st) {
00319     if (!IsSavegameVersionBefore(68)) {
00320       for (CargoID i = 0; i < NUM_CARGO; i++) {
00321         GoodsEntry *ge = &st->goods[i];
00322         SlObject(ge, GetGoodsDesc());
00323       }
00324     }
00325     SlObject(st, _old_station_desc);
00326   }
00327 }
00328 
00329 
00330 static const SaveLoad _base_station_desc[] = {
00331         SLE_VAR(BaseStation, xy,                     SLE_UINT32),
00332         SLE_REF(BaseStation, town,                   REF_TOWN),
00333         SLE_VAR(BaseStation, string_id,              SLE_STRINGID),
00334         SLE_STR(BaseStation, name,                   SLE_STR | SLF_ALLOW_CONTROL, 0),
00335         SLE_VAR(BaseStation, delete_ctr,             SLE_UINT8),
00336         SLE_VAR(BaseStation, owner,                  SLE_UINT8),
00337         SLE_VAR(BaseStation, facilities,             SLE_UINT8),
00338         SLE_VAR(BaseStation, build_date,             SLE_INT32),
00339 
00340   /* Used by newstations for graphic variations */
00341         SLE_VAR(BaseStation, random_bits,            SLE_UINT16),
00342         SLE_VAR(BaseStation, waiting_triggers,       SLE_UINT8),
00343         SLE_VAR(BaseStation, num_specs,              SLE_UINT8),
00344 
00345         SLE_END()
00346 };
00347 
00348 static OldPersistentStorage _old_st_persistent_storage;
00349 
00350 static const SaveLoad _station_desc[] = {
00351   SLE_WRITEBYTE(Station, facilities,                 FACIL_NONE),
00352   SLE_ST_INCLUDE(),
00353 
00354         SLE_VAR(Station, train_station.tile,         SLE_UINT32),
00355         SLE_VAR(Station, train_station.w,            SLE_FILE_U8 | SLE_VAR_U16),
00356         SLE_VAR(Station, train_station.h,            SLE_FILE_U8 | SLE_VAR_U16),
00357 
00358         SLE_REF(Station, bus_stops,                  REF_ROADSTOPS),
00359         SLE_REF(Station, truck_stops,                REF_ROADSTOPS),
00360         SLE_VAR(Station, dock_tile,                  SLE_UINT32),
00361         SLE_VAR(Station, airport.tile,               SLE_UINT32),
00362     SLE_CONDVAR(Station, airport.w,                  SLE_FILE_U8 | SLE_VAR_U16, 140, SL_MAX_VERSION),
00363     SLE_CONDVAR(Station, airport.h,                  SLE_FILE_U8 | SLE_VAR_U16, 140, SL_MAX_VERSION),
00364         SLE_VAR(Station, airport.type,               SLE_UINT8),
00365     SLE_CONDVAR(Station, airport.layout,             SLE_UINT8,                 145, SL_MAX_VERSION),
00366         SLE_VAR(Station, airport.flags,              SLE_UINT64),
00367     SLE_CONDVAR(Station, airport.rotation,           SLE_UINT8,                 145, SL_MAX_VERSION),
00368    SLEG_CONDARR(_old_st_persistent_storage.storage,  SLE_UINT32, 16,            145, 160),
00369     SLE_CONDREF(Station, airport.psa,                REF_STORAGE,               161, SL_MAX_VERSION),
00370 
00371         SLE_VAR(Station, indtype,                    SLE_UINT8),
00372 
00373         SLE_VAR(Station, time_since_load,            SLE_UINT8),
00374         SLE_VAR(Station, time_since_unload,          SLE_UINT8),
00375         SLE_VAR(Station, last_vehicle_type,          SLE_UINT8),
00376         SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT8),
00377         SLE_LST(Station, loading_vehicles,           REF_VEHICLE),
00378     SLE_CONDVAR(Station, always_accepted,            SLE_UINT32, 127, SL_MAX_VERSION),
00379 
00380         SLE_END()
00381 };
00382 
00383 static const SaveLoad _waypoint_desc[] = {
00384   SLE_WRITEBYTE(Waypoint, facilities,                FACIL_WAYPOINT),
00385   SLE_ST_INCLUDE(),
00386 
00387         SLE_VAR(Waypoint, town_cn,                   SLE_UINT16),
00388 
00389     SLE_CONDVAR(Waypoint, train_station.tile,        SLE_UINT32,                  124, SL_MAX_VERSION),
00390     SLE_CONDVAR(Waypoint, train_station.w,           SLE_FILE_U8 | SLE_VAR_U16,   124, SL_MAX_VERSION),
00391     SLE_CONDVAR(Waypoint, train_station.h,           SLE_FILE_U8 | SLE_VAR_U16,   124, SL_MAX_VERSION),
00392 
00393         SLE_END()
00394 };
00395 
00400 const SaveLoad *GetBaseStationDescription()
00401 {
00402   return _base_station_desc;
00403 }
00404 
00405 static void RealSave_STNN(BaseStation *bst)
00406 {
00407   bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0;
00408   SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
00409 
00410   if (!waypoint) {
00411     Station *st = Station::From(bst);
00412     for (CargoID i = 0; i < NUM_CARGO; i++) {
00413       SlObject(&st->goods[i], GetGoodsDesc());
00414     }
00415   }
00416 
00417   for (uint i = 0; i < bst->num_specs; i++) {
00418     SlObject(&bst->speclist[i], _station_speclist_desc);
00419   }
00420 }
00421 
00422 static void Save_STNN()
00423 {
00424   BaseStation *st;
00425   /* Write the stations */
00426   FOR_ALL_BASE_STATIONS(st) {
00427     SlSetArrayIndex(st->index);
00428     SlAutolength((AutolengthProc*)RealSave_STNN, st);
00429   }
00430 }
00431 
00432 static void Load_STNN()
00433 {
00434   int index;
00435 
00436   while ((index = SlIterateArray()) != -1) {
00437     bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
00438 
00439     BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
00440     SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
00441 
00442     if (!waypoint) {
00443       Station *st = Station::From(bst);
00444 
00445       /* Before savegame version 161, persistent storages were not stored in a pool. */
00446       if (IsSavegameVersionBefore(161) && !IsSavegameVersionBefore(145) && st->facilities & FACIL_AIRPORT) {
00447         /* Store the old persistent storage. The GRFID will be added later. */
00448         assert(PersistentStorage::CanAllocateItem());
00449         st->airport.psa = new PersistentStorage(0);
00450         memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(st->airport.psa->storage));
00451       }
00452 
00453       for (CargoID i = 0; i < NUM_CARGO; i++) {
00454         SlObject(&st->goods[i], GetGoodsDesc());
00455       }
00456     }
00457 
00458     if (bst->num_specs != 0) {
00459       /* Allocate speclist memory when loading a game */
00460       bst->speclist = CallocT<StationSpecList>(bst->num_specs);
00461       for (uint i = 0; i < bst->num_specs; i++) {
00462         SlObject(&bst->speclist[i], _station_speclist_desc);
00463       }
00464     }
00465   }
00466 }
00467 
00468 static void Ptrs_STNN()
00469 {
00470   /* Don't run when savegame version lower than 123. */
00471   if (IsSavegameVersionBefore(123)) return;
00472 
00473   Station *st;
00474   FOR_ALL_STATIONS(st) {
00475     for (CargoID i = 0; i < NUM_CARGO; i++) {
00476       GoodsEntry *ge = &st->goods[i];
00477       SlObject(ge, GetGoodsDesc());
00478     }
00479     SlObject(st, _station_desc);
00480   }
00481 
00482   Waypoint *wp;
00483   FOR_ALL_WAYPOINTS(wp) {
00484     SlObject(wp, _waypoint_desc);
00485   }
00486 }
00487 
00488 static void Save_ROADSTOP()
00489 {
00490   RoadStop *rs;
00491 
00492   FOR_ALL_ROADSTOPS(rs) {
00493     SlSetArrayIndex(rs->index);
00494     SlObject(rs, _roadstop_desc);
00495   }
00496 }
00497 
00498 static void Load_ROADSTOP()
00499 {
00500   int index;
00501 
00502   while ((index = SlIterateArray()) != -1) {
00503     RoadStop *rs = new (index) RoadStop(INVALID_TILE);
00504 
00505     SlObject(rs, _roadstop_desc);
00506   }
00507 }
00508 
00509 static void Ptrs_ROADSTOP()
00510 {
00511   RoadStop *rs;
00512   FOR_ALL_ROADSTOPS(rs) {
00513     SlObject(rs, _roadstop_desc);
00514   }
00515 }
00516 
00517 extern const ChunkHandler _station_chunk_handlers[] = {
00518   { 'STNS', NULL,          Load_STNS,     Ptrs_STNS,     NULL, CH_ARRAY },
00519   { 'STNN', Save_STNN,     Load_STNN,     Ptrs_STNN,     NULL, CH_ARRAY },
00520   { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, NULL, CH_ARRAY | CH_LAST},
00521 };