75 DEFINE_OLD_POOL(RoadStop, RoadStop, RoadStopPoolNewBlock, NULL) |
75 DEFINE_OLD_POOL(RoadStop, RoadStop, RoadStopPoolNewBlock, NULL) |
76 |
76 |
77 |
77 |
78 extern void UpdateAirplanesOnNewStation(Station *st); |
78 extern void UpdateAirplanesOnNewStation(Station *st); |
79 |
79 |
80 static void InitializeRoadStop(RoadStop *road_stop, RoadStop *previous, TileIndex tile, StationID index) |
|
81 { |
|
82 road_stop->xy = tile; |
|
83 road_stop->used = true; |
|
84 road_stop->status = 3; //stop is free |
|
85 road_stop->next = NULL; |
|
86 road_stop->prev = previous; |
|
87 road_stop->station = index; |
|
88 road_stop->num_vehicles = 0; |
|
89 } |
|
90 |
80 |
91 RoadStop* GetPrimaryRoadStop(const Station* st, RoadStopType type) |
81 RoadStop* GetPrimaryRoadStop(const Station* st, RoadStopType type) |
92 { |
82 { |
93 switch (type) { |
83 switch (type) { |
94 case RS_BUS: return st->bus_stops; |
84 case RS_BUS: return st->bus_stops; |
120 for (rs = GetPrimaryRoadStop(st, type); rs != NULL; rs = rs->next) num++; |
110 for (rs = GetPrimaryRoadStop(st, type); rs != NULL; rs = rs->next) num++; |
121 |
111 |
122 return num; |
112 return num; |
123 } |
113 } |
124 |
114 |
125 RoadStop *AllocateRoadStop(void) |
|
126 { |
|
127 RoadStop *rs; |
|
128 |
|
129 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
130 * TODO - This is just a temporary stage, this will be removed. */ |
|
131 for (rs = GetRoadStop(0); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) { |
|
132 if (!IsValidRoadStop(rs)) { |
|
133 RoadStopID index = rs->index; |
|
134 |
|
135 memset(rs, 0, sizeof(*rs)); |
|
136 rs->index = index; |
|
137 |
|
138 return rs; |
|
139 } |
|
140 } |
|
141 |
|
142 /* Check if we can add a block to the pool */ |
|
143 if (AddBlockToPool(&_RoadStop_pool)) return AllocateRoadStop(); |
|
144 |
|
145 return NULL; |
|
146 } |
|
147 |
115 |
148 /* Calculate the radius of the station. Basicly it is the biggest |
116 /* Calculate the radius of the station. Basicly it is the biggest |
149 * radius that is available within the station */ |
117 * radius that is available within the station */ |
150 static uint FindCatchmentRadius(const Station* st) |
118 static uint FindCatchmentRadius(const Station* st) |
151 { |
119 { |
1391 st = GetClosestStationFromTile(tile, 8, _current_player); |
1359 st = GetClosestStationFromTile(tile, 8, _current_player); |
1392 if (st != NULL && st->facilities != 0) st = NULL; |
1360 if (st != NULL && st->facilities != 0) st = NULL; |
1393 } |
1361 } |
1394 |
1362 |
1395 //give us a road stop in the list, and check if something went wrong |
1363 //give us a road stop in the list, and check if something went wrong |
1396 road_stop = AllocateRoadStop(); |
1364 road_stop = new RoadStop(tile, INVALID_STATION); |
1397 if (road_stop == NULL) { |
1365 if (road_stop == NULL) { |
1398 return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS); |
1366 return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS); |
1399 } |
1367 } |
1400 |
1368 |
1401 if (st != NULL && |
1369 if (st != NULL && |
1441 if (flags & DC_EXEC) { |
1409 if (flags & DC_EXEC) { |
1442 //point to the correct item in the _busstops or _truckstops array |
1410 //point to the correct item in the _busstops or _truckstops array |
1443 *currstop = road_stop; |
1411 *currstop = road_stop; |
1444 |
1412 |
1445 //initialize an empty station |
1413 //initialize an empty station |
1446 InitializeRoadStop(road_stop, prev, tile, st->index); |
1414 road_stop->prev = prev; |
|
1415 road_stop->station = st->index; |
1447 if (!st->facilities) st->xy = tile; |
1416 if (!st->facilities) st->xy = tile; |
1448 st->facilities |= (type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP; |
1417 st->facilities |= (type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP; |
1449 st->owner = _current_player; |
1418 st->owner = _current_player; |
1450 |
1419 |
1451 st->build_date = _date; |
1420 st->build_date = _date; |
1497 //removed the first stop in the list |
1466 //removed the first stop in the list |
1498 //need to set the primary element to the next stop |
1467 //need to set the primary element to the next stop |
1499 *primary_stop = (*primary_stop)->next; |
1468 *primary_stop = (*primary_stop)->next; |
1500 } |
1469 } |
1501 |
1470 |
1502 DeleteRoadStop(cur_stop); |
1471 delete cur_stop; |
1503 DoClearSquare(tile); |
1472 DoClearSquare(tile); |
1504 st->rect.AfterRemoveTile(st, tile); |
1473 st->rect.AfterRemoveTile(st, tile); |
1505 |
1474 |
1506 UpdateStationVirtCoordDirty(st); |
1475 UpdateStationVirtCoordDirty(st); |
1507 DeleteStationIfEmpty(st); |
1476 DeleteStationIfEmpty(st); |
2352 } |
2321 } |
2353 } |
2322 } |
2354 } |
2323 } |
2355 |
2324 |
2356 return 0; |
2325 return 0; |
2357 } |
|
2358 |
|
2359 /** |
|
2360 * Cleanup a RoadStop. Make sure no vehicles try to go to this roadstop. |
|
2361 */ |
|
2362 void DestroyRoadStop(RoadStop* rs) |
|
2363 { |
|
2364 Vehicle *v; |
|
2365 |
|
2366 /* Clear the slot assignment of all vehicles heading for this road stop */ |
|
2367 if (rs->num_vehicles != 0) { |
|
2368 FOR_ALL_VEHICLES(v) { |
|
2369 if (v->type == VEH_Road && v->u.road.slot == rs) { |
|
2370 ClearSlot(v); |
|
2371 } |
|
2372 } |
|
2373 } |
|
2374 assert(rs->num_vehicles == 0); |
|
2375 |
|
2376 if (rs->prev != NULL) rs->prev->next = rs->next; |
|
2377 if (rs->next != NULL) rs->next->prev = rs->prev; |
|
2378 } |
2326 } |
2379 |
2327 |
2380 |
2328 |
2381 void DeleteAllPlayerStations(void) |
2329 void DeleteAllPlayerStations(void) |
2382 { |
2330 { |
3057 |
3005 |
3058 /* In older versions, we had just 1 tile for a bus/lorry, now we have more.. |
3006 /* In older versions, we had just 1 tile for a bus/lorry, now we have more.. |
3059 * convert, if needed */ |
3007 * convert, if needed */ |
3060 if (CheckSavegameVersion(6)) { |
3008 if (CheckSavegameVersion(6)) { |
3061 if (st->bus_tile_obsolete != 0) { |
3009 if (st->bus_tile_obsolete != 0) { |
3062 st->bus_stops = AllocateRoadStop(); |
3010 st->bus_stops = new RoadStop(st->bus_tile_obsolete, st->index); |
3063 if (st->bus_stops == NULL) |
3011 if (st->bus_stops == NULL) |
3064 error("Station: too many busstations in savegame"); |
3012 error("Station: too many busstations in savegame"); |
3065 |
3013 |
3066 InitializeRoadStop(st->bus_stops, NULL, st->bus_tile_obsolete, st->index); |
|
3067 } |
3014 } |
3068 if (st->lorry_tile_obsolete != 0) { |
3015 if (st->lorry_tile_obsolete != 0) { |
3069 st->truck_stops = AllocateRoadStop(); |
3016 st->truck_stops = new RoadStop(st->lorry_tile_obsolete, st->index); |
3070 if (st->truck_stops == NULL) |
3017 if (st->truck_stops == NULL) |
3071 error("Station: too many truckstations in savegame"); |
3018 error("Station: too many truckstations in savegame"); |
3072 |
3019 |
3073 InitializeRoadStop(st->truck_stops, NULL, st->lorry_tile_obsolete, st->index); |
|
3074 } |
3020 } |
3075 } |
3021 } |
3076 } |
3022 } |
3077 |
3023 |
3078 /* This is to ensure all pointers are within the limits of _stations_size */ |
3024 /* This is to ensure all pointers are within the limits of _stations_size */ |
3092 static void Load_ROADSTOP(void) |
3038 static void Load_ROADSTOP(void) |
3093 { |
3039 { |
3094 int index; |
3040 int index; |
3095 |
3041 |
3096 while ((index = SlIterateArray()) != -1) { |
3042 while ((index = SlIterateArray()) != -1) { |
3097 RoadStop *rs; |
3043 RoadStop *rs = new (index) RoadStop(INVALID_TILE, INVALID_STATION); |
3098 |
3044 |
3099 if (!AddBlockIfNeeded(&_RoadStop_pool, index)) |
|
3100 error("RoadStops: failed loading savegame: too many RoadStops"); |
|
3101 |
|
3102 rs = GetRoadStop(index); |
|
3103 SlObject(rs, _roadstop_desc); |
3045 SlObject(rs, _roadstop_desc); |
3104 } |
3046 } |
3105 } |
3047 } |
3106 |
3048 |
3107 extern const ChunkHandler _station_chunk_handlers[] = { |
3049 extern const ChunkHandler _station_chunk_handlers[] = { |