src/station_cmd.cpp
changeset 6338 0fb4f452873c
parent 6326 c904c7ea1c8d
child 6344 c5c1b17c8925
equal deleted inserted replaced
6337:6f3f247870f1 6338:0fb4f452873c
    33 #include "newgrf_station.h"
    33 #include "newgrf_station.h"
    34 #include "yapf/yapf.h"
    34 #include "yapf/yapf.h"
    35 #include "date.h"
    35 #include "date.h"
    36 #include "helpers.hpp"
    36 #include "helpers.hpp"
    37 #include "misc/autoptr.hpp"
    37 #include "misc/autoptr.hpp"
       
    38 #include "road.h"
    38 
    39 
    39 /**
    40 /**
    40  * Called if a new block is added to the station-pool
    41  * Called if a new block is added to the station-pool
    41  */
    42  */
    42 static void StationPoolNewBlock(uint start_item)
    43 static void StationPoolNewBlock(uint start_item)
  1245 }
  1246 }
  1246 
  1247 
  1247 /** Build a bus or truck stop
  1248 /** Build a bus or truck stop
  1248  * @param tile tile to build the stop at
  1249  * @param tile tile to build the stop at
  1249  * @param p1 entrance direction (DiagDirection)
  1250  * @param p1 entrance direction (DiagDirection)
  1250  * @param p2 0 for Bus stops, 1 for truck stops
  1251  * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
       
  1252  *           bit 1: 0 for normal, 1 for drive-through
       
  1253  *           bit 2: 0 for normal, 1 for build over road
       
  1254  *           bit 3: 0 for player owned road, 1 for town owned road
  1251  */
  1255  */
  1252 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1256 int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1253 {
  1257 {
  1254 	Station *st;
  1258 	Station *st;
  1255 	RoadStop *road_stop;
  1259 	RoadStop *road_stop;
  1256 	int32 cost;
  1260 	int32 cost;
  1257 	int32 ret;
  1261 	int32 ret;
  1258 	bool type = !!p2;
  1262 	bool type = HASBIT(p2, 0);
       
  1263 	bool is_drive_through = HASBIT(p2, 1);
       
  1264 	Owner cur_owner = _current_player;
  1259 
  1265 
  1260 	/* Saveguard the parameters */
  1266 	/* Saveguard the parameters */
  1261 	if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
  1267 	if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
       
  1268 	/* If it is a drive-through stop check for valid axis */
       
  1269 	if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR;
       
  1270 	/* If overbuilding a road check tile is a valid road tile */
       
  1271 	if (HASBIT(p2, 2) && !(IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL)) return CMD_ERROR;
       
  1272 	/* If overbuilding a town road,check tile is town owned and patch setting is enabled */
       
  1273 	if (HASBIT(p2, 3) && !(_patches.road_stop_on_town_road && IsTileOwner(tile, OWNER_TOWN))) return CMD_ERROR;
  1262 
  1274 
  1263 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1275 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1264 
  1276 
  1265 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
  1277 	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
  1266 		return CMD_ERROR;
  1278 		return CMD_ERROR;
  1267 
  1279 
  1268 	ret = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL);
  1280 	if (is_drive_through & HASBIT(p2, 3)) _current_player = OWNER_TOWN;
       
  1281 	ret = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL);
       
  1282 	_current_player = cur_owner;
  1269 	if (CmdFailed(ret)) return ret;
  1283 	if (CmdFailed(ret)) return ret;
  1270 	cost = ret;
  1284 	cost = HASBIT(p2, 2) ? 0 : ret; // Don't add cost of clearing road when overbuilding
  1271 
  1285 
  1272 	st = GetStationAround(tile, 1, 1, INVALID_STATION);
  1286 	st = GetStationAround(tile, 1, 1, INVALID_STATION);
  1273 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
  1287 	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
  1274 
  1288 
  1275 	/* Find a station close to us */
  1289 	/* Find a station close to us */
  1331 		//initialize an empty station
  1345 		//initialize an empty station
  1332 		st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile);
  1346 		st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile);
  1333 
  1347 
  1334 		st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
  1348 		st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
  1335 
  1349 
  1336 		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, (DiagDirection)p1);
  1350 		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, is_drive_through, (DiagDirection)p1);
       
  1351 		if (is_drive_through & HASBIT(p2, 3)) SetStopBuiltOnTownRoad(tile);
  1337 
  1352 
  1338 		UpdateStationVirtCoordDirty(st);
  1353 		UpdateStationVirtCoordDirty(st);
  1339 		UpdateStationAcceptance(st, false);
  1354 		UpdateStationAcceptance(st, false);
  1340 		RebuildStationLists();
  1355 		RebuildStationLists();
  1341 		InvalidateWindow(WC_STATION_LIST, st->owner);
  1356 		InvalidateWindow(WC_STATION_LIST, st->owner);
  1393 	}
  1408 	}
  1394 
  1409 
  1395 	return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
  1410 	return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
  1396 }
  1411 }
  1397 
  1412 
  1398 
  1413 /** Remove a bus or truck stop
       
  1414  * @param tile tile to remove the stop from
       
  1415  * @param p1 not used
       
  1416  * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
       
  1417  */
       
  1418 int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1419 {
       
  1420 	Station* st;
       
  1421 	bool is_drive_through;
       
  1422 	bool is_towns_road = false;
       
  1423 	RoadBits road_bits;
       
  1424 	int32 ret;
       
  1425 
       
  1426 	/* Make sure the specified tile is a road stop of the correct type */
       
  1427 	if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR;
       
  1428 	st = GetStationByTile(tile);
       
  1429 	/* Save the stop info before it is removed */
       
  1430 	is_drive_through = IsDriveThroughStopTile(tile);
       
  1431 	road_bits = GetAnyRoadBits(tile);
       
  1432 	if (is_drive_through) is_towns_road = GetStopBuiltOnTownRoad(tile);
       
  1433 
       
  1434 	ret = RemoveRoadStop(st, flags, tile);
       
  1435 
       
  1436 	/* If the stop was a drive-through stop replace the road */
       
  1437 	if ((flags & DC_EXEC) && !CmdFailed(ret) && is_drive_through) {
       
  1438 		uint index = 0;
       
  1439 		Owner cur_owner = _current_player;
       
  1440 
       
  1441 		if (is_towns_road) {
       
  1442 			index = ClosestTownFromTile(tile, _patches.dist_local_authority)->index;
       
  1443 			_current_player = OWNER_TOWN;
       
  1444 		}
       
  1445 		DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
       
  1446 		_current_player = cur_owner;
       
  1447 	}
       
  1448 
       
  1449 	return ret;
       
  1450 }
  1399 
  1451 
  1400 // FIXME -- need to move to its corresponding Airport variable
  1452 // FIXME -- need to move to its corresponding Airport variable
  1401 // Country Airfield (small)
  1453 // Country Airfield (small)
  1402 static const byte _airport_sections_country[] = {
  1454 static const byte _airport_sections_country[] = {
  1403 	54, 53, 52, 65,
  1455 	54, 53, 52, 65,
  2225 		if (v->u.road.state < RVSB_IN_ROAD_STOP && v->u.road.frame == 0) {
  2277 		if (v->u.road.state < RVSB_IN_ROAD_STOP && v->u.road.frame == 0) {
  2226 			if (IsRoadStop(tile)) {
  2278 			if (IsRoadStop(tile)) {
  2227 				/* Attempt to allocate a parking bay in a road stop */
  2279 				/* Attempt to allocate a parking bay in a road stop */
  2228 				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
  2280 				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
  2229 
  2281 
       
  2282 				if (IsDriveThroughStopTile(tile)) {
       
  2283 					/* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
       
  2284 					byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1;
       
  2285 
       
  2286 					if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER;
       
  2287 
       
  2288 					/* Check if the vehicle is stopping at this road stop */
       
  2289 					if (GetRoadStopType(tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
       
  2290 							v->current_order.dest == GetStationIndex(tile)) {
       
  2291 						SETBIT(v->u.road.state, RVS_IS_STOPPING);
       
  2292 						rs->AllocateDriveThroughBay(side);
       
  2293 					}
       
  2294 
       
  2295 					/* Indicate if vehicle is using second bay. */
       
  2296 					if (side == 1) SETBIT(v->u.road.state, RVS_USING_SECOND_BAY);
       
  2297 					/* Indicate a drive-through stop */
       
  2298 					SETBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP);
       
  2299 					return VETSB_CONTINUE;
       
  2300 				}
       
  2301 
       
  2302 				/* For normal (non drive-through) road stops */
  2230 				/* Check if station is busy or if there are no free bays. */
  2303 				/* Check if station is busy or if there are no free bays. */
  2231 				if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
  2304 				if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
  2232 
  2305 
  2233 				SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);
  2306 				SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);
  2234 
  2307 
  2691 
  2764 
  2692 	switch (GetStationType(tile)) {
  2765 	switch (GetStationType(tile)) {
  2693 		case STATION_RAIL:    return RemoveRailroadStation(st, tile, flags);
  2766 		case STATION_RAIL:    return RemoveRailroadStation(st, tile, flags);
  2694 		case STATION_AIRPORT: return RemoveAirport(st, flags);
  2767 		case STATION_AIRPORT: return RemoveAirport(st, flags);
  2695 		case STATION_TRUCK:
  2768 		case STATION_TRUCK:
  2696 		case STATION_BUS:     return RemoveRoadStop(st, flags, tile);
  2769 			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
       
  2770 				return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION);
       
  2771 			return RemoveRoadStop(st, flags, tile);
       
  2772 		case STATION_BUS:
       
  2773 			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
       
  2774 				return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION);
       
  2775 			return RemoveRoadStop(st, flags, tile);
  2697 		case STATION_BUOY:    return RemoveBuoy(st, flags);
  2776 		case STATION_BUOY:    return RemoveBuoy(st, flags);
  2698 		case STATION_DOCK:    return RemoveDock(st, flags);
  2777 		case STATION_DOCK:    return RemoveDock(st, flags);
  2699 		default: break;
  2778 		default: break;
  2700 	}
  2779 	}
  2701 
  2780