branch | gamebalance |
changeset 9895 | 7bd07f43b0e3 |
parent 6527 | f584ab6d87f8 |
child 9903 | dc85aaa556ae |
9894:70d78ac95d6c | 9895:7bd07f43b0e3 |
---|---|
328 SetDParam(1, st->facilities); |
328 SetDParam(1, st->facilities); |
329 UpdateViewportSignPos(&st->sign, pt.x, pt.y, STR_305C_0); |
329 UpdateViewportSignPos(&st->sign, pt.x, pt.y, STR_305C_0); |
330 } |
330 } |
331 |
331 |
332 // Update the virtual coords needed to draw the station sign for all stations. |
332 // Update the virtual coords needed to draw the station sign for all stations. |
333 void UpdateAllStationVirtCoord(void) |
333 void UpdateAllStationVirtCoord() |
334 { |
334 { |
335 Station* st; |
335 Station* st; |
336 |
336 |
337 FOR_ALL_STATIONS(st) { |
337 FOR_ALL_STATIONS(st) { |
338 UpdateStationVirtCoord(st); |
338 UpdateStationVirtCoord(st); |
447 } |
447 } |
448 } |
448 } |
449 } |
449 } |
450 } |
450 } |
451 |
451 |
452 typedef struct ottd_Rectangle { |
452 struct ottd_Rectangle { |
453 uint min_x; |
453 uint min_x; |
454 uint min_y; |
454 uint min_y; |
455 uint max_x; |
455 uint max_x; |
456 uint max_y; |
456 uint max_y; |
457 } ottd_Rectangle; |
457 }; |
458 |
458 |
459 static inline void MergePoint(ottd_Rectangle* rect, TileIndex tile) |
459 static inline void MergePoint(ottd_Rectangle* rect, TileIndex tile) |
460 { |
460 { |
461 uint x = TileX(tile); |
461 uint x = TileX(tile); |
462 uint y = TileY(tile); |
462 uint y = TileY(tile); |
527 // Adjust in case our station only accepts fewer kinds of goods |
527 // Adjust in case our station only accepts fewer kinds of goods |
528 for (uint i = 0; i != NUM_CARGO; i++) { |
528 for (uint i = 0; i != NUM_CARGO; i++) { |
529 uint amt = min(accepts[i], 15); |
529 uint amt = min(accepts[i], 15); |
530 |
530 |
531 // Make sure the station can accept the goods type. |
531 // Make sure the station can accept the goods type. |
532 if ((i != CT_PASSENGERS && !(st->facilities & (byte)~FACIL_BUS_STOP)) || |
532 bool is_passengers = IsCargoInClass(i, CC_PASSENGERS); |
533 (i == CT_PASSENGERS && !(st->facilities & (byte)~FACIL_TRUCK_STOP))) |
533 if ((!is_passengers && !(st->facilities & (byte)~FACIL_BUS_STOP)) || |
534 (is_passengers && !(st->facilities & (byte)~FACIL_TRUCK_STOP))) |
|
534 amt = 0; |
535 amt = 0; |
535 |
536 |
536 SB(st->goods[i].waiting_acceptance, 12, 4, amt); |
537 SB(st->goods[i].waiting_acceptance, 12, 4, amt); |
537 } |
538 } |
538 |
539 |
1399 }; |
1400 }; |
1400 |
1401 |
1401 // Intercontinental Airport (vlarge) - 4 runways |
1402 // Intercontinental Airport (vlarge) - 4 runways |
1402 static const byte _airport_sections_intercontinental[] = { |
1403 static const byte _airport_sections_intercontinental[] = { |
1403 102, 120, 89, 89, 89, 89, 89, 89, 118, |
1404 102, 120, 89, 89, 89, 89, 89, 89, 118, |
1404 120, 22, 22, 22, 22, 22, 22, 119, 117, |
1405 120, 23, 23, 23, 23, 23, 23, 119, 117, |
1405 87, 54, 87, 8, 8, 8, 8, 51, 117, |
1406 87, 54, 87, 8, 8, 8, 8, 51, 117, |
1406 87, 162, 87, 85, 116, 116, 8, 9, 10, |
1407 87, 162, 87, 85, 116, 116, 8, 9, 10, |
1407 87, 8, 8, 11, 31, 11, 8, 160, 32, |
1408 87, 8, 8, 11, 31, 11, 8, 160, 32, |
1408 32, 160, 8, 11, 27, 11, 8, 8, 10, |
1409 32, 160, 8, 11, 27, 11, 8, 8, 10, |
1409 87, 8, 8, 11, 30, 11, 8, 8, 10, |
1410 87, 8, 8, 11, 30, 11, 8, 8, 10, |
1410 87, 142, 8, 11, 29, 11, 10, 163, 10, |
1411 87, 142, 8, 11, 29, 11, 10, 163, 10, |
1411 87, 164, 87, 8, 8, 8, 10, 37, 117, |
1412 87, 164, 87, 8, 8, 8, 10, 37, 117, |
1412 87, 120, 89, 89, 89, 89, 89, 89, 119, |
1413 87, 120, 89, 89, 89, 89, 89, 89, 119, |
1413 121, 22, 22, 22, 22, 22, 22, 119, 37 |
1414 121, 23, 23, 23, 23, 23, 23, 119, 37 |
1414 }; |
1415 }; |
1415 |
1416 |
1416 |
1417 |
1417 // Commuter Airfield (small) |
1418 // Commuter Airfield (small) |
1418 static const byte _airport_sections_commuter[] = { |
1419 static const byte _airport_sections_commuter[] = { |
1627 int32 CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1628 int32 CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1628 { |
1629 { |
1629 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
1630 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
1630 |
1631 |
1631 if (!IsClearWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE); |
1632 if (!IsClearWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE); |
1633 if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
|
1632 |
1634 |
1633 /* allocate and initialize new station */ |
1635 /* allocate and initialize new station */ |
1634 Station *st = new Station(tile); |
1636 Station *st = new Station(tile); |
1635 if (st == NULL) return CMD_ERROR; |
1637 if (st == NULL) return CMD_ERROR; |
1636 |
1638 |
1668 /* Checks if any ship is servicing the buoy specified. Returns yes or no */ |
1670 /* Checks if any ship is servicing the buoy specified. Returns yes or no */ |
1669 static bool CheckShipsOnBuoy(Station *st) |
1671 static bool CheckShipsOnBuoy(Station *st) |
1670 { |
1672 { |
1671 const Vehicle *v; |
1673 const Vehicle *v; |
1672 FOR_ALL_VEHICLES(v) { |
1674 FOR_ALL_VEHICLES(v) { |
1673 if (v->type == VEH_Ship) { |
1675 if (v->type == VEH_SHIP) { |
1674 const Order *order; |
1676 const Order *order; |
1675 FOR_VEHICLE_ORDERS(v, order) { |
1677 FOR_VEHICLE_ORDERS(v, order) { |
1676 if (order->type == OT_GOTO_STATION && order->dest == st->index) { |
1678 if (order->type == OT_GOTO_STATION && order->dest == st->index) { |
1677 return true; |
1679 return true; |
1678 } |
1680 } |
1746 default: return_cmd_error(STR_304B_SITE_UNSUITABLE); |
1748 default: return_cmd_error(STR_304B_SITE_UNSUITABLE); |
1747 } |
1749 } |
1748 |
1750 |
1749 if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR; |
1751 if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR; |
1750 |
1752 |
1753 if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
|
1754 |
|
1751 cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
1755 cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
1752 if (CmdFailed(cost)) return CMD_ERROR; |
1756 if (CmdFailed(cost)) return CMD_ERROR; |
1753 |
1757 |
1754 TileIndex tile_cur = tile + TileOffsByDiagDir(direction); |
1758 TileIndex tile_cur = tile + TileOffsByDiagDir(direction); |
1755 |
1759 |
1756 if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) { |
1760 if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) { |
1757 return_cmd_error(STR_304B_SITE_UNSUITABLE); |
1761 return_cmd_error(STR_304B_SITE_UNSUITABLE); |
1758 } |
1762 } |
1763 |
|
1764 if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
|
1759 |
1765 |
1760 cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
1766 cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
1761 if (CmdFailed(cost)) return CMD_ERROR; |
1767 if (CmdFailed(cost)) return CMD_ERROR; |
1762 |
1768 |
1763 tile_cur += TileOffsByDiagDir(direction); |
1769 tile_cur += TileOffsByDiagDir(direction); |
2069 } |
2075 } |
2070 |
2076 |
2071 |
2077 |
2072 static void AnimateTile_Station(TileIndex tile) |
2078 static void AnimateTile_Station(TileIndex tile) |
2073 { |
2079 { |
2074 typedef struct AnimData { |
2080 struct AnimData { |
2075 StationGfx from; // first sprite |
2081 StationGfx from; // first sprite |
2076 StationGfx to; // last sprite |
2082 StationGfx to; // last sprite |
2077 byte delay; |
2083 byte delay; |
2078 } AnimData; |
2084 }; |
2079 |
2085 |
2080 static const AnimData data[] = { |
2086 static const AnimData data[] = { |
2081 { GFX_RADAR_LARGE_FIRST, GFX_RADAR_LARGE_LAST, 3 }, |
2087 { GFX_RADAR_LARGE_FIRST, GFX_RADAR_LARGE_LAST, 3 }, |
2082 { GFX_WINDSACK_FIRST, GFX_WINDSACK_LAST, 1 }, |
2088 { GFX_WINDSACK_FIRST, GFX_WINDSACK_LAST, 1 }, |
2083 { GFX_RADAR_INTERNATIONAL_FIRST, GFX_RADAR_INTERNATIONAL_LAST, 3 }, |
2089 { GFX_RADAR_INTERNATIONAL_FIRST, GFX_RADAR_INTERNATIONAL_LAST, 3 }, |
2101 |
2107 |
2102 |
2108 |
2103 static void ClickTile_Station(TileIndex tile) |
2109 static void ClickTile_Station(TileIndex tile) |
2104 { |
2110 { |
2105 if (IsHangar(tile)) { |
2111 if (IsHangar(tile)) { |
2106 ShowDepotWindow(tile, VEH_Aircraft); |
2112 ShowDepotWindow(tile, VEH_AIRCRAFT); |
2107 } else { |
2113 } else { |
2108 ShowStationViewWindow(GetStationIndex(tile)); |
2114 ShowStationViewWindow(GetStationIndex(tile)); |
2109 } |
2115 } |
2110 } |
2116 } |
2111 |
2117 |
2113 215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0 |
2119 215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0 |
2114 }; |
2120 }; |
2115 |
2121 |
2116 static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y) |
2122 static uint32 VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y) |
2117 { |
2123 { |
2118 if (v->type == VEH_Train) { |
2124 if (v->type == VEH_TRAIN) { |
2119 if (IsRailwayStation(tile) && IsFrontEngine(v) && |
2125 if (IsRailwayStation(tile) && IsFrontEngine(v) && |
2120 !IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) { |
2126 !IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) { |
2121 StationID station_id = GetStationIndex(tile); |
2127 StationID station_id = GetStationIndex(tile); |
2122 |
2128 |
2123 if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) || |
2129 if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) || |
2143 } |
2149 } |
2144 } |
2150 } |
2145 } |
2151 } |
2146 } |
2152 } |
2147 } |
2153 } |
2148 } else if (v->type == VEH_Road) { |
2154 } else if (v->type == VEH_ROAD) { |
2149 if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) { |
2155 if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) { |
2150 if (IsRoadStop(tile)) { |
2156 if (IsRoadStop(tile)) { |
2151 /* Attempt to allocate a parking bay in a road stop */ |
2157 /* Attempt to allocate a parking bay in a road stop */ |
2152 RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile)); |
2158 RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile)); |
2153 |
2159 |
2156 byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1; |
2162 byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1; |
2157 |
2163 |
2158 if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER; |
2164 if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER; |
2159 |
2165 |
2160 /* Check if the vehicle is stopping at this road stop */ |
2166 /* Check if the vehicle is stopping at this road stop */ |
2161 if (GetRoadStopType(tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) && |
2167 if (GetRoadStopType(tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) && |
2162 v->current_order.dest == GetStationIndex(tile)) { |
2168 v->current_order.dest == GetStationIndex(tile)) { |
2163 SETBIT(v->u.road.state, RVS_IS_STOPPING); |
2169 SETBIT(v->u.road.state, RVS_IS_STOPPING); |
2164 rs->AllocateDriveThroughBay(side); |
2170 rs->AllocateDriveThroughBay(side); |
2165 } |
2171 } |
2166 |
2172 |
2208 byte_inc_sat(&st->time_since_load); |
2214 byte_inc_sat(&st->time_since_load); |
2209 byte_inc_sat(&st->time_since_unload); |
2215 byte_inc_sat(&st->time_since_unload); |
2210 |
2216 |
2211 GoodsEntry *ge = st->goods; |
2217 GoodsEntry *ge = st->goods; |
2212 do { |
2218 do { |
2219 /* Slowly increase the rating back to his original level in the case we |
|
2220 * didn't deliver cargo yet to this station. This happens when a bribe |
|
2221 * failed while you didn't moved that cargo yet to a station. */ |
|
2222 if (ge->enroute_from == INVALID_STATION && ge->rating < INITIAL_STATION_RATING) |
|
2223 ge->rating++; |
|
2224 /* Only change the rating if we are moving this cargo */ |
|
2213 if (ge->enroute_from != INVALID_STATION) { |
2225 if (ge->enroute_from != INVALID_STATION) { |
2214 byte_inc_sat(&ge->enroute_time); |
2226 byte_inc_sat(&ge->enroute_time); |
2215 byte_inc_sat(&ge->days_since_pickup); |
2227 byte_inc_sat(&ge->days_since_pickup); |
2216 |
2228 |
2217 int rating = 0; |
2229 int rating = 0; |
2232 |
2244 |
2233 if (IsValidPlayer(st->owner) && HASBIT(st->town->statues, st->owner)) rating += 26; |
2245 if (IsValidPlayer(st->owner) && HASBIT(st->town->statues, st->owner)) rating += 26; |
2234 |
2246 |
2235 { |
2247 { |
2236 byte days = ge->days_since_pickup; |
2248 byte days = ge->days_since_pickup; |
2237 if (st->last_vehicle_type == VEH_Ship) |
2249 if (st->last_vehicle_type == VEH_SHIP) |
2238 days >>= 2; |
2250 days >>= 2; |
2239 (days > 21) || |
2251 (days > 21) || |
2240 (rating += 25, days > 12) || |
2252 (rating += 25, days > 12) || |
2241 (rating += 25, days > 6) || |
2253 (rating += 25, days > 6) || |
2242 (rating += 45, days > 3) || |
2254 (rating += 45, days > 3) || |
2297 st->delete_ctr = b; |
2309 st->delete_ctr = b; |
2298 |
2310 |
2299 if (b == 0) UpdateStationRating(st); |
2311 if (b == 0) UpdateStationRating(st); |
2300 } |
2312 } |
2301 |
2313 |
2302 void OnTick_Station(void) |
2314 void OnTick_Station() |
2303 { |
2315 { |
2304 if (_game_mode == GM_EDITOR) return; |
2316 if (_game_mode == GM_EDITOR) return; |
2305 |
2317 |
2306 uint i = _station_tick_ctr; |
2318 uint i = _station_tick_ctr; |
2307 if (++_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0; |
2319 if (++_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0; |
2310 |
2322 |
2311 Station *st; |
2323 Station *st; |
2312 FOR_ALL_STATIONS(st) StationHandleSmallTick(st); |
2324 FOR_ALL_STATIONS(st) StationHandleSmallTick(st); |
2313 } |
2325 } |
2314 |
2326 |
2315 void StationMonthlyLoop(void) |
2327 void StationMonthlyLoop() |
2316 { |
2328 { |
2317 } |
2329 } |
2318 |
2330 |
2319 |
2331 |
2320 void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius) |
2332 void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius) |
2412 if (around[i] == NULL) { |
2424 if (around[i] == NULL) { |
2413 if (!st->IsBuoy() && |
2425 if (!st->IsBuoy() && |
2414 (st->town->exclusive_counter == 0 || st->town->exclusivity == st->owner) && // check exclusive transport rights |
2426 (st->town->exclusive_counter == 0 || st->town->exclusivity == st->owner) && // check exclusive transport rights |
2415 st->goods[type].rating != 0 && |
2427 st->goods[type].rating != 0 && |
2416 (!_patches.selectgoods || st->goods[type].last_speed > 0) && // if last_speed is 0, no vehicle has been there. |
2428 (!_patches.selectgoods || st->goods[type].last_speed > 0) && // if last_speed is 0, no vehicle has been there. |
2417 ((st->facilities & ~FACIL_BUS_STOP) != 0 || type == CT_PASSENGERS) && // if we have other fac. than a bus stop, or the cargo is passengers |
2429 ((st->facilities & ~FACIL_BUS_STOP) != 0 || IsCargoInClass(type, CC_PASSENGERS)) && // if we have other fac. than a bus stop, or the cargo is passengers |
2418 ((st->facilities & ~FACIL_TRUCK_STOP) != 0 || type != CT_PASSENGERS)) { // if we have other fac. than a cargo bay or the cargo is not passengers |
2430 ((st->facilities & ~FACIL_TRUCK_STOP) != 0 || !IsCargoInClass(type, CC_PASSENGERS))) { // if we have other fac. than a cargo bay or the cargo is not passengers |
2419 if (_patches.modified_catchment) { |
2431 if (_patches.modified_catchment) { |
2420 // min and max coordinates of the producer relative |
2432 // min and max coordinates of the producer relative |
2421 const int x_min_prod = 9; |
2433 const int x_min_prod = 9; |
2422 const int x_max_prod = 8 + w_prod; |
2434 const int x_max_prod = 8 + w_prod; |
2423 const int y_min_prod = 9; |
2435 const int y_min_prod = 9; |
2535 st->train_tile = 0; |
2547 st->train_tile = 0; |
2536 st->had_vehicle_of_type = 0; |
2548 st->had_vehicle_of_type = 0; |
2537 st->time_since_load = 255; |
2549 st->time_since_load = 255; |
2538 st->time_since_unload = 255; |
2550 st->time_since_unload = 255; |
2539 st->delete_ctr = 0; |
2551 st->delete_ctr = 0; |
2540 st->last_vehicle_type = VEH_Invalid; |
2552 st->last_vehicle_type = VEH_INVALID; |
2541 st->facilities = FACIL_AIRPORT | FACIL_DOCK; |
2553 st->facilities = FACIL_AIRPORT | FACIL_DOCK; |
2542 st->build_date = _date; |
2554 st->build_date = _date; |
2543 |
2555 |
2544 for (uint j = 0; j != NUM_CARGO; j++) { |
2556 for (uint j = 0; j != NUM_CARGO; j++) { |
2545 st->goods[j].waiting_acceptance = 0; |
2557 st->goods[j].waiting_acceptance = 0; |
2546 st->goods[j].days_since_pickup = 0; |
2558 st->goods[j].days_since_pickup = 0; |
2547 st->goods[j].enroute_from = INVALID_STATION; |
2559 st->goods[j].enroute_from = INVALID_STATION; |
2548 st->goods[j].enroute_from_xy = INVALID_TILE; |
2560 st->goods[j].enroute_from_xy = INVALID_TILE; |
2549 st->goods[j].rating = 175; |
2561 st->goods[j].rating = INITIAL_STATION_RATING; |
2550 st->goods[j].last_speed = 0; |
2562 st->goods[j].last_speed = 0; |
2551 st->goods[j].last_age = 255; |
2563 st->goods[j].last_age = 255; |
2552 } |
2564 } |
2553 |
2565 |
2554 UpdateStationVirtCoordDirty(st); |
2566 UpdateStationVirtCoordDirty(st); |
2641 } |
2653 } |
2642 |
2654 |
2643 return CMD_ERROR; |
2655 return CMD_ERROR; |
2644 } |
2656 } |
2645 |
2657 |
2646 void InitializeStations(void) |
2658 void InitializeStations() |
2647 { |
2659 { |
2648 /* Clean the station pool and create 1 block in it */ |
2660 /* Clean the station pool and create 1 block in it */ |
2649 CleanPool(&_Station_pool); |
2661 CleanPool(&_Station_pool); |
2650 AddBlockToPool(&_Station_pool); |
2662 AddBlockToPool(&_Station_pool); |
2651 |
2663 |
2656 _station_tick_ctr = 0; |
2668 _station_tick_ctr = 0; |
2657 |
2669 |
2658 } |
2670 } |
2659 |
2671 |
2660 |
2672 |
2661 void AfterLoadStations(void) |
2673 void AfterLoadStations() |
2662 { |
2674 { |
2663 /* Update the speclists of all stations to point to the currently loaded custom stations. */ |
2675 /* Update the speclists of all stations to point to the currently loaded custom stations. */ |
2664 Station *st; |
2676 Station *st; |
2665 FOR_ALL_STATIONS(st) { |
2677 FOR_ALL_STATIONS(st) { |
2666 for (uint i = 0; i < st->num_specs; i++) { |
2678 for (uint i = 0; i < st->num_specs; i++) { |
2789 static void SaveLoad_STNS(Station *st) |
2801 static void SaveLoad_STNS(Station *st) |
2790 { |
2802 { |
2791 SlObject(st, _station_desc); |
2803 SlObject(st, _station_desc); |
2792 for (uint i = 0; i != NUM_CARGO; i++) { |
2804 for (uint i = 0; i != NUM_CARGO; i++) { |
2793 SlObject(&st->goods[i], _goods_desc); |
2805 SlObject(&st->goods[i], _goods_desc); |
2794 |
|
2795 /* In older versions, enroute_from had 0xFF as INVALID_STATION, is now 0xFFFF */ |
|
2796 if (CheckSavegameVersion(7) && st->goods[i].enroute_from == 0xFF) { |
|
2797 st->goods[i].enroute_from = INVALID_STATION; |
|
2798 } |
|
2799 if (CheckSavegameVersion(44)) { |
|
2800 /* Store position of the station where the goods come from, so there are no |
|
2801 * very high payments when stations get removed. However, if the station |
|
2802 * where the goods came from is already removed, the source information is |
|
2803 * lost. In that case we set it to the position of this station */ |
|
2804 st->goods[i].enroute_from_xy = IsValidStationID(st->goods[i].enroute_from) ? GetStation(st->goods[i].enroute_from)->xy : st->xy; |
|
2805 } |
|
2806 } |
2806 } |
2807 |
2807 |
2808 if (st->num_specs != 0) { |
2808 if (st->num_specs != 0) { |
2809 /* Allocate speclist memory when loading a game */ |
2809 /* Allocate speclist memory when loading a game */ |
2810 if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs); |
2810 if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs); |
2812 SlObject(&st->speclist[i], _station_speclist_desc); |
2812 SlObject(&st->speclist[i], _station_speclist_desc); |
2813 } |
2813 } |
2814 } |
2814 } |
2815 } |
2815 } |
2816 |
2816 |
2817 static void Save_STNS(void) |
2817 static void Save_STNS() |
2818 { |
2818 { |
2819 Station *st; |
2819 Station *st; |
2820 // Write the stations |
2820 // Write the stations |
2821 FOR_ALL_STATIONS(st) { |
2821 FOR_ALL_STATIONS(st) { |
2822 SlSetArrayIndex(st->index); |
2822 SlSetArrayIndex(st->index); |
2823 SlAutolength((AutolengthProc*)SaveLoad_STNS, st); |
2823 SlAutolength((AutolengthProc*)SaveLoad_STNS, st); |
2824 } |
2824 } |
2825 } |
2825 } |
2826 |
2826 |
2827 static void Load_STNS(void) |
2827 static void Load_STNS() |
2828 { |
2828 { |
2829 int index; |
2829 int index; |
2830 while ((index = SlIterateArray()) != -1) { |
2830 while ((index = SlIterateArray()) != -1) { |
2831 Station *st = new (index) Station(); |
2831 Station *st = new (index) Station(); |
2832 |
2832 |
2845 |
2845 |
2846 /* This is to ensure all pointers are within the limits of _stations_size */ |
2846 /* This is to ensure all pointers are within the limits of _stations_size */ |
2847 if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0; |
2847 if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0; |
2848 } |
2848 } |
2849 |
2849 |
2850 static void Save_ROADSTOP(void) |
2850 static void Save_ROADSTOP() |
2851 { |
2851 { |
2852 RoadStop *rs; |
2852 RoadStop *rs; |
2853 |
2853 |
2854 FOR_ALL_ROADSTOPS(rs) { |
2854 FOR_ALL_ROADSTOPS(rs) { |
2855 SlSetArrayIndex(rs->index); |
2855 SlSetArrayIndex(rs->index); |
2856 SlObject(rs, _roadstop_desc); |
2856 SlObject(rs, _roadstop_desc); |
2857 } |
2857 } |
2858 } |
2858 } |
2859 |
2859 |
2860 static void Load_ROADSTOP(void) |
2860 static void Load_ROADSTOP() |
2861 { |
2861 { |
2862 int index; |
2862 int index; |
2863 |
2863 |
2864 while ((index = SlIterateArray()) != -1) { |
2864 while ((index = SlIterateArray()) != -1) { |
2865 RoadStop *rs = new (index) RoadStop(INVALID_TILE); |
2865 RoadStop *rs = new (index) RoadStop(INVALID_TILE); |