File diff r6011:0c796a4db1e8 → r6012:6160fb57dc8a
src/station_cmd.cpp
Show inline comments
 
@@ -35,6 +35,7 @@
 
#include "date.h"
 
#include "helpers.hpp"
 
#include "misc/autoptr.hpp"
 
#include "road.h"
 

	
 
/**
 
 * Called if a new block is added to the station-pool
 
@@ -1247,7 +1248,10 @@ static RoadStop **FindRoadStopSpot(bool 
 
/** Build a bus or truck stop
 
 * @param tile tile to build the stop at
 
 * @param p1 entrance direction (DiagDirection)
 
 * @param p2 0 for Bus stops, 1 for truck stops
 
 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
 
 *           bit 1: 0 for normal, 1 for drive-through
 
 *           bit 2: 0 for normal, 1 for build over road
 
 *           bit 3: 0 for player owned road, 1 for town owned road
 
 */
 
int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
@@ -1255,19 +1259,29 @@ int32 CmdBuildRoadStop(TileIndex tile, u
 
	RoadStop *road_stop;
 
	int32 cost;
 
	int32 ret;
 
	bool type = !!p2;
 
	bool type = HASBIT(p2, 0);
 
	bool is_drive_through = HASBIT(p2, 1);
 
	Owner cur_owner = _current_player;
 

	
 
	/* Saveguard the parameters */
 
	if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
 
	/* If it is a drive-through stop check for valid axis */
 
	if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR;
 
	/* If overbuilding a road check tile is a valid road tile */
 
	if (HASBIT(p2, 2) && !(IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL)) return CMD_ERROR;
 
	/* If overbuilding a town road,check tile is town owned and patch setting is enabled */
 
	if (HASBIT(p2, 3) && !(_patches.road_stop_on_town_road && IsTileOwner(tile, OWNER_TOWN))) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
 
		return CMD_ERROR;
 

	
 
	ret = CheckFlatLandBelow(tile, 1, 1, flags, 1 << p1, NULL);
 
	if (is_drive_through & HASBIT(p2, 3)) _current_player = OWNER_TOWN;
 
	ret = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL);
 
	_current_player = cur_owner;
 
	if (CmdFailed(ret)) return ret;
 
	cost = ret;
 
	cost = HASBIT(p2, 2) ? 0 : ret; // Don't add cost of clearing road when overbuilding
 

	
 
	st = GetStationAround(tile, 1, 1, INVALID_STATION);
 
	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
@@ -1333,7 +1347,8 @@ int32 CmdBuildRoadStop(TileIndex tile, u
 

	
 
		st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
 

	
 
		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, (DiagDirection)p1);
 
		MakeRoadStop(tile, st->owner, st->index, type ? RoadStop::TRUCK : RoadStop::BUS, is_drive_through, (DiagDirection)p1);
 
		if (is_drive_through & HASBIT(p2, 3)) SetStopBuiltOnTownRoad(tile);
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
@@ -1395,7 +1410,44 @@ static int32 RemoveRoadStop(Station *st,
 
	return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station;
 
}
 

	
 

	
 
/** Remove a bus or truck stop
 
 * @param tile tile to remove the stop from
 
 * @param p1 not used
 
 * @param p2 bit 0: 0 for Bus stops, 1 for truck stops
 
 */
 
int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Station* st;
 
	bool is_drive_through;
 
	bool is_towns_road = false;
 
	RoadBits road_bits;
 
	int32 ret;
 

	
 
	/* Make sure the specified tile is a road stop of the correct type */
 
	if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR;
 
	st = GetStationByTile(tile);
 
	/* Save the stop info before it is removed */
 
	is_drive_through = IsDriveThroughStopTile(tile);
 
	road_bits = GetAnyRoadBits(tile);
 
	if (is_drive_through) is_towns_road = GetStopBuiltOnTownRoad(tile);
 

	
 
	ret = RemoveRoadStop(st, flags, tile);
 

	
 
	/* If the stop was a drive-through stop replace the road */
 
	if ((flags & DC_EXEC) && !CmdFailed(ret) && is_drive_through) {
 
		uint index = 0;
 
		Owner cur_owner = _current_player;
 

	
 
		if (is_towns_road) {
 
			index = ClosestTownFromTile(tile, _patches.dist_local_authority)->index;
 
			_current_player = OWNER_TOWN;
 
		}
 
		DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
 
		_current_player = cur_owner;
 
	}
 

	
 
	return ret;
 
}
 

	
 
// FIXME -- need to move to its corresponding Airport variable
 
// Country Airfield (small)
 
@@ -2227,6 +2279,27 @@ static uint32 VehicleEnter_Station(Vehic
 
				/* Attempt to allocate a parking bay in a road stop */
 
				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
 

	
 
				if (IsDriveThroughStopTile(tile)) {
 
					/* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */
 
					byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1;
 

	
 
					if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER;
 

	
 
					/* Check if the vehicle is stopping at this road stop */
 
					if (GetRoadStopType(tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
 
							v->current_order.dest == GetStationIndex(tile)) {
 
						SETBIT(v->u.road.state, RVS_IS_STOPPING);
 
						rs->AllocateDriveThroughBay(side);
 
					}
 

	
 
					/* Indicate if vehicle is using second bay. */
 
					if (side == 1) SETBIT(v->u.road.state, RVS_USING_SECOND_BAY);
 
					/* Indicate a drive-through stop */
 
					SETBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP);
 
					return VETSB_CONTINUE;
 
				}
 

	
 
				/* For normal (non drive-through) road stops */
 
				/* Check if station is busy or if there are no free bays. */
 
				if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
 

	
 
@@ -2693,7 +2766,13 @@ static int32 ClearTile_Station(TileIndex
 
		case STATION_RAIL:    return RemoveRailroadStation(st, tile, flags);
 
		case STATION_AIRPORT: return RemoveAirport(st, flags);
 
		case STATION_TRUCK:
 
		case STATION_BUS:     return RemoveRoadStop(st, flags, tile);
 
			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
 
				return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION);
 
			return RemoveRoadStop(st, flags, tile);
 
		case STATION_BUS:
 
			if (IsDriveThroughStopTile(tile) && GetStopBuiltOnTownRoad(tile))
 
				return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION);
 
			return RemoveRoadStop(st, flags, tile);
 
		case STATION_BUOY:    return RemoveBuoy(st, flags);
 
		case STATION_DOCK:    return RemoveDock(st, flags);
 
		default: break;