diff --git a/src/lang/english.txt b/src/lang/english.txt index bc24aac3fc..8df4c00602 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3174,7 +3174,8 @@ STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Railway track w STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Railway track with combo- and path signals STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Railway track with combo- and one-way path signals STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Railway track with path and one-way path signals -STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Railway train depot +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Standard railway train depot +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT_EXTENDED :Extended railway train depot STR_LAI_ROAD_DESCRIPTION_ROAD :Road STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Road with street lights @@ -5155,6 +5156,8 @@ STR_ERROR_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Can't bu STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING_DEPOT :{WHITE}... adjoins more than one existing depot STR_ERROR_DEPOT_TYPE_NOT_AVAILABLE :{WHITE}... depot type not available +STR_ERROR_DEPOT_EXTENDING_PLATFORMS :{WHITE}Extending already reserved depot platforms +STR_ERROR_DEPOT_EXTENDED_RAIL_DEPOT_IS_NOT_FREE :{WHITE}Extended rail depot has a reserved tile and can't be converted STR_ERROR_CAN_T_RENAME_DEPOT :{WHITE}Can't rename depot... diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index 9580086799..979cfb060b 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -646,7 +646,9 @@ bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, b /** if any track changes, this counter is incremented - that will invalidate segment cost cache */ int CSegmentCostCacheBase::s_rail_change_counter = 0; +extern void FixBigRailDepotSprites(Tile tile); void YapfNotifyTrackLayoutChange(TileIndex tile, Track track) { + FixBigRailDepotSprites(tile); CSegmentCostCacheBase::NotifyTrackLayoutChange(tile, track); } diff --git a/src/pbs.cpp b/src/pbs.cpp index 03b5311f89..209f2c0acf 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -446,3 +446,26 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo return !HasReservedTracks(ft.m_new_tile, TrackdirBitsToTrackBits(ft.m_new_td_bits)); } + +/** + * Fix the sprites of depots to show it opened or closed depending on its neighbours. + * @param t Tile that has changed. + */ +void FixBigRailDepotSprites(Tile t) +{ + if (t == INVALID_TILE) return; + + /* Expand tile area to check. */ + TileArea ta = TileArea(t).Expand(1); + + for (Tile tile : ta) { + if (!IsExtendedRailDepotTile(tile)) continue; + CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(GetTileRailType(tile))->compatible_railtypes); + Track track = GetRailDepotTrack(tile); + Trackdir trackdir = TrackToTrackdir(track); + if (track == TRACK_X) trackdir = ReverseTrackdir(trackdir); + bool opened = ft.Follow(tile, trackdir); + if (track == TRACK_Y) opened = !opened; + SB(tile.m5(), 1, 1, opened); + } +} diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index cb07c49d1c..2868d174b5 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -956,6 +956,7 @@ CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex end_tile, Tile * @param railtype rail type * @param dir entrance direction * @param adjacent allow adjacent depots + * @param extended build extended depots * @param join_to depot to join to * @param end_tile end tile of the area to be built * @return the cost of this operation or an error @@ -963,11 +964,13 @@ CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex end_tile, Tile * @todo When checking for the tile slope, * distinguish between "Flat land required" and "land sloped in wrong direction" */ -CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir, bool adjacent, DepotID join_to, TileIndex end_tile) +CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir, bool adjacent, bool extended, DepotID join_to, TileIndex end_tile) { /* check railtype and valid direction for depot (0 through 3), 4 in total */ if (!ValParamRailType(railtype) || !IsValidDiagDirection(dir)) return CMD_ERROR; + if (Company::IsValidHumanID(_current_company) && !HasBit(_settings_game.depot.rail_depot_types, extended)) return_cmd_error(STR_ERROR_DEPOT_TYPE_NOT_AVAILABLE); + CommandCost cost(EXPENSES_CONSTRUCTION); TileArea ta(tile, end_tile); Depot *depot = nullptr; @@ -976,14 +979,42 @@ CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType rai CommandCost ret = FindJoiningDepot(ta, VEH_TRAIN, join_to, depot, adjacent, flags); if (ret.Failed()) return ret; + Axis axis = DiagDirToAxis(dir); + /* Do not allow extending already occupied platforms. */ + if (extended && join_to != NEW_DEPOT) { + TileArea ta_ext = TileArea(ta.tile, ta.w, ta.h).Expand(1); + + uint max_coord; + uint min_coord; + if (axis == AXIS_X) { + min_coord = TileY(ta.tile); + max_coord = min_coord + ta.h; + } else { + min_coord = TileX(ta.tile); + max_coord = min_coord + ta.w; + } + + for (Tile t : ta_ext) { + if (!IsExtendedRailDepotTile(t)) continue; + if (GetDepotIndex(t) != depot->index) continue; + if (GetRailType(t) != railtype) continue; + if (!HasDepotReservation(t)) continue; + if (DiagDirToAxis(GetRailDepotDirection(t)) != axis) continue; + uint current = (axis == AXIS_X) ? TileY(t) : TileX(t); + if (!IsInsideMM(current, min_coord, max_coord)) continue; + return_cmd_error(STR_ERROR_DEPOT_EXTENDING_PLATFORMS); + } + } + uint8_t num_new_depot_tiles = 0; - uint8_t num_rotated_depot_tiles = 0; + uint8_t num_overbuilt_depot_tiles = 0; /* Prohibit construction if * The tile is non-flat AND * 1) build-on-slopes is disabled * 2) the tile is steep i.e. spans two height levels * 3) the exit points in the wrong direction + * 4) the tile is not an already built depot (or it is a compatible single rail tile for building extended depots) */ for (Tile t : ta) { if (IsBridgeAbove(t)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -994,42 +1025,82 @@ CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType rai !CanBuildDepotByTileh(dir, tileh)) { return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); } + if (extended && !CanBuildDepotByTileh(ReverseDiagDir(dir), tileh)) { + return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); + } cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - /* Check whether a depot tile exists and it needs to be rotated. */ - if (IsRailDepotTile(t) && GetDepotIndex(t) == join_to && railtype == GetRailType(t)) { - if (dir == GetRailDepotDirection(t)) continue; + if (extended) { + if (IsPlainRailTile(t) && !HasSignals(t) && GetRailType(t) == railtype) { + /* Allow overbuilding if the tile: + * - has rail, but no signals + * - it has exactly one track + * - the track is in line with the depot + * - the current rail type is the same as the to-be-built + */ + TrackBits tracks = GetTrackBits(t); + Track track = RemoveFirstTrack(&tracks); + uint invalid_dirs = 5 << DiagDirToAxis(dir); + Track expected_track = HasBit(invalid_dirs, DIAGDIR_NE) ? TRACK_X : TRACK_Y; - ret = EnsureNoVehicleOnGround(t); - if (ret.Failed()) return ret; + if (tracks == TRACK_BIT_NONE && track == expected_track) { + cost.AddCost(Command::Do(flags, t, track).GetCost()); + /* With flags & ~DC_EXEC CmdLandscapeClear would fail since the rail still exists */ + if (cost.Failed()) return cost; + goto new_depot_tile; + } + } - num_rotated_depot_tiles++; - if (flags & DC_EXEC) { - SetRailDepotExitDirection(t, dir); + /* Skip already existing and compatible extended depots. */ + if (IsRailDepotTile(t) && IsExtendedRailDepotTile(t) && + GetDepotIndex(t) == join_to && railtype == GetRailType(t)) { + if (axis == DiagDirToAxis(GetRailDepotDirection(t))) continue; } } else { - cost.AddCost(Command::Do(flags, t)); - if (cost.Failed()) return cost; + /* Check whether this is a standard depot tile and it needs to be rotated. */ + if (IsRailDepotTile(t) && IsStandardRailDepotTile(t) && + GetDepotIndex(t) == join_to && railtype == GetRailType(t)) { + if (dir == GetRailDepotDirection(t)) continue; - num_new_depot_tiles++; - if (flags & DC_EXEC) { - MakeRailDepot(t, _current_company, depot->index, dir, railtype); - MarkTileDirtyByTile(t); + ret = EnsureNoVehicleOnGround(t); + if (ret.Failed()) return ret; + + num_overbuilt_depot_tiles++; + if (flags & DC_EXEC) { + SetRailDepotExitDirection(t, dir); + AddSideToSignalBuffer(t, INVALID_DIAGDIR, _current_company); + YapfNotifyTrackLayoutChange(t, DiagDirToDiagTrack(dir)); + MarkTileDirtyByTile(t); + } + continue; } } + cost.AddCost(Command::Do(flags, t)); + if (cost.Failed()) return cost; + +new_depot_tile: + num_new_depot_tiles++; + if (flags & DC_EXEC) { - AddSideToSignalBuffer(t, INVALID_DIAGDIR, _current_company); + MakeRailDepot(t, _current_company, depot->index, dir, railtype); + SB(t.m5(), 5, 1, extended); + + if (extended) { + AddTrackToSignalBuffer(t, DiagDirToDiagTrack(dir), _current_company); + } else { + AddSideToSignalBuffer(t, INVALID_DIAGDIR, _current_company); + } YapfNotifyTrackLayoutChange(t, DiagDirToDiagTrack(dir)); MarkTileDirtyByTile(t); } } - if (num_new_depot_tiles + num_rotated_depot_tiles == 0) return CommandCost(); + if (num_new_depot_tiles + num_overbuilt_depot_tiles == 0) return CommandCost(); - cost.AddCost(_price[PR_BUILD_DEPOT_TRAIN] * (num_new_depot_tiles + num_rotated_depot_tiles)); - cost.AddCost(RailBuildCost(railtype) * (num_new_depot_tiles + num_rotated_depot_tiles)); + cost.AddCost(_price[PR_BUILD_DEPOT_TRAIN] * (num_new_depot_tiles + num_overbuilt_depot_tiles)); + cost.AddCost(RailBuildCost(railtype) * (num_new_depot_tiles + num_overbuilt_depot_tiles)); if (flags & DC_EXEC) { Company::Get(_current_company)->infrastructure.rail[railtype] += num_new_depot_tiles; @@ -1551,6 +1622,56 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) return nullptr; } +/** + * Returns whether a depot has an extended depot + * tile which is reserved. + * @param Depot pointer to a depot + * @return true iff \a dep has an extended depot tile reserved. + */ +bool HasAnyExtendedDepotReservedTile(Depot *dep) +{ + assert(dep != nullptr); + for (TileIndex tile : dep->ta) { + if (!IsExtendedDepotTile(tile)) continue; + if (GetDepotIndex(tile) != dep->index) continue; + if (HasDepotReservation(tile)) return true; + } + + return false; +} + +CommandCost ConvertExtendedDepot(DoCommandFlag flags, Depot *dep, RailType rail_type) +{ + CommandCost cost(EXPENSES_CONSTRUCTION); + assert(dep->owner == _current_company); + Company *c = Company::Get(dep->owner); + + for (TileIndex tile : dep->ta) { + if (!IsDepotTile(tile)) continue; + if (GetDepotIndex(tile) != dep->index) continue; + assert(!HasDepotReservation(tile)); + assert(dep->owner == GetTileOwner(tile)); + + /* Original railtype we are converting from */ + RailType type = GetRailType(tile); + + if (type == rail_type || (_settings_game.vehicle.disable_elrails && rail_type == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue; + + cost.AddCost(RailConvertCost(type, rail_type)); + + if (flags & DC_EXEC) { + c->infrastructure.rail[type]--; + c->infrastructure.rail[rail_type]++; + SetRailType(tile, rail_type); + MarkTileDirtyByTile(tile); + YapfNotifyTrackLayoutChange(tile, GetRailDepotTrack(tile)); + DirtyCompanyInfrastructureWindows(c->index); + } + } + + return cost; +} + /** * Convert one rail type to the other. You can convert normal rail to * monorail/maglev easily or vice-versa. @@ -1664,11 +1785,12 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s if (flags & DC_EXEC) { /* notify YAPF about the track layout change */ YapfNotifyTrackLayoutChange(tile, GetRailDepotTrack(tile)); - - if (find(affected_depots.begin(), affected_depots.end(), (tile)) == affected_depots.end()) { - affected_depots.push_back(GetDepotIndex(tile)); - } } + + if (find(affected_depots.begin(), affected_depots.end(), (tile)) == affected_depots.end()) { + affected_depots.push_back(GetDepotIndex(tile)); + } + cost.AddCost(RailConvertCost(type, totype)); } else { // RAIL_TILE_NORMAL, RAIL_TILE_SIGNALS if (flags & DC_EXEC) { @@ -1760,14 +1882,18 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s } } - if (flags & DC_EXEC) { - /* Update affected depots. */ - for (auto &depot_tile : affected_depots) { - Depot *dep = Depot::Get(depot_tile); + /* Update affected depots. */ + for (auto &depot_tile : affected_depots) { + Depot *dep = Depot::Get(depot_tile); + if (HasAnyExtendedDepotReservedTile(dep)) cost.MakeError(STR_ERROR_DEPOT_EXTENDED_RAIL_DEPOT_IS_NOT_FREE); + + if (flags & DC_EXEC) { dep->RescanDepotTiles(); InvalidateWindowData(WC_VEHICLE_DEPOT, dep->index); } + } + if (flags & DC_EXEC) { /* Railtype changed, update trains as when entering different track */ for (Train *v : affected_trains) { v->ConsistChanged(CCF_TRACK); @@ -1777,7 +1903,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s return found_convertible_track ? cost : error; } -static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) +static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags, bool keep_rail) { assert(IsRailDepotTile(tile)); @@ -1789,6 +1915,15 @@ static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) CommandCost ret = EnsureNoVehicleOnGround(tile); if (ret.Failed()) return ret; + if (HasDepotReservation(tile)) return CMD_ERROR; + + CommandCost total_cost(EXPENSES_CONSTRUCTION); + + if (keep_rail) { + /* Don't refund the 'steel' of the track when we keep the rail. */ + total_cost.AddCost(-_price[PR_CLEAR_RAIL]); + } + if (flags & DC_EXEC) { Depot *depot = Depot::GetByTile(tile); Company *c = Company::GetIfValid(depot->owner); @@ -1802,12 +1937,24 @@ static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) if (v != nullptr) FreeTrainTrackReservation(v); } - c->infrastructure.rail[GetRailType(tile)]--; - DirtyCompanyInfrastructureWindows(c->index); + Track track = GetRailDepotTrack(tile); + RailType rt = GetRailType(tile); + bool is_extended_depot = IsExtendedDepot(tile); DoClearSquare(tile); - AddSideToSignalBuffer(tile, dir, c->index); + if (keep_rail) { + MakeRailNormal(tile, depot->owner, TrackToTrackBits(track), rt); + } else { + c->infrastructure.rail[GetRailType(tile)]--; + DirtyCompanyInfrastructureWindows(c->index); + } + + if (is_extended_depot) { + AddTrackToSignalBuffer(tile, DiagDirToDiagTrack(dir), c->index); + } else { + AddSideToSignalBuffer(tile, dir, c->index); + } YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir)); if (v != nullptr) TryPathReserve(v, true); @@ -1815,7 +1962,8 @@ static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) depot->AfterAddRemove(TileArea(tile), false); } - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_TRAIN]); + total_cost.AddCost(_price[PR_CLEAR_DEPOT_TRAIN]); + return total_cost; } /** @@ -1834,7 +1982,7 @@ CommandCost CmdRemoveTrainDepot(DoCommandFlag flags, TileIndex start_tile, TileI TileArea ta(start_tile, end_tile); for (TileIndex t : ta) { if (!IsRailDepotTile(t)) continue; - CommandCost ret = RemoveTrainDepot(t, flags); + CommandCost ret = RemoveTrainDepot(t, flags, IsExtendedDepot(t)); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -1890,7 +2038,7 @@ static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags) } case RAIL_TILE_DEPOT: - return RemoveTrainDepot(tile, flags); + return RemoveTrainDepot(tile, flags, false); default: return CMD_ERROR; @@ -2742,6 +2890,13 @@ static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, } case RAIL_TILE_DEPOT: { + if (IsExtendedRailDepot(tile)) { + Track track = GetRailDepotTrack(tile); + trackbits = TrackToTrackBits(track); + break; + } + + /* Small depot. */ DiagDirection dir = GetRailDepotDirection(tile); if (side != INVALID_DIAGDIR && side != dir) break; @@ -2839,7 +2994,7 @@ static void GetTileDesc_Track(TileIndex tile, TileDesc *td) } case RAIL_TILE_DEPOT: - td->str = STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT; + td->str = IsExtendedDepot(tile) ? STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT_EXTENDED : STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT; if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL) { if (td->rail_speed > 0) { td->rail_speed = std::min(td->rail_speed, 61); @@ -3065,6 +3220,14 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price[PR_CLEAR_WATER] : (Money)0); } else if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() && AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) { + if (IsExtendedRailDepotTile(tile) && GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) { + DiagDirection direction = GetRailDepotDirection(tile); + if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction) || + !AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) { + return Command::Do(flags, tile); + } + } + return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } return Command::Do(flags, tile); diff --git a/src/rail_cmd.h b/src/rail_cmd.h index 775bfa7ed7..bcd28fa2e3 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -19,7 +19,7 @@ CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex end_tile, TileI CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, Track track); CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType railtype, Track track, bool auto_remove_signals); CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, Track track); -CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir, bool adjacent, DepotID depot_id, TileIndex end_tile); +CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir, bool adjacent, bool extended, DepotID depot_id, TileIndex end_tile); CommandCost CmdRemoveTrainDepot(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile); CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, Track track, SignalType sigtype, SignalVariant sigvar, bool convert_signal, bool skip_existing_signals, bool ctrl_pressed, SignalType cycle_start, SignalType cycle_stop, uint8_t num_dir_cycle, uint8_t signals_copy); CommandCost CmdRemoveSingleSignal(DoCommandFlag flags, TileIndex tile, Track track); @@ -42,6 +42,6 @@ DEF_CMD_TRAIT(CMD_REMOVE_SIGNAL_TRACK, CmdRemoveSignalTrack, CMD_AUTO, CommandCallback CcPlaySound_CONSTRUCTION_RAIL; CommandCallback CcStation; CommandCallback CcBuildRailTunnel; -void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, RailType rt, DiagDirection dir, bool adjacent, DepotID join_to, TileIndex end_tile); +void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, RailType rt, DiagDirection dir, bool adjacent, bool extended, DepotID join_to, TileIndex end_tile); #endif /* RAIL_CMD_H */ diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 6001a5de03..0e801ba782 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -138,9 +138,10 @@ static const DiagDirection _place_depot_extra_dir[12] = { DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE, }; -void CcRailDepot(Commands, const CommandCost &result, TileIndex start_tile, RailType, DiagDirection dir, bool, DepotID, TileIndex end_tile) +void CcRailDepot(Commands, const CommandCost &result, TileIndex start_tile, RailType, DiagDirection dir, bool, bool extended, DepotID, TileIndex end_tile) { if (result.Failed()) return; + if (extended) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, start_tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); @@ -613,7 +614,8 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT)) { + case WID_RAT_BUILD_EXTENDED_DEPOT: + if (HandlePlacePushButton(this, widget, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT)) { ShowBuildTrainDepotPicker(this); this->last_user_action = widget; } @@ -700,10 +702,14 @@ struct BuildRailToolbarWindow : Window { PlaceProc_DemolishArea(tile); break; - case WID_RAT_BUILD_DEPOT: { + case WID_RAT_BUILD_DEPOT: + case WID_RAT_BUILD_EXTENDED_DEPOT: { CloseWindowById(WC_SELECT_DEPOT, VEH_TRAIN); - ViewportPlaceMethod vpm = (DiagDirToAxis(_build_depot_direction) == 0) ? VPM_X_LIMITED : VPM_Y_LIMITED; + ViewportPlaceMethod vpm = VPM_X_AND_Y_LIMITED; + if (this->last_user_action == WID_RAT_BUILD_DEPOT) { + vpm = (DiagDirToAxis(_build_depot_direction) == 0) ? VPM_X_LIMITED : VPM_Y_LIMITED; + } VpStartPlaceSizing(tile, vpm, _remove_button_clicked ? DDSP_REMOVE_DEPOT : DDSP_BUILD_DEPOT); VpSetPlaceSizingLimit(_settings_game.depot.depot_spread); break; @@ -805,13 +811,15 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_BUILD_DEPOT: + case DDSP_REMOVE_DEPOT: if (_remove_button_clicked) { Command::Post(STR_ERROR_CAN_T_REMOVE_TRAIN_DEPOT, CcPlaySound_CONSTRUCTION_RAIL, start_tile, end_tile); } else { bool adjacent = _ctrl_pressed; + bool extended = this->last_user_action == WID_RAT_BUILD_EXTENDED_DEPOT; auto proc = [=](DepotID join_to) -> bool { - return Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, start_tile, _cur_railtype, _build_depot_direction, adjacent, join_to, end_tile); + return Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, start_tile, _cur_railtype, _build_depot_direction, adjacent, extended, join_to, end_tile); }; ShowSelectDepotIfNeeded(TileArea(start_tile, end_tile), proc, VEH_TRAIN); diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index f0c79fcff9..d92010de7f 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -145,7 +145,7 @@ DiagDirection entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? DIAGDIR_SE : DIAGDIR_NW) : (::TileX(tile) < ::TileX(front) ? DIAGDIR_SW : DIAGDIR_NE); - return ScriptObject::Command::Do(tile, (::RailType)ScriptObject::GetRailType(), entrance_dir, false, INVALID_DEPOT, tile); + return ScriptObject::Command::Do(tile, (::RailType)ScriptObject::GetRailType(), entrance_dir, false, false, INVALID_DEPOT, tile); } /* static */ bool ScriptRail::RemoveRailDepot(TileIndex start_tile, TileIndex end_tile)