diff --git a/cm_changelog.txt b/cm_changelog.txt index f3d769dfd7..b6c7eb0131 100644 --- a/cm_changelog.txt +++ b/cm_changelog.txt @@ -78,6 +78,8 @@ This is usable for any OpenTTD servers - Fixed measurement tooltips. - Fixed n-ice community login by Chucky and iSoSyS. - Show the number of hidden vehicles in buy and autoreplace windows. +- Renamed cm_*_order_mod settings to cm_*_station_mod. +- Added cm_ctrl_depot_mod, cm_shift_depot_mod, cm_ctrl_shift_depot_mod settings to configure modifier keys for depot orders. - Added a setting to disable activate-on-release behaviour of toolbar dropdown buttons. - Added Russian translation. diff --git a/src/citymania/cm_cargo_table_gui.cpp b/src/citymania/cm_cargo_table_gui.cpp index 21b2b4dd52..42cfc42ed6 100644 --- a/src/citymania/cm_cargo_table_gui.cpp +++ b/src/citymania/cm_cargo_table_gui.cpp @@ -186,15 +186,15 @@ static const NWidgetPart _nested_cargos_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 1), NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::scaled.framerect.top, WidgetDimensions::scaled.framerect.right, WidgetDimensions::scaled.framerect.bottom, WidgetDimensions::scaled.framerect.left), SetPIP(0, 9, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CT_HEADER_CARGO), SetFill(1, 0), SetPadding(2,2,2,2), SetStringTip(CM_STR_TOOLBAR_CARGOS_HEADER_CARGO, CM_STR_TOOLBAR_CARGOS_HEADER_CARGO), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CT_HEADER_AMOUNT), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CT_HEADER_INCOME), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_CT_HEADER_AMOUNT), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_CT_HEADER_INCOME), SetMinimalSize(108, 16), SetFill(1, 0), SetPadding(2,2,2,2), EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 1), NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::scaled.framerect.top, WidgetDimensions::scaled.framerect.right, WidgetDimensions::scaled.framerect.bottom, WidgetDimensions::scaled.framerect.left), SetPIP(0, 9, 0), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_CT_LIST),SetFill(1, 0), SetPadding(2,2,2,2), SetResize(1, 1), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_CT_AMOUNT),SetMinimalSize(108, 0),SetFill(1, 0), SetPadding(2,2,2,2), SetResize(1, 1), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_CT_INCOME),SetMinimalSize(108, 0),SetFill(1, 0), SetPadding(2,2,2,2), SetResize(1, 1), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_CT_LIST),SetFill(1, 0), SetPadding(2,2,2,2), SetResize(1, 1), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_CT_AMOUNT),SetMinimalSize(108, 0),SetFill(1, 0), SetPadding(2,2,2,2), SetResize(1, 1), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_CT_INCOME),SetMinimalSize(108, 0),SetFill(1, 0), SetPadding(2,2,2,2), SetResize(1, 1), EndContainer(), EndContainer(), }; diff --git a/src/citymania/cm_colour.hpp b/src/citymania/cm_colour.hpp index 805cecaf02..26ed3dea59 100644 --- a/src/citymania/cm_colour.hpp +++ b/src/citymania/cm_colour.hpp @@ -3,11 +3,22 @@ #include #include "../blitter/32bpp_base.hpp" +#include "../palette_func.h" // PC_WHITE, PC_BLACK +#include namespace citymania { extern const uint8_t RGB_TO_M[]; +// ', '.join(["true" if grf.srgb_color_distance(c, (255, 255, 255)) > grf.srgb_color_distance(c, (0, 0, 0)) else "false" for c in grf.PALETTE]) +constexpr std::array IS_M_CLOSER_TO_BLACK = { true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, true, true, true, true, false, false, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, false, false, true, true, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, false, true, true, true, true, true, false, false, false, true, true, true, true, false, false, false, false, true, true, true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false, true, true, true, false, false, false, false, false, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, true, false, false, false, false, false, true, true, true, true, true, true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, false, true, true, true, false, false, false, false, true, true, true, true, true, false, true, true, true, true, true, true, false, false, false, true, false }; + +constexpr std::array BLINK_COLOUR = { 141, 7, 9, 10, 11, 12, 13, 14, 2, 2, 3, 4, 5, 6, 6, 8, 22, 22, 135, 210, 2, 3, 16, 18, 29, 30, 59, 31, 69, 24, 25, 26, 37, 38, 38, 39, 104, 32, 33, 35, 77, 47, 166, 166, 49, 49, 41, 41, 42, 125, 55, 85, 86, 37, 120, 65, 69, 104, 24, 25, 78, 120, 121, 197, 60, 54, 55, 27, 85, 28, 126, 78, 79, 79, 167, 167, 167, 178, 71, 72, 94, 94, 95, 95, 95, 209, 80, 81, 101, 102, 31, 103, 69, 80, 81, 82, 101, 102, 103, 103, 69, 96, 97, 98, 36, 111, 37, 120, 121, 121, 39, 105, 79, 120, 167, 167, 167, 178, 122, 122, 61, 108, 79, 79, 167, 167, 168, 71, 133, 134, 134, 177, 177, 128, 16, 18, 142, 142, 143, 143, 143, 136, 136, 171, 150, 150, 151, 151, 152, 152, 144, 200, 154, 156, 213, 213, 212, 153, 128, 154, 155, 157, 166, 166, 180, 180, 180, 124, 35, 7, 174, 143, 176, 176, 170, 130, 131, 132, 77, 166, 166, 166, 165, 165, 180, 180, 180, 180, 62, 63, 27, 65, 53, 61, 62, 62, 55, 55, 204, 151, 151, 152, 152, 152, 198, 154, 80, 81, 83, 84, 19, 157, 156, 154, 154, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 78, 79, 167, 168, 72, 180, 180, 180, 180, 62, 62, 63, 77, 181, 29, 30, 95, 86, 152, 152, 152, 152, 152, 153, 128, 19, 161, 153, 8 }; + +static inline uint8_t GetBlinkColour(uint8_t m) { + return BLINK_COLOUR[m]; +} + static inline uint8_t GetMForRGB(uint8_t r, uint8_t g, uint8_t b) { return RGB_TO_M[((uint)(r & 0xf0) >> 4) | ((uint)g & 0xf0) | ((uint)(b & 0xf0) << 4)]; } diff --git a/src/citymania/cm_command_type.hpp b/src/citymania/cm_command_type.hpp index 50d8059569..422aa1ad36 100644 --- a/src/citymania/cm_command_type.hpp +++ b/src/citymania/cm_command_type.hpp @@ -28,11 +28,13 @@ namespace citymania { typedef std::function CommandCallback; extern bool _no_estimate_command; +extern bool _automatic_command; extern CommandCallback _current_callback; class Command { public: bool no_estimate_flag = false; + bool automatic_flag = false; CompanyID company = CompanyID::Invalid(); StringID error = (StringID)0; CommandCallback callback = nullptr; @@ -50,10 +52,12 @@ public: if (this->company != CompanyID::Invalid()) _current_company = company; _no_estimate_command = this->no_estimate_flag; + _automatic_command = this->automatic_flag; _current_callback = this->callback; bool res = this->_post(reinterpret_cast<::CommandCallback *>(reinterpret_cast(callback))); _current_company = company_backup; _no_estimate_command = false; + _automatic_command = false; return res; } @@ -84,6 +88,13 @@ public: return *this; } + Command &set_auto() { + // Doesn't count for apm + this->automatic_flag = true; + this->no_estimate_flag = true; + return *this; + } + Command &as_company(CompanyID company) { this->company = company; return *this; diff --git a/src/citymania/cm_commands.cpp b/src/citymania/cm_commands.cpp index 643dbaa7a6..6c2a40a326 100644 --- a/src/citymania/cm_commands.cpp +++ b/src/citymania/cm_commands.cpp @@ -20,6 +20,7 @@ std::map>> _command_callb std::queue> _command_sent; CommandCallback _current_callback = nullptr; bool _no_estimate_command = false; +bool _automatic_command = false; template class SumLast { diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index 1b07092a08..11bfdbb167 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -184,9 +184,6 @@ struct TileZoning { static std::unique_ptr _mz = nullptr; static IndustryType _industry_forbidden_tiles = IT_INVALID; -extern const Station *_station_to_join; -extern const Station *_highlight_station_to_join; -extern TileArea _highlight_join_area; extern bool _fn_mod; std::set, std::greater>> _town_cache; @@ -545,31 +542,6 @@ void ObjectHighlight::AddTile(TileIndex tile, ObjectTileHighlight &&oh) { this->tiles.insert(std::make_pair(tile, std::move(oh))); } -void ObjectHighlight::AddStationOverlayData(int w, int h, int rad, StationCoverageType sct) { - if (!_settings_game.station.modified_catchment) rad = CA_UNMODIFIED; - auto production = citymania::GetProductionAroundTiles(this->tile, w, h, rad); - bool has_header = false; - for (CargoType i = 0; i < NUM_CARGO; i++) { - if (production[i] == 0) continue; - - switch (sct) { - case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CargoClass::Passengers)) continue; break; - case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CargoClass::Passengers)) continue; break; - case SCT_ALL: break; - default: NOT_REACHED(); - } - - const CargoSpec *cs = CargoSpec::Get(i); - if (cs == nullptr) continue; - - if (!has_header) { - this->overlay_data.emplace_back(0, PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_SUPPLIES)); - has_header = true; - } - this->overlay_data.emplace_back(1, cs->GetCargoIcon(), GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_CARGO, i, production[i] >> 8)); - } -} - void ObjectHighlight::UpdateTiles() { this->tiles.clear(); this->sprites.clear(); @@ -633,7 +605,6 @@ void ObjectHighlight::UpdateTiles() { tile_track += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta } while (--numtracks); - this->AddStationOverlayData(ta.w, ta.h, CA_TRAIN, SCT_ALL); break; } case Type::ROAD_STOP: { @@ -655,9 +626,6 @@ void ObjectHighlight::UpdateTiles() { for (TileIndex tile : ta) { this->AddTile(tile, ObjectTileHighlight::make_road_stop(palette, this->roadtype, this->ddir, this->is_truck, this->road_stop_spec_class, this->road_stop_spec_index)); } - auto sct = (this->is_truck ? SCT_NON_PASSENGERS_ONLY : SCT_PASSENGERS_ONLY); - auto rad = (this->is_truck ? CA_BUS : CA_TRUCK); - this->AddStationOverlayData(ta.w, ta.h, rad, sct); break; } @@ -689,7 +657,6 @@ void ObjectHighlight::UpdateTiles() { for (AirportTileTableIterator iter(as->layouts[this->airport_layout].tiles.data(), this->tile); iter != INVALID_TILE; ++iter) { this->AddTile(iter, ObjectTileHighlight::make_airport_tile(palette, iter.GetStationGfx())); } - this->AddStationOverlayData(as->size_x, as->size_y, as->catchment, SCT_ALL); break; } case Type::BLUEPRINT: @@ -819,43 +786,6 @@ void ObjectHighlight::UpdateTiles() { } } -void ObjectHighlight::UpdateOverlay() { - HideBuildInfoOverlay(); - auto w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); - if (w == nullptr) return; - auto vp = IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y); - if (vp == nullptr) return; - - if (this->tile == INVALID_TILE) { - HideBuildInfoOverlay(); - return; - } - - auto err = this->cost.GetErrorMessage(); - // auto extra_err = this->cost.GetExtraErrorMessage(); - bool no_money = (err == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY); - this->overlay_data.emplace_back(0, PAL_NONE, GetString(no_money ? CM_STR_BUILD_INFO_OVERLAY_COST_NO_MONEY : CM_STR_BUILD_INFO_OVERLAY_COST_OK, this->cost.GetCost())); - // if (this->cost.Failed() && err != STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) { - // if (err == INVALID_STRING_ID) { - // this->overlay_data.emplace_back(PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_ERROR_UNKNOWN)); - // } else { - // SetDParam(0, err); - // this->overlay_data.emplace_back(PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_ERROR)); - // } - // if (extra_err != INVALID_STRING_ID) { - // SetDParam(0, extra_err); - // this->overlay_data.emplace_back(PAL_NONE, GetString(CM_STR_BUILD_INFO_OVERLAY_ERROR)); - // } - // } - - // Point pt = RemapCoords2(TileX(this->tile) * TILE_SIZE + TILE_SIZE / 2, TileY(this->tile) * TILE_SIZE + TILE_SIZE / 2); - Point pt = RemapCoords2(TileX(this->tile) * TILE_SIZE, TileY(this->tile) * TILE_SIZE); - pt.x = UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left; - pt.y = UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top; - // this->overlay_pos = pt; - ShowBuildInfoOverlay(pt.x, pt.y, this->overlay_data); -} - void ObjectHighlight::MarkDirty() { for (const auto &kv: this->tiles) { MarkTileDirtyByTile(kv.first); @@ -1834,8 +1764,6 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) bool draw_selection = ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0); const Station *highlight_station = _viewport_highlight_station; - if (_highlight_station_to_join) highlight_station = _highlight_station_to_join; - if (draw_selection) { // const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN}; // auto color = pal[(int)_station_building_status]; @@ -1878,20 +1806,6 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) const SpriteID pal2[] = {PAL_NONE, CM_PALETTE_TINT_WHITE, CM_PALETTE_TINT_BLUE}; th.ground_pal = th.structure_pal = pal2[b.second]; } - - if (_highlight_join_area.tile != INVALID_TILE) { - auto b = CalcTileBorders(ti->tile, [](TileIndex t) { - return _highlight_join_area.Contains(t) ? 1 : 0; - }); - th.add_border(b.first, CM_SPR_PALETTE_ZONING_LIGHT_BLUE); - if (b.second) { - switch (th.ground_pal) { - case CM_PALETTE_TINT_WHITE: th.ground_pal = th.structure_pal = CM_PALETTE_TINT_CYAN_WHITE; break; - case CM_PALETTE_TINT_BLUE: break; - default: th.ground_pal = th.structure_pal = CM_PALETTE_TINT_CYAN; break; - } - } - } } void CalcCBAcceptanceBorders(TileHighlight &th, TileIndex tile, SpriteID border_pal, SpriteID ground_pal) { @@ -2247,7 +2161,6 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) { _thd.cm.MarkDirty(); _thd.cm = _thd.cm_new; _thd.cm.UpdateTiles(); - _thd.cm.UpdateOverlay(); _thd.cm.MarkDirty(); } return new_drawstyle; @@ -2423,7 +2336,6 @@ PaletteID GetTreeShadePal(TileIndex tile) { ActiveTool _at; - static void ResetVanillaHighlight() { if (_thd.window_class != WC_INVALID) { /* Undo clicking on button and drag & drop */ @@ -2472,7 +2384,7 @@ void UpdateActiveTool() { auto tile = pt.x == -1 ? INVALID_TILE : TileVirtXY(pt.x, pt.y); ToolGUIInfo info; - if (citymania::StationBuildTool::active_highlight.has_value()) { + if (citymania::HasSelectedStationHighlight()) { info = GetSelectedStationGUIInfo(); } else if (_at.tool != nullptr) { _at.tool->Update(pt, tile); diff --git a/src/citymania/cm_highlight_type.hpp b/src/citymania/cm_highlight_type.hpp index 0bb386a5d9..b9869c2050 100644 --- a/src/citymania/cm_highlight_type.hpp +++ b/src/citymania/cm_highlight_type.hpp @@ -28,9 +28,6 @@ namespace citymania { -typedef std::function(TileIndex start_tile, TileIndex end_tile)> HighlightGenerator; - - enum ZoningBorder: uint8 { NONE = 0, TOP_LEFT = 1, @@ -76,19 +73,6 @@ public: }; -class TileIndexWrapper { -public: - TileIndex tile; - TileIndexWrapper() {} - TileIndexWrapper(TileIndex tile) - :tile{tile} {} - - inline operator TileIndex () const - { - return this->tile; - } -}; - class ObjectTileHighlight { public: enum class Type : uint8_t { @@ -405,25 +389,11 @@ public: void DrawOverlay(DrawPixelInfo *dpi); void AddStationOverlayData(int w, int h, int rad, StationCoverageType sct); void UpdateTiles(); - void UpdateOverlay(); void MarkDirty(); }; typedef std::tuple ToolGUIInfo; -class Preview { -public: - virtual ~Preview() {} - virtual void Update(Point pt, TileIndex tile) = 0; - virtual void HandleMouseMove() {}; - virtual bool HandleMousePress() { return false; }; - virtual void HandleMouseRelease() {}; - virtual bool HandleMouseClick(Viewport* /* vp */, Point /* pt */, TileIndex /* tile */, bool /* double_click */) { return false; }; - virtual std::pair GetGUIInfo() = 0; - virtual CursorID GetCursor() = 0; - virtual void OnStationRemoved(const Station* /* station */) {}; -}; - class Action { public: virtual ~Action() = default; diff --git a/src/citymania/cm_hotkeys.cpp b/src/citymania/cm_hotkeys.cpp index e6faa4ba4f..ed6767cfc2 100644 --- a/src/citymania/cm_hotkeys.cpp +++ b/src/citymania/cm_hotkeys.cpp @@ -25,6 +25,7 @@ struct StationPickerSelection { Axis axis; ///< Selected orientation of the station. }; extern StationPickerSelection _station_gui; ///< Settings of the station picker. +extern bool _generating_world; namespace citymania { @@ -48,6 +49,7 @@ static void PurgeLastActions() { } void CountEffectiveAction() { + if (_generating_world) return; auto now = std::chrono::steady_clock::now(); if (!_first_effective_tick) _first_effective_tick = now; _effective_actions++; @@ -66,7 +68,7 @@ std::pair GetEPM() { if (!_first_effective_tick) return std::make_pair(0, 0); PurgeLastActions(); auto ms = std::chrono::duration_cast(now - *_first_effective_tick).count(); - if (ms == 0) return std::make_pair(0, 0); + if (ms < 1000) return std::make_pair(0, _last_actions.size()); return std::make_pair(_effective_actions * 60000 / ms, _last_actions.size()); } diff --git a/src/citymania/cm_minimap.cpp b/src/citymania/cm_minimap.cpp index a652db245b..c454af1633 100644 --- a/src/citymania/cm_minimap.cpp +++ b/src/citymania/cm_minimap.cpp @@ -29,6 +29,7 @@ #include +#include "cm_colour.hpp" #include "cm_hotkeys.hpp" #include "cm_minimap.hpp" @@ -249,11 +250,7 @@ bool is_cached_industry(const Industry *ind) { MinimapIndustryKdtreeEntry get_industry_entry(const Industry *ind) { auto x = TileX(ind->location.tile) * TILE_SIZE + ind->location.w * TILE_SIZE / 2; auto y = TileY(ind->location.tile) * TILE_SIZE + ind->location.h * TILE_SIZE / 2; - uint num_outputs = 0; - for (auto i = 0; i < INDUSTRY_NUM_OUTPUTS; i++) - if (ind->produced[i].cargo != INVALID_CARGO) - num_outputs++; - _max_industry_outputs = std::max(_max_industry_outputs, num_outputs); + _max_industry_outputs = std::max(_max_industry_outputs, ind->produced.size()); return {(int16)((y - x) / 8), (int16)((y + x) / 8), ind->index}; } @@ -854,10 +851,11 @@ inline uint32 SmallMapWindow::GetTileColours(const TileArea &ta) const * This has the highest priority above any value in _tiletype_importance. */ IndustryType type = Industry::GetByTile(ti)->type; if (_legend_from_industries[_industry_to_list_pos[type]].show_on_map) { - if (type == _smallmap_industry_highlight) { - if (_smallmap_industry_highlight_state) return MKCOLOUR_XXXX(PC_WHITE); + auto map_colour = GetIndustrySpec(type)->map_colour; + if (type == _smallmap_industry_highlight && _smallmap_industry_highlight_state) { + return MKCOLOUR_XXXX(GetBlinkColour(map_colour)); } else { - return GetIndustrySpec(type)->map_colour * 0x01010101; + return map_colour * 0x01010101; } } /* Otherwise make it disappear */ @@ -1034,18 +1032,16 @@ void SmallMapWindow::DrawIndustryProduction(const DrawPixelInfo *dpi) const ); IconTextSizeHelper its{SPR_CARGO_COAL, WidgetDimensions::scaled.framerect}; - for (auto i = 0; i < INDUSTRY_NUM_OUTPUTS; i++) { - if (ind->produced[i].cargo == INVALID_CARGO) continue; - its.add(GetString(STR_JUST_INT, ind->produced[i].history[LAST_MONTH].production), FS_SMALL); + for (auto &pc : ind->produced) { + its.add(GetString(STR_JUST_INT, pc.history[LAST_MONTH].production), FS_SMALL); } its.calculate(); this->industry_max_sign = maxdim(this->industry_max_sign, its.size); auto [r, ir] = its.make_rects(pt.x, pt.y); GfxFillRect(r, PALETTE_TO_TRANSPARENT, FILLRECT_RECOLOUR); - for (auto i = 0; i < INDUSTRY_NUM_OUTPUTS; i++) { - if (ind->produced[i].cargo == INVALID_CARGO) continue; - DrawSprite(CargoSpec::Get(ind->produced[i].cargo)->GetCargoIcon(), PAL_NONE, ir.left, ir.top + its.icon_ofs_y); - auto str = GetString(STR_JUST_INT, ind->produced[i].history[LAST_MONTH].production); + for (auto &pc : ind->produced) { + DrawSprite(CargoSpec::Get(pc.cargo)->GetCargoIcon(), PAL_NONE, ir.left, ir.top + its.icon_ofs_y); + auto str = GetString(STR_JUST_INT, pc.history[LAST_MONTH].production); DrawString(ir.left + its.text_ofs_x, ir.right, ir.top + its.text_ofs_y, str, TC_WHITE, SA_LEFT, false, FS_SMALL); ir.top += its.line_height; } @@ -1440,7 +1436,8 @@ std::string SmallMapWindow::GetWidgetString(WidgetID widget, StringID stringid) params[0] = tbl->legend; params[1] = Industry::GetIndustryTypeCount(tbl->type); if (tbl->show_on_map && tbl->type == _smallmap_industry_highlight) { - legend_colour = _smallmap_industry_highlight_state ? PC_WHITE : PC_BLACK; + auto mc = GetIndustrySpec(tbl->type)->map_colour; + legend_colour = _smallmap_industry_highlight_state ? GetBlinkColour(mc) : mc; } [[fallthrough]]; diff --git a/src/citymania/cm_station_gui.cpp b/src/citymania/cm_station_gui.cpp index 69c077d2db..26a7951d2b 100644 --- a/src/citymania/cm_station_gui.cpp +++ b/src/citymania/cm_station_gui.cpp @@ -29,6 +29,7 @@ #include "../town.h" #include "../viewport_func.h" #include "../viewport_kdtree.h" +#include "../window_func.h" // SetWindowDirty #include "../window_gui.h" #include "../zoom_type.h" #include "../zoom_func.h" @@ -36,10 +37,12 @@ #include "generated/cm_gen_commands.hpp" #include +#include #include #include #include #include +#include bool _remove_button_clicked; // replace vanilla static vars @@ -77,13 +80,20 @@ extern uint8_t _selected_airport_layout; ///< selected airport layout n namespace citymania { -const Station *_highlight_station_to_join = nullptr; -TileArea _highlight_join_area; - bool UseImprovedStationJoin() { return _settings_client.gui.cm_use_improved_station_join && _settings_game.station.distant_join_stations; } +namespace StationAction { + struct Create {}; + struct Join { StationID station; }; + struct Picker {}; + + using Mode = std::variant; +}; + +StationAction::Mode _station_action = StationAction::Create{}; + static const int MAX_TILE_EXTENT_LEFT = ZOOM_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. static const int MAX_TILE_EXTENT_RIGHT = ZOOM_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. static const int MAX_TILE_EXTENT_TOP = ZOOM_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). @@ -105,30 +115,9 @@ void MarkTileAreaDirty(const TileArea &ta) { p2.y + MAX_TILE_EXTENT_BOTTOM); } -static void UpdateHiglightJoinArea(const Station *station) { - if (!station) { - MarkTileAreaDirty(_highlight_join_area); - _highlight_join_area.tile = INVALID_TILE; - return; - } - // auto &r = _station_to_join->rect; - // auto d = (int)_settings_game.station.station_spread - 1; - // TileArea ta( - // TileXY(std::max(r.right - d, 0), - // std::max(r.bottom - d, 0)), - // TileXY(std::min(r.left + d, Map::SizeX() - 1), - // std::min(r.top + d, Map::SizeY() - 1)) - // ); - // if (_highlight_join_area.tile == ta.tile && - // _highlight_join_area.w == ta.w && - // _highlight_join_area.h == ta.h) return; - // _highlight_join_area = ta; - MarkTileAreaDirty(_highlight_join_area); -} - -static void MarkCoverageAreaDirty(const Station *station) { - MarkTileAreaDirty(station->catchment_tiles); -} +// static void MarkCoverageAreaDirty(const Station *station) { +// MarkTileAreaDirty(station->catchment_tiles); +// } void MarkCoverageHighlightDirty() { MarkCatchmentTilesDirty(); @@ -568,36 +557,155 @@ extern DiagDirection AddAutodetectionRotation(DiagDirection ddir); // cm_highli // if (this->station_to_join == station->index) this->station_to_join = StationID::Invalid(); // } +// Non-tool station highlight management (coverage area and picker selection) + +enum class StationHighlightMode { + None, + Picker, + Coverage +}; + +std::optional _active_highlight_object = std::nullopt; +StationID _selected_station = StationID::Invalid(); +StationHighlightMode _station_highlight_mode = StationHighlightMode::None; + void SetSelectedStationToJoin(StationID station_id) { - StationBuildTool::current_selected_station = station_id; + _selected_station = station_id; UpdateActiveTool(); } -void ResetJoinStationHighlight() { - StationBuildTool::active_highlight = std::nullopt; - SetSelectedStationToJoin(StationID::Invalid()); +void ResetSelectedStationToJoin() { + _station_highlight_mode = StationHighlightMode::None; + UpdateActiveTool(); } +void SetHighlightCoverageStation(Station *station, bool sel) { + if (_station_highlight_mode == StationHighlightMode::Picker) return; + SetWindowDirty(WC_STATION_VIEW, _selected_station); + if (station == nullptr || !sel) { + _station_highlight_mode = StationHighlightMode::None; + } else { + _selected_station = station->index; + _station_highlight_mode = StationHighlightMode::Coverage; + } + SetWindowDirty(WC_STATION_VIEW, _selected_station); + UpdateActiveTool(); +} + +static void ResetHighlightCoverageStation() { + SetHighlightCoverageStation(nullptr, false); +} + +bool IsHighlightCoverageStation(const Station *station) { + if (_station_highlight_mode != StationHighlightMode::Coverage) return false; + if (station == nullptr) return false; + return station->index == _selected_station; +} void OnStationRemoved(const Station *station) { // if (_last_built_station == station) _last_built_station = nullptr; - if (StationBuildTool::station_to_join == station->index) { - StationBuildTool::station_to_join = StationID::Invalid(); + if (auto mode = std::get_if(&_station_action); mode && mode->station == station->index) { + _station_action = StationAction::Create{}; UpdateActiveTool(); } - if (StationBuildTool::current_selected_station == station->index) { - StationBuildTool::current_selected_station = StationID::Invalid(); + if (_selected_station == station->index) { + _selected_station = StationID::Invalid(); + if (_station_highlight_mode == StationHighlightMode::Coverage) { + _station_highlight_mode = StationHighlightMode::None; + SetWindowDirty(WC_STATION_VIEW, _selected_station); + } UpdateActiveTool(); } // TODO? // if (GetActiveTool() != nullptr) GetActiveTool()->OnStationRemoved(station); } +static void SetActiveHighlightObject(std::optional &ohl) { + _active_highlight_object = ohl; + if (_active_highlight_object.has_value()) _active_highlight_object->UpdateTiles(); + if (_station_highlight_mode == StationHighlightMode::Coverage) + SetWindowDirty(WC_STATION_VIEW, _selected_station); + _station_highlight_mode = StationHighlightMode::Picker; +} + void AbortStationPlacement() { // TODO is it necessary? // SetHighlightStationToJoin(station=nullptr, with_area=false); } +bool HasSelectedStationHighlight() { + return _station_highlight_mode != StationHighlightMode::None; +} + +static HighlightMap PrepareHighilightMap(Station *st_join, std::optional ohl, SpriteID pal, bool show_join_area, bool show_coverage, uint rad) { + bool add_current = true; // FIXME + + auto hlmap = ohl.has_value() ? ohl->GetHighlightMap(pal) : HighlightMap{}; + TileArea join_area; + std::set coverage_area; + + if (show_join_area && st_join != nullptr) { + join_area = GetStationJoinArea(st_join->index); + hlmap.AddTileArea(join_area, CM_PALETTE_TINT_CYAN); + } + + if (show_coverage && st_join != nullptr) { + // Add joining station coverage + for (auto t : st_join->catchment_tiles) { + auto pal = join_area.Contains(t) ? CM_PALETTE_TINT_CYAN_WHITE : CM_PALETTE_TINT_WHITE; + hlmap.Add(t, ObjectTileHighlight::make_tint(pal)); + coverage_area.insert(t); + } + } + + auto area = ohl.has_value() ? ohl->GetArea() : std::nullopt; + if (!_settings_game.station.modified_catchment) rad = CA_UNMODIFIED; + std::optional rad_area = std::nullopt; + if (area.has_value()) { + auto xarea = area.value(); + xarea.Expand(rad); + xarea.ClampToMap(); + rad_area = xarea; + } + if (show_coverage && add_current && rad_area.has_value()) { + // Add current station coverage + for (auto t : rad_area.value()) { + auto pal = join_area.Contains(t) ? CM_PALETTE_TINT_CYAN_WHITE : CM_PALETTE_TINT_WHITE; + hlmap.Add(t, ObjectTileHighlight::make_tint(pal)); + coverage_area.insert(t); + } + } + + if (show_coverage) { + hlmap.AddTilesBorder(coverage_area, CM_PALETTE_TINT_WHITE); + } + + if (st_join != nullptr) { + // Highlight joining station blue + TileArea ta(TileXY(st_join->rect.left, st_join->rect.top), TileXY(st_join->rect.right, st_join->rect.bottom)); + for (TileIndex t : ta) { + if (!IsTileType(t, MP_STATION) || GetStationIndex(t) != st_join->index) continue; + hlmap.Add(t, ObjectTileHighlight::make_struct_tint(CM_PALETTE_TINT_BLUE)); + } + } + + return hlmap; +} + +ToolGUIInfo GetSelectedStationGUIInfo() { + if (_station_highlight_mode == StationHighlightMode::None) return {}; + auto st = Station::GetIfValid(_selected_station); + + auto hlmap = PrepareHighilightMap( + st, + _station_highlight_mode == StationHighlightMode::Picker ? _active_highlight_object : std::nullopt, + CM_PALETTE_TINT_WHITE, + false, + _station_highlight_mode == StationHighlightMode::Coverage, + 0 + ); + return {hlmap, {}, {}}; +} // --- Action base class --- void Action::OnStationRemoved(const Station *) {} @@ -647,90 +755,43 @@ ToolGUIInfo RemoveAction::GetGUIInfo() { template void RemoveAction::OnStationRemoved(const Station *) {} -static HighlightMap PrepareHighilighMap(Station *st_join, ObjectHighlight &ohl, SpriteID pal, bool show_join_area, StationCoverageType sct, uint rad) { - bool add_current = true; // FIXME - bool show_coverage = (rad > 0); - - auto hlmap = ohl.GetHighlightMap(pal); - TileArea join_area; - std::set coverage_area; - - if (show_join_area && st_join != nullptr) { - join_area = GetStationJoinArea(st_join->index); - hlmap.AddTileArea(join_area, CM_PALETTE_TINT_CYAN); - } - - if (show_coverage && st_join != nullptr) { - // Add joining station coverage - for (auto t : st_join->catchment_tiles) { - auto pal = join_area.Contains(t) ? CM_PALETTE_TINT_CYAN_WHITE : CM_PALETTE_TINT_WHITE; - hlmap.Add(t, ObjectTileHighlight::make_tint(pal)); - coverage_area.insert(t); - } - } - - auto area = ohl.GetArea(); - if (!_settings_game.station.modified_catchment) rad = CA_UNMODIFIED; - std::optional rad_area = std::nullopt; - if (area.has_value()) { - auto xarea = area.value(); - xarea.Expand(rad); - xarea.ClampToMap(); - rad_area = xarea; - } - if (show_coverage && add_current && rad_area.has_value()) { - // Add current station coverage - for (auto t : rad_area.value()) { - auto pal = join_area.Contains(t) ? CM_PALETTE_TINT_CYAN_WHITE : CM_PALETTE_TINT_WHITE; - hlmap.Add(t, ObjectTileHighlight::make_tint(pal)); - coverage_area.insert(t); - } - } - - if (show_coverage) { - hlmap.AddTilesBorder(coverage_area, CM_PALETTE_TINT_WHITE); - } - - if (st_join != nullptr) { - // Highlight joining station blue - TileArea ta(TileXY(st_join->rect.left, st_join->rect.top), TileXY(st_join->rect.right, st_join->rect.bottom)); - for (TileIndex t : ta) { - if (!IsTileType(t, MP_STATION) || GetStationIndex(t) != st_join->index) continue; - hlmap.Add(t, ObjectTileHighlight::make_struct_tint(CM_PALETTE_TINT_BLUE)); - } - } - - return hlmap; -} - ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, up cmd, StationCoverageType sct, uint rad) { if (!cmd || !ohl.has_value()) return {}; ohl.value().UpdateTiles(); + auto palette = CM_PALETTE_TINT_WHITE; + auto area = ohl.value().GetArea(); auto cost = cmd->test(); + if (std::holds_alternative(_station_action)) { + palette = CM_PALETTE_TINT_YELLOW; + } else { + palette = cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP; + } bool show_coverage = _settings_client.gui.station_show_coverage; - auto hlmap = PrepareHighilighMap( - Station::GetIfValid(StationBuildTool::station_to_join), + Station *to_join = nullptr; + if (auto mode = std::get_if(&_station_action)) + to_join = Station::GetIfValid(mode->station); + auto hlmap = PrepareHighilightMap( + to_join, ohl.value(), - cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP, + palette, true, - sct, - show_coverage ? rad : 0 + show_coverage, + rad ); // Prepare build overlay BuildInfoOverlayData data; - if (StationBuildTool::station_to_join != StationID::Invalid()) { - data.emplace_back(0, PAL_NONE, GetString(CM_STR_BULID_INFO_OVERLAY_JOIN_STATION, StationBuildTool::station_to_join)); + if (auto mode = std::get_if(&_station_action)) { + data.emplace_back(0, PAL_NONE, GetString(CM_STR_BULID_INFO_OVERLAY_JOIN_STATION, mode->station)); } else { data.emplace_back(0, PAL_NONE, GetString(CM_STR_BULID_INFO_OVERLAY_NEW_STATION)); } - auto area = ohl.value().GetArea(); if (area.has_value()) { // Add supplied cargo information // TODO can we use rad_area since we already have it? @@ -825,26 +886,61 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, return {hlmap, data, cost}; } -ToolGUIInfo GetSelectedStationGUIInfo() { - if (!StationBuildTool::active_highlight.has_value()) return {}; - auto &ohl = StationBuildTool::active_highlight.value(); - // TODO maybe update or none at all? - ohl.UpdateTiles(); - auto hlmap = PrepareHighilighMap( - Station::GetIfValid(StationBuildTool::current_selected_station), - ohl, - CM_PALETTE_TINT_WHITE, - false, - SCT_ALL, - 0 - ); - return {hlmap, {}, {}}; -} - // --- SizedPlacementAction --- template void SizedPlacementAction::Update(Point, TileIndex tile) { this->cur_tile = tile; + if (UseImprovedStationJoin()) return; + + _station_action = StationAction::Create{}; + + auto area = this->GetArea(); + if (!area.has_value()) return; + auto cmdptr = this->handler.GetCommand(tile, StationID::Invalid()); + auto cmd = dynamic_cast(cmdptr.get()); + if (cmd == nullptr) return; + + if (!_settings_game.station.distant_join_stations && _fn_mod) return; + + area->Expand(1); + area->ClampToMap(); + StationID to_join = StationID::Invalid(); + bool ambigous_join = false; + for (auto tile : area.value()) { + if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) { + Station *st = Station::GetByTile(tile); + if (st == nullptr || st->index == to_join) continue; + if (to_join != StationID::Invalid()) { + to_join = StationID::Invalid(); + if (_settings_game.station.distant_join_stations) + ambigous_join = true; + break; + } + to_join = st->index; + // TODO check for command to return multiple? but also check each to + // see if they can be built + // if (this->GetCommand(true, st->index)->test().Succeeded()) { + // if (this->station_to_join != INVALID_STATION) { + // this->station_to_join = INVALID_STATION; + // this->palette = CM_PALETTE_TINT_YELLOW; + // break; + // } else this->station_to_join = st->index; + // } + } + } + + if (!_settings_game.station.distant_join_stations) return; + + if (ambigous_join) _station_action = StationAction::Picker{}; + else if (to_join != StationID::Invalid()) _station_action = StationAction::Join{to_join}; + else _station_action = StationAction::Create{}; + + // cmd->station_to_join = NEW_STATION; + // cmd->adjacent = true; + + // if (StationBuildTool::station_to_join == INVALID_STATION && !cmd->test().Succeeded()) { + // StationBuildTool::ambigous_join = false; + // } } template @@ -931,12 +1027,11 @@ template void StationSelectAction::HandleMouseRelease() { // TODO station sign click if (!IsValidTile(this->cur_tile)) return; - this->selected_station = StationID::Invalid(); + _station_action = StationAction::Create{}; if (IsTileType(this->cur_tile, MP_STATION)) { auto st = Station::GetByTile(this->cur_tile); - if (st) this->selected_station = st->index; + if (st) _station_action = StationAction::Join{st->index}; } - this->handler.SelectStationToJoin(this->selected_station); } template @@ -956,15 +1051,11 @@ ToolGUIInfo StationSelectAction::GetGUIInfo() { template void StationSelectAction::OnStationRemoved(const Station *station) { - if (this->selected_station == station->index) this->selected_station = StationID::Invalid(); + // if (this->selected_station == station->index) this->selected_station = INVALID_STATION; } // --- StationBuildTool --- -StationID StationBuildTool::station_to_join = StationID::Invalid(); -StationID StationBuildTool::current_selected_station = StationID::Invalid(); -std::optional StationBuildTool::active_highlight = std::nullopt; - TileArea GetCommandArea(const up &cmd) { if (auto rail_cmd = dynamic_cast(cmd.get())) { auto w = rail_cmd->numtracks; @@ -979,23 +1070,27 @@ TileArea GetCommandArea(const up &cmd) { return {dock_cmd->tile, tile_to}; } else if (auto airport_cmd = dynamic_cast(cmd.get())) { const AirportSpec *as = AirportSpec::Get(airport_cmd->airport_type); + if (as == nullptr) return {}; return {airport_cmd->tile, as->size_x, as->size_y}; } NOT_REACHED(); } + +StationBuildTool::StationBuildTool() { + ResetHighlightCoverageStation(); +} + template bool StationBuildTool::ExecuteBuildCommand(Thandler *handler, Tcallback callback, Targ arg) { - if (UseImprovedStationJoin()) { - auto cmd = handler->GetCommand(arg, StationBuildTool::station_to_join); - StationBuildTool::active_highlight = std::nullopt; + if (auto mode = std::get_if(&_station_action)) { + auto cmd = handler->GetCommand(arg, mode->station); return cmd ? cmd->post(callback) : false; } // Vanilla joining behaviour auto cmd = handler->GetCommand(arg, StationID::Invalid()); auto proc = [cmd=sp{std::move(cmd)}, callback](bool test, StationID to_join) -> bool { - StationBuildTool::station_to_join = to_join; if (!cmd) return false; auto station_cmd = dynamic_cast(cmd.get()); if (station_cmd == nullptr) return false; @@ -1003,16 +1098,16 @@ bool StationBuildTool::ExecuteBuildCommand(Thandler *handler, Tcallback callback if (test) { return cmd->test().Succeeded(); } else { - StationBuildTool::active_highlight = std::nullopt; + ResetSelectedStationToJoin(); return cmd->post(callback); } }; auto ohl = handler->GetObjectHighlight(arg); if (!ohl.has_value()) return false; - StationBuildTool::active_highlight = ohl; auto area = ohl->GetArea(); if (!area.has_value()) return false; + SetActiveHighlightObject(ohl); ShowSelectStationIfNeeded(area.value(), proc); return true; } @@ -1035,6 +1130,14 @@ bool RailStationBuildTool::RemoveHandler::Execute(TileArea area) { return cmd->post(&CcPlaySound_CONSTRUCTION_RAIL); } +std::optional RailStationBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const { + if (!IsValidTile(tile)) return std::nullopt; + auto w = _settings_client.gui.station_numtracks; + auto h = _settings_client.gui.station_platlength; + if (_station_gui.axis == AXIS_X) std::swap(w, h); + return TileArea{tile, w, h}; +} + up RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) { // TODO mostly same as DragNDropPlacement auto cmd = make_up( @@ -1046,7 +1149,7 @@ up RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex ti _station_gui.sel_class, _station_gui.sel_type, to_join, - true + _fn_mod ); cmd->with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION); return cmd; @@ -1071,7 +1174,7 @@ up RailStationBuildTool::DragNDropPlacementHandler::GetCommand(TileArea _station_gui.sel_class, _station_gui.sel_type, to_join, - true + _fn_mod ); cmd->with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION); return cmd; @@ -1179,7 +1282,7 @@ up RoadStopBuildTool::DragNDropPlacementHandler::GetCommand(TileArea ar _roadstop_gui.sel_class, _roadstop_gui.sel_type, to_join, - true + _fn_mod ); return res; @@ -1275,14 +1378,23 @@ bool DockBuildTool::RemoveHandler::Execute(TileArea area) { } // SizedPlacementHandler + +std::optional DockBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const { + if (!IsValidTile(tile)) return std::nullopt; + DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); + TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile); + return TileArea{tile, tile_to}; +} + up DockBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) { return make_up( tile, to_join, - true + _fn_mod ); } + bool DockBuildTool::SizedPlacementHandler::Execute(TileIndex tile) { return this->tool.ExecuteBuildCommand(this, &CcBuildDocks, tile); } @@ -1349,17 +1461,28 @@ bool AirportBuildTool::RemoveHandler::Execute(TileArea area) { } // SizedPlacementHandler + +std::optional AirportBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const { + if (!IsValidTile(tile)) return std::nullopt; + auto as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index); + if (as == nullptr) return std::nullopt; + return TileArea{tile, as->size_x, as->size_y}; +} + up AirportBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) { - // STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, - auto airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); + auto as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index); + if (as == nullptr) return nullptr; + auto airport_type = as->GetIndex(); auto layout = _selected_airport_layout; - return make_up( + auto cmd = make_up( tile, airport_type, layout, - StationBuildTool::station_to_join, - true + to_join, + _fn_mod ); + cmd->with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE); + return cmd; } bool AirportBuildTool::SizedPlacementHandler::Execute(TileIndex tile) { @@ -1429,5 +1552,4 @@ template class DragNDropPlacementAction; template class SizedPlacementAction; - } // namespace citymania diff --git a/src/citymania/cm_station_gui.hpp b/src/citymania/cm_station_gui.hpp index 48ffae7a2b..48a7e2c3ee 100644 --- a/src/citymania/cm_station_gui.hpp +++ b/src/citymania/cm_station_gui.hpp @@ -48,7 +48,13 @@ DiagDirection AutodetectRoadObjectDirection(TileIndex tile, Point pt, RoadType r DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area, Point pt, RoadType roadtype); DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt); void SetSelectedStationToJoin(StationID station_id); -void ResetJoinStationHighlight(); +void ResetSelectedStationToJoin(); + +void SetHighlightCoverageStation(Station *station, bool sel); +bool IsHighlightCoverageStation(const Station *station); + +bool HasSelectedStationHighlight(); +ToolGUIInfo GetSelectedStationGUIInfo(); struct OverlayParams { @@ -89,7 +95,6 @@ public: class StationSelectHandler { public: virtual ~StationSelectHandler() = default; - virtual void SelectStationToJoin(StationID station_id) = 0; }; template concept ImplementsStationSelectHandler = std::derived_from; @@ -99,7 +104,6 @@ class StationSelectAction : public Action { private: Handler handler; TileIndex cur_tile = INVALID_TILE; - StationID selected_station = StationID::Invalid(); public: StationSelectAction(const Handler &handler) : handler{handler} {} ~StationSelectAction() override = default; @@ -125,6 +129,7 @@ public: virtual bool Execute(TileIndex tile) = 0; virtual std::optional GetObjectHighlight(TileIndex tile) = 0; virtual std::pair GetCatchmentParams() = 0; + virtual std::optional GetArea(TileIndex tile) const = 0; }; template concept ImplementsSizedPlacementHandler = std::derived_from; @@ -138,7 +143,7 @@ public: SizedPlacementAction(const Handler &handler) : handler{handler} {} ~SizedPlacementAction() override = default; void Update(Point pt, TileIndex tile) override; - std::optional GetArea() const override { return std::nullopt; }; + std::optional GetArea() const override { return this->handler.GetArea(this->cur_tile); } bool HandleMousePress() override; void HandleMouseRelease() override; ToolGUIInfo GetGUIInfo() override; @@ -176,20 +181,18 @@ public: class StationBuildTool : public Tool { public: - static StationID station_to_join; - static StationID current_selected_station; - static std::optional active_highlight; + // static StationID station_to_join; + // static bool ambigous_join; class StationSelectHandler : public citymania::StationSelectHandler { public: StationBuildTool &tool; StationSelectHandler(StationBuildTool &tool) : tool(tool) {} ~StationSelectHandler() {} - void SelectStationToJoin(StationID station_id) override { this->tool.SelectStationToJoin(station_id); }; }; + StationBuildTool(); ~StationBuildTool() override = default; - void SelectStationToJoin(StationID station_id) { StationBuildTool::station_to_join = station_id; }; ToolGUIInfo GetGUIInfo() override { if (!this->action) return {}; return this->action->GetGUIInfo(); @@ -223,6 +226,7 @@ private: bool Execute(TileIndex tile) override; std::optional GetObjectHighlight(TileIndex tile) override; std::pair GetCatchmentParams() override { return {this->tool.GetCatchmentParams()}; }; + std::optional GetArea(TileIndex tile) const override; }; class DragNDropPlacementHandler: public citymania::DragNDropPlacementHandler { @@ -309,6 +313,7 @@ private: bool Execute(TileIndex tile) override; std::optional GetObjectHighlight(TileIndex tile) override; std::pair GetCatchmentParams() override { return {SCT_ALL, CA_DOCK}; }; + std::optional GetArea(TileIndex tile) const override; }; public: @@ -343,6 +348,7 @@ private: bool Execute(TileIndex tile) override; std::optional GetObjectHighlight(TileIndex tile) override; std::pair GetCatchmentParams() override; + std::optional GetArea(TileIndex tile) const override; }; public: @@ -355,8 +361,6 @@ private: Mode mode; }; -ToolGUIInfo GetSelectedStationGUIInfo(); - } // namespace citymania #endif diff --git a/src/command.cpp b/src/command.cpp index 03cdb96bc4..1e50017e03 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -246,8 +246,6 @@ void CommandHelperBase::InternalPostResult(CommandCost &res, TileIndex tile, boo int x = TileX(tile) * TILE_SIZE; int y = TileY(tile) * TILE_SIZE; - // FIXME if (!(cmd & CMD_NO_ESTIMATE) && my_cmd) citymania::CountEffectiveAction(); - if (res.Failed()) { /* Only show the error when it's for us. */ if (estimate_only || (IsLocalCompany() && err_message != 0 && my_cmd)) { diff --git a/src/command_func.h b/src/command_func.h index 007b55beef..09d93b5558 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -24,7 +24,9 @@ extern uint32 _frame_counter; struct CommandPacket; namespace citymania { extern CommandCost _command_execute_cost; + extern bool _automatic_command; void ExecuteCurrentCallback(const CommandCost &cost); + void CountEffectiveAction(); } /** @@ -304,6 +306,7 @@ protected: Tret res = Execute(err_message, reinterpret_cast(reinterpret_cast(callback)), my_cmd, estimate_only, network_command, tile, args); InternalPostResult(ExtractCommandCost(res), tile, estimate_only, only_sending, err_message, my_cmd); citymania::_command_execute_cost = ExtractCommandCost(res); + if (!estimate_only && !only_sending && !citymania::_automatic_command && my_cmd) citymania::CountEffectiveAction(); if (!estimate_only && !only_sending && callback != nullptr) { if constexpr (std::is_same_v) { diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 4fe13910e7..79f8364c63 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -63,7 +63,6 @@ namespace citymania { void ChangeGraphBackgroundColour(NWidgetPart *nwid_begin, NWidgetPart *nwid_end) { for (auto w = nwid_begin; w != nwid_end; w++) { switch (w->type) { - case WWT_TEXT: case WWT_RESIZEBOX: case WWT_MATRIX: case NWID_VSCROLLBAR: diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 476820a2b3..16f9d8d80b 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -3201,7 +3201,7 @@ struct IndustryCargoesWindow : public Window { Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { std::string cargo_str; - if (_settings_client.gui.developer >= 1) + if (!_settings_client.gui.newgrf_developer_tools) cargo_str = GetString(CM_STR_CARGO_WITH_ID, cs->name, cs->Index()); else cargo_str = GetString(cs->name); @@ -3222,7 +3222,7 @@ struct IndustryCargoesWindow : public Window { if (!indsp->enabled) continue; std::string indsp_str; - if (_settings_client.gui.developer >= 1) + if (!_settings_client.gui.newgrf_developer_tools) indsp_str = GetString(CM_STR_INDUSTRY_TYPE_WITH_ID, indsp->name, ind); else indsp_str = GetString(indsp->name); diff --git a/src/lang/english.txt b/src/lang/english.txt index ae88fdc084..b6611fbf38 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -6285,19 +6285,27 @@ CM_STR_NETWORK_COMPANY_LIST_SPECTATE :Spectate CM_STR_RAIL_TOOLBAR_TOOLTIP_BLUEPRINT :{BLACK}Rail blueprint tool (copy-paste) -CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL :Ctrl+click: {STRING2} -CM_STR_CONFIG_SETTING_ORDER_MOD_SHIFT :Shift+click: {STRING2} -CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL_SHIFT :Ctrl+Shift+lick: {STRING2} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT :Alt+Click: {STRING2} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_SHIFT :Alt+Shift+click: {STRING2} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_CTRL :Ctrl+Alt+click: {STRING2} -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE :do nothing -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FULL_LOAD_ANY :Full load any cargo -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_TRANSFER_CARGO :Transfer cargo -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_UNLOAD_ALL :Force unload of all cargo -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FEEDER_LOAD :Feeder Load (replace first order) -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FEEDER_UNLOAD :Feeder Unload (replace last order) -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NO_LOAD :Do not load any cargo +CM_STR_CONFIG_SETTING_STATION_MOD_CTRL :Ctrl+click station: {STRING2} +CM_STR_CONFIG_SETTING_STATION_MOD_SHIFT :Shift+click station: {STRING2} +CM_STR_CONFIG_SETTING_STATION_MOD_CTRL_SHIFT :Ctrl+Shift+click station: {STRING2} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT :Alt+Click station: {STRING2} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT_SHIFT :Alt+Shift+click station: {STRING2} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT_CTRL :Ctrl+Alt+click station: {STRING2} +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE :Do nothing +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FULL_LOAD_ANY :Full load any cargo +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_TRANSFER_CARGO :Transfer cargo +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_UNLOAD_ALL :Force unload of all cargo +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FEEDER_LOAD :Feeder Load (replace first order) +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FEEDER_UNLOAD :Feeder Unload (replace last order) +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NO_LOAD :Do not load any cargo + +CM_STR_CONFIG_SETTING_DEPOT_MOD_CTRL :Ctrl+click depot: {STRING2} +CM_STR_CONFIG_SETTING_DEPOT_MOD_SHIFT :Shift+click depot: {STRING2} +CM_STR_CONFIG_SETTING_DEPOT_MOD_CTRL_SHIFT :Ctrl+Shift+click depot: {STRING2} +CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_NONE :Do nothing +CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_SERVICE :Service if needed +CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_STOP :Stop +CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_UNBUNCH :Unbunch CM_STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS :Keep depot building tools active after usage: {STRING2} CM_STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT :Keep the building tools for road, train and ship depots (reversible by placing with Ctrl). diff --git a/src/lang/german.txt b/src/lang/german.txt index a21546dd03..20f056004f 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -6228,19 +6228,19 @@ CM_STR_NETWORK_COMPANY_LIST_SPECTATE :Zuschauen CM_STR_RAIL_TOOLBAR_TOOLTIP_BLUEPRINT :{BLACK}Schienen-Blaupausen-Tool (kopieren-einfügen) -CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL :Strg+Linksklick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_SHIFT :Umschalt+Linksklick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL_SHIFT :Strg+Umschalt+Linksklick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT :Alt+Linksklick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_SHIFT :Alt+Umschalt+Linksklick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_CTRL :Strg+Alt+Linksklick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE :Nichts machen -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FULL_LOAD_ANY :Mit beliebiger Fracht voll beladen -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_TRANSFER_CARGO :Fracht umladen -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_UNLOAD_ALL :Entladen jeder Fracht erzwingen -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FEEDER_LOAD :Zulieferer-Beladung (ersten Auftrag ersetzen) -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FEEDER_UNLOAD :Zulieferer-Entladung (letzten Auftrag ersetzen) -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NO_LOAD :Mit keiner Fracht beladen +CM_STR_CONFIG_SETTING_STATION_MOD_CTRL :Strg+Linksklick station: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_SHIFT :Umschalt+Linksklick station: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_CTRL_SHIFT :Strg+Umschalt+Linksklick station: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT :Alt+Linksklick station: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT_SHIFT :Alt+Umschalt+Linksklick station: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT_CTRL :Strg+Alt+Linksklick station: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE :Nichts machen +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FULL_LOAD_ANY :Mit beliebiger Fracht voll beladen +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_TRANSFER_CARGO :Fracht umladen +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_UNLOAD_ALL :Entladen jeder Fracht erzwingen +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FEEDER_LOAD :Zulieferer-Beladung (ersten Auftrag ersetzen) +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FEEDER_UNLOAD :Zulieferer-Entladung (letzten Auftrag ersetzen) +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NO_LOAD :Mit keiner Fracht beladen CM_STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS :Die Depot-Bauwerkzeuge nach Benutzung weiter aktiviert lassen: {STRING} CM_STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT :Die Bauwerkzeuge für Fahrzeug- und Zugdepot sowie Werft behalten (umkehrbar durch platzieren mit Strg). diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 5c754090ae..20024a612c 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -6545,19 +6545,19 @@ CM_STR_NETWORK_COMPANY_LIST_SPECTATE :Стать зр CM_STR_RAIL_TOOLBAR_TOOLTIP_BLUEPRINT :{BLACK}Чертежи рельсов (копировать-вставить) -CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL :Ctrl+click: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_SHIFT :Shift+click: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL_SHIFT :Ctrl+Shift+lick: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT :Alt+Click: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_SHIFT :Alt+Shift+click: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_CTRL :Ctrl+Alt+click: {STRING} -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE :ничего не делать -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FULL_LOAD_ANY :Полная загрузка любым грузом -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_TRANSFER_CARGO :Передать груз -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_UNLOAD_ALL :Выгрузит весь груз -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FEEDER_LOAD :Загрузка фидера (заменяет первое задание) -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_FEEDER_UNLOAD :Разгрузка фидера (заменяет последнее задание) -CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NO_LOAD :Ничего не загружать +CM_STR_CONFIG_SETTING_STATION_MOD_CTRL :Ctrl+click по станции: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_SHIFT :Shift+click по станции: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_CTRL_SHIFT :Ctrl+Shift+click по станции: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT :Alt+Click по станции: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT_SHIFT :Alt+Shift+click по станции: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ALT_CTRL :Ctrl+Alt+click по станции: {STRING} +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE :ничего не делать +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FULL_LOAD_ANY :Полная загрузка любым грузом +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_TRANSFER_CARGO :Передать груз +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_UNLOAD_ALL :Выгрузит весь груз +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FEEDER_LOAD :Загрузка фидера (заменяет первое задание) +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_FEEDER_UNLOAD :Разгрузка фидера (заменяет последнее задание) +CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NO_LOAD :Ничего не загружать CM_STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS :Оставлять инструмент строительства депо открытым после использования: {STRING} CM_STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT :Оставлять инструмент строительства депо открытым после использования (поведение инвертируется нажанием Fn). diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 3deb30634a..77aa35f916 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -7,6 +7,7 @@ /** @file order_gui.cpp GUI related to orders. */ +#include "gfx_func.h" #include "stdafx.h" #include "command_func.h" #include "viewport_func.h" @@ -473,7 +474,22 @@ static std::pair GetOrderCmdFromTile(const Vehicle *v, Ti ODTFB_PART_OF_ORDERS, (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); - if (citymania::_fn_mod) { + uint8 os = 0; + if (_ctrl_pressed) { + if (_shift_pressed) os = _settings_client.gui.cm_ctrl_shift_depot_mod; + else os = _settings_client.gui.cm_ctrl_depot_mod; + } else if (_shift_pressed) { + os = _settings_client.gui.cm_shift_depot_mod; + } + + switch (os) { + case 1: order.SetDepotOrderType((OrderDepotTypeFlags)(order.GetDepotOrderType() | ODTFB_SERVICE)); break; + case 2: order.SetDepotActionType(ODATFB_HALT); break; + case 3: order.SetDepotActionType(ODATFB_UNBUNCH); break; + default: break; + } + + if (order.GetDepotActionType() & ODATFB_UNBUNCH) { /* Check to see if we are allowed to make this an unbunching order. */ bool failed = false; if (v->HasFullLoadOrder()) { @@ -497,7 +513,7 @@ static std::pair GetOrderCmdFromTile(const Vehicle *v, Ti } /* Now we are allowed to set the action type. */ - order.SetDepotActionType(ODATFB_UNBUNCH); + // order.SetDepotActionType(ODATFB_UNBUNCH); } return {order, FeederOrderMod::NONE}; @@ -552,20 +568,20 @@ static std::pair GetOrderCmdFromTile(const Vehicle *v, Ti uint8 os = 0xff; if (_ctrl_pressed) { if (_shift_pressed) - os = _settings_client.gui.cm_ctrl_shift_order_mod; + os = _settings_client.gui.cm_ctrl_shift_station_mod; else if (_alt_pressed) - os = _settings_client.gui.cm_alt_ctrl_order_mod; + os = _settings_client.gui.cm_alt_ctrl_station_mod; else - os = _settings_client.gui.cm_ctrl_order_mod; + os = _settings_client.gui.cm_ctrl_station_mod; } else if (_shift_pressed) { if (_alt_pressed) - os = _settings_client.gui.cm_alt_shift_order_mod; + os = _settings_client.gui.cm_alt_shift_station_mod; else - os = _settings_client.gui.cm_shift_order_mod; + os = _settings_client.gui.cm_shift_station_mod; } else if (_alt_pressed) - os = _settings_client.gui.cm_alt_order_mod; + os = _settings_client.gui.cm_alt_station_mod; auto feeder_mod = FeederOrderMod::NONE; if (os != 0xff) { @@ -1628,7 +1644,7 @@ public: if (feeder_mod == FeederOrderMod::LOAD) { if (citymania::cmd::InsertOrder(this->vehicle->tile, this->vehicle->index, 1, cmd) .with_error(STR_ERROR_CAN_T_INSERT_NEW_ORDER) - .no_estimate() + .set_auto() .post()) { citymania::cmd::DeleteOrder(this->vehicle->tile, this->vehicle->index, 0) .with_error(STR_ERROR_CAN_T_DELETE_THIS_ORDER) @@ -1639,7 +1655,7 @@ public: } else if (feeder_mod == FeederOrderMod::UNLOAD) { // still flushes the whole order table if (citymania::cmd::InsertOrder(this->vehicle->tile, this->vehicle->index, this->vehicle->GetNumOrders(), cmd) .with_error(STR_ERROR_CAN_T_INSERT_NEW_ORDER) - .no_estimate() + .set_auto() .post()) { citymania::cmd::DeleteOrder(this->vehicle->tile, this->vehicle->index, this->vehicle->GetNumOrders() + (int)_networking - 2) .with_error(STR_ERROR_CAN_T_DELETE_THIS_ORDER) diff --git a/src/settings_type.h b/src/settings_type.h index 91e2d3dd2f..375b8dadfe 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -246,12 +246,17 @@ struct GUISettings { uint32 cm_powerfund_money; ///< minimum amount of money for powerfund to work uint16 cm_powerfund_houses; ///< powerfunding maximum houses limit - uint8 cm_ctrl_order_mod; ///< goto action shortcut CTRL+LEFT-CLICK - uint8 cm_shift_order_mod; ///< goto action shortcut SHIFT+LEFT-CLICK - uint8 cm_ctrl_shift_order_mod; ///< goto action shortcut CTRL+SHIFT+LEFT-CLICK - uint8 cm_alt_order_mod; ///< goto action shortcut ALT+LEFT-CLICK - uint8 cm_alt_shift_order_mod; ///< goto action shortcut ALT+SHIFT+LEFT-CLICK - uint8 cm_alt_ctrl_order_mod; ///< goto action shortcut ALT+CTRL+LEFT-CLICK + uint8 cm_ctrl_station_mod; ///< station action shortcut on CTRL+LEFT-CLICK + uint8 cm_shift_station_mod; ///< station action shortcut on SHIFT+LEFT-CLICK + uint8 cm_ctrl_shift_station_mod; ///< station action shortcut on CTRL+SHIFT+LEFT-CLICK + uint8 cm_alt_station_mod; ///< station action shortcut on ALT+LEFT-CLICK + uint8 cm_alt_shift_station_mod; ///< station action shortcut on ALT+SHIFT+LEFT-CLICK + uint8 cm_alt_ctrl_station_mod; ///< station action shortcut on ALT+CTRL+LEFT-CLICK + + uint8 cm_ctrl_depot_mod; ///< depot action shortcut on CTRL+LEFT-CLICK + uint8 cm_shift_depot_mod; ///< depot action shortcut on SHIFT+LEFT-CLICK + uint8 cm_ctrl_shift_depot_mod; ///< depot action shortcut on CTRL+SHIFT+LEFT-CLICK + bool cm_no_loading_on_transfer_order; ///< automatically set no-loading when ordering to transfer all cargo bool cm_no_loading_on_unload_order; ///< automatically set no-loading when ordering to unload all cargo diff --git a/src/station_gui.cpp b/src/station_gui.cpp index b8c367eddc..ed54b9577d 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1491,7 +1491,7 @@ struct StationViewWindow : public Window { extern const Station *_viewport_highlight_station; this->SetWidgetDisabledState(WID_SV_CATCHMENT, st->facilities == StationFacilities{}); - this->SetWidgetLoweredState(WID_SV_CATCHMENT, _viewport_highlight_station == st); + this->SetWidgetLoweredState(WID_SV_CATCHMENT, citymania::IsHighlightCoverageStation(st)); this->DrawWidgets(); @@ -1991,7 +1991,8 @@ struct StationViewWindow : public Window { break; case WID_SV_CATCHMENT: - SetViewportCatchmentStation(Station::Get(this->window_number), !this->IsWidgetLowered(WID_SV_CATCHMENT)); + citymania::SetHighlightCoverageStation(Station::Get(this->window_number), !this->IsWidgetLowered(WID_SV_CATCHMENT)); + // SetViewportCatchmentStation(Station::Get(this->window_number), !this->IsWidgetLowered(WID_SV_CATCHMENT)); break; case WID_SV_LOCATION: @@ -2365,7 +2366,7 @@ struct SelectStationWindow : Window { void Close([[maybe_unused]] int data = 0) override { if constexpr (std::is_same_v) SetViewportCatchmentSpecializedStation(nullptr, true); - else citymania::ResetJoinStationHighlight(); + else citymania::ResetSelectedStationToJoin(); _thd.freeze = false; this->Window::Close(); diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 530cedafb0..ffe00c1f5b 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -233,7 +233,7 @@ struct StatusBarWindow : Window { this->SetWidgetDirty(WID_S_LEFT); }}; - TimeoutTimer cm_epm_interval = {std::chrono::seconds(1), [this]() { + IntervalTimer cm_epm_interval = {std::chrono::seconds(1), [this](uint) { this->SetWidgetDirty(CM_WID_S_APM); }}; }; diff --git a/src/table/settings/cmclient_settings.ini b/src/table/settings/cmclient_settings.ini index 53b1d085e9..0b07e4bbf4 100644 --- a/src/table/settings/cmclient_settings.ini +++ b/src/table/settings/cmclient_settings.ini @@ -2,7 +2,8 @@ static void cm_v_RedrawStatusBar(int32 new_value); static void cm_v_RedrawGraphs(int32 new_value); -static std::initializer_list _order_mod_actions{"nothing", "full_load", "transfer", "unload_all", "feeder_load", "feeder_unload", "no_load"}; +static std::initializer_list _station_mod_actions{"nothing", "full_load", "transfer", "unload_all", "feeder_load", "feeder_unload", "no_load"}; +static std::initializer_list _depot_mod_actions{"nothing", "service", "stop", "unbunch"}; static std::initializer_list _mod_keys{"none", "shift", "ctrl", "alt", "command"}; static std::initializer_list _shaded_tree_options{"always_off", "always_on", "as_server"}; static std::initializer_list _graph_background_options{"black", "grey"}; @@ -64,69 +65,102 @@ def = true str = CM_STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD [SDTC_OMANY] -var = gui.cm_ctrl_order_mod +var = gui.cm_ctrl_station_mod type = SLE_UINT8 flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania def = 1 max = 6 -full = _order_mod_actions -str = CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL -strval = CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +full = _station_mod_actions +str = CM_STR_CONFIG_SETTING_STATION_MOD_CTRL +strval = CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE cat = SC_BASIC [SDTC_OMANY] -var = gui.cm_shift_order_mod +var = gui.cm_shift_station_mod type = SLE_UINT8 flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania def = 0 max = 6 -full = _order_mod_actions -str = CM_STR_CONFIG_SETTING_ORDER_MOD_SHIFT -strval = CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +full = _station_mod_actions +str = CM_STR_CONFIG_SETTING_STATION_MOD_SHIFT +strval = CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE cat = SC_BASIC [SDTC_OMANY] -var = gui.cm_ctrl_shift_order_mod +var = gui.cm_ctrl_shift_station_mod type = SLE_UINT8 flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania def = 2 max = 6 -full = _order_mod_actions -str = CM_STR_CONFIG_SETTING_ORDER_MOD_CTRL_SHIFT -strval = CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +full = _station_mod_actions +str = CM_STR_CONFIG_SETTING_STATION_MOD_CTRL_SHIFT +strval = CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE cat = SC_BASIC [SDTC_OMANY] -var = gui.cm_alt_order_mod +var = gui.cm_alt_station_mod type = SLE_UINT8 flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania def = 4 max = 6 -full = _order_mod_actions -str = CM_STR_CONFIG_SETTING_ORDER_MOD_ALT -strval = CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +full = _station_mod_actions +str = CM_STR_CONFIG_SETTING_STATION_MOD_ALT +strval = CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE cat = SC_BASIC [SDTC_OMANY] -var = gui.cm_alt_shift_order_mod +var = gui.cm_alt_shift_station_mod type = SLE_UINT8 flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania def = 3 max = 6 -full = _order_mod_actions -str = CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_SHIFT -strval = CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +full = _station_mod_actions +str = CM_STR_CONFIG_SETTING_STATION_MOD_ALT_SHIFT +strval = CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE cat = SC_BASIC [SDTC_OMANY] -var = gui.cm_alt_ctrl_order_mod +var = gui.cm_alt_ctrl_station_mod type = SLE_UINT8 flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania def = 5 max = 6 -full = _order_mod_actions -str = CM_STR_CONFIG_SETTING_ORDER_MOD_ALT_CTRL -strval = CM_STR_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +full = _station_mod_actions +str = CM_STR_CONFIG_SETTING_STATION_MOD_ALT_CTRL +strval = CM_STR_CONFIG_SETTING_STATION_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_ctrl_depot_mod +type = SLE_UINT8 +flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania +def = 3 +max = 3 +full = _depot_mod_actions +str = CM_STR_CONFIG_SETTING_DEPOT_MOD_CTRL +strval = CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_shift_depot_mod +type = SLE_UINT8 +flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania +def = 1 +max = 3 +full = _depot_mod_actions +str = CM_STR_CONFIG_SETTING_DEPOT_MOD_SHIFT +strval = CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_ctrl_shift_depot_mod +type = SLE_UINT8 +flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania +def = 2 +max = 3 +full = _depot_mod_actions +str = CM_STR_CONFIG_SETTING_DEPOT_MOD_CTRL_SHIFT +strval = CM_STR_CONFIG_SETTING_DEPOT_MOD_ACTION_NONE cat = SC_BASIC [SDTC_BOOL] diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 9b9ec7e5e1..5d0316fca3 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1017,7 +1017,7 @@ static void DoRegularFunding(Town *t) } else if (TimerGameTick::counter - t->cm.last_funding < Ticks::TOWN_GROWTH_TICKS) return; citymania::cmd::DoTownAction(t->xy, t->index, TownAction::FundBuildings) - .no_estimate() + .set_auto() .as_company(_local_company) .post(); t->cm.last_funding = TimerGameTick::counter; @@ -1062,7 +1062,7 @@ static void DoRegularAdvertising(Town *t) { t->cm.last_advertisement = TimerGameTick::counter; citymania::cmd::DoTownAction(t->xy, t->index, TownAction::AdvertiseLarge) - .no_estimate() + .set_auto() .as_company(_local_company) .with_callback([=] (bool res) -> bool { if (!res) return true;