src/station_cmd.cpp
changeset 5959 6a4c261987c3
parent 5948 f835a89667df
child 5960 8ba5759e1d8d
equal deleted inserted replaced
5958:82161fb80839 5959:6a4c261987c3
    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[] = {