diff --git a/cm_changelog.txt b/cm_changelog.txt index 1eaa2ab082..de54453904 100644 --- a/cm_changelog.txt +++ b/cm_changelog.txt @@ -75,9 +75,11 @@ This is usable for any OpenTTD servers == CHANGELOG == *** ??? *** -- Fix company selection when clicking in online players window. -- Fix cargo selection in charts. -- Fix shaded trees setting UI. +- Added a hotkey to switch industry layouts when funding (MMB by default). +- Fixed crash when no graphics were installed. +- Fixed company selection when clicking in online players window. +- Fixed cargo selection in charts. +- Fixed shaded trees setting UI. *** 12.2 (3 Apr 2022) *** - OpenTTD update. diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index 43491fda47..e6cafbf1d7 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -18,6 +18,7 @@ #include "../newgrf_roadtype.h" #include "../newgrf_station.h" #include "../spritecache.h" +#include "../strings_func.h" #include "../town.h" #include "../town_kdtree.h" #include "../tilearea_type.h" @@ -54,6 +55,8 @@ extern DiagDirection _build_depot_direction; ///< Currently selected depot direc extern DiagDirection _road_station_picker_orientation; extern DiagDirection _road_depot_orientation; extern uint32 _realtime_tick; +extern uint32 _cm_funding_layout; +extern IndustryType _cm_funding_type; extern void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const StationSpec *statspec); struct RailStationGUISettings { @@ -175,6 +178,12 @@ ObjectTileHighlight ObjectTileHighlight::make_point(SpriteID palette) { return ObjectTileHighlight(Type::POINT, palette); } +ObjectTileHighlight ObjectTileHighlight::make_numbered_rect(SpriteID palette, uint32 number) { + auto oh = ObjectTileHighlight(Type::NUMBERED_RECT, palette); + oh.u.numbered_rect.number = number; + return oh; +} + bool ObjectHighlight::operator==(const ObjectHighlight& oh) { if (this->type != oh.type) return false; @@ -263,6 +272,14 @@ ObjectHighlight ObjectHighlight::make_polyrail(TileIndex start_tile, TileIndex e return oh; } +ObjectHighlight ObjectHighlight::make_industry(TileIndex tile, IndustryType ind_type, uint32 ind_layout) { + auto oh = ObjectHighlight{ObjectHighlight::Type::INDUSTRY}; + oh.tile = tile; + oh.ind_type = ind_type; + oh.ind_layout = ind_layout; + return oh; +} + /** * Try to add an additional rail-track at the entrance of a depot * @param tile Tile to use for adding the rail-track @@ -497,6 +514,9 @@ void ObjectHighlight::UpdateTiles() { add_track(this->tile2, this->end_tile2, this->trackdir2, PALETTE_SEL_TILE_BLUE, INVALID_TILE, INVALID_TILE); break; } + case Type::INDUSTRY: + this->AddTile(this->tile, ObjectTileHighlight::make_numbered_rect(CM_PALETTE_TINT_WHITE, this->ind_layout)); + break; default: NOT_REACHED(); } @@ -962,6 +982,24 @@ void ObjectHighlight::Draw(const TileInfo *ti) { case ObjectTileHighlight::Type::POINT: DrawSelectionPoint(oth.palette, ti); break; + case ObjectTileHighlight::Type::NUMBERED_RECT: { + DrawTileSelectionRect(ti, oth.palette); + ViewportSign sign; + auto string_id = oth.u.numbered_rect.number ? CM_STR_LAYOUT_NUM : CM_STR_LAYOUT_RANDOM; + + SetDParam(0, oth.u.numbered_rect.number); + char buffer[DRAW_STRING_BUFFER]; + GetString(buffer, string_id, lastof(buffer)); + auto bb = GetStringBoundingBox(buffer); + sign.width_normal = VPSM_LEFT + Align(bb.width, 2) + VPSM_RIGHT; + Point pt = RemapCoords2(TileX(ti->tile) * TILE_SIZE + TILE_SIZE / 2, TileY(ti->tile) * TILE_SIZE + TILE_SIZE / 2); + sign.center = pt.x; + sign.top = pt.y - bb.height / 2; + + ViewportAddString(_cur_dpi, ZOOM_LVL_OUT_8X, &sign, + string_id, STR_NULL, STR_NULL, oth.u.numbered_rect.number, 0, COLOUR_WHITE); + break; + } default: break; } @@ -1398,12 +1436,17 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) { _thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE); auto pt = GetTileBelowCursor(); auto tile = (pt.x == -1 ? INVALID_TILE : TileVirtXY(pt.x, pt.y)); + bool force_new = false; // fprintf(stderr, "UPDATE %d %d %d %d\n", tile, _thd.size.x, _thd.size.y, (int)((_thd.place_mode & HT_DRAG_MASK) == HT_RECT)); if (_thd.place_mode == CM_HT_BLUEPRINT_PLACE) { UpdateBlueprintTileSelection(pt, tile); new_drawstyle = CM_HT_BLUEPRINT_PLACE; } else if (pt.x == -1) { } else if (_thd.make_square_red) { + } else if (_thd.select_proc == CM_DDSP_FUND_INDUSTRY) { + _thd.cm_new = ObjectHighlight::make_industry(tile, _cm_funding_type, _cm_funding_layout); + force_new = true; + new_drawstyle = HT_RECT; } else if (_thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT) { auto dir = _road_depot_orientation; if (dir == DEPOTDIR_AUTO) { @@ -1466,7 +1509,7 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) { TileVirtXY(_thd.selend2.x, _thd.selend2.y), _thd.cm_poly_dir2); } - if (_thd.cm != _thd.cm_new) { + if (force_new || _thd.cm != _thd.cm_new) { _thd.cm.MarkDirty(); _thd.cm = _thd.cm_new; _thd.cm.MarkDirty(); diff --git a/src/citymania/cm_highlight_type.hpp b/src/citymania/cm_highlight_type.hpp index 4bff4b87b1..2afede1ac8 100644 --- a/src/citymania/cm_highlight_type.hpp +++ b/src/citymania/cm_highlight_type.hpp @@ -33,6 +33,7 @@ public: ROAD_DEPOT, AIRPORT_TILE, POINT, + NUMBERED_RECT, END, }; @@ -77,6 +78,9 @@ public: struct { StationGfx gfx; } airport_tile; + struct { + uint32 number; + } numbered_rect; } u; ObjectTileHighlight(Type type, SpriteID palette): type{type}, palette{palette} {} @@ -91,6 +95,7 @@ public: static ObjectTileHighlight make_road_depot(SpriteID palette, RoadType roadtype, DiagDirection ddir); static ObjectTileHighlight make_airport_tile(SpriteID palette, StationGfx gfx); static ObjectTileHighlight make_point(SpriteID palette); + static ObjectTileHighlight make_numbered_rect(SpriteID palette, uint32 number); }; @@ -212,6 +217,7 @@ public: AIRPORT = 5, BLUEPRINT = 6, POLYRAIL = 7, + INDUSTRY = 8, }; Type type = Type::NONE; @@ -228,6 +234,8 @@ public: int airport_type = 0; byte airport_layout = 0; sp blueprint = nullptr; + IndustryType ind_type = INVALID_INDUSTRYTYPE; + uint32 ind_layout = 0; protected: bool tiles_updated = false; @@ -252,6 +260,8 @@ public: static ObjectHighlight make_polyrail(TileIndex start_tile, TileIndex end_tile, Trackdir trackdir, TileIndex start_tile2, TileIndex end_tile2, Trackdir trackdir2); + static ObjectHighlight make_industry(TileIndex tile, IndustryType ind_type, uint32 ind_layout); + void Draw(const TileInfo *ti); void DrawOverlay(DrawPixelInfo *dpi); void MarkDirty(); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 36109856e4..c61d6a9187 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -51,8 +51,13 @@ #include "safeguards.h" +static const int CM_HOTKEY_MASK = 0x1000; +static const int CM_HOTKEY_SWITCH_LAYOUT = 0x1001; + bool _ignore_restrictions; std::bitset _displayed_industries; ///< Communication from the industry chain window to the smallmap window about what industries to display. +uint32 _cm_funding_layout; +IndustryType _cm_funding_type; /** Cargo suffix type (for which window is it requested) */ enum CargoSuffixType { @@ -309,7 +314,7 @@ class BuildIndustryWindow : public Window { bool enabled[NUM_INDUSTRYTYPES + 1]; ///< availability state, coming from CBID_INDUSTRY_PROBABILITY (if ever) Scrollbar *vscroll; Dimension legend; ///< Dimension of the legend 'blob'. - + bool funding_enabled; /** The largest allowed minimum-width of the window, given in line heights */ @@ -351,7 +356,7 @@ class BuildIndustryWindow : public Window { * I'll be damned if there are none available ;) */ if (this->selected_index == -1) { this->selected_index = 0; - this->selected_type = this->index[0]; + _cm_funding_type = this->selected_type = this->index[0]; citymania::SetIndustryForbiddenTilesHighlight(this->selected_type); } @@ -419,7 +424,8 @@ public: BuildIndustryWindow(WindowDesc *desc) : Window(desc) { this->selected_index = -1; - this->selected_type = INVALID_INDUSTRYTYPE; + _cm_funding_type = this->selected_type = INVALID_INDUSTRYTYPE; + _cm_funding_layout = 0; this->funding_enabled = false; @@ -688,7 +694,8 @@ public: int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_DPI_MATRIX_WIDGET); if (y < this->count) { // Is it within the boundaries of available data? this->selected_index = y; - this->selected_type = this->index[y]; + _cm_funding_type = this->selected_type = this->index[y]; + _cm_funding_layout = 0; citymania::SetIndustryForbiddenTilesHighlight(this->selected_type); const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type); @@ -750,6 +757,7 @@ public: const IndustrySpec *indsp = GetIndustrySpec(this->selected_type); uint32 seed = InteractiveRandom(); uint32 layout_index = InteractiveRandomRange((uint32)indsp->layouts.size()); + if (_cm_funding_layout > 0) layout_index = _cm_funding_layout - 1; if (_game_mode == GM_EDITOR) { /* Show error if no town exists at all */ @@ -823,6 +831,16 @@ public: virtual EventState OnHotkey(int hotkey) { + switch (hotkey) { + case CM_HOTKEY_SWITCH_LAYOUT: + if (this->selected_type != INVALID_INDUSTRYTYPE && _thd.select_proc == CM_DDSP_FUND_INDUSTRY) { + const IndustrySpec *indspec = GetIndustrySpec(this->selected_type); + size_t num_layouts = indspec->layouts.size(); + MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection + _cm_funding_layout = (_cm_funding_layout + 1) % (num_layouts + 1); + return ES_HANDLED; + } else return ES_NOT_HANDLED; + } return Window::OnHotkey(hotkey); } @@ -832,6 +850,7 @@ public: static Hotkey build_industry_hotkeys[] = { Hotkey((uint16)0, "display_chain", WID_DPI_DISPLAY_WIDGET), Hotkey((uint16)0, "build_button", WID_DPI_FUND_WIDGET), + Hotkey(CM_WKC_MOUSE_MIDDLE, "cm_switch_layout", CM_HOTKEY_SWITCH_LAYOUT), HOTKEY_LIST_END }; diff --git a/src/lang/english.txt b/src/lang/english.txt index bf7f483668..3accb9236e 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5979,3 +5979,6 @@ CM_STR_CONFIG_SETTING_ENABLE_POLYRAIL_TERRAFORM_HELPTEXT :Allows to use experime CM_STR_NETWORK_CLIENT_LIST_WATCH_TOOLTIP :{BLACK}Watch this company CM_STR_NETWORK_CLIENT_LIST_HQ_TOOLTIP :{BLACK}View company headquarters CM_STR_WATCH_LOCATION_TOOLTIP :{BLACK}Centre the main view on the location. Ctrl+Click opens a new viewport on the location + +CM_STR_LAYOUT_NUM :{BLACK}{NUM} +CM_STR_LAYOUT_RANDOM :{BLACK}rng \ No newline at end of file