mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r19231) -Feature: Allow overbuilding of road stops.
This commit is contained in:
parent
aba24e44cf
commit
a4a66ec1aa
|
@ -258,3 +258,19 @@ class AIWaypointList extends _AIWaypointList {
|
||||||
::_AIWaypointList.constructor(AIWaypoint.WAYPOINT_RAIL);
|
::_AIWaypointList.constructor(AIWaypoint.WAYPOINT_RAIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AIRoad._BuildRoadStation <- AIRoad.BuildRoadStation;
|
||||||
|
AIRoad.BuildRoadStation <- function(tile, front, road_veh_type, station_id)
|
||||||
|
{
|
||||||
|
if (AIRoad.IsRoadStationTile(tile)) return false;
|
||||||
|
|
||||||
|
return AIRoad._BuildRoadStation(tile, front, road_veh_type, station_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
AIRoad._BuildDriveThroughRoadStation <- AIRoad.BuildDriveThroughRoadStation;
|
||||||
|
AIRoad.BuildDriveThroughRoadStation <- function(tile, front, road_veh_type, station_id)
|
||||||
|
{
|
||||||
|
if (AIRoad.IsRoadStationTile(tile)) return false;
|
||||||
|
|
||||||
|
return AIRoad._BuildDriveThroughRoadStation(tile, front, road_veh_type, station_id);
|
||||||
|
}
|
||||||
|
|
|
@ -7,5 +7,20 @@
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Enable when adding the first compatability code:
|
AILog.Info("1.0 API compatability in effect.");
|
||||||
* AILog.Info("1.0 API compatability in effect"); */
|
|
||||||
|
AIRoad._BuildRoadStation <- AIRoad.BuildRoadStation;
|
||||||
|
AIRoad.BuildRoadStation <- function(tile, front, road_veh_type, station_id)
|
||||||
|
{
|
||||||
|
if (AIRoad.IsRoadStationTile(tile)) return false;
|
||||||
|
|
||||||
|
return AIRoad._BuildRoadStation(tile, front, road_veh_type, station_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
AIRoad._BuildDriveThroughRoadStation <- AIRoad.BuildDriveThroughRoadStation;
|
||||||
|
AIRoad.BuildDriveThroughRoadStation <- function(tile, front, road_veh_type, station_id)
|
||||||
|
{
|
||||||
|
if (AIRoad.IsRoadStationTile(tile)) return false;
|
||||||
|
|
||||||
|
return AIRoad._BuildDriveThroughRoadStation(tile, front, road_veh_type, station_id);
|
||||||
|
}
|
||||||
|
|
|
@ -7259,7 +7259,7 @@
|
||||||
BuildRoadStation(): false
|
BuildRoadStation(): false
|
||||||
BuildRoadStation(): false
|
BuildRoadStation(): false
|
||||||
BuildRoadStation(): true
|
BuildRoadStation(): true
|
||||||
BuildRoadStation(): false
|
BuildRoadStation(): true
|
||||||
IsStationTile(): true
|
IsStationTile(): true
|
||||||
IsStationTile(): false
|
IsStationTile(): false
|
||||||
HasRoadType(Road): true
|
HasRoadType(Road): true
|
||||||
|
@ -8452,11 +8452,11 @@
|
||||||
14 => 1
|
14 => 1
|
||||||
12 => 1
|
12 => 1
|
||||||
Age ListDump:
|
Age ListDump:
|
||||||
|
14 => 1
|
||||||
|
13 => 1
|
||||||
|
12 => 1
|
||||||
17 => 0
|
17 => 0
|
||||||
16 => 0
|
16 => 0
|
||||||
14 => 0
|
|
||||||
13 => 0
|
|
||||||
12 => 0
|
|
||||||
MaxAge ListDump:
|
MaxAge ListDump:
|
||||||
16 => 10980
|
16 => 10980
|
||||||
14 => 10980
|
14 => 10980
|
||||||
|
@ -8465,10 +8465,10 @@
|
||||||
12 => 5490
|
12 => 5490
|
||||||
AgeLeft ListDump:
|
AgeLeft ListDump:
|
||||||
16 => 10980
|
16 => 10980
|
||||||
14 => 10980
|
14 => 10979
|
||||||
17 => 7320
|
17 => 7320
|
||||||
13 => 5490
|
13 => 5489
|
||||||
12 => 5490
|
12 => 5489
|
||||||
CurrentSpeed ListDump:
|
CurrentSpeed ListDump:
|
||||||
12 => 21
|
12 => 21
|
||||||
17 => 0
|
17 => 0
|
||||||
|
@ -8486,7 +8486,7 @@
|
||||||
16 => 0
|
16 => 0
|
||||||
14 => 0
|
14 => 0
|
||||||
13 => 0
|
13 => 0
|
||||||
12 => 0
|
12 => -1
|
||||||
ProfitLastYear ListDump:
|
ProfitLastYear ListDump:
|
||||||
17 => 0
|
17 => 0
|
||||||
16 => 0
|
16 => 0
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
*
|
*
|
||||||
* 1.1.0 is not yet released. The following changes are not set in stone yet.
|
* 1.1.0 is not yet released. The following changes are not set in stone yet.
|
||||||
*
|
*
|
||||||
|
* Other changes:
|
||||||
|
* \li AIRoad::BuildRoadStation now allows overbuilding
|
||||||
|
* \li AIRoad::BuildDriveThroughRoadStation now allows overbuilding
|
||||||
|
*
|
||||||
* \b 1.0.0
|
* \b 1.0.0
|
||||||
*
|
*
|
||||||
* 1.0.0 is not yet released. The following changes are not set in stone yet.
|
* 1.0.0 is not yet released. The following changes are not set in stone yet.
|
||||||
|
|
|
@ -3425,6 +3425,7 @@ STR_ERROR_CAN_T_REMOVE_BUS_STATION :{WHITE}Can't re
|
||||||
STR_ERROR_CAN_T_REMOVE_TRUCK_STATION :{WHITE}Can't remove lorry station...
|
STR_ERROR_CAN_T_REMOVE_TRUCK_STATION :{WHITE}Can't remove lorry station...
|
||||||
STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION :{WHITE}Can't remove passenger tram station...
|
STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION :{WHITE}Can't remove passenger tram station...
|
||||||
STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION :{WHITE}Can't remove freight tram station...
|
STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION :{WHITE}Can't remove freight tram station...
|
||||||
|
STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST :{WHITE}Must remove road stop first
|
||||||
|
|
||||||
STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}Must demolish railway station first
|
STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}Must demolish railway station first
|
||||||
STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}Must demolish bus station first
|
STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}Must demolish bus station first
|
||||||
|
|
|
@ -804,11 +804,13 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl
|
||||||
* @param flags Operation to perform.
|
* @param flags Operation to perform.
|
||||||
* @param invalid_dirs Prohibited directions (set of DiagDirections).
|
* @param invalid_dirs Prohibited directions (set of DiagDirections).
|
||||||
* @param is_drive_through True if trying to build a drive-through station.
|
* @param is_drive_through True if trying to build a drive-through station.
|
||||||
|
* @param is_truck_stop True when building a truck stop, false otherwise.
|
||||||
* @param axis Axis of a drive-through road stop.
|
* @param axis Axis of a drive-through road stop.
|
||||||
|
* @param station StationID to be queried and returned if available.
|
||||||
* @param rts Road types to build. Bits already built at the tile will be removed.
|
* @param rts Road types to build. Bits already built at the tile will be removed.
|
||||||
* @return The cost in case of success, or an error code if it failed.
|
* @return The cost in case of success, or an error code if it failed.
|
||||||
*/
|
*/
|
||||||
static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, Axis axis, RoadTypes &rts)
|
static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, bool is_truck_stop, Axis axis, StationID *station, RoadTypes &rts)
|
||||||
{
|
{
|
||||||
CommandCost cost(EXPENSES_CONSTRUCTION);
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||||
int allowed_z = -1;
|
int allowed_z = -1;
|
||||||
|
@ -818,43 +820,64 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags
|
||||||
if (ret.Failed()) return ret;
|
if (ret.Failed()) return ret;
|
||||||
cost.AddCost(ret);
|
cost.AddCost(ret);
|
||||||
|
|
||||||
bool build_over_road = is_drive_through && IsNormalRoadTile(cur_tile);
|
/* If station is set, then we have special handling to allow building on top of already existing stations.
|
||||||
/* Road bits in the wrong direction. */
|
* Station points to INVALID_STATION if we can build on any station.
|
||||||
if (build_over_road && (GetAllRoadBits(cur_tile) & (axis == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
* Or it points to a station if we're only allowed to build on exactly that station. */
|
||||||
|
if (station != NULL && IsTileType(cur_tile, MP_STATION)) {
|
||||||
RoadTypes cur_rts = IsNormalRoadTile(cur_tile) ? GetRoadTypes(cur_tile) : ROADTYPES_NONE;
|
if (!IsRoadStop(cur_tile)) {
|
||||||
uint num_roadbits = 0;
|
return ClearTile_Station(cur_tile, DC_AUTO); // Get error message.
|
||||||
if (build_over_road) {
|
} else {
|
||||||
/* There is a road, check if we can build road+tram stop over it. */
|
if (is_truck_stop != IsTruckStop(cur_tile) ||
|
||||||
if (HasBit(cur_rts, ROADTYPE_ROAD)) {
|
is_drive_through != IsDriveThroughStopTile(cur_tile) ||
|
||||||
Owner road_owner = GetRoadOwner(cur_tile, ROADTYPE_ROAD);
|
HasBit(rts, ROADTYPE_TRAM) != HasBit(GetRoadTypes(cur_tile), ROADTYPE_TRAM)) {
|
||||||
if (road_owner == OWNER_TOWN) {
|
return ClearTile_Station(cur_tile, DC_AUTO); // Get error message.
|
||||||
if (!_settings_game.construction.road_stop_on_town_road) return_cmd_error(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD);
|
|
||||||
} else if (!_settings_game.construction.road_stop_on_competitor_road && road_owner != OWNER_NONE && !CheckOwnership(road_owner)) {
|
|
||||||
return CMD_ERROR;
|
|
||||||
}
|
}
|
||||||
num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_ROAD));
|
StationID st = GetStationIndex(cur_tile);
|
||||||
}
|
if (*station == INVALID_STATION) {
|
||||||
|
*station = st;
|
||||||
/* There is a tram, check if we can build road+tram stop over it. */
|
} else if (*station != st) {
|
||||||
if (HasBit(cur_rts, ROADTYPE_TRAM)) {
|
return_cmd_error(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING);
|
||||||
Owner tram_owner = GetRoadOwner(cur_tile, ROADTYPE_TRAM);
|
|
||||||
if (!_settings_game.construction.road_stop_on_competitor_road && tram_owner != OWNER_NONE && !CheckOwnership(tram_owner)) {
|
|
||||||
return CMD_ERROR;
|
|
||||||
}
|
}
|
||||||
num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_TRAM));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do not remove roadtypes! */
|
|
||||||
rts |= cur_rts;
|
|
||||||
} else {
|
} else {
|
||||||
ret = DoCommand(cur_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
bool build_over_road = is_drive_through && IsNormalRoadTile(cur_tile);
|
||||||
if (ret.Failed()) return ret;
|
/* Road bits in the wrong direction. */
|
||||||
cost.AddCost(ret);
|
if (build_over_road && (GetAllRoadBits(cur_tile) & (axis == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||||
}
|
|
||||||
|
|
||||||
uint roadbits_to_build = CountBits(rts) * 2 - num_roadbits;
|
RoadTypes cur_rts = IsNormalRoadTile(cur_tile) ? GetRoadTypes(cur_tile) : ROADTYPES_NONE;
|
||||||
cost.AddCost(_price[PR_BUILD_ROAD] * roadbits_to_build);
|
uint num_roadbits = 0;
|
||||||
|
if (build_over_road) {
|
||||||
|
/* There is a road, check if we can build road+tram stop over it. */
|
||||||
|
if (HasBit(cur_rts, ROADTYPE_ROAD)) {
|
||||||
|
Owner road_owner = GetRoadOwner(cur_tile, ROADTYPE_ROAD);
|
||||||
|
if (road_owner == OWNER_TOWN) {
|
||||||
|
if (!_settings_game.construction.road_stop_on_town_road) return_cmd_error(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD);
|
||||||
|
} else if (!_settings_game.construction.road_stop_on_competitor_road && road_owner != OWNER_NONE && !CheckOwnership(road_owner)) {
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_ROAD));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There is a tram, check if we can build road+tram stop over it. */
|
||||||
|
if (HasBit(cur_rts, ROADTYPE_TRAM)) {
|
||||||
|
Owner tram_owner = GetRoadOwner(cur_tile, ROADTYPE_TRAM);
|
||||||
|
if (!_settings_game.construction.road_stop_on_competitor_road && tram_owner != OWNER_NONE && !CheckOwnership(tram_owner)) {
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_TRAM));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do not remove roadtypes! */
|
||||||
|
rts |= cur_rts;
|
||||||
|
} else {
|
||||||
|
ret = DoCommand(cur_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||||
|
if (ret.Failed()) return ret;
|
||||||
|
cost.AddCost(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint roadbits_to_build = CountBits(rts) * 2 - num_roadbits;
|
||||||
|
cost.AddCost(_price[PR_BUILD_ROAD] * roadbits_to_build);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cost;
|
return cost;
|
||||||
|
@ -1595,6 +1618,22 @@ static RoadStop **FindRoadStopSpot(bool truck_station, Station *st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a nearby station that joins this road stop.
|
||||||
|
* @param existing_stop an existing road stop we build over
|
||||||
|
* @param station_to_join the station to join to
|
||||||
|
* @param adjacent whether adjacent stations are allowed
|
||||||
|
* @param ta the area of the newly build station
|
||||||
|
* @param st 'return' pointer for the found station
|
||||||
|
* @return command cost with the error or 'okay'
|
||||||
|
*/
|
||||||
|
static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID station_to_join, bool adjacent, TileArea ta, Station **st)
|
||||||
|
{
|
||||||
|
return FindJoiningBaseStation<Station, STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST>(existing_stop, station_to_join, adjacent, ta, st);
|
||||||
|
}
|
||||||
|
|
||||||
/** Build a bus or truck stop.
|
/** Build a bus or truck stop.
|
||||||
* @param tile Northernmost tile of the stop.
|
* @param tile Northernmost tile of the stop.
|
||||||
* @param flags Operation to perform.
|
* @param flags Operation to perform.
|
||||||
|
@ -1651,12 +1690,13 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||||
|
|
||||||
/* Total road stop cost. */
|
/* Total road stop cost. */
|
||||||
CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]);
|
CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]);
|
||||||
CommandCost ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << ddir : 1 << ddir, is_drive_through, DiagDirToAxis(ddir), rts);
|
StationID est = INVALID_STATION;
|
||||||
|
CommandCost ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << ddir : 1 << ddir, is_drive_through, type, DiagDirToAxis(ddir), &est, rts);
|
||||||
if (ret.Failed()) return ret;
|
if (ret.Failed()) return ret;
|
||||||
cost.AddCost(ret);
|
cost.AddCost(ret);
|
||||||
|
|
||||||
Station *st = NULL;
|
Station *st = NULL;
|
||||||
ret = FindJoiningStation(INVALID_STATION, station_to_join, HasBit(p2, 5), roadstop_area, &st);
|
ret = FindJoiningRoadStop(est, station_to_join, HasBit(p2, 5), roadstop_area, &st);
|
||||||
if (ret.Failed()) return ret;
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
/* Find a deleted station close to us */
|
/* Find a deleted station close to us */
|
||||||
|
@ -1690,6 +1730,10 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
/* Check every tile in the area. */
|
/* Check every tile in the area. */
|
||||||
TILE_AREA_LOOP(cur_tile, roadstop_area) {
|
TILE_AREA_LOOP(cur_tile, roadstop_area) {
|
||||||
|
if (IsTileType(cur_tile, MP_STATION) && IsRoadStop(cur_tile)) {
|
||||||
|
RemoveRoadStop(cur_tile, flags);
|
||||||
|
}
|
||||||
|
|
||||||
RoadStop *road_stop = new RoadStop(cur_tile);
|
RoadStop *road_stop = new RoadStop(cur_tile);
|
||||||
/* Insert into linked list of RoadStops. */
|
/* Insert into linked list of RoadStops. */
|
||||||
RoadStop **currstop = FindRoadStopSpot(type, st);
|
RoadStop **currstop = FindRoadStopSpot(type, st);
|
||||||
|
|
Loading…
Reference in New Issue