|
@@ -609,19 +609,19 @@ static void DeleteStationIfEmpty(Station
|
|
|
InvalidateWindow(WC_STATION_LIST, st->owner);
|
|
|
}
|
|
|
/* station remains but it probably lost some parts - station sign should stay in the station boundaries */
|
|
|
UpdateStationSignCoord(st);
|
|
|
}
|
|
|
|
|
|
static int32 ClearTile_Station(TileIndex tile, byte flags);
|
|
|
static CommandCost ClearTile_Station(TileIndex tile, byte flags);
|
|
|
|
|
|
// Tries to clear the given area. Returns the cost in case of success.
|
|
|
// Or an error code if it failed.
|
|
|
int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station, bool check_clear = true)
|
|
|
CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station, bool check_clear = true)
|
|
|
{
|
|
|
int32 cost = 0;
|
|
|
CommandCost cost = 0;
|
|
|
int allowed_z = -1;
|
|
|
|
|
|
BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
|
|
|
if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) {
|
|
|
return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
|
|
|
}
|
|
@@ -677,13 +677,13 @@ int32 CheckFlatLandBelow(TileIndex tile,
|
|
|
*station = st;
|
|
|
} else if (*station != st) {
|
|
|
return_cmd_error(STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING);
|
|
|
}
|
|
|
}
|
|
|
} else if (check_clear) {
|
|
|
int32 ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
CommandCost ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
cost += ret;
|
|
|
}
|
|
|
} END_TILE_LOOP(tile_cur, w, h, tile)
|
|
|
|
|
|
return cost;
|
|
@@ -798,16 +798,16 @@ static void GetStationLayout(byte *layou
|
|
|
* - p1 = (bit 24) - allow stations directly adjacent to other stations.
|
|
|
* @param p2 various bitstuffed elements
|
|
|
* - p2 = (bit 0- 3) - railtype (p2 & 0xF)
|
|
|
* - p2 = (bit 8-15) - custom station class
|
|
|
* - p2 = (bit 16-23) - custom station id
|
|
|
*/
|
|
|
int32 CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
int w_org, h_org;
|
|
|
int32 ret;
|
|
|
CommandCost ret;
|
|
|
|
|
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
|
|
|
|
/* Does the authority allow this? */
|
|
|
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
|
|
|
if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
|
|
@@ -835,13 +835,13 @@ int32 CmdBuildRailroadStation(TileIndex
|
|
|
// Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station)
|
|
|
StationID est = INVALID_STATION;
|
|
|
// If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
|
|
|
// for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
|
|
|
ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
int32 cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
|
|
|
CommandCost cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
|
|
|
|
|
|
Station *st = NULL;
|
|
|
bool check_surrounding = true;
|
|
|
|
|
|
if (_patches.adjacent_stations) {
|
|
|
if (est != INVALID_STATION) {
|
|
@@ -1051,13 +1051,13 @@ restart:
|
|
|
* This allows for custom-built station with holes and weird layouts
|
|
|
* @param tile tile of station piece to remove
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 start_tile
|
|
|
* @param p2 unused
|
|
|
*/
|
|
|
int32 CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
TileIndex start = p1 == 0 ? tile : p1;
|
|
|
|
|
|
/* Count of the number of tiles removed */
|
|
|
int quantity = 0;
|
|
|
|
|
@@ -1122,13 +1122,13 @@ int32 CmdRemoveFromRailroadStation(TileI
|
|
|
if (quantity == 0) return CMD_ERROR;
|
|
|
|
|
|
return _price.remove_rail_station * quantity;
|
|
|
}
|
|
|
|
|
|
|
|
|
static int32 RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
|
|
|
static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
|
|
|
{
|
|
|
/* if there is flooding and non-uniform stations are enabled, remove platforms tile by tile */
|
|
|
if (_current_player == OWNER_WATER && _patches.nonuniform_stations)
|
|
|
return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAILROAD_STATION);
|
|
|
|
|
|
/* Current player owns the station? */
|
|
@@ -1139,13 +1139,13 @@ static int32 RemoveRailroadStation(Stati
|
|
|
tile = st->train_tile;
|
|
|
int w = st->trainst_w;
|
|
|
int h = st->trainst_h;
|
|
|
|
|
|
assert(w != 0 && h != 0);
|
|
|
|
|
|
int32 cost = 0;
|
|
|
CommandCost cost = 0;
|
|
|
/* clear all areas of the station */
|
|
|
do {
|
|
|
int w_bak = w;
|
|
|
do {
|
|
|
// for nonuniform stations, only remove tiles that are actually train station tiles
|
|
|
if (st->TileBelongsToRailStation(tile)) {
|
|
@@ -1188,13 +1188,13 @@ static int32 RemoveRailroadStation(Stati
|
|
|
* @param tile The tile on which the railtype is to be convert.
|
|
|
* @param totype The railtype we want to convert to
|
|
|
* @param exec Switches between test and execute mode
|
|
|
* @return The cost and state of the operation
|
|
|
* @retval CMD_ERROR An error occured during the operation.
|
|
|
*/
|
|
|
int32 DoConvertStationRail(TileIndex tile, RailType totype, bool exec)
|
|
|
CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec)
|
|
|
{
|
|
|
const Station* st = GetStationByTile(tile);
|
|
|
|
|
|
if (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile)) return CMD_ERROR;
|
|
|
|
|
|
// tile is not a railroad station?
|
|
@@ -1240,13 +1240,13 @@ static RoadStop **FindRoadStopSpot(bool
|
|
|
* @param p1 entrance direction (DiagDirection)
|
|
|
* @param p2 bit 0: 0 for Bus stops, 1 for truck stops
|
|
|
* bit 1: 0 for normal, 1 for drive-through
|
|
|
* bit 2..4: the roadtypes
|
|
|
* bit 5: allow stations directly adjacent to other stations.
|
|
|
*/
|
|
|
int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
bool type = HASBIT(p2, 0);
|
|
|
bool is_drive_through = HASBIT(p2, 1);
|
|
|
bool build_over_road = is_drive_through && IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL;
|
|
|
bool town_owned_road = build_over_road && IsTileOwner(tile, OWNER_TOWN);
|
|
|
RoadTypes rts = (RoadTypes)GB(p2, 2, 3);
|
|
@@ -1264,13 +1264,13 @@ int32 CmdBuildRoadStop(TileIndex tile, u
|
|
|
if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
|
|
|
|
|
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
|
|
|
|
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
|
|
|
|
|
|
int32 cost = 0;
|
|
|
CommandCost cost = 0;
|
|
|
|
|
|
/* Not allowed to build over this road */
|
|
|
if (build_over_road) {
|
|
|
if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
|
|
|
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) return CMD_ERROR;
|
|
|
|
|
@@ -1368,13 +1368,13 @@ int32 CmdBuildRoadStop(TileIndex tile, u
|
|
|
rs_auto_delete.Release();
|
|
|
}
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
|
// Remove a bus station
|
|
|
static int32 RemoveRoadStop(Station *st, uint32 flags, TileIndex tile)
|
|
|
static CommandCost RemoveRoadStop(Station *st, uint32 flags, TileIndex tile)
|
|
|
{
|
|
|
if (_current_player != OWNER_WATER && !CheckOwnership(st->owner)) {
|
|
|
return CMD_ERROR;
|
|
|
}
|
|
|
|
|
|
bool is_truck = IsTruckStop(tile);
|
|
@@ -1422,26 +1422,26 @@ static int32 RemoveRoadStop(Station *st,
|
|
|
/** Remove a bus or truck stop
|
|
|
* @param tile tile to remove the stop from
|
|
|
* @param flags operation to perform
|
|
|
* @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)
|
|
|
CommandCost CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
/* 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;
|
|
|
Station *st = GetStationByTile(tile);
|
|
|
/* Save the stop info before it is removed */
|
|
|
bool is_drive_through = IsDriveThroughStopTile(tile);
|
|
|
RoadTypes rts = GetRoadTypes(tile);
|
|
|
RoadBits road_bits = IsDriveThroughStopTile(tile) ?
|
|
|
((GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y) :
|
|
|
DiagDirToRoadBits(GetRoadStopDir(tile));
|
|
|
bool is_towns_road = is_drive_through && GetStopBuiltOnTownRoad(tile);
|
|
|
|
|
|
int32 ret = RemoveRoadStop(st, flags, tile);
|
|
|
CommandCost 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) {
|
|
|
/* Rebuild the drive throuhg road stop. As a road stop can only be
|
|
|
* removed by the owner of the roadstop, _current_player is the
|
|
|
* owner of the road stop. */
|
|
@@ -1547,13 +1547,13 @@ static const byte * const _airport_secti
|
|
|
/** Place an Airport.
|
|
|
* @param tile tile where airport will be built
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 airport type, @see airport.h
|
|
|
* @param p2 (bit 0) - allow airports directly adjacent to other airports.
|
|
|
*/
|
|
|
int32 CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
bool airport_upgrade = true;
|
|
|
|
|
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
|
|
|
|
/* Check if a valid, buildable airport was chosen for construction */
|
|
@@ -1579,15 +1579,15 @@ int32 CmdBuildAirport(TileIndex tile, ui
|
|
|
}
|
|
|
|
|
|
const AirportFTAClass *afc = GetAirport(p1);
|
|
|
int w = afc->size_x;
|
|
|
int h = afc->size_y;
|
|
|
|
|
|
int32 ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
|
|
|
CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
int32 cost = ret;
|
|
|
CommandCost cost = ret;
|
|
|
|
|
|
Station *st = NULL;
|
|
|
|
|
|
if (!_patches.adjacent_stations || !HASBIT(p2, 0)) {
|
|
|
st = GetStationAround(tile, w, h, INVALID_STATION);
|
|
|
if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
|
|
@@ -1673,24 +1673,24 @@ int32 CmdBuildAirport(TileIndex tile, ui
|
|
|
st_auto_delete.Release();
|
|
|
}
|
|
|
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
|
static int32 RemoveAirport(Station *st, uint32 flags)
|
|
|
static CommandCost RemoveAirport(Station *st, uint32 flags)
|
|
|
{
|
|
|
if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
|
|
|
return CMD_ERROR;
|
|
|
|
|
|
TileIndex tile = st->airport_tile;
|
|
|
|
|
|
const AirportFTAClass *afc = st->Airport();
|
|
|
int w = afc->size_x;
|
|
|
int h = afc->size_y;
|
|
|
|
|
|
int32 cost = w * h * _price.remove_airport;
|
|
|
CommandCost cost = w * h * _price.remove_airport;
|
|
|
|
|
|
Vehicle *v;
|
|
|
FOR_ALL_VEHICLES(v) {
|
|
|
if (!(v->type == VEH_AIRCRAFT && IsNormalAircraft(v))) continue;
|
|
|
|
|
|
if (v->u.air.targetairport == st->index && v->u.air.state != FLYING) return CMD_ERROR;
|
|
@@ -1727,13 +1727,13 @@ static int32 RemoveAirport(Station *st,
|
|
|
/** Build a buoy.
|
|
|
* @param tile tile where to place the bouy
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 unused
|
|
|
* @param p2 unused
|
|
|
*/
|
|
|
int32 CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
|
|
|
|
if (!IsClearWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE);
|
|
|
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
|
|
|
|
|
@@ -1786,13 +1786,13 @@ static bool CheckShipsOnBuoy(Station *st
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static int32 RemoveBuoy(Station *st, uint32 flags)
|
|
|
static CommandCost RemoveBuoy(Station *st, uint32 flags)
|
|
|
{
|
|
|
/* XXX: strange stuff */
|
|
|
if (!IsValidPlayer(_current_player)) return_cmd_error(INVALID_STRING_ID);
|
|
|
|
|
|
TileIndex tile = st->dock_tile;
|
|
|
|
|
@@ -1836,15 +1836,15 @@ static const byte _dock_h_chk[4] = { 1,
|
|
|
/** Build a dock/haven.
|
|
|
* @param tile tile where dock will be built
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 (bit 0) - allow docks directly adjacent to other docks.
|
|
|
* @param p2 unused
|
|
|
*/
|
|
|
int32 CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
int32 cost;
|
|
|
CommandCost cost;
|
|
|
|
|
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
|
|
|
|
DiagDirection direction;
|
|
|
switch (GetTileSlope(tile, NULL)) {
|
|
|
case SLOPE_SW: direction = DIAGDIR_NE; break;
|
|
@@ -1935,13 +1935,13 @@ int32 CmdBuildDock(TileIndex tile, uint3
|
|
|
/* success, so don't delete the new station */
|
|
|
st_auto_delete.Release();
|
|
|
}
|
|
|
return _price.build_dock;
|
|
|
}
|
|
|
|
|
|
static int32 RemoveDock(Station *st, uint32 flags)
|
|
|
static CommandCost RemoveDock(Station *st, uint32 flags)
|
|
|
{
|
|
|
if (!CheckOwnership(st->owner)) return CMD_ERROR;
|
|
|
|
|
|
TileIndex tile1 = st->dock_tile;
|
|
|
TileIndex tile2 = tile1 + TileOffsByDiagDir(GetDockDirection(tile1));
|
|
|
|
|
@@ -2491,13 +2491,13 @@ static void UpdateStationWaiting(Station
|
|
|
/** Rename a station
|
|
|
* @param tile unused
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 station ID that is to be renamed
|
|
|
* @param p2 unused
|
|
|
*/
|
|
|
int32 CmdRenameStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
CommandCost CmdRenameStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
if (!IsValidStationID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
|
|
|
Station *st = GetStation(p1);
|
|
|
|
|
|
if (!CheckOwnership(st->owner)) return CMD_ERROR;
|
|
|
|
|
@@ -2745,13 +2745,13 @@ static bool CanRemoveRoadWithStop(TileIn
|
|
|
|
|
|
bool edge_road;
|
|
|
return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, &edge_road, ROADTYPE_ROAD) &&
|
|
|
CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_TRAM), OWNER_TOWN, &edge_road, ROADTYPE_TRAM);
|
|
|
}
|
|
|
|
|
|
static int32 ClearTile_Station(TileIndex tile, byte flags)
|
|
|
static CommandCost ClearTile_Station(TileIndex tile, byte flags)
|
|
|
{
|
|
|
if (flags & DC_AUTO) {
|
|
|
switch (GetStationType(tile)) {
|
|
|
case STATION_RAIL: return_cmd_error(STR_300B_MUST_DEMOLISH_RAILROAD);
|
|
|
case STATION_AIRPORT: return_cmd_error(STR_300E_MUST_DEMOLISH_AIRPORT_FIRST);
|
|
|
case STATION_TRUCK: return_cmd_error(HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM) ? STR_3047_MUST_DEMOLISH_CARGO_TRAM_STATION : STR_3047_MUST_DEMOLISH_TRUCK_STATION);
|