From 01ac0e653fa466ed0d05a37053c572d19664b09f Mon Sep 17 00:00:00 2001 From: J0anJosep Date: Sat, 26 Aug 2023 17:58:37 +0200 Subject: [PATCH] Feature: Allow building extended ship depots. --- src/dock_gui.cpp | 49 +++++++++++++++++++++++++++----- src/lang/english.txt | 6 ++-- src/script/api/script_marine.cpp | 2 +- src/water_cmd.cpp | 11 +++++-- src/water_cmd.h | 2 +- src/water_map.h | 7 +++-- src/widgets/dock_widget.h | 3 +- 7 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 2cc37266a5..2b2a369665 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -113,7 +113,12 @@ struct BuildDocksToolbarWindow : Window { { if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false); - if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_DT_DEPOT)) SetViewportHighlightDepot(INVALID_DEPOT, true); + + if (_game_mode == GM_NORMAL && + ((this->HasWidget(WID_DT_DEPOT) && this->IsWidgetLowered(WID_DT_DEPOT)) || + (this->HasWidget(WID_DT_EXTENDED_DEPOT) && this->IsWidgetLowered(WID_DT_EXTENDED_DEPOT)))) { + SetViewportHighlightDepot(INVALID_DEPOT, true); + } this->Window::Close(); } @@ -130,6 +135,7 @@ struct BuildDocksToolbarWindow : Window { bool can_build = CanBuildVehicleInfrastructure(VEH_SHIP); this->SetWidgetsDisabledState(!can_build, WID_DT_DEPOT, + WID_DT_EXTENDED_DEPOT, WID_DT_STATION, WID_DT_BUOY); if (!can_build) { @@ -140,11 +146,13 @@ struct BuildDocksToolbarWindow : Window { if (_game_mode != GM_EDITOR) { if (!can_build) { /* Show in the tooltip why this button is disabled. */ - this->GetWidget(WID_DT_DEPOT)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE); + if (this->HasWidget(WID_DT_DEPOT)) this->GetWidget(WID_DT_DEPOT)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE); + if (this->HasWidget(WID_DT_EXTENDED_DEPOT)) this->GetWidget(WID_DT_EXTENDED_DEPOT)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE); this->GetWidget(WID_DT_STATION)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE); this->GetWidget(WID_DT_BUOY)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE); } else { - this->GetWidget(WID_DT_DEPOT)->SetToolTip(STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP); + if (this->HasWidget(WID_DT_DEPOT)) this->GetWidget(WID_DT_DEPOT)->SetToolTip(STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP); + if (this->HasWidget(WID_DT_EXTENDED_DEPOT)) this->GetWidget(WID_DT_EXTENDED_DEPOT)->SetToolTip(STR_WATERWAYS_TOOLBAR_BUILD_EXTENDED_DEPOT_TOOLTIP); this->GetWidget(WID_DT_STATION)->SetToolTip(STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP); this->GetWidget(WID_DT_BUOY)->SetToolTip(STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP); } @@ -167,6 +175,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_DEPOT: // Build depot button + case WID_DT_EXTENDED_DEPOT: if (HandlePlacePushButton(this, widget, SPR_CURSOR_SHIP_DEPOT, HT_RECT)) { ShowBuildDocksDepotPicker(this); } @@ -209,7 +218,8 @@ struct BuildDocksToolbarWindow : Window { PlaceProc_DemolishArea(tile); break; - case WID_DT_DEPOT: { // Build depot button + case WID_DT_DEPOT: // Build depot button + case WID_DT_EXTENDED_DEPOT: { CloseWindowById(WC_SELECT_DEPOT, VEH_SHIP); ViewportPlaceMethod vpm = _ship_depot_direction != AXIS_X ? VPM_LIMITED_X_FIXED_Y : VPM_LIMITED_Y_FIXED_X; @@ -274,8 +284,10 @@ struct BuildDocksToolbarWindow : Window { break; case DDSP_BUILD_DEPOT: { bool adjacent = _ctrl_pressed; + bool extended = this->last_clicked_widget == WID_DT_EXTENDED_DEPOT; + auto proc = [=](DepotID join_to) -> bool { - return Command::Post(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, start_tile, _ship_depot_direction, adjacent, join_to, end_tile); + return Command::Post(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, start_tile, _ship_depot_direction, adjacent, extended, join_to, end_tile); }; ShowSelectDepotIfNeeded(TileArea(start_tile, end_tile), proc, VEH_SHIP); @@ -291,7 +303,11 @@ struct BuildDocksToolbarWindow : Window { { if (_game_mode != GM_EDITOR && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true); - if (_game_mode != GM_EDITOR && this->IsWidgetLowered(WID_DT_DEPOT)) SetViewportHighlightDepot(INVALID_DEPOT, true); + if (_game_mode != GM_EDITOR && + ((this->HasWidget(WID_DT_DEPOT) && this->IsWidgetLowered(WID_DT_DEPOT)) || + (this->HasWidget(WID_DT_EXTENDED_DEPOT) && this->IsWidgetLowered(WID_DT_EXTENDED_DEPOT)))) { + SetViewportHighlightDepot(INVALID_DEPOT, true); + } this->RaiseButtons(); @@ -346,6 +362,25 @@ struct BuildDocksToolbarWindow : Window { }, DockToolbarGlobalHotkeys}; }; +/** + * Add the depot icons depending on availability of construction. + * @return Panel with water depot buttons. + */ +static std::unique_ptr MakeNWidgetWaterDepot() +{ + auto hor = std::make_unique(); + + if (HasBit(_settings_game.depot.water_depot_types, 0)) { + hor->Add(std::make_unique(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_DEPOT, SPR_IMG_SHIP_DEPOT, STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP)); + } + + if (HasBit(_settings_game.depot.water_depot_types, 1)) { + hor->Add(std::make_unique(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_EXTENDED_DEPOT, SPR_IMG_SHIP_DEPOT, STR_WATERWAYS_TOOLBAR_BUILD_EXTENDED_DEPOT_TOOLTIP)); + } + + return hor; +} + /** * Nested widget parts of docks toolbar, game version. * Position of #WID_DT_RIVER widget has changed. @@ -361,7 +396,7 @@ static constexpr NWidgetPart _nested_build_docks_toolbar_widgets[] = { NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_LOCK), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_BUILD_LOCK, STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(5, 22), SetFill(1, 1), EndContainer(), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_DEMOLISH), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC), - NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_DEPOT), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_SHIP_DEPOT, STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP), + NWidgetFunction(MakeNWidgetWaterDepot), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_STATION), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_SHIP_DOCK, STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_BUOY), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_BUOY, STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_DT_BUILD_AQUEDUCT), SetMinimalSize(23, 22), SetFill(0, 1), SetDataTip(SPR_IMG_AQUEDUCT, STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP), diff --git a/src/lang/english.txt b/src/lang/english.txt index db85c9e349..f1354b08e6 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2959,7 +2959,8 @@ STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Waterway STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Waterways STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Build canals. Also press Shift to show cost estimate only STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Build locks. Also press Shift to show cost estimate only -STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Build ship depot (for buying and servicing ships). Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Build standard ship depot (for buying and servicing ships). Ctrl+Click to select another depot to join. Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUILD_EXTENDED_DEPOT_TOOLTIP :{BLACK}Build extended ship depot (for buying and servicing ships). Ctrl+Click to select another depot to join. Also press Shift to show cost estimate only STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Build ship dock. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Place a buoy which can be used as a waypoint. Also press Shift to show cost estimate only STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Build aqueduct. Also press Shift to show cost estimate only @@ -3202,7 +3203,8 @@ STR_LAI_WATER_DESCRIPTION_CANAL :Canal STR_LAI_WATER_DESCRIPTION_LOCK :Lock STR_LAI_WATER_DESCRIPTION_RIVER :River STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK :Coast or riverbank -STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT :Ship depot +STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT :Standard ship depot +STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT_EXTENDED :Extended ship depot # Industries come directly from their industry names diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index 5e6d60a6c6..5b30290d4b 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.cpp @@ -83,7 +83,7 @@ EnforcePrecondition(false, ::IsValidTile(front)); EnforcePrecondition(false, (::TileX(front) == ::TileX(tile)) != (::TileY(front) == ::TileY(tile))); - return ScriptObject::Command::Do(tile, ::TileX(front) == ::TileX(tile) ? AXIS_Y : AXIS_X, false, INVALID_DEPOT, tile); + return ScriptObject::Command::Do(tile, ::TileX(front) == ::TileX(tile) ? AXIS_Y : AXIS_X, false, false, INVALID_DEPOT, tile); } /* static */ bool ScriptMarine::BuildDock(TileIndex tile, StationID station_id) diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 7c265e81cc..235b111412 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -97,12 +97,17 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile) * @param tile first tile where ship depot is built * @param axis depot orientation (Axis) * @param adjacent allow adjacent depots + * @param extended whether to build an extended depot * @param join_to depot to join to * @param end_tile end tile of area to be built * @return the cost of this operation or an error */ -CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis, bool adjacent, DepotID join_to, TileIndex end_tile) +CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis, bool adjacent, bool extended, DepotID join_to, TileIndex end_tile) { + if (Company::IsValidHumanID(_current_company) && !HasBit(_settings_game.depot.water_depot_types, extended)) { + return_cmd_error(STR_ERROR_DEPOT_TYPE_NOT_AVAILABLE); + } + if (!IsValidAxis(axis)) return CMD_ERROR; TileIndex tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); @@ -149,7 +154,7 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis, bo if (flags & DC_EXEC) { DepotPart dp = northern_tiles.Contains(t) ? DEPOT_PART_NORTH : DEPOT_PART_SOUTH; - MakeShipDepot(t, _current_company, depot->index, dp, axis, wc); + MakeShipDepot(t, _current_company, depot->index, extended, dp, axis, wc); CheckForDockingTile(t); MarkTileDirtyByTile(t); } @@ -984,7 +989,7 @@ static void GetTileDesc_Water(TileIndex tile, TileDesc *td) case WATER_TILE_COAST: td->str = STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK; break; case WATER_TILE_LOCK : td->str = STR_LAI_WATER_DESCRIPTION_LOCK; break; case WATER_TILE_DEPOT: - td->str = STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT; + td->str = IsExtendedDepot(tile) ? STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT_EXTENDED : STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT; td->build_date = Depot::GetByTile(tile)->build_date; break; default: NOT_REACHED(); diff --git a/src/water_cmd.h b/src/water_cmd.h index 60e00d4a4c..02efc043ce 100644 --- a/src/water_cmd.h +++ b/src/water_cmd.h @@ -13,7 +13,7 @@ #include "command_type.h" #include "water_map.h" -CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis, bool adjacent, DepotID depot_id, TileIndex end_tile); +CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis, bool adjacent, bool extended, DepotID depot_id, TileIndex end_tile); CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal); CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile); diff --git a/src/water_map.h b/src/water_map.h index 18626e8fb4..3cfdac071a 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -24,6 +24,8 @@ enum WaterTileTypeBitLayout { WBL_TYPE_LOCK = 0x1, ///< Lock ('type' bitfield). WBL_TYPE_DEPOT = 0x2, ///< Depot ('type' bitfield). + WBL_DEPOT_EXTENDED = 5, ///< Bit for the standard/extended depot flag. + WBL_COAST_FLAG = 0, ///< Flag for coast. WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientation bitfield. @@ -464,11 +466,12 @@ inline void MakeCanal(Tile t, Owner o, uint8_t random_bits) * @param t Tile to place the ship depot section. * @param o Owner of the depot. * @param did Depot ID. + * @param extended True if building an extended depot. * @param part Depot part (either #DEPOT_PART_NORTH or #DEPOT_PART_SOUTH). * @param a Axis of the depot. * @param original_water_class Original water class. */ -inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, WaterClass original_water_class) +inline void MakeShipDepot(Tile t, Owner o, DepotID did, bool extended, DepotPart part, Axis a, WaterClass original_water_class) { SetTileType(t, MP_WATER); SetTileOwner(t, o); @@ -477,7 +480,7 @@ inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, t.m2() = did; t.m3() = 0; t.m4() = 0; - t.m5() = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; + t.m5() = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | extended << WBL_DEPOT_EXTENDED | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; SB(t.m6(), 2, 4, 0); t.m7() = 0; } diff --git a/src/widgets/dock_widget.h b/src/widgets/dock_widget.h index 0a1f480eb6..84f39589c0 100644 --- a/src/widgets/dock_widget.h +++ b/src/widgets/dock_widget.h @@ -22,7 +22,8 @@ enum DockToolbarWidgets : WidgetID { WID_DT_CANAL, ///< Build canal button. WID_DT_LOCK, ///< Build lock button. WID_DT_DEMOLISH, ///< Demolish aka dynamite button. - WID_DT_DEPOT, ///< Build depot button. + WID_DT_DEPOT, ///< Build standard depot button. + WID_DT_EXTENDED_DEPOT, ///< Build extended depot button. WID_DT_STATION, ///< Build station button. WID_DT_BUOY, ///< Build buoy button. WID_DT_RIVER, ///< Build river button (in scenario editor).