diff --git a/README.md b/README.md index 79b566f7d..29281264b 100644 --- a/README.md +++ b/README.md @@ -69,10 +69,10 @@ been applied. Valid values for any short can be found in [KEYMAPPING.md](KEYMAPP | -----------: | -------------------------------- | | F10 | Bug fixer (exits game) | | F1-F5 | Zoom presets | -| Q | Zoom Out | -| E | Zoom In | +| Q | Zoom In | +| E | Zoom Out | | MINUS | Zoom (min) | -| EQUALS | Zoom (default) | +| = | Zoom (default) | | BACKSPACE | Zoom (max) | | C | Open/Focus Chat - Full Screen | | Alt-C | Open/Focus Chat - Side of Screen | @@ -109,9 +109,12 @@ action items such as: | Key | Shortcut | | ------: | ---------------- | -| T | Events | +| T | Away Teams | | G | Galaxy | +| Ctrl-G | Galaxy (native) | | H | System | +| Shift-E | Events | +| Ctrl-E | Events (native) | | Shift-G | Exterior View | | Shift-H | Interior View | | B | Bookmarks | @@ -125,7 +128,6 @@ action items such as: | O | Command Center | | Shift-O | Officers | | Shift-Q | Q-Trials | -| Shift-T | Away Teams | | X | ExoComp | | Z | Daily Missions | diff --git a/example_community_patch_settings_da.toml b/example_community_patch_settings_da.toml index 4e4003d2f..98c078e80 100644 --- a/example_community_patch_settings_da.toml +++ b/example_community_patch_settings_da.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Gå til begivenheder show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Gå til Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Gå til galaksen show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Gå til gaver show_gifts = "/" diff --git a/example_community_patch_settings_de.toml b/example_community_patch_settings_de.toml index 2dda59892..e185936c6 100644 --- a/example_community_patch_settings_de.toml +++ b/example_community_patch_settings_de.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Zu den Events show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Zu den Exocomps show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Zur Galaxie show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Zu den Geschenken show_gifts = "/" diff --git a/example_community_patch_settings_en-GB-x-cockney.toml b/example_community_patch_settings_en-GB-x-cockney.toml index 0ccf711ca..4969e2e40 100644 --- a/example_community_patch_settings_en-GB-x-cockney.toml +++ b/example_community_patch_settings_en-GB-x-cockney.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Go to Events show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Go to Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Go to Galaxy show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Go to Gifts show_gifts = "/" diff --git a/example_community_patch_settings_en-x-minionese.toml b/example_community_patch_settings_en-x-minionese.toml index 9f1e1e3a6..e0facf124 100644 --- a/example_community_patch_settings_en-x-minionese.toml +++ b/example_community_patch_settings_en-x-minionese.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Go to Events show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Go to Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Go to Galaxy show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Go to Gifts show_gifts = "/" diff --git a/example_community_patch_settings_en.toml b/example_community_patch_settings_en.toml index 9ffe927fe..9e31340b9 100644 --- a/example_community_patch_settings_en.toml +++ b/example_community_patch_settings_en.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Go to Events show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Go to Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Go to Galaxy show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Go to Gifts show_gifts = "/" diff --git a/example_community_patch_settings_es.toml b/example_community_patch_settings_es.toml index b89c9a2e8..5750f6711 100644 --- a/example_community_patch_settings_es.toml +++ b/example_community_patch_settings_es.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Ir a eventos show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Ir a Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Ir a la galaxia show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Ir a regalos show_gifts = "/" diff --git a/example_community_patch_settings_fr.toml b/example_community_patch_settings_fr.toml index fdbc5f79d..c415cc260 100644 --- a/example_community_patch_settings_fr.toml +++ b/example_community_patch_settings_fr.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Aller aux événements show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Aller aux Exocomps show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Aller à la galaxie show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Aller aux cadeaux show_gifts = "/" diff --git a/example_community_patch_settings_nl.toml b/example_community_patch_settings_nl.toml index b2b39b208..bf1bdde48 100644 --- a/example_community_patch_settings_nl.toml +++ b/example_community_patch_settings_nl.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Ga naar Evenementen show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Ga naar Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Ga naar Sterrenstelsel show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Ga naar Cadeaus show_gifts = "/" diff --git a/example_community_patch_settings_ru.toml b/example_community_patch_settings_ru.toml index ad3db036a..92e084d7b 100644 --- a/example_community_patch_settings_ru.toml +++ b/example_community_patch_settings_ru.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Перейти к событиям show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Перейти к экзокомпу show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Перейти к галактике show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Перейти к подаркам show_gifts = "/" diff --git a/example_community_patch_settings_tlh.toml b/example_community_patch_settings_tlh.toml index b9bce7597..3e7be9c88 100644 --- a/example_community_patch_settings_tlh.toml +++ b/example_community_patch_settings_tlh.toml @@ -455,6 +455,9 @@ show_daily = "Z" # Go Daq Events show_events = "SHIFT-E" +# Scopely shortcut-native Events Action +native_shortcut_events = "CTRL-E" + # Go Daq Exocomp show_exocomp = "X" @@ -464,6 +467,9 @@ show_factions = "F" # Go Daq Galaxy show_galaxy = "G" +# Scopely shortcut-native Galaxy Action +native_shortcut_galaxy = "CTRL-G" + # Go Daq Gifts show_gifts = "/" diff --git a/mods/src/config.cc b/mods/src/config.cc index 95deab836..654110174 100644 --- a/mods/src/config.cc +++ b/mods/src/config.cc @@ -1226,6 +1226,8 @@ void Config::Load() parse_config_shortcut(config, parsed, "show_chatside1", GameFunction::ShowChatSide1, DCSH::show_chatside1); parse_config_shortcut(config, parsed, "show_chatside2", GameFunction::ShowChatSide2, DCSH::show_chatside2); parse_config_shortcut(config, parsed, "show_galaxy", GameFunction::ShowGalaxy, DCSH::show_galaxy); + parse_config_shortcut_aliases(config, parsed, "native_shortcut_galaxy", GameFunction::NativeShortcutGalaxy, + DCSH::native_shortcut_galaxy, {"show_galaxy_native"}); parse_config_shortcut(config, parsed, "show_system", GameFunction::ShowSystem, DCSH::show_system); parse_config_shortcut(config, parsed, "zoom_preset1", GameFunction::ZoomPreset1, DCSH::zoom_preset1); parse_config_shortcut(config, parsed, "zoom_preset2", GameFunction::ZoomPreset2, DCSH::zoom_preset2); @@ -1261,6 +1263,8 @@ void Config::Load() parse_config_shortcut(config, parsed, "show_commander", GameFunction::ShowCommander, DCSH::show_commander); parse_config_shortcut(config, parsed, "show_daily", GameFunction::ShowDaily, DCSH::show_daily); parse_config_shortcut(config, parsed, "show_events", GameFunction::ShowEvents, DCSH::show_events); + parse_config_shortcut(config, parsed, "native_shortcut_events", GameFunction::NativeShortcutEvents, + DCSH::native_shortcut_events); parse_config_shortcut(config, parsed, "show_exocomp", GameFunction::ShowExoComp, DCSH::show_exocomp); parse_config_shortcut(config, parsed, "show_factions", GameFunction::ShowFactions, DCSH::show_factions); parse_config_shortcut(config, parsed, "show_inventory", GameFunction::ShowInventory, DCSH::show_inventory); diff --git a/mods/src/defaultconfig.h b/mods/src/defaultconfig.h index b22cad5b8..edd136053 100644 --- a/mods/src/defaultconfig.h +++ b/mods/src/defaultconfig.h @@ -129,6 +129,10 @@ namespace Shortcuts constexpr const char* set_zoom_preset3 = "SHIFT-F3"; constexpr const char* set_zoom_preset4 = "SHIFT-F4"; constexpr const char* set_zoom_preset5 = "SHIFT-F5"; + + constexpr const char* native_shortcut_events = "CTRL-E"; + constexpr const char* native_shortcut_galaxy = "CTRL-G"; + constexpr const char* show_alliance = "ALT-'"; constexpr const char* show_alliance_armada = "CTRL-'"; constexpr const char* show_alliance_help = "SHIFT-'"; diff --git a/mods/src/patches/gamefunctions.h b/mods/src/patches/gamefunctions.h index bd4b0fb50..3ad39fd59 100644 --- a/mods/src/patches/gamefunctions.h +++ b/mods/src/patches/gamefunctions.h @@ -40,11 +40,13 @@ enum GameFunction { ShowStationInterior, ShoWStationExterior, ShowGalaxy, + NativeShortcutGalaxy, ShowSystem, ShowChat, ShowChatSide1, ShowChatSide2, ShowEvents, + NativeShortcutEvents, ShowSettings, ZoomPreset1, ZoomPreset2, diff --git a/mods/src/patches/parts/hotkeys.cc b/mods/src/patches/parts/hotkeys.cc index f04ddafb1..e5e8a6143 100644 --- a/mods/src/patches/parts/hotkeys.cc +++ b/mods/src/patches/parts/hotkeys.cc @@ -34,6 +34,7 @@ #include "prime/ScanEngageButtonsWidget.h" #include "prime/ScreenManager.h" #include "prime/SelectableList.h" +#include "prime/ShortcutsManager.h" #include "patches/key.h" #include "patches/mapkey.h" @@ -42,6 +43,7 @@ #include +#include #include #include @@ -52,6 +54,38 @@ static bool reset_focus_next_frame = false; static int show_info_pending = 0; +static const MethodInfo* on_events_action = nullptr; +static const MethodInfo* on_galaxy_action = nullptr; + +struct InputActionCallbackContext { + void* state; + int32_t action_index; +}; + +static_assert(sizeof(InputActionCallbackContext) == 16); + +bool InvokeNativeShortcut(const MethodInfo* method, const char* action_name) +{ + auto* shortcuts_manager = ShortcutsManager::Instance(); + if (!shortcuts_manager || !method) { + spdlog::warn("[Hotkeys] native {} shortcut is unavailable", action_name); + return false; + } + + // These callbacks do not inspect CallbackContext, but runtime_invoke still requires storage for the value-type + // argument. Using the managed invoker also avoids platform-specific by-value ABI assumptions. + InputActionCallbackContext context{}; + void* args[]{&context}; + Il2CppException* exception = nullptr; + il2cpp_runtime_invoke(method, shortcuts_manager, args, &exception); + if (exception) { + spdlog::warn("[Hotkeys] native {} shortcut raised exception={}", action_name, static_cast(exception)); + return false; + } + + return true; +} + bool force_space_action_next_frame = false; void ChangeNavigationSection(SectionID sectionID); @@ -399,6 +433,9 @@ void ScreenManager_Update_Hook(auto original, ScreenManager* _this) return GotoSection(SectionID::Shop_MainFactions); } else if (MapKey::IsDown(GameFunction::ShoWStationExterior)) { return GotoSection(SectionID::Starbase_Exterior); + } else if (MapKey::IsDown(GameFunction::NativeShortcutGalaxy)) { + InvokeNativeShortcut(on_galaxy_action, "Galaxy"); + return; } else if (MapKey::IsDown(GameFunction::ShowGalaxy)) { return ChangeNavigationSection(SectionID::Navigation_Galaxy); } else if (MapKey::IsDown(GameFunction::ShowStationInterior)) { @@ -423,6 +460,9 @@ void ScreenManager_Update_Hook(auto original, ScreenManager* _this) return GotoSection(SectionID::FleetCommander_Management); } else if (MapKey::IsDown(GameFunction::ShowAwayTeam)) { return GotoSection(SectionID::Missions_AwayTeamsList); + } else if (MapKey::IsDown(GameFunction::NativeShortcutEvents)) { + InvokeNativeShortcut(on_events_action, "Events"); + return; } else if (MapKey::IsDown(GameFunction::ShowEvents)) { return GotoSection(SectionID::Tournament_Group_Selection); } else if (MapKey::IsDown(GameFunction::ShowExoComp)) { @@ -1034,6 +1074,16 @@ void InstallHotkeyHooks() if (!shortcuts_manager_helper.isValidHelper()) { ErrorMsg::MissingHelper("GameInput", "ShortcutsManager"); } else { + on_events_action = shortcuts_manager_helper.GetMethodInfo("OnEventsAction", 1); + if (on_events_action == nullptr) { + ErrorMsg::MissingMethod("ShortcutsManager", "OnEventsAction"); + } + + on_galaxy_action = shortcuts_manager_helper.GetMethodInfo("OnGalaxyAction", 1); + if (on_galaxy_action == nullptr) { + ErrorMsg::MissingMethod("ShortcutsManager", "OnGalaxyAction"); + } + auto ptr_can_user_shortcuts = shortcuts_manager_helper.GetMethod("InitializeActions"); if (ptr_can_user_shortcuts == nullptr) { ErrorMsg::MissingMethod("ShortcutsManager", "InitializeActions"); diff --git a/mods/src/patches/parts/zoom.cc b/mods/src/patches/parts/zoom.cc index c19de3af1..e4b08f588 100644 --- a/mods/src/patches/parts/zoom.cc +++ b/mods/src/patches/parts/zoom.cc @@ -145,47 +145,51 @@ void NavigationZoom_Update_Hook(auto original, NavigationZoom *_this) EnsureSystemZoomRange(_this); + const auto camera_shortcuts_enabled = config->hotkeys_enabled && !config->use_scopely_hotkeys; + if (!Key::IsInputFocused()) { - if (MapKey::IsDown(GameFunction::SetZoomPreset1)) { - return StoreZoom("System Preset 1", config->system_zoom_preset_1, _this); - } else if (MapKey::IsDown(GameFunction::SetZoomPreset2)) { - return StoreZoom("System Preset 2", config->system_zoom_preset_2, _this); - } else if (MapKey::IsDown(GameFunction::SetZoomPreset3)) { - return StoreZoom("System Preset 3", config->system_zoom_preset_3, _this); - } else if (MapKey::IsDown(GameFunction::SetZoomPreset4)) { - return StoreZoom("System Preset 4", config->system_zoom_preset_4, _this); - } else if (MapKey::IsDown(GameFunction::SetZoomPreset5)) { - return StoreZoom("System Preset 5", config->system_zoom_preset_5, _this); - } else if (MapKey::IsDown(GameFunction::SetZoomDefault)) { - return StoreZoom("System Default", config->default_system_zoom, _this); - } + if (camera_shortcuts_enabled) { + if (MapKey::IsDown(GameFunction::SetZoomPreset1)) { + return StoreZoom("System Preset 1", config->system_zoom_preset_1, _this); + } else if (MapKey::IsDown(GameFunction::SetZoomPreset2)) { + return StoreZoom("System Preset 2", config->system_zoom_preset_2, _this); + } else if (MapKey::IsDown(GameFunction::SetZoomPreset3)) { + return StoreZoom("System Preset 3", config->system_zoom_preset_3, _this); + } else if (MapKey::IsDown(GameFunction::SetZoomPreset4)) { + return StoreZoom("System Preset 4", config->system_zoom_preset_4, _this); + } else if (MapKey::IsDown(GameFunction::SetZoomPreset5)) { + return StoreZoom("System Preset 5", config->system_zoom_preset_5, _this); + } else if (MapKey::IsDown(GameFunction::SetZoomDefault)) { + return StoreZoom("System Default", config->default_system_zoom, _this); + } - do_absolute_zoom = true; - if (MapKey::IsDown(GameFunction::ZoomPreset1)) { - zoomDelta = config->system_zoom_preset_1; - do_store_zoom = true; - } else if (MapKey::IsDown(GameFunction::ZoomPreset2)) { - zoomDelta = config->system_zoom_preset_2; - do_store_zoom = true; - } else if (MapKey::IsDown(GameFunction::ZoomPreset3)) { - zoomDelta = config->system_zoom_preset_3; - do_store_zoom = true; - } else if (MapKey::IsDown(GameFunction::ZoomPreset4)) { - zoomDelta = config->system_zoom_preset_4; - do_store_zoom = true; - } else if (MapKey::IsDown(GameFunction::ZoomPreset5)) { - zoomDelta = config->system_zoom_preset_5; - do_store_zoom = true; - } + do_absolute_zoom = true; + if (MapKey::IsDown(GameFunction::ZoomPreset1)) { + zoomDelta = config->system_zoom_preset_1; + do_store_zoom = true; + } else if (MapKey::IsDown(GameFunction::ZoomPreset2)) { + zoomDelta = config->system_zoom_preset_2; + do_store_zoom = true; + } else if (MapKey::IsDown(GameFunction::ZoomPreset3)) { + zoomDelta = config->system_zoom_preset_3; + do_store_zoom = true; + } else if (MapKey::IsDown(GameFunction::ZoomPreset4)) { + zoomDelta = config->system_zoom_preset_4; + do_store_zoom = true; + } else if (MapKey::IsDown(GameFunction::ZoomPreset5)) { + zoomDelta = config->system_zoom_preset_5; + do_store_zoom = true; + } - if (config->hotkeys_extended) { - if (MapKey::IsDown(GameFunction::ZoomReset)) { - do_absolute_zoom = false; - do_default_zoom = true; - } else if (MapKey::IsDown(GameFunction::ZoomMin)) { - zoomDelta = config->zoom; - } else if (MapKey::IsDown(GameFunction::ZoomMax)) { - zoomDelta = 100; + if (config->hotkeys_extended) { + if (MapKey::IsDown(GameFunction::ZoomReset)) { + do_absolute_zoom = false; + do_default_zoom = true; + } else if (MapKey::IsDown(GameFunction::ZoomMin)) { + zoomDelta = config->zoom; + } else if (MapKey::IsDown(GameFunction::ZoomMax)) { + zoomDelta = 100; + } } } @@ -199,7 +203,7 @@ void NavigationZoom_Update_Hook(auto original, NavigationZoom *_this) zoomDelta = config->keyboard_zoom_speed * dt; } - if (MapKey::IsPressed(GameFunction::ZoomIn) || do_absolute_zoom) { + if ((camera_shortcuts_enabled && MapKey::IsPressed(GameFunction::ZoomIn)) || do_absolute_zoom) { vec3 mousePos; GetMousePosition(&mousePos); _this->_zoomLocation = vec2{.x = mousePos.x, .y = mousePos.y}; @@ -213,7 +217,7 @@ void NavigationZoom_Update_Hook(auto original, NavigationZoom *_this) auto worldPos = GetMouseWorldPos(_this->_sceneCamera, &mousePos); _this->_worldPoint = worldPos; _this->ZoomCameraAtWorldPoint(); - } else if (MapKey::IsPressed(GameFunction::ZoomOut) && !Key::IsInputFocused()) { + } else if (camera_shortcuts_enabled && MapKey::IsPressed(GameFunction::ZoomOut)) { vec3 mousePos; GetMousePosition(&mousePos); _this->_zoomLocation = vec2{.x = mousePos.x, .y = mousePos.y}; diff --git a/mods/src/prime/ShortcutsManager.h b/mods/src/prime/ShortcutsManager.h new file mode 100644 index 000000000..5529506f2 --- /dev/null +++ b/mods/src/prime/ShortcutsManager.h @@ -0,0 +1,14 @@ +#pragma once + +#include "MonoSingleton.h" + +struct ShortcutsManager : MonoSingleton { + friend struct MonoSingleton; + +private: + static IL2CppClassHelper& get_class_helper() + { + static auto class_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.GameInput", "ShortcutsManager"); + return class_helper; + } +};