From d75253d491ccff6e51c42490365565517cbfd8c5 Mon Sep 17 00:00:00 2001 From: dP Date: Mon, 30 Jun 2025 00:32:52 +0500 Subject: [PATCH 1/9] Fix apm and average apm display --- src/citymania/cm_command_type.hpp | 11 +++++++++++ src/citymania/cm_commands.cpp | 1 + src/citymania/cm_hotkeys.cpp | 4 +++- src/citymania/cm_station_gui.cpp | 5 +++-- src/command.cpp | 2 -- src/command_func.h | 3 +++ src/order_gui.cpp | 4 ++-- src/statusbar_gui.cpp | 2 +- src/town_cmd.cpp | 4 ++-- 9 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/citymania/cm_command_type.hpp b/src/citymania/cm_command_type.hpp index 52b6a0a393..b35292a7fc 100644 --- a/src/citymania/cm_command_type.hpp +++ b/src/citymania/cm_command_type.hpp @@ -27,11 +27,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 = INVALID_COMPANY; StringID error = (StringID)0; CommandCallback callback = nullptr; @@ -49,10 +51,12 @@ public: if (this->company != INVALID_COMPANY) _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; } @@ -83,6 +87,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 db80261d9b..28a32cdfe2 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_hotkeys.cpp b/src/citymania/cm_hotkeys.cpp index ffdd5c9a1e..0c139a806e 100644 --- a/src/citymania/cm_hotkeys.cpp +++ b/src/citymania/cm_hotkeys.cpp @@ -28,6 +28,7 @@ struct RailStationGUISettings { byte station_count; ///< Number of custom stations (if newstations is \c true ) }; extern RailStationGUISettings _railstation; ///< Settings of the station builder GUI +extern bool _generating_world; namespace citymania { @@ -51,6 +52,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++; @@ -69,7 +71,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_station_gui.cpp b/src/citymania/cm_station_gui.cpp index 82f81b7034..8570b4faa0 100644 --- a/src/citymania/cm_station_gui.cpp +++ b/src/citymania/cm_station_gui.cpp @@ -1360,16 +1360,17 @@ bool AirportBuildTool::RemoveHandler::Execute(TileArea area) { // SizedPlacementHandler up AirportBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) { - // STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); byte layout = _selected_airport_layout; - return make_up( + auto cmd = make_up( tile, airport_type, layout, StationBuildTool::station_to_join, true ); + cmd->with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE); + return cmd; } bool AirportBuildTool::SizedPlacementHandler::Execute(TileIndex tile) { diff --git a/src/command.cpp b/src/command.cpp index 2feba43a35..dbea28b064 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -245,8 +245,6 @@ void CommandHelperBase::InternalPostResult(const CommandCost &res, TileIndex til 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 5b65827810..6d6ffa71a2 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(); } /** @@ -314,6 +316,7 @@ protected: Tret res = Execute(err_message, 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/order_gui.cpp b/src/order_gui.cpp index 85c8047ad8..23590a9aa4 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1650,7 +1650,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) @@ -1661,7 +1661,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/statusbar_gui.cpp b/src/statusbar_gui.cpp index d9e586dcfe..07b6cc9aee 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -243,7 +243,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/town_cmd.cpp b/src/town_cmd.cpp index 1b26a9d44d..0b03b90d75 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -970,7 +970,7 @@ static void DoRegularFunding(Town *t) } else if (TimerGameTick::counter - t->last_funding < Ticks::TOWN_GROWTH_TICKS) return; citymania::cmd::DoTownAction(t->xy, t->index, HK_FUND) - .no_estimate() + .set_auto() .as_company(_local_company) .post(); t->last_funding = TimerGameTick::counter; @@ -1007,7 +1007,7 @@ static void DoRegularAdvertising(Town *t) { auto prev_rating = t->ad_ref_goods_entry->rating; citymania::cmd::DoTownAction(t->xy, t->index, HK_LADVERT) - .no_estimate() + .set_auto() .as_company(_local_company) .with_callback([=] (bool res) -> bool { if (res && prev_rating == t->ad_ref_goods_entry->rating) { From 13d49039ad15a8402d174a5d88927c59762039ca Mon Sep 17 00:00:00 2001 From: dP Date: Thu, 3 Jul 2025 18:59:12 +0500 Subject: [PATCH 2/9] Fix cargo id in industry chains display and make it use newgrf_developer_tools setting --- src/industry_gui.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 44aea3dc39..7b71afcea2 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -3213,8 +3213,7 @@ struct IndustryCargoesWindow : public Window { DropDownList lst; Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - if (_settings_client.gui.developer < 1) { - lst.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false)); + if (!_settings_client.gui.newgrf_developer_tools) { lst.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false)); continue; } @@ -3236,7 +3235,7 @@ struct IndustryCargoesWindow : public Window { for (IndustryType ind : _sorted_industry_types) { const IndustrySpec *indsp = GetIndustrySpec(ind); if (!indsp->enabled) continue; - if (_settings_client.gui.developer < 1) { + if (!_settings_client.gui.newgrf_developer_tools) { lst.push_back(std::make_unique(indsp->name, ind, false)); continue; } From ff94d155cfa6634be4752bebae1431bc215de4a2 Mon Sep 17 00:00:00 2001 From: dP Date: Fri, 4 Jul 2025 00:37:25 +0500 Subject: [PATCH 3/9] Fix: Don't highlight last built station in non-improved join mode --- src/citymania/cm_station_gui.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/citymania/cm_station_gui.cpp b/src/citymania/cm_station_gui.cpp index 8570b4faa0..d1dfec930a 100644 --- a/src/citymania/cm_station_gui.cpp +++ b/src/citymania/cm_station_gui.cpp @@ -651,7 +651,7 @@ 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) { +static HighlightMap PrepareHighilightMap(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); @@ -715,8 +715,8 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, bool show_coverage = _settings_client.gui.station_show_coverage; - auto hlmap = PrepareHighilighMap( - Station::GetIfValid(StationBuildTool::station_to_join), + auto hlmap = PrepareHighilightMap( + UseImprovedStationJoin() ? Station::GetIfValid(StationBuildTool::station_to_join) : nullptr, ohl.value(), cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP, true, @@ -839,7 +839,7 @@ ToolGUIInfo GetSelectedStationGUIInfo() { auto &ohl = StationBuildTool::active_highlight.value(); // TODO maybe update or none at all? ohl.UpdateTiles(); - auto hlmap = PrepareHighilighMap( + auto hlmap = PrepareHighilightMap( Station::GetIfValid(StationBuildTool::current_selected_station), ohl, CM_PALETTE_TINT_WHITE, @@ -1005,7 +1005,6 @@ bool StationBuildTool::ExecuteBuildCommand(Thandler *handler, Tcallback callback // Vanilla joining behaviour auto cmd = handler->GetCommand(arg, INVALID_STATION); 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; From 9998060ffa59ea68839d80f3a5f9feb4576a02d6 Mon Sep 17 00:00:00 2001 From: dP Date: Fri, 4 Jul 2025 02:05:13 +0500 Subject: [PATCH 4/9] Blink industries on the minimap with similar colour --- src/citymania/cm_colour.hpp | 13 +++++++++++-- src/citymania/cm_minimap.cpp | 12 ++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/citymania/cm_colour.hpp b/src/citymania/cm_colour.hpp index 79ef6837c5..e74cafec47 100644 --- a/src/citymania/cm_colour.hpp +++ b/src/citymania/cm_colour.hpp @@ -2,11 +2,22 @@ #define CM_COLOUR_HPP #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)]; } @@ -27,8 +38,6 @@ static inline Colour Remap32RGBA(uint r, uint g, uint b, uint a, Colour current, return Remap32RGBANoCheck(r, g, b, a, current, remap); } - - } // namespace citymania #endif diff --git a/src/citymania/cm_minimap.cpp b/src/citymania/cm_minimap.cpp index a2ea68e338..cabf3e5d86 100644 --- a/src/citymania/cm_minimap.cpp +++ b/src/citymania/cm_minimap.cpp @@ -28,6 +28,7 @@ #include +#include "cm_colour.hpp" #include "cm_hotkeys.hpp" #include "cm_minimap.hpp" @@ -854,10 +855,12 @@ 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) { + Debug(misc, 0, "BLINK {}", map_colour); + return MKCOLOUR_XXXX(GetBlinkColour(map_colour)); } else { - return GetIndustrySpec(type)->map_colour * 0x01010101; + return map_colour * 0x01010101; } } /* Otherwise make it disappear */ @@ -1431,7 +1434,8 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() SetDParam(0, tbl->legend); SetDParam(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 ]]; From 860cf98042153cc16187dac4da430dad142cfe07 Mon Sep 17 00:00:00 2001 From: dP Date: Thu, 10 Jul 2025 15:30:48 +0500 Subject: [PATCH 5/9] Use new tool highlight for station coverage button --- src/citymania/cm_highlight.cpp | 2 +- src/citymania/cm_station_gui.cpp | 221 +++++++++++++++++++------------ src/citymania/cm_station_gui.hpp | 13 +- src/station_gui.cpp | 7 +- 4 files changed, 149 insertions(+), 94 deletions(-) diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index 5cae50f24e..53684c87ee 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -2486,7 +2486,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_station_gui.cpp b/src/citymania/cm_station_gui.cpp index d1dfec930a..0dab2b31ff 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" @@ -572,16 +573,50 @@ extern DiagDirection AddAutodetectionRotation(DiagDirection ddir); // cm_highli // if (this->station_to_join == station->index) this->station_to_join = INVALID_STATION; // } +// 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 = INVALID_STATION; +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(INVALID_STATION); +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; @@ -589,19 +624,105 @@ void OnStationRemoved(const Station *station) { StationBuildTool::station_to_join = INVALID_STATION; UpdateActiveTool(); } - if (StationBuildTool::current_selected_station == station->index) { - StationBuildTool::current_selected_station = INVALID_STATION; + if (_selected_station == station->index) { + _selected_station = INVALID_STATION; + 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, StationCoverageType sct, 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, + SCT_ALL, + 0 + ); + return {hlmap, {}, {}}; +} // --- Action base class --- void Action::OnStationRemoved(const Station *) {} @@ -651,62 +772,6 @@ ToolGUIInfo RemoveAction::GetGUIInfo() { template void RemoveAction::OnStationRemoved(const Station *) {} -static HighlightMap PrepareHighilightMap(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(); @@ -720,8 +785,9 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, ohl.value(), cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP, true, + show_coverage, sct, - show_coverage ? rad : 0 + rad ); // Prepare build overlay @@ -834,22 +900,6 @@ 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 = PrepareHighilightMap( - 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) { @@ -972,8 +1022,6 @@ void StationSelectAction::OnStationRemoved(const Station *station) { // --- StationBuildTool --- StationID StationBuildTool::station_to_join = INVALID_STATION; -StationID StationBuildTool::current_selected_station = INVALID_STATION; -std::optional StationBuildTool::active_highlight = std::nullopt; TileArea GetCommandArea(const up &cmd) { if (auto rail_cmd = dynamic_cast(cmd.get())) { @@ -994,11 +1042,15 @@ TileArea GetCommandArea(const up &cmd) { 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; return cmd ? cmd->post(callback) : false; } @@ -1012,16 +1064,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; } @@ -1439,5 +1491,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 a2930df0fc..7da44401a5 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 { @@ -177,8 +183,6 @@ public: class StationBuildTool : public Tool { public: static StationID station_to_join; - static StationID current_selected_station; - static std::optional active_highlight; class StationSelectHandler : public citymania::StationSelectHandler { public: @@ -188,6 +192,7 @@ public: 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 { @@ -355,8 +360,6 @@ private: Mode mode; }; -ToolGUIInfo GetSelectedStationGUIInfo(); - } // namespace citymania #endif diff --git a/src/station_gui.cpp b/src/station_gui.cpp index de2fda931a..b9e96eb818 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1452,7 +1452,7 @@ struct StationViewWindow : public Window { extern const Station *_viewport_highlight_station; this->SetWidgetDisabledState(WID_SV_CATCHMENT, st->facilities == FACIL_NONE); - this->SetWidgetLoweredState(WID_SV_CATCHMENT, _viewport_highlight_station == st); + this->SetWidgetLoweredState(WID_SV_CATCHMENT, citymania::IsHighlightCoverageStation(st)); this->DrawWidgets(); @@ -1946,7 +1946,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: @@ -2340,7 +2341,7 @@ struct SelectStationWindow : WindowPopup { 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(); From 251f90f0d8d76bfba5cab69ccb70fc2b77d68ce4 Mon Sep 17 00:00:00 2001 From: dP Date: Thu, 10 Jul 2025 15:34:46 +0500 Subject: [PATCH 6/9] Remove old overlay and preview code --- src/citymania/cm_highlight.cpp | 72 ----------------------------- src/citymania/cm_highlight_type.hpp | 30 ------------ src/citymania/cm_station_gui.cpp | 33 ++----------- 3 files changed, 5 insertions(+), 130 deletions(-) diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index 53684c87ee..cf075287ab 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -549,33 +549,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 (CargoID i = 0; i < NUM_CARGO; i++) { - if (production[i] == 0) continue; - - switch (sct) { - case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CC_PASSENGERS)) continue; break; - case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CC_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; - } - SetDParam(0, i); - SetDParam(1, production[i] >> 8); - this->overlay_data.emplace_back(1, cs->GetCargoIcon(), GetString(CM_STR_BUILD_INFO_OVERLAY_STATION_CARGO)); - } -} - void ObjectHighlight::UpdateTiles() { this->tiles.clear(); this->sprites.clear(); @@ -639,7 +612,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: { @@ -661,9 +633,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; } @@ -697,7 +666,6 @@ void ObjectHighlight::UpdateTiles() { for (AirportTileTableIterator iter(as->table[this->airport_layout], this->tile); iter != INVALID_TILE; ++iter) { this->AddTile(iter, ObjectTileHighlight::make_airport_tile(palette, iter.GetStationGfx())); } - this->AddStationOverlayData(w, h, as->catchment, SCT_ALL); break; } case Type::BLUEPRINT: @@ -827,44 +795,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); - SetDParam(0, this->cost.GetCost()); - 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)); - // 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); @@ -2258,7 +2188,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; @@ -2437,7 +2366,6 @@ PaletteID GetTreeShadePal(TileIndex tile) { ActiveTool _at; - static void ResetVanillaHighlight() { if (_thd.window_class != WC_INVALID) { /* Undo clicking on button and drag & drop */ diff --git a/src/citymania/cm_highlight_type.hpp b/src/citymania/cm_highlight_type.hpp index 51acf9e55b..7d4e5449e7 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_station_gui.cpp b/src/citymania/cm_station_gui.cpp index 0dab2b31ff..1a3b92e9be 100644 --- a/src/citymania/cm_station_gui.cpp +++ b/src/citymania/cm_station_gui.cpp @@ -110,30 +110,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(); @@ -653,7 +632,7 @@ 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, StationCoverageType sct, uint rad) { +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{}; @@ -718,7 +697,6 @@ ToolGUIInfo GetSelectedStationGUIInfo() { CM_PALETTE_TINT_WHITE, false, _station_highlight_mode == StationHighlightMode::Coverage, - SCT_ALL, 0 ); return {hlmap, {}, {}}; @@ -786,7 +764,6 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP, true, show_coverage, - sct, rad ); @@ -1417,7 +1394,7 @@ up AirportBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, tile, airport_type, layout, - StationBuildTool::station_to_join, + to_join, true ); cmd->with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE); From 2ba94395542bf4c58584d033832b8c5309bb17f5 Mon Sep 17 00:00:00 2001 From: dP Date: Thu, 10 Jul 2025 18:23:24 +0500 Subject: [PATCH 7/9] Add settings to set depot order modifier hotkeys --- cm_changelog.txt | 2 + src/lang/english.txt | 34 ++++++---- src/lang/german.txt | 26 ++++---- src/lang/russian.txt | 26 ++++---- src/order_gui.cpp | 32 ++++++--- src/settings_gui.cpp | 15 +++-- src/settings_type.h | 17 +++-- src/table/settings/cmclient_settings.ini | 84 +++++++++++++++++------- 8 files changed, 152 insertions(+), 84 deletions(-) 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/lang/english.txt b/src/lang/english.txt index b504386f44..330fcc8e2c 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -6221,19 +6221,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 53e1eea96a..9854b3a18a 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -6217,19 +6217,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 667b01cec0..12cdaad461 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -6444,19 +6444,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 23590a9aa4..6d621f16a0 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" @@ -490,7 +491,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()) { @@ -514,7 +530,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}; @@ -560,20 +576,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) { diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index b86f1ef8b0..0cb3344024 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2159,12 +2159,15 @@ static SettingsContainer &GetSettingsTree() orders->Add(new SettingEntry("gui.new_nonstop")); orders->Add(new SettingEntry("gui.quick_goto")); orders->Add(new SettingEntry("gui.stop_location")); - orders->Add(new SettingEntry("gui.cm_ctrl_order_mod")); - orders->Add(new SettingEntry("gui.cm_shift_order_mod")); - orders->Add(new SettingEntry("gui.cm_ctrl_shift_order_mod")); - orders->Add(new SettingEntry("gui.cm_alt_order_mod")); - orders->Add(new SettingEntry("gui.cm_alt_shift_order_mod")); - orders->Add(new SettingEntry("gui.cm_alt_ctrl_order_mod")); + orders->Add(new SettingEntry("gui.cm_ctrl_station_mod")); + orders->Add(new SettingEntry("gui.cm_shift_station_mod")); + orders->Add(new SettingEntry("gui.cm_ctrl_shift_station_mod")); + orders->Add(new SettingEntry("gui.cm_alt_station_mod")); + orders->Add(new SettingEntry("gui.cm_alt_shift_station_mod")); + orders->Add(new SettingEntry("gui.cm_alt_ctrl_station_mod")); + orders->Add(new SettingEntry("gui.cm_ctrl_depot_mod")); + orders->Add(new SettingEntry("gui.cm_shift_depot_mod")); + orders->Add(new SettingEntry("gui.cm_ctrl_shift_depot_mod")); } } diff --git a/src/settings_type.h b/src/settings_type.h index c19dc1af2a..b808bd2ae7 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -231,12 +231,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/table/settings/cmclient_settings.ini b/src/table/settings/cmclient_settings.ini index 7d450bfbf2..10babc9ced 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"}; @@ -62,69 +63,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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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 = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | CM_SF_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] From c1a01798e643a073bb318736a80d594a90982e37 Mon Sep 17 00:00:00 2001 From: dP Date: Sun, 13 Jul 2025 17:30:22 +0500 Subject: [PATCH 8/9] Remove debug output --- src/citymania/cm_minimap.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/citymania/cm_minimap.cpp b/src/citymania/cm_minimap.cpp index cabf3e5d86..ffd152e43f 100644 --- a/src/citymania/cm_minimap.cpp +++ b/src/citymania/cm_minimap.cpp @@ -857,7 +857,6 @@ inline uint32 SmallMapWindow::GetTileColours(const TileArea &ta) const if (_legend_from_industries[_industry_to_list_pos[type]].show_on_map) { auto map_colour = GetIndustrySpec(type)->map_colour; if (type == _smallmap_industry_highlight && _smallmap_industry_highlight_state) { - Debug(misc, 0, "BLINK {}", map_colour); return MKCOLOUR_XXXX(GetBlinkColour(map_colour)); } else { return map_colour * 0x01010101; From 9a3e78d46457976b491e13ebf4b68a7b1b64403e Mon Sep 17 00:00:00 2001 From: dP Date: Thu, 4 Sep 2025 14:13:06 +0500 Subject: [PATCH 9/9] Fix non-improved station joning --- src/citymania/cm_highlight.cpp | 19 ----- src/citymania/cm_station_gui.cpp | 142 +++++++++++++++++++++++++------ src/citymania/cm_station_gui.hpp | 13 +-- src/viewport.cpp | 4 +- 4 files changed, 127 insertions(+), 51 deletions(-) diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index cf075287ab..b2e377803c 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -188,9 +188,6 @@ struct TileZoning { static TileZoning *_mz = nullptr; static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE; -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; @@ -1775,8 +1772,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]; @@ -1819,20 +1814,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) { diff --git a/src/citymania/cm_station_gui.cpp b/src/citymania/cm_station_gui.cpp index 1a3b92e9be..bf627a45b8 100644 --- a/src/citymania/cm_station_gui.cpp +++ b/src/citymania/cm_station_gui.cpp @@ -37,10 +37,12 @@ #include "generated/cm_gen_commands.hpp" #include +#include #include #include #include #include +#include bool _remove_button_clicked; // replace vanilla static vars @@ -83,13 +85,20 @@ extern byte _selected_airport_layout; ///< selected airport layout numb 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 && _settings_game.station.adjacent_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_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). @@ -599,8 +608,8 @@ bool IsHighlightCoverageStation(const Station *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 = INVALID_STATION; + if (auto mode = std::get_if(&_station_action); mode && mode->station == station->index) { + _station_action = StationAction::Create{}; UpdateActiveTool(); } if (_selected_station == station->index) { @@ -753,15 +762,25 @@ void RemoveAction::OnStationRemoved(const Station *) {} 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; + Station *to_join = nullptr; + if (auto mode = std::get_if(&_station_action)) + to_join = Station::GetIfValid(mode->station); auto hlmap = PrepareHighilightMap( - UseImprovedStationJoin() ? Station::GetIfValid(StationBuildTool::station_to_join) : nullptr, + to_join, ohl.value(), - cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP, + palette, true, show_coverage, rad @@ -771,14 +790,13 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, BuildInfoOverlayData data; - if (StationBuildTool::station_to_join != INVALID_STATION) { - SetDParam(0, StationBuildTool::station_to_join); + if (auto mode = std::get_if(&_station_action)) { + SetDParam(0, mode->station); data.emplace_back(0, PAL_NONE, GetString(CM_STR_BULID_INFO_OVERLAY_JOIN_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? @@ -881,6 +899,57 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional ohl, 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, INVALID_STATION); + 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 = INVALID_STATION; + 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 != INVALID_STATION) { + to_join = INVALID_STATION; + 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 != INVALID_STATION) _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 @@ -967,12 +1036,11 @@ template void StationSelectAction::HandleMouseRelease() { // TODO station sign click if (!IsValidTile(this->cur_tile)) return; - this->selected_station = INVALID_STATION; + _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 @@ -993,13 +1061,11 @@ ToolGUIInfo StationSelectAction::GetGUIInfo() { template void StationSelectAction::OnStationRemoved(const Station *station) { - if (this->selected_station == station->index) this->selected_station = INVALID_STATION; + // if (this->selected_station == station->index) this->selected_station = INVALID_STATION; } // --- StationBuildTool --- -StationID StationBuildTool::station_to_join = INVALID_STATION; - TileArea GetCommandArea(const up &cmd) { if (auto rail_cmd = dynamic_cast(cmd.get())) { auto w = rail_cmd->numtracks; @@ -1014,6 +1080,7 @@ 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(); @@ -1026,8 +1093,8 @@ StationBuildTool::StationBuildTool() { template bool StationBuildTool::ExecuteBuildCommand(Thandler *handler, Tcallback callback, Targ arg) { - if (UseImprovedStationJoin()) { - auto cmd = handler->GetCommand(arg, StationBuildTool::station_to_join); + if (auto mode = std::get_if(&_station_action)) { + auto cmd = handler->GetCommand(arg, mode->station); return cmd ? cmd->post(callback) : false; } @@ -1073,6 +1140,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 (_railstation.orientation == 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( @@ -1084,7 +1159,7 @@ up RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex ti _railstation.station_class, _railstation.station_type, to_join, - true + _fn_mod ); cmd->with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION); return cmd; @@ -1109,7 +1184,7 @@ up RailStationBuildTool::DragNDropPlacementHandler::GetCommand(TileArea _railstation.station_class, _railstation.station_type, to_join, - true + _fn_mod ); cmd->with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION); return cmd; @@ -1217,7 +1292,7 @@ up RoadStopBuildTool::DragNDropPlacementHandler::GetCommand(TileArea ar _roadstop_gui_settings.roadstop_class, _roadstop_gui_settings.roadstop_type, to_join, - true + _fn_mod ); return res; @@ -1313,14 +1388,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); } @@ -1387,15 +1471,25 @@ 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) { - byte 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; + byte airport_type = as->GetIndex(); byte layout = _selected_airport_layout; auto cmd = make_up( tile, airport_type, layout, to_join, - true + _fn_mod ); cmd->with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE); return cmd; diff --git a/src/citymania/cm_station_gui.hpp b/src/citymania/cm_station_gui.hpp index 7da44401a5..f57cef7e54 100644 --- a/src/citymania/cm_station_gui.hpp +++ b/src/citymania/cm_station_gui.hpp @@ -95,7 +95,6 @@ public: class StationSelectHandler { public: virtual ~StationSelectHandler() = default; - virtual void SelectStationToJoin(StationID station_id) = 0; }; template concept ImplementsStationSelectHandler = std::derived_from; @@ -105,7 +104,6 @@ class StationSelectAction : public Action { private: Handler handler; TileIndex cur_tile = INVALID_TILE; - StationID selected_station = INVALID_STATION; public: StationSelectAction(const Handler &handler) : handler{handler} {} ~StationSelectAction() override = default; @@ -131,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; @@ -144,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; @@ -182,19 +181,18 @@ public: class StationBuildTool : public Tool { public: - static StationID station_to_join; + // 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(); @@ -228,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 { @@ -314,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: @@ -348,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: diff --git a/src/viewport.cpp b/src/viewport.cpp index b24a885abb..60bbcdabd3 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -3237,8 +3237,8 @@ static void CheckOverflow(int &test, int &other, int max, int mult) test = max; } -// static const uint X_DIRS = (1 << DIR_NE) | (1 << DIR_SW); -// static const uint Y_DIRS = (1 << DIR_SE) | (1 << DIR_NW); +static const uint X_DIRS = (1 << DIR_NE) | (1 << DIR_SW); +static const uint Y_DIRS = (1 << DIR_SE) | (1 << DIR_NW); static const uint HORZ_DIRS = (1 << DIR_W) | (1 << DIR_E); // static const uint VERT_DIRS = (1 << DIR_N) | (1 << DIR_S);