src/station_cmd.cpp
changeset 6157 c64e66c3804e
parent 6156 5adeec1679a4
child 6164 a4458b13cca9
equal deleted inserted replaced
6156:5adeec1679a4 6157:c64e66c3804e
  1272 	}
  1272 	}
  1273 
  1273 
  1274 	return _price.build_rail >> 1;
  1274 	return _price.build_rail >> 1;
  1275 }
  1275 }
  1276 
  1276 
  1277 /** Heavy wizardry used to add a roadstop to a station.
  1277 /**
  1278  * To understand the function, lets first look at what is passed around,
       
  1279  * especially the last parameter. CmdBuildRoadStop allocates a road
       
  1280  * stop and needs to put that stop into the linked list of road stops.
       
  1281  * It (CmdBuildRoadStop) has a **currstop pointer which points to element
       
  1282  * in the linked list of stops (each element in this list being a pointer
       
  1283  * in itself, hence the double pointer). We (FindRoadStopSpot) need to
       
  1284  * modify this pointer (**currstop) thus we need to pass by reference,
       
  1285  * obtaining a triple pointer (***currstop). When finished, **currstop
       
  1286  * in CmdBuildRoadStop will contain the address of the pointer which will
       
  1287  * then point into the global roadstop array.
       
  1288  * @param[in] truck_station Determines whether a stop is RoadStop::BUS or RoadStop::TRUCK
  1278  * @param[in] truck_station Determines whether a stop is RoadStop::BUS or RoadStop::TRUCK
  1289  * @param[in] station The station to do the whole procedure for
  1279  * @param[in] station The station to do the whole procedure for
  1290  * @param[out] currstop See the detailed function description
  1280  * @return a pointer to where to link a new RoadStop*
  1291  * @param prev See the detailed function description
       
  1292  */
  1281  */
  1293 static void FindRoadStopSpot(bool truck_station, Station* st, RoadStop*** currstop)
  1282 static RoadStop **FindRoadStopSpot(bool truck_station, Station* st)
  1294 {
  1283 {
  1295 	RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops;
  1284 	RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops;
  1296 
  1285 
  1297 	if (*primary_stop == NULL) {
  1286 	if (*primary_stop == NULL) {
  1298 		//we have no roadstop of the type yet, so write a "primary stop"
  1287 		//we have no roadstop of the type yet, so write a "primary stop"
  1299 		*currstop = primary_stop;
  1288 		return primary_stop;
  1300 	} else {
  1289 	} else {
  1301 		//there are stops already, so append to the end of the list
  1290 		//there are stops already, so append to the end of the list
  1302 		*currstop = &(*primary_stop)->next;
  1291 		RoadStop *stop = *primary_stop;
  1303 		while (**currstop != NULL) {
  1292 		while (stop->next != NULL) stop = stop->next;
  1304 			*currstop = &(**currstop)->next;
  1293 		return &stop->next;
  1305 		}
       
  1306 	}
  1294 	}
  1307 }
  1295 }
  1308 
  1296 
  1309 /** Build a bus or truck stop
  1297 /** Build a bus or truck stop
  1310  * @param tile tile to build the stop at
  1298  * @param tile tile to build the stop at
  1313  */
  1301  */
  1314 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1302 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1315 {
  1303 {
  1316 	Station *st;
  1304 	Station *st;
  1317 	RoadStop *road_stop;
  1305 	RoadStop *road_stop;
  1318 	RoadStop **currstop;
       
  1319 	int32 cost;
  1306 	int32 cost;
  1320 	int32 ret;
  1307 	int32 ret;
  1321 	bool type = !!p2;
  1308 	bool type = !!p2;
  1322 
  1309 
  1323 	/* Saveguard the parameters */
  1310 	/* Saveguard the parameters */
  1363 		if (st->owner != OWNER_NONE && st->owner != _current_player) {
  1350 		if (st->owner != OWNER_NONE && st->owner != _current_player) {
  1364 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
  1351 			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
  1365 		}
  1352 		}
  1366 
  1353 
  1367 		if (!st->rect.BeforeAddTile(tile, StationRect::ADD_TEST)) return CMD_ERROR;
  1354 		if (!st->rect.BeforeAddTile(tile, StationRect::ADD_TEST)) return CMD_ERROR;
  1368 
       
  1369 		FindRoadStopSpot(type, st, &currstop);
       
  1370 	} else {
  1355 	} else {
  1371 		/* allocate and initialize new station */
  1356 		/* allocate and initialize new station */
  1372 		st = new Station(tile);
  1357 		st = new Station(tile);
  1373 		if (st == NULL) return CMD_ERROR;
  1358 		if (st == NULL) return CMD_ERROR;
  1374 
  1359 
  1377 
  1362 
  1378 
  1363 
  1379 		Town *t = st->town = ClosestTownFromTile(tile, (uint)-1);
  1364 		Town *t = st->town = ClosestTownFromTile(tile, (uint)-1);
  1380 		if (!GenerateStationName(st, tile, 0)) return CMD_ERROR;
  1365 		if (!GenerateStationName(st, tile, 0)) return CMD_ERROR;
  1381 
  1366 
  1382 		FindRoadStopSpot(type, st, &currstop);
       
  1383 
       
  1384 		if (IsValidPlayer(_current_player) && (flags & DC_EXEC) != 0) {
  1367 		if (IsValidPlayer(_current_player) && (flags & DC_EXEC) != 0) {
  1385 			SETBIT(t->have_ratings, _current_player);
  1368 			SETBIT(t->have_ratings, _current_player);
  1386 		}
  1369 		}
  1387 
  1370 
  1388 		st->sign.width_1 = 0;
  1371 		st->sign.width_1 = 0;
  1389 	}
  1372 	}
  1390 
  1373 
  1391 	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
  1374 	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
  1392 
  1375 
  1393 	if (flags & DC_EXEC) {
  1376 	if (flags & DC_EXEC) {
  1394 		//point to the correct item in the _busstops or _truckstops array
  1377 		// Insert into linked list of RoadStops
       
  1378 		RoadStop **currstop = FindRoadStopSpot(type, st);
  1395 		*currstop = road_stop;
  1379 		*currstop = road_stop;
  1396 
  1380 
  1397 		//initialize an empty station
  1381 		//initialize an empty station
  1398 		st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile);
  1382 		st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile);
  1399 
  1383