diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 92d34a0191..bf22fcb5f6 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1843,6 +1843,40 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do return CommandCost(); } +/** + * Return whether industry can be built on tile or not + * regardless of terrain + */ +bool CanBuildIndustryOnTile(IndustryType type, TileIndex tile) { + const IndustrySpec *indspec = GetIndustrySpec(type); + CommandCost ret; + + if (HasBit(indspec->callback_mask, CBM_IND_LOCATION)) { + ret = CheckIfCallBackAllowsCreation( + tile, type, 0, 0, 0, _current_company, + _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION); + } else { + ret = _check_new_industry_procs[GetIndustrySpec(type)->check_proc](tile); + } + if (ret.Failed()) + return false; + + ret = CheckIfFarEnoughFromConflictingIndustry(tile, type); + if (ret.Failed()) + return false; + + Town *t = NULL; + ret = FindTownForIndustry(tile, type, &t); + if (ret.Failed()) + return false; + + ret = CheckIfIndustryIsAllowed(tile, type, t); + if (ret.Failed()) + return false; + + return true; +} + /** * Build/Fund an industry * @param tile tile where industry is built diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 6b83715672..89a6226d92 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -182,6 +182,21 @@ static const NWidgetPart _nested_build_industry_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_DPI_INFOPANEL), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetResize(1, 0), + NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(140, 14), SetDataTip(STR_FUND_INDUSTRY_FORBIDDEN_TILES_TITLE, STR_NULL), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_DPI_FT_OFF), SetMinimalSize(60, 12), + SetDataTip(STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF, STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_DPI_FT_ON), SetMinimalSize(60, 12), + SetDataTip(STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON, STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON_TOOLTIP), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 2), + EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXTBTN, COLOUR_DARK_GREEN, WID_DPI_DISPLAY_WIDGET), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_INDUSTRY_DISPLAY_CHAIN, STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP), @@ -248,6 +263,7 @@ class BuildIndustryWindow : public Window { if (this->selected_index == -1) { this->selected_index = 0; this->selected_type = this->index[0]; + SetIndustryForbiddenTilesHighlight(this->selected_type); } this->vscroll->SetCount(this->count); @@ -272,11 +288,17 @@ public: this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_DPI_SCROLLBAR); + this->LowerWidget(_settings_client.gui.show_industry_forbidden_tiles + WID_DPI_FT_OFF); this->FinishInitNested(0); this->SetButtons(); } + ~BuildIndustryWindow() + { + SetIndustryForbiddenTilesHighlight(INVALID_INDUSTRYTYPE); + } + virtual void OnInit() { this->SetupArrays(); @@ -486,6 +508,7 @@ public: if (y < this->count) { // Is it within the boundaries of available data? this->selected_index = y; this->selected_type = this->index[y]; + SetIndustryForbiddenTilesHighlight(this->selected_type); const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? NULL : GetIndustrySpec(this->selected_type); this->SetDirty(); @@ -529,6 +552,16 @@ public: } break; } + + case WID_DPI_FT_OFF: + case WID_DPI_FT_ON: + this->RaiseWidget(_settings_client.gui.show_industry_forbidden_tiles + WID_DPI_FT_OFF); + _settings_client.gui.show_industry_forbidden_tiles = (widget != WID_DPI_FT_OFF); + this->LowerWidget(_settings_client.gui.show_industry_forbidden_tiles + WID_DPI_FT_OFF); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + this->SetDirty(); + MarkWholeScreenDirty(); + break; } } diff --git a/src/industry_type.h b/src/industry_type.h index 97b82c52d4..4c5a923c0a 100644 --- a/src/industry_type.h +++ b/src/industry_type.h @@ -12,6 +12,8 @@ #ifndef INDUSTRY_TYPE_H #define INDUSTRY_TYPE_H +#include "tile_type.h" + typedef uint16 IndustryID; typedef uint16 IndustryGfx; typedef uint8 IndustryType; @@ -38,5 +40,6 @@ static const IndustryGfx INVALID_INDUSTRYTILE = NUM_INDUSTRYTILES; ///< one a static const int INDUSTRY_COMPLETED = 3; ///< final stage of industry construction. void CheckIndustries(); +bool CanBuildIndustryOnTile(IndustryType type, TileIndex tile); #endif /* INDUSTRY_TYPE_H */ diff --git a/src/lang/english.txt b/src/lang/english.txt index cde2870c50..f7f8aa7f49 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5261,3 +5261,10 @@ STR_TTE_INDUSTRY :{WHITE}{STRING} STR_TTE_STATION_NAME :{LTBLUE}{STATION} STR_TTE_STATION :{WHITE}{STRING} {BLACK}{CARGO_SHORT} {YELLOW}{NUM} % STR_LAND_AREA_INFORMATION_POP :{BLACK}Population: {LTBLUE}{NUM} + +# Industry funding forbidden tiles +STR_FUND_INDUSTRY_FORBIDDEN_TILES_TITLE :{BLACK}Forbidden areas highlight +STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF :{BLACK}Off +STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON :{BLACK}On +STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF_TOOLTIP :{BLACK}Don't highlight areas where particular industry can not be funded +STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON_TOOLTIP :{BLACK}Highlight areas where particular industry can not be funded \ No newline at end of file diff --git a/src/settings_type.h b/src/settings_type.h index 87be200980..9ed095ff89 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -171,6 +171,7 @@ struct GUISettings { uint8 cb_distance_check; ///< zoning cb distance bool enable_extra_tooltips; ///< enable extra tooltips when hovering over various elements bool polyrail_double_click; ///< finish polyrail with mouse double click + bool show_industry_forbidden_tiles; ///< higlight areas where industry placement is forbidden regardless of terrain /** * Returns true when the user has sufficient privileges to edit newgrfs on a running game diff --git a/src/table/settings.ini b/src/table/settings.ini index a1d1c9551f..ed2f0b5a82 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -4069,5 +4069,11 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = false str = STR_CONFIG_SETTING_POLYRAIL_DOUBLECLICK_TOOLTIPS +[SDTC_BOOL] +var = gui.show_industry_forbidden_tiles +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = false +cat = SC_BASIC + [SDT_END] diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h index 144c990f6a..6e5346abd4 100644 --- a/src/tilehighlight_func.h +++ b/src/tilehighlight_func.h @@ -15,6 +15,7 @@ #include "gfx_type.h" #include "tilehighlight_type.h" #include "track_type.h" +#include "industry_type.h" void PlaceProc_DemolishArea(TileIndex tile); bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile); @@ -35,6 +36,8 @@ void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track void ResetRailPlacementSnapping(); bool CurrentlySnappingRailPlacement(); +void SetIndustryForbiddenTilesHighlight(IndustryType type); + extern TileHighlightData _thd; #endif /* TILEHIGHLIGHT_FUNC_H */ diff --git a/src/viewport.cpp b/src/viewport.cpp index b880678fd7..f636808073 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -92,6 +92,7 @@ #include "table/strings.h" #include "table/palettes.h" #include "zoning.h" +#include "industry_type.h" #include "safeguards.h" @@ -216,6 +217,8 @@ static LineSnapPoints _tile_snap_points; ///< Tile to which a rail track will be static LineSnapPoints _rail_snap_points; ///< Set of points where a rail track will be snapped to (polyline tool). static LineSnapPoint _current_snap_lock; ///< Start point and direction at which selected track is locked on currently (while dragging in polyline mode). +static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE; + static RailSnapMode GetRailSnapMode(); static void SetRailSnapMode(RailSnapMode mode); static TileIndex GetRailSnapTile(); @@ -1110,6 +1113,22 @@ static void DrawTileSelection(const TileInfo *ti) } } +void SetIndustryForbiddenTilesHighlight(IndustryType type) { + if (_settings_client.gui.show_industry_forbidden_tiles && + _industry_forbidden_tiles != type) { + MarkWholeScreenDirty(); + } + _industry_forbidden_tiles = type; +} + +static void DrawIndustryForbiddenTiles(const TileInfo *ti) { + if (_settings_client.gui.show_industry_forbidden_tiles && + _industry_forbidden_tiles != INVALID_INDUSTRYTYPE && + !CanBuildIndustryOnTile(_industry_forbidden_tiles, ti->tile)) { + DrawTileSelectionRect(ti, PALETTE_SEL_TILE_RED); + } +} + /** * Returns the y coordinate in the viewport coordinate system where the given * tile is painted. @@ -1235,6 +1254,7 @@ static void ViewportAddLandscape() _tile_type_procs[tile_type]->draw_tile_proc(&tile_info); if (tile_info.tile != INVALID_TILE){ DrawTileZoning(&tile_info); + DrawIndustryForbiddenTiles(&tile_info); DrawTileSelection(&tile_info); } } diff --git a/src/widgets/industry_widget.h b/src/widgets/industry_widget.h index fcdd3edd5d..ba31c619e6 100644 --- a/src/widgets/industry_widget.h +++ b/src/widgets/industry_widget.h @@ -19,6 +19,8 @@ enum DynamicPlaceIndustriesWidgets { WID_DPI_INFOPANEL, ///< Info panel about the industry. WID_DPI_DISPLAY_WIDGET, ///< Display chain button. WID_DPI_FUND_WIDGET, ///< Fund button. + WID_DPI_FT_OFF, ///< Forbidden tiles highlight off button. + WID_DPI_FT_ON, ///< Forbidden tiles highlight on button. }; /** Widgets of the #IndustryViewWindow class. */