diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index e29493a747..0406beade1 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -70,6 +70,9 @@ STR_VIEWPORT_TOWN_TINY_EXCELLENT_RATING :{TINY_FONT}{GRE STR_CONFIG_SETTING_TOWN_GROWTH_EXTREME_SLOW :Extremely slow STR_CONFIG_SETTING_TOWN_GROWTH_VERY_SLOW :Very slow +##after STR_ABOUT_MENU_LAND_BLOCK_INFO +STR_ABOUT_MENU_SHOW_PICKER_TOOL :Picker tool + ##after STR_ABOUT_MENU_SHOW_FRAMERATE STR_ABOUT_MENU_SHOW_TOGGLE_MODIFIER_KEYS :Modifier key window diff --git a/src/object.h b/src/object.h index c374ba9501..eb96b461a3 100644 --- a/src/object.h +++ b/src/object.h @@ -19,5 +19,6 @@ void UpdateCompanyHQ(TileIndex tile, uint score); void BuildObject(ObjectType type, TileIndex tile, CompanyID owner = OWNER_NONE, struct Town *town = nullptr, uint8 view = 0); Window *ShowBuildObjectPicker(); +void ShowBuildObjectPickerAndSelect(const ObjectSpec *spec); #endif /* OBJECT_H */ diff --git a/src/object_gui.cpp b/src/object_gui.cpp index a65fd457fe..50f8c4400c 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -755,6 +755,27 @@ Window *ShowBuildObjectPicker() return nullptr; } +/** Show our object picker, and select a particular spec. */ +void ShowBuildObjectPickerAndSelect(const ObjectSpec *spec) +{ + if (spec == nullptr || !spec->IsAvailable() || !ObjectClass::HasUIClass()) return; + + int spec_id = -1; + const ObjectClass *objclass = ObjectClass::Get(spec->cls_id); + for (int i = 0; i < (int)objclass->GetSpecCount(); i++) { + if (objclass->GetSpec(i) == spec) { + spec_id = i; + } + } + if (spec_id < 0) return; + + BuildObjectWindow *w = AllocateWindowDescFront(&_build_object_desc, 0, true); + if (w != nullptr) { + w->SelectOtherClass(spec->cls_id); + w->SelectOtherObject(spec_id); + } +} + /** Reset all data of the object GUI. */ void InitializeObjectGui() { diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 5051a10896..f4c1f3f6d1 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1145,6 +1145,22 @@ private: } } + void SelectClass(StationClassID station_class_id) { + if (_railstation.station_class != station_class_id) { + StationClass *station_class = StationClass::Get(station_class_id); + _railstation.station_class = station_class_id; + _railstation.station_count = station_class->GetSpecCount(); + _railstation.station_type = 0; + + this->CheckSelectedSize(station_class->GetSpec(_railstation.station_type)); + + NWidgetMatrix *matrix = this->GetWidget(WID_BRAS_MATRIX); + matrix->SetCount(_railstation.station_count); + matrix->SetClicked(_railstation.station_type); + this->SetDirty(); + } + } + public: BuildRailStationWindow(WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(desc, parent), filter_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE) { @@ -1639,18 +1655,7 @@ public: int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BRAS_NEWST_LIST); if (y >= (int)this->station_classes.size()) return; StationClassID station_class_id = this->station_classes[y]; - if (_railstation.station_class != station_class_id) { - StationClass *station_class = StationClass::Get(station_class_id); - _railstation.station_class = station_class_id; - _railstation.station_count = station_class->GetSpecCount(); - _railstation.station_type = 0; - - this->CheckSelectedSize(station_class->GetSpec(_railstation.station_type)); - - NWidgetMatrix *matrix = this->GetWidget(WID_BRAS_MATRIX); - matrix->SetCount(_railstation.station_count); - matrix->SetClicked(_railstation.station_type); - } + this->SelectClass(station_class_id); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); this->SetDirty(); DeleteWindowById(WC_SELECT_STATION, 0); @@ -1683,6 +1688,13 @@ public: CheckRedrawStationCoverage(this); } + void SelectClassAndSpec(StationClassID class_id, int spec_id) + { + this->SelectClass(class_id); + this->EnsureSelectedStationClassIsVisible(); + this->OnClick({}, WID_BRAS_IMAGE | (spec_id << 16), 1); + } + static HotkeyList hotkeys; }; @@ -2482,6 +2494,11 @@ struct BuildRailWaypointWindow : PickerWindowBase { { CheckRedrawWaypointCoverage(this, false); } + + void SelectWaypointSpec(int spec_id) + { + this->OnClick({}, WID_BRW_WAYPOINT | (spec_id << 16), 1); + } }; /** Nested widget definition for the build NewGRF rail waypoint window */ @@ -2692,3 +2709,51 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) return list; } + +void ShowBuildRailStationPickerAndSelect(StationType station_type, const StationSpec *spec) +{ + if (!IsStationAvailable(spec)) return; + + StationClassID class_id; + if (spec != nullptr) { + if ((spec->cls_id == STAT_CLASS_WAYP) != (station_type == STATION_WAYPOINT)) return; + class_id = spec->cls_id; + } else { + class_id = (station_type == STATION_ROADWAYPOINT) ? STAT_CLASS_WAYP : STAT_CLASS_DFLT; + } + + int spec_id = -1; + const StationClass *stclass = StationClass::Get(class_id); + for (int i = 0; i < (int)stclass->GetSpecCount(); i++) { + if (stclass->GetSpec(i) == spec) { + spec_id = i; + } + } + if (spec_id < 0) return; + + + Window *w = FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL); + if (w == nullptr) { + extern RailType _last_built_railtype; + w = ShowBuildRailToolbar(_last_built_railtype); + } + if (w == nullptr) return; + + auto trigger_widget = [&](int widget) { + if (!w->IsWidgetLowered(widget)) { + w->OnHotkey(widget); + } + }; + + if (station_type == STATION_WAYPOINT) { + trigger_widget(WID_RAT_BUILD_WAYPOINT); + + BuildRailWaypointWindow *waypoint_window = dynamic_cast(FindWindowById(WC_BUILD_WAYPOINT, TRANSPORT_RAIL)); + if (waypoint_window != nullptr) waypoint_window->SelectWaypointSpec(spec_id); + } else { + trigger_widget(WID_RAT_BUILD_STATION); + + BuildRailStationWindow *station_window = dynamic_cast(FindWindowById(WC_BUILD_STATION, TRANSPORT_RAIL)); + if (station_window != nullptr) station_window->SelectClassAndSpec(class_id, spec_id); + } +} diff --git a/src/rail_gui.h b/src/rail_gui.h index cd67a7f1cf..5a8deca087 100644 --- a/src/rail_gui.h +++ b/src/rail_gui.h @@ -15,6 +15,7 @@ #include "widgets/dropdown_type.h" struct Window *ShowBuildRailToolbar(RailType railtype); +void ShowBuildRailStationPickerAndSelect(StationType station_type, const StationSpec *spec); void ReinitGuiAfterToggleElrail(bool disable); void ResetSignalVariant(int32 = 0); void InitializeRailGUI(); diff --git a/src/road_gui.cpp b/src/road_gui.cpp index ec5436b5f2..ba2b330828 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -858,28 +858,34 @@ struct BuildRoadToolbarWindow : Window { static HotkeyList tram_hotkeys; }; -/** - * Handler for global hotkeys of the BuildRoadToolbarWindow. - * @param hotkey Hotkey - * @param last_build Last build road type - * @return ES_HANDLED if hotkey was accepted. - */ -static EventState RoadTramToolbarGlobalHotkeys(int hotkey, RoadType last_build, RoadTramType rtt) +Window *CreateRoadTramToolbarForRoadType(RoadType roadtype, RoadTramType rtt) { Window* w = nullptr; switch (_game_mode) { case GM_NORMAL: - w = ShowBuildRoadToolbar(last_build); + w = ShowBuildRoadToolbar(roadtype); break; case GM_EDITOR: - if ((GetRoadTypes(true) & ((rtt == RTT_ROAD) ? ~_roadtypes_type : _roadtypes_type)) == ROADTYPES_NONE) return ES_NOT_HANDLED; - w = ShowBuildRoadScenToolbar(last_build); + if ((GetRoadTypes(true) & ((rtt == RTT_ROAD) ? ~_roadtypes_type : _roadtypes_type)) == ROADTYPES_NONE) return nullptr; + w = ShowBuildRoadScenToolbar(roadtype); break; default: break; } + return w; +} + +/** + * Handler for global hotkeys of the BuildRoadToolbarWindow. + * @param hotkey Hotkey + * @param last_build Last build road type + * @return ES_HANDLED if hotkey was accepted. + */ +static EventState RoadTramToolbarGlobalHotkeys(int hotkey, RoadType last_build, RoadTramType rtt) +{ + Window* w = CreateRoadTramToolbarForRoadType(last_build, rtt); if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); @@ -1227,7 +1233,7 @@ enum BuildRoadStopHotkeys { struct BuildRoadStationWindow : public PickerWindowBase { private: - RoadStopType roadStopType; ///< The RoadStopType for this Window. + RoadStopType road_stop_type; ///< The RoadStopType for this Window. uint line_height; ///< Height of a single line in the newstation selection matrix. uint coverage_height; ///< Height of the coverage texts. Scrollbar *vscrollList; ///< Vertical scrollbar of the new station list. @@ -1271,13 +1277,29 @@ private: this->UpdateBuildingHeight(spec->height); } + void SelectClass(RoadStopClassID class_id) { + if (_roadstop_gui_settings.roadstop_class != class_id && GetIfClassHasNewStopsByType(RoadStopClass::Get(class_id), this->road_stop_type, _cur_roadtype)) { + _roadstop_gui_settings.roadstop_class = class_id; + RoadStopClass *rsclass = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class); + _roadstop_gui_settings.roadstop_count = rsclass->GetSpecCount(); + _roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, std::max(0, (int)_roadstop_gui_settings.roadstop_count - 1)); + this->SelectFirstAvailableTypeIfUnavailable(); + + NWidgetMatrix *matrix = this->GetWidget(WID_BROS_MATRIX); + matrix->SetCount(_roadstop_gui_settings.roadstop_count); + matrix->SetClicked(_roadstop_gui_settings.roadstop_type); + this->CheckSelectedSpec(); + this->SetDirty(); + } + } + public: BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(desc, parent), filter_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE) { this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WidgetDimensions::scaled.vsep_normal; this->vscrollList = nullptr; this->vscrollMatrix = nullptr; - this->roadStopType = rs; + this->road_stop_type = rs; bool newstops = GetIfNewStopsByType(rs, _cur_roadtype); this->CreateNestedTree(); @@ -1338,7 +1360,7 @@ public: _roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, _roadstop_gui_settings.roadstop_count - 1); /* Reset back to default class if the previously selected class is not available for this road stop type. */ - if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), roadStopType, _cur_roadtype)) { + if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), this->road_stop_type, _cur_roadtype)) { _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; } @@ -1391,7 +1413,7 @@ public: continue; } RoadStopClass *rs_class = RoadStopClass::Get(rs_id); - if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(rs_id); + if (GetIfClassHasNewStopsByType(rs_class, this->road_stop_type, _cur_roadtype)) this->roadstop_classes.push_back(rs_id); } if (this->ShowNewStops()) { @@ -1682,18 +1704,7 @@ public: int y = this->vscrollList->GetScrolledRowFromWidget(pt.y, this, WID_BROS_NEWST_LIST); if (y >= (int)this->roadstop_classes.size()) return; RoadStopClassID class_id = this->roadstop_classes[y]; - if (_roadstop_gui_settings.roadstop_class != class_id && GetIfClassHasNewStopsByType(RoadStopClass::Get(class_id), roadStopType, _cur_roadtype)) { - _roadstop_gui_settings.roadstop_class = class_id; - RoadStopClass *rsclass = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class); - _roadstop_gui_settings.roadstop_count = rsclass->GetSpecCount(); - _roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, std::max(0, (int)_roadstop_gui_settings.roadstop_count - 1)); - this->SelectFirstAvailableTypeIfUnavailable(); - - NWidgetMatrix *matrix = this->GetWidget(WID_BROS_MATRIX); - matrix->SetCount(_roadstop_gui_settings.roadstop_count); - matrix->SetClicked(_roadstop_gui_settings.roadstop_type); - this->CheckSelectedSpec(); - } + this->SelectClass(class_id); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); this->SetDirty(); DeleteWindowById(WC_SELECT_STATION, 0); @@ -1731,6 +1742,18 @@ public: CheckRedrawStationCoverage(this); } + void SelectClassAndSpec(RoadStopClassID class_id, int spec_id) + { + this->SelectClass(class_id); + this->EnsureSelectedClassIsVisible(); + + if (_roadstop_gui_settings.roadstop_class != class_id) { + /* could not select class*/ + return; + } + this->OnClick({}, WID_BROS_IMAGE | (spec_id << 16), 1); + } + static HotkeyList hotkeys; }; @@ -2021,6 +2044,11 @@ struct BuildRoadWaypointWindow : PickerWindowBase { { CheckRedrawWaypointCoverage(this, true); } + + void SelectWaypointSpec(int spec_id) + { + this->OnClick({}, WID_BROW_WAYPOINT | (spec_id << 16), 1); + } }; /** Nested widget definition for the build NewGRF road waypoint window */ @@ -2247,3 +2275,64 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts) return list; } + +static BuildRoadToolbarWindow *GetRoadToolbarWindowForRoadStop(const RoadStopSpec *spec, RoadTramType rtt_preferred) +{ + extern RoadType _last_built_roadtype; + extern RoadType _last_built_tramtype; + + BuildRoadToolbarWindow *w = dynamic_cast(FindWindowById(_game_mode == GM_EDITOR ? WC_SCEN_BUILD_TOOLBAR : WC_BUILD_TOOLBAR, TRANSPORT_ROAD)); + if (w != nullptr) { + if (spec != nullptr && ((HasBit(spec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(_cur_roadtype)) || + (HasBit(spec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(_cur_roadtype)))) { + delete w; + } else { + return w; + } + } + + return dynamic_cast(CreateRoadTramToolbarForRoadType(rtt_preferred == RTT_TRAM ? _last_built_tramtype : _last_built_roadtype, rtt_preferred)); +} + +void ShowBuildRoadStopPickerAndSelect(StationType station_type, const RoadStopSpec *spec, RoadTramType rtt_preferred) +{ + if (!IsRoadStopAvailable(spec, station_type)) return; + + RoadStopClassID class_id; + if (spec != nullptr) { + if ((spec->cls_id == ROADSTOP_CLASS_WAYP) != (station_type == STATION_ROADWAYPOINT)) return; + class_id = spec->cls_id; + } else { + class_id = (station_type == STATION_ROADWAYPOINT) ? ROADSTOP_CLASS_WAYP : ROADSTOP_CLASS_DFLT; + } + + int spec_id = -1; + const RoadStopClass *rsclass = RoadStopClass::Get(class_id); + for (int i = 0; i < (int)rsclass->GetSpecCount(); i++) { + if (rsclass->GetSpec(i) == spec) { + spec_id = i; + } + } + if (spec_id < 0) return; + + BuildRoadToolbarWindow *w = GetRoadToolbarWindowForRoadStop(spec, rtt_preferred); + if (w == nullptr) return; + + auto trigger_widget = [&](int widget) { + if (!w->IsWidgetLowered(widget)) { + w->OnHotkey(widget); + } + }; + + if (station_type == STATION_ROADWAYPOINT) { + trigger_widget(WID_ROT_BUILD_WAYPOINT); + + BuildRoadWaypointWindow *waypoint_window = dynamic_cast(FindWindowById(WC_BUILD_WAYPOINT, TRANSPORT_ROAD)); + if (waypoint_window != nullptr) waypoint_window->SelectWaypointSpec(spec_id); + } else { + trigger_widget((station_type == STATION_BUS) ? WID_ROT_BUS_STATION : WID_ROT_TRUCK_STATION); + + BuildRoadStationWindow *roadstop_window = dynamic_cast(FindWindowById((station_type == STATION_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION, TRANSPORT_ROAD)); + if (roadstop_window != nullptr) roadstop_window->SelectClassAndSpec(class_id, spec_id); + } +} diff --git a/src/road_gui.h b/src/road_gui.h index 580c11e32e..ba19fb558b 100644 --- a/src/road_gui.h +++ b/src/road_gui.h @@ -17,6 +17,8 @@ struct Window *ShowBuildRoadToolbar(RoadType roadtype); struct Window *ShowBuildRoadScenToolbar(RoadType roadtype); +struct Window *CreateRoadTramToolbarForRoadType(RoadType roadtype, RoadTramType rtt); +void ShowBuildRoadStopPickerAndSelect(StationType station_type, const RoadStopSpec *spec, RoadTramType rtt_preferred); void ConnectRoadToStructure(TileIndex tile, DiagDirection direction); DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement = false, bool all_option = false); DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts); diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 8799f8d9ee..6ac6d0ea54 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -55,6 +55,10 @@ #include "screenshot_gui.h" #include "league_gui.h" #include "league_base.h" +#include "object.h" +#include "newgrf_object.h" +#include "newgrf_roadstop.h" +#include "newgrf_station.h" #include "widgets/toolbar_widget.h" @@ -84,6 +88,7 @@ enum CallBackFunction { CBF_NONE, CBF_PLACE_SIGN, CBF_PLACE_LANDINFO, + CBF_PLACE_PICKER, }; static CallBackFunction _last_started_action = CBF_NONE; ///< Last started user action. @@ -1113,7 +1118,8 @@ static CallBackFunction MenuClickNewspaper(int index) */ enum HelpMenuEntries { HME_LANDINFO = 0, - HME_CONSOLE = 2, + HME_PICKER, + HME_CONSOLE = 3, HME_SCRIPT_DEBUG, HME_SCREENSHOT, HME_FRAMERATE, @@ -1128,6 +1134,77 @@ enum HelpMenuEntries { HME_LAST_NON_DEV = HME_SPRITE_ALIGNER, }; +static void ShowBuildRailToolbarFromTile(TileIndex tile) +{ + ShowBuildRailToolbar(GetRailType(tile)); +} + +static void ShowBuildRoadToolbarFromTile(TileIndex tile) +{ + if (HasRoadTypeRoad(tile)) { + CreateRoadTramToolbarForRoadType(GetRoadTypeRoad(tile), RTT_ROAD); + } else { + CreateRoadTramToolbarForRoadType(GetRoadTypeTram(tile), RTT_TRAM); + } +} + +static void UsePickerTool(TileIndex tile) +{ + switch (GetTileType(tile)) { + case MP_RAILWAY: + ShowBuildRailToolbarFromTile(tile); + break; + + case MP_ROAD: { + ShowBuildRoadToolbarFromTile(tile); + break; + } + + case MP_STATION: { + StationType station_type = GetStationType(tile); + switch (station_type) { + case STATION_RAIL: + case STATION_WAYPOINT: + ShowBuildRailStationPickerAndSelect(station_type, GetStationSpec(tile)); + break; + + case STATION_TRUCK: + case STATION_BUS: + case STATION_ROADWAYPOINT: + ShowBuildRoadStopPickerAndSelect(station_type, GetRoadStopSpec(tile), HasRoadTypeRoad(tile) ? RTT_ROAD : RTT_TRAM); + break; + + default: + break; + } + break; + } + + case MP_TUNNELBRIDGE: + switch (GetTunnelBridgeTransportType(tile)) { + case TRANSPORT_RAIL: + ShowBuildRailToolbarFromTile(tile); + break; + + case TRANSPORT_ROAD: + ShowBuildRoadToolbarFromTile(tile); + break; + + default: + break; + } + break; + + case MP_OBJECT: { + ShowBuildObjectPickerAndSelect(ObjectSpec::GetByTile(tile)); + break; + } + + default: + break; + } +} + static CallBackFunction PlaceLandBlockInfo() { if (_last_started_action == CBF_PLACE_LANDINFO) { @@ -1139,6 +1216,18 @@ static CallBackFunction PlaceLandBlockInfo() } } +static CallBackFunction PlacePickerTool() +{ + if (_last_started_action == CBF_PLACE_PICKER) { + ResetObjectToPlace(); + return CBF_NONE; + } else { + SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0); + SetSelectionPalette(SPR_ZONING_INNER_HIGHLIGHT_GREEN); + return CBF_PLACE_PICKER; + } +} + static CallBackFunction ToolbarHelpClick(Window *w) { PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? HME_LAST : HME_LAST_NON_DEV); @@ -1204,6 +1293,7 @@ static CallBackFunction MenuClickHelp(int index) { switch (index) { case HME_LANDINFO: return PlaceLandBlockInfo(); + case HME_PICKER: return PlacePickerTool(); case HME_CONSOLE: IConsoleSwitch(); break; case HME_SCRIPT_DEBUG: ShowScriptDebugWindow(); break; case HME_SCREENSHOT: ShowScreenshotWindow(); break; @@ -2148,6 +2238,7 @@ struct MainToolbarWindow : Window { case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break; case MTHK_SIGN_LIST: ShowSignList(); break; case MTHK_LANDINFO: cbf = PlaceLandBlockInfo(); break; + case MTHK_PICKER: cbf = PlacePickerTool(); break; case MTHK_PLAN_LIST: ShowPlansWindow(); break; case MTHK_LINK_GRAPH_LEGEND: ShowLinkGraphLegend(); break; case MTHK_MESSAGE_HISTORY: ShowMessageHistory(); break; @@ -2171,6 +2262,10 @@ struct MainToolbarWindow : Window { ShowLandInfo(tile); break; + case CBF_PLACE_PICKER: + UsePickerTool(tile); + break; + default: NOT_REACHED(); } } @@ -2270,6 +2365,7 @@ static Hotkey maintoolbar_hotkeys[] = { Hotkey((uint16)0, "client_list", MTHK_CLIENT_LIST), Hotkey((uint16)0, "sign_list", MTHK_SIGN_LIST), Hotkey((uint16)0, "land_info", MTHK_LANDINFO), + Hotkey((uint16)0, "picker_tool", MTHK_PICKER), Hotkey('P', "plan_list", MTHK_PLAN_LIST), Hotkey('Y', "link_graph_legend", MTHK_LINK_GRAPH_LEGEND), Hotkey((uint16)0, "message_history", MTHK_MESSAGE_HISTORY), @@ -2558,6 +2654,10 @@ struct ScenarioEditorToolbarWindow : Window { ShowLandInfo(tile); break; + case CBF_PLACE_PICKER: + UsePickerTool(tile); + break; + default: NOT_REACHED(); } } diff --git a/src/toolbar_gui.h b/src/toolbar_gui.h index 60d81a2a45..47a8d1d4d8 100644 --- a/src/toolbar_gui.h +++ b/src/toolbar_gui.h @@ -45,6 +45,7 @@ enum MainToolbarHotkeys { MTHK_BUILD_TREES, MTHK_MUSIC, MTHK_LANDINFO, + MTHK_PICKER, MTHK_SCRIPT_DEBUG, MTHK_SMALL_SCREENSHOT, MTHK_ZOOMEDIN_SCREENSHOT, diff --git a/src/viewport.cpp b/src/viewport.cpp index c5a79f37ce..8e35d546c4 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -4633,7 +4633,12 @@ static void SetSelectionTilesDirty() void SetSelectionRed(bool b) { - _thd.square_palette = b ? PALETTE_SEL_TILE_RED : PAL_NONE; + SetSelectionPalette(b ? PALETTE_SEL_TILE_RED : PAL_NONE); +} + +void SetSelectionPalette(PaletteID pal) +{ + _thd.square_palette = pal; SetSelectionTilesDirty(); } diff --git a/src/viewport_func.h b/src/viewport_func.h index 46db27af34..82d6c59ad2 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -23,6 +23,7 @@ struct ViewportDrawerDynamic; static const int TILE_HEIGHT_STEP = 50; ///< One Z unit tile height difference is displayed as 50m. void SetSelectionRed(bool); +void SetSelectionPalette(PaletteID); void ClearViewportCache(Viewport *vp); void ClearViewportLandPixelCache(Viewport *vp);