diff --git a/.gitignore b/.gitignore index aff6ba6..fe2831d 100644 --- a/.gitignore +++ b/.gitignore @@ -262,3 +262,7 @@ __pycache__/ dependencies/MenuAPI\.net\.dll postbuild\.cmd + +postbuild-fivem.cmd + +postbuild-redm.cmd diff --git a/MenuAPI/Menu.cs b/MenuAPI/Menu.cs index 5d03a57..c7b9b4b 100644 --- a/MenuAPI/Menu.cs +++ b/MenuAPI/Menu.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using CitizenFX.Core; using static CitizenFX.Core.Native.API; +using static CitizenFX.Core.Native.Function; +using static CitizenFX.Core.Native.Hash; namespace MenuAPI { @@ -72,6 +73,7 @@ public class Menu /// The new of this item. public delegate void IndexChangedEvent(Menu menu, MenuItem oldItem, MenuItem newItem, int oldIndex, int newIndex); +#if FIVEM /// /// Triggered when the changes. /// @@ -90,6 +92,7 @@ public class Menu /// The current position of the slider bar. /// The index of this . public delegate void SliderItemSelectedEvent(Menu menu, MenuSliderItem sliderItem, int sliderPosition, int itemIndex); +#endif /// /// Triggered when a 's value was changed. @@ -151,7 +154,7 @@ public class Menu /// Parameters: menu, oldSelectedItem, newSelectedItem, oldIndex, newIndex. /// public event IndexChangedEvent OnIndexChange; - +#if FIVEM /// /// Triggered when the changes. /// Parameters: menu, sliderItem, oldPosition, newPosition, itemIndex @@ -163,6 +166,7 @@ public class Menu /// Parameters: menu, sliderItem, sliderPosition, itemIndex. /// public event SliderItemSelectedEvent OnSliderItemSelect; +#endif /// /// Triggered when a 's value was changed. @@ -257,6 +261,7 @@ protected virtual void IndexChangeEvent(Menu menu, MenuItem oldItem, MenuItem ne OnIndexChange?.Invoke(menu, oldItem, newItem, oldIndex, newIndex); } +#if FIVEM /// /// Triggered when the changes. /// @@ -281,6 +286,7 @@ protected virtual void SliderSelectedEvent(Menu menu, MenuSliderItem sliderItem, { OnSliderItemSelect?.Invoke(menu, sliderItem, sliderPosition, itemIndex); } +#endif /// /// Triggered when a 's value was changed. @@ -304,18 +310,24 @@ protected virtual void DynamicListItemSelectEvent(Menu menu, MenuDynamicListItem { OnDynamicListItemSelect?.Invoke(menu, dynamicListItem, currentItem); } - #endregion #endregion #region constants or readonlys +#if FIVEM public const float Width = 500f; +#endif +#if REDM + public const float Width = 300F; +#endif #endregion #region private variables - private static SizeF headerSize = new SizeF(Width, 110f); + private static KeyValuePair headerSize = new KeyValuePair(Width, 110f); + private int index = 0; + public int ViewIndexOffset { get; private set; } = 0; private List VisibleMenuItems @@ -340,8 +352,10 @@ private List VisibleMenuItems private List FilterItems { get; set; } = new List(); private List MenuItems { get; set; } = new List(); +#if FIVEM private readonly int ColorPanelScaleform = RequestScaleformMovie("COLOUR_SWITCHER_02"); // Could probably be improved, but was getting some glitchy results if it wasn't pre-loaded. private readonly int OpacityPanelScaleform = RequestScaleformMovie("COLOUR_SWITCHER_01"); // Could probably be improved, but was getting some glitchy results if it wasn't pre-loaded. +#endif #endregion #region Public Variables @@ -359,9 +373,13 @@ private List VisibleMenuItems public bool Visible { get; set; } = false; +#if FIVEM public bool LeftAligned => MenuController.MenuAlignment == MenuController.MenuAlignmentOption.Left; - - public PointF Position { get; private set; } = new PointF(0f, 0f); + public KeyValuePair Position { get; private set; } = new KeyValuePair(0f, 0f); +#endif +#if REDM + public KeyValuePair Position { get; private set; } = new KeyValuePair(0f, 20f); +#endif public float MenuItemsYOffset { get; private set; } = 0f; @@ -379,6 +397,7 @@ private List VisibleMenuItems private bool filterActive = false; +#if FIVEM public Dictionary InstructionalButtons = new Dictionary() { { Control.FrontendAccept, GetLabelText("HUD_INPUT28") }, { Control.FrontendCancel, GetLabelText("HUD_INPUT53") } }; public List CustomInstructionalButtons = new List(); @@ -394,6 +413,7 @@ public InstructionalButton(string controlString, string instructionText) this.instructionText = instructionText; } } +#endif public enum ControlPressCheckType { @@ -442,8 +462,10 @@ public Menu(string name, string subtitle) { MenuTitle = name; MenuSubtitle = subtitle; +#if FIVEM this.SetWeaponStats(0f, 0f, 0f, 0f); this.SetWeaponComponentStats(0f, 0f, 0f, 0f); +#endif } #endregion @@ -624,19 +646,28 @@ public void SelectItem(MenuItem item) { ListItemSelectEvent(this, listItem, listItem.ListIndex, listItem.Index); } + else if (item is MenuDynamicListItem dynamicListItem) + { + DynamicListItemSelectEvent(this, dynamicListItem, dynamicListItem.CurrentItem); + } +#if FIVEM else if (item is MenuSliderItem slider) { SliderSelectedEvent(this, slider, slider.Position, slider.Index); } - else if (item is MenuDynamicListItem dynamicListItem) + else { - DynamicListItemSelectEvent(this, dynamicListItem, dynamicListItem.CurrentItem); + ItemSelectedEvent(item, item.Index); } + PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM else { ItemSelectedEvent(item, item.Index); + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "SELECT", "HUD_SHOP_SOUNDSET", 1); } - PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif if (MenuController.MenuButtons.ContainsKey(item)) { // this updates the parent menu. @@ -647,7 +678,14 @@ public void SelectItem(MenuItem item) } } else if (item != null && !item.Enabled) + { +#if FIVEM PlaySoundFrontend(-1, "ERROR", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_ERROR", "HUD_SHOP_SOUNDSET", 1); +#endif + } } /// @@ -655,7 +693,13 @@ public void SelectItem(MenuItem item) /// public void GoBack() { +#if FIVEM PlaySoundFrontend(-1, "BACK", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "Back", "HUD_SHOP_SOUNDSET", 1); +#endif CloseMenu(); if (ParentMenu != null) { @@ -720,7 +764,12 @@ public void GoUp() } IndexChangeEvent(this, oldItem, currItem, oldItem.Index, CurrentIndex); +#if FIVEM PlaySoundFrontend(-1, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_UP", "HUD_SHOP_SOUNDSET", 1); +#endif } } @@ -761,7 +810,12 @@ public void GoDown() } } IndexChangeEvent(this, oldItem, currItem, oldItem.Index, CurrentIndex); +#if FIVEM PlaySoundFrontend(-1, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_DOWN", "HUD_SHOP_SOUNDSET", 1); +#endif } } @@ -788,10 +842,17 @@ public void GoLeft() newIndex--; } listItem.ListIndex = newIndex; + ListItemIndexChangeEvent(this, listItem, oldIndex, newIndex, listItem.Index); +#if FIVEM PlaySoundFrontend(-1, "NAV_LEFT_RIGHT", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_LEFT", "HUD_SHOP_SOUNDSET", 1); +#endif } } +#if FIVEM else if (item.Enabled && item is MenuSliderItem slider) { if (slider.Position > slider.Min) @@ -805,19 +866,27 @@ public void GoLeft() PlaySoundFrontend(-1, "ERROR", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); } } +#endif else if (item.Enabled && item is MenuDynamicListItem dynList) { string oldValue = dynList.CurrentItem; string newSelectedItem = dynList.Callback(dynList, true); dynList.CurrentItem = newSelectedItem; DynamicListItemCurrentItemChanged(this, dynList, oldValue, newSelectedItem); +#if FIVEM PlaySoundFrontend(-1, "NAV_LEFT_RIGHT", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_RIGHT", "HUD_SHOP_SOUNDSET", 1); +#endif } +#if FIVEM // If it's a checkbox, just trigger the box instead. else if (item.Enabled && item is MenuCheckboxItem checkbox) { SelectItem(checkbox); } +#endif // If the item is enabled and it's not any of the above, just select it. else if (item.Enabled) { @@ -850,9 +919,15 @@ public void GoRight() } listItem.ListIndex = newIndex; ListItemIndexChangeEvent(this, listItem, oldIndex, newIndex, listItem.Index); +#if FIVEM PlaySoundFrontend(-1, "NAV_LEFT_RIGHT", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_RIGHT", "HUD_SHOP_SOUNDSET", 1); +#endif } } +#if FIVEM else if (item.Enabled && item is MenuSliderItem slider) { if (slider.Position < slider.Max) @@ -866,19 +941,27 @@ public void GoRight() PlaySoundFrontend(-1, "ERROR", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); } } +#endif else if (item.Enabled && item is MenuDynamicListItem dynList) { string oldValue = dynList.CurrentItem; string newSelectedItem = dynList.Callback(dynList, false); dynList.CurrentItem = newSelectedItem; DynamicListItemCurrentItemChanged(this, dynList, oldValue, newSelectedItem); +#if FIVEM PlaySoundFrontend(-1, "NAV_LEFT_RIGHT", "HUD_FRONTEND_DEFAULT_SOUNDSET", false); +#endif +#if REDM + Call((CitizenFX.Core.Native.Hash)0xCE5D0FFE83939AF1, -1, "NAV_RIGHT", "HUD_SHOP_SOUNDSET", 1); +#endif } +#if FIVEM // If it's a checkbox, just trigger the box instead. else if (item.Enabled && item is MenuCheckboxItem checkbox) { SelectItem(checkbox); } +#endif // If the item is enabled and it's not any of the above, just select it. else if (item.Enabled) { @@ -919,7 +1002,7 @@ public void ResetFilter() filterActive = false; FilterItems.Clear(); } - +#if FIVEM public void SetWeaponStats(float damage, float fireRate, float accuracy, float range) { WeaponStats = new float[4] @@ -941,6 +1024,7 @@ public void SetWeaponComponentStats(float damage, float fireRate, float accuracy MathUtil.Clamp(WeaponStats[3] + range, 0f, 1f) }; } +#endif #endregion @@ -951,7 +1035,14 @@ public void SetWeaponComponentStats(float damage, float fireRate, float accuracy /// internal async void Draw() { +#if FIVEM if (!Game.IsPaused && IsScreenFadedIn() && !IsPlayerSwitchInProgress() && !Game.PlayerPed.IsDead) +#endif +#if REDM + if (!Call(IS_PAUSE_MENU_ACTIVE) && + Call(IS_SCREEN_FADED_IN) && + !Call(IS_ENTITY_DEAD, PlayerPedId())) +#endif { #region Listen for custom key presses. if (ButtonPressHandlers.Count > 0) @@ -962,11 +1053,17 @@ internal async void Draw() { if (handler.disableControl) { +#if FIVEM Game.DisableControlThisFrame(0, handler.control); +#endif +#if REDM + Call(DISABLE_CONTROL_ACTION, 0, handler.control, true); +#endif } switch (handler.pressType) { +#if FIVEM case ControlPressCheckType.JUST_PRESSED: if (Game.IsControlJustPressed(0, handler.control) || Game.IsDisabledControlJustPressed(0, handler.control)) handler.function.Invoke(this, handler.control); @@ -983,6 +1080,25 @@ internal async void Draw() if (!Game.IsControlPressed(0, handler.control) && !Game.IsDisabledControlPressed(0, handler.control)) handler.function.Invoke(this, handler.control); break; +#endif +#if REDM + case ControlPressCheckType.JUST_PRESSED: + if (Call(IS_CONTROL_JUST_PRESSED, 0, handler.control) || Call(IS_DISABLED_CONTROL_JUST_PRESSED, 0, handler.control)) + handler.function.Invoke(this, handler.control); + break; + case ControlPressCheckType.JUST_RELEASED: + if (Call(IS_CONTROL_JUST_RELEASED, 0, handler.control) || Call(IS_DISABLED_CONTROL_JUST_RELEASED, 0, handler.control)) + handler.function.Invoke(this, handler.control); + break; + case ControlPressCheckType.PRESSED: + if (Call(IS_CONTROL_PRESSED, 0, handler.control) || Call(IS_DISABLED_CONTROL_PRESSED, 0, handler.control)) + handler.function.Invoke(this, handler.control); + break; + case ControlPressCheckType.RELEASED: + if (!Call(IS_CONTROL_PRESSED, 0, handler.control) && !Call(IS_DISABLED_CONTROL_PRESSED, 0, handler.control)) + handler.function.Invoke(this, handler.control); + break; +#endif default: break; } @@ -997,13 +1113,14 @@ internal async void Draw() if (!string.IsNullOrEmpty(MenuTitle)) { #region Draw Header Background +#if FIVEM SetScriptGfxAlign(LeftAligned ? 76 : 82, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); - float x = (Position.X + (headerSize.Width / 2f)) / MenuController.ScreenWidth; - float y = (Position.Y + (headerSize.Height / 2f)) / MenuController.ScreenHeight; - float width = headerSize.Width / MenuController.ScreenWidth; - float height = headerSize.Height / MenuController.ScreenHeight; + float x = (Position.Key + (headerSize.Key / 2f)) / MenuController.ScreenWidth; + float y = (Position.Value + (headerSize.Value/ 2f)) / MenuController.ScreenHeight; + float width = headerSize.Key / MenuController.ScreenWidth; + float height = headerSize.Value / MenuController.ScreenHeight; if (!string.IsNullOrEmpty(HeaderTexture.Key) && !string.IsNullOrEmpty(HeaderTexture.Value)) { @@ -1024,12 +1141,22 @@ internal async void Draw() ResetScriptGfxAlign(); +#endif +#if REDM + SetScriptGfxDrawOrder(2); + float x = (Position.Key + (headerSize.Key / 2f)) / MenuController.ScreenWidth; + float y = (Position.Value + (headerSize.Value / 2f)) / MenuController.ScreenHeight; + float width = headerSize.Key / MenuController.ScreenWidth; + float height = headerSize.Value / MenuController.ScreenHeight; + Call(DRAW_SPRITE, MenuController._texture_dict, MenuController._header_texture, x, y, width, height, 0f, 181, 17, 18, 255); + SetScriptGfxDrawOrder(1); +#endif #endregion #region Draw Header Menu Title +#if FIVEM int font = 1; float size = (45f * 27f) / MenuController.ScreenHeight; - SetScriptGfxAlign(76, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); @@ -1041,38 +1168,70 @@ internal async void Draw() AddTextComponentSubstringPlayerName(MenuTitle); if (LeftAligned) { - EndTextCommandDisplayText(((headerSize.Width / 2f) / MenuController.ScreenWidth), y - (GetTextScaleHeight(size, font) / 2f)); + EndTextCommandDisplayText(((headerSize.Key / 2f) / MenuController.ScreenWidth), y - (GetTextScaleHeight(size, font) / 2f)); } else { - EndTextCommandDisplayText(GetSafeZoneSize() - ((headerSize.Width / 2f) / MenuController.ScreenWidth), y - (GetTextScaleHeight(size, font) / 2f)); + EndTextCommandDisplayText(GetSafeZoneSize() - ((headerSize.Key / 2f) / MenuController.ScreenWidth), y - (GetTextScaleHeight(size, font) / 2f)); } ResetScriptGfxAlign(); - MenuItemsYOffset = headerSize.Height; + MenuItemsYOffset = headerSize.Value; +#endif + +#if REDM + Call(SET_TEXT_CENTRE, true); + float size = (45f * 27f) / MenuController.ScreenHeight; + Call(SET_TEXT_SCALE, size, size); + + SetScriptGfxDrawOrder(3); + //SetTextWrap(textMinX, textMaxX); + int font = 10; + Call((CitizenFX.Core.Native.Hash)0xADA9255D, font); + Call(_DRAW_TEXT, Call(_CREATE_VAR_STRING, 10, "LITERAL_STRING", MenuTitle ?? "N/A"), ((headerSize.Key / 2f) / MenuController.ScreenWidth), y - (45f / MenuController.ScreenHeight)); + SetScriptGfxDrawOrder(1); + MenuItemsYOffset = headerSize.Value; +#endif #endregion } + else + { +#if REDM + MenuItemsYOffset = 40f; +#endif + } #endregion #region Draw Subtitle { +#if FIVEM #region draw subtitle background SetScriptGfxAlign(LeftAligned ? 76 : 82, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); float bgHeight = 38f; - - float x = (Position.X + (headerSize.Width / 2f)) / MenuController.ScreenWidth; - float y = ((Position.Y + MenuItemsYOffset + (bgHeight / 2f)) / MenuController.ScreenHeight); - float width = headerSize.Width / MenuController.ScreenWidth; + float x = (Position.Key + (headerSize.Key / 2f)) / MenuController.ScreenWidth; + float y = ((Position.Value + MenuItemsYOffset + (bgHeight / 2f)) / MenuController.ScreenHeight); + float width = headerSize.Key / MenuController.ScreenWidth; float height = bgHeight / MenuController.ScreenHeight; DrawRect(x, y, width, height, 0, 0, 0, 250); ResetScriptGfxAlign(); #endregion +#endif + +#if REDM + float bgHeight = 38f; + float x = (Position.Key + (headerSize.Key / 2f)) / MenuController.ScreenWidth; + float y = ((Position.Value + MenuItemsYOffset + (bgHeight / 2f)) / MenuController.ScreenHeight); + float width = headerSize.Key / MenuController.ScreenWidth; + float height = bgHeight / MenuController.ScreenHeight; +#endif + +#if FIVEM #region draw subtitle text if (!string.IsNullOrEmpty(MenuSubtitle)) { @@ -1103,14 +1262,29 @@ internal async void Draw() } else { - EndTextCommandDisplayText(GetSafeZoneSize() - ((headerSize.Width - 10f) / MenuController.ScreenWidth), y - (GetTextScaleHeight(size, font) / 2f + (4f / MenuController.ScreenHeight))); + EndTextCommandDisplayText(GetSafeZoneSize() - ((headerSize.Key - 10f) / MenuController.ScreenWidth), y - (GetTextScaleHeight(size, font) / 2f + (4f / MenuController.ScreenHeight))); } - ResetScriptGfxAlign(); } #endregion +#endif + +#if REDM + if (!string.IsNullOrEmpty(MenuSubtitle)) + { + SetScriptGfxDrawOrder(3); + float size = (14f * 27f) / MenuController.ScreenHeight; + Call(SET_TEXT_SCALE, size, size); + Call(SET_TEXT_CENTRE, true); + int font = 9; + Call((CitizenFX.Core.Native.Hash)0xADA9255D, font); + Call(_DRAW_TEXT, Call(_CREATE_VAR_STRING, 10, "LITERAL_STRING", MenuSubtitle ?? "N/A"), x, y - (52f / MenuController.ScreenHeight)); + SetScriptGfxDrawOrder(1); + } +#endif #region draw counter + pre-counter text +#if FIVEM string counterText = $"{CounterPreText ?? ""}{CurrentIndex + 1} / {Size}"; if (!string.IsNullOrEmpty(CounterPreText) || MaxItemsOnScreen < Size) { @@ -1150,6 +1324,24 @@ internal async void Draw() { MenuItemsYOffset += bgHeight - 1f; } +#endif +#if REDM + if (Size > 0) + { + float textSize = (12f * 27f) / MenuController.ScreenHeight; + Call(SET_TEXT_SCALE, textSize, textSize); + Call((CitizenFX.Core.Native.Hash)0x50A41AD966910F03, 135, 135, 135, 255); // _SET_TEXT_COLOUR / 0x50A41AD966910F03 + Call(SET_TEXT_CENTRE, true); + float textMinX = (headerSize.Key / 2f) / MenuController.ScreenWidth; + float textMaxX = (Width - 10f) / MenuController.ScreenWidth; + float textY = (MenuItemsYOffset + 38f * (MathUtil.Clamp(Size, 0, MaxItemsOnScreen) + 1) - 11f) / MenuController.ScreenHeight; + int font = 23; + Call((CitizenFX.Core.Native.Hash)0xADA9255D, font); + //SetTextWrap(textMinX, textMaxX); + + Call(_DRAW_TEXT, Call(_CREATE_VAR_STRING, 10, "LITERAL_STRING", $"{CurrentIndex + 1} of {Size}"), textMinX, textY); + } +#endif #endregion } @@ -1158,21 +1350,55 @@ internal async void Draw() #region Draw menu items background gradient if (Size > 0) { +#if FIVEM SetScriptGfxAlign(LeftAligned ? 76 : 82, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); +#endif + //DrawSprite(MenuController._texture_dict, "gradient_bgd", x, y, width, height, 0f, 255, 255, 255, 255); +#if FIVEM float bgHeight = 38f * MathUtil.Clamp(Size, 0, MaxItemsOnScreen); - - float x = (Position.X + (headerSize.Width / 2f)) / MenuController.ScreenWidth; - float y = ((Position.Y + MenuItemsYOffset + ((bgHeight + 1f) / 2f)) / MenuController.ScreenHeight); - float width = headerSize.Width / MenuController.ScreenWidth; + float x = (Position.Key + (headerSize.Key / 2f)) / MenuController.ScreenWidth; + float y = ((Position.Value + MenuItemsYOffset + ((bgHeight + 1f) / 2f)) / MenuController.ScreenHeight); + float width = headerSize.Key / MenuController.ScreenWidth; float height = (bgHeight + 1f) / MenuController.ScreenHeight; - //DrawSprite(MenuController._texture_dict, "gradient_bgd", x, y, width, height, 0f, 255, 255, 255, 255); - DrawRect(x, y, width, height, 0, 0, 0, 180); ResetScriptGfxAlign(); + DrawRect(x, y, width, height, 0, 0, 0, 180); MenuItemsYOffset += bgHeight - 1f; +#endif +#if REDM + //float x = (Position.Key + ((headerSize.Key) / 2f)) / MenuController.ScreenWidth; + //float y = ((Position.Value + MenuItemsYOffset + ((bgHeight + 1f) / 2f) /) / MenuController.ScreenHeight); + //float width = (headerSize.Key + 16f) / MenuController.ScreenWidth; + //float height = (bgHeight + 17f) / MenuController.ScreenHeight; + float bgHeight = 38f * MathUtil.Clamp(Size, 0, MaxItemsOnScreen); + var currentMenuItem = GetCurrentMenuItem(); + float descriptionBoxHeight = 0f; + if (currentMenuItem != null && !string.IsNullOrEmpty(currentMenuItem.Description)) + { + int count = (currentMenuItem.Description.Count((a => { return a == '\n'; })) - 1); + if (count < 1) + { + descriptionBoxHeight = 42f; + } + else + { + descriptionBoxHeight = (38f * count) + 30f; + } + + bgHeight += descriptionBoxHeight; + } + float actualBgYLocation = ((38f + (38f / 2f) + (bgHeight / 2f)) / MenuController.ScreenHeight); + float x = (Position.Key + (headerSize.Key / 2f)) / MenuController.ScreenWidth; + float y = ((Position.Value + MenuItemsYOffset + ((bgHeight + 1f - (headerSize.Value)) / 2f) + 19f) / MenuController.ScreenHeight); + float width = headerSize.Key / MenuController.ScreenWidth; + float height = (headerSize.Value + bgHeight + 33f + 38f) / MenuController.ScreenHeight; + Call(DRAW_SPRITE, MenuController._texture_dict, MenuController._header_texture, x, y, width, height, 0f, 0, 0, 0, 240); + Call(DRAW_SPRITE, MenuController._texture_dict, MenuController._header_texture, x, y + actualBgYLocation - (descriptionBoxHeight / MenuController.ScreenHeight), width, 38f / MenuController.ScreenHeight, 0f, 55, 55, 55, 255); + MenuItemsYOffset += bgHeight - descriptionBoxHeight - 1f; +#endif } #endregion @@ -1185,17 +1411,18 @@ internal async void Draw() } } #endregion + float descriptionYOffset = 0f; +#if FIVEM #region Up Down overflow Indicator - float descriptionYOffset = 0f; if (Size > 0) { if (Size > MaxItemsOnScreen) { - #region background + #region background float width = Width / MenuController.ScreenWidth; float height = 60f / MenuController.ScreenWidth; - float x = (Position.X + (Width / 2f)) / MenuController.ScreenWidth; + float x = (Position.Key + (Width / 2f)) / MenuController.ScreenWidth; float y = MenuItemsYOffset / MenuController.ScreenHeight + (height / 2f) + (6f / MenuController.ScreenHeight); SetScriptGfxAlign(LeftAligned ? 76 : 82, 84); @@ -1204,9 +1431,9 @@ internal async void Draw() DrawRect(x, y, width, height, 0, 0, 0, 180); descriptionYOffset = height; ResetScriptGfxAlign(); - #endregion + #endregion - #region up/down icons + #region up/down icons SetScriptGfxAlign(76, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); float xMin = 0f; @@ -1253,12 +1480,12 @@ internal async void Draw() } ResetScriptGfxAlign(); - #endregion + #endregion } } #endregion - +#endif #region Draw Description if (Size > 0) { @@ -1269,10 +1496,10 @@ internal async void Draw() int font = 0; float textSize = (14f * 27f) / MenuController.ScreenHeight; +#if FIVEM float textMinX = 0f + (10f / MenuController.ScreenWidth); float textMaxX = Width / MenuController.ScreenWidth - (10f / MenuController.ScreenWidth); float textY = MenuItemsYOffset / MenuController.ScreenHeight + (16f / MenuController.ScreenHeight) + descriptionYOffset; - SetScriptGfxAlign(76, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); @@ -1325,13 +1552,28 @@ internal async void Draw() } ResetScriptGfxAlign(); +#endif +#if REDM + + Call(SET_TEXT_SCALE, textSize, textSize); + Call(SET_TEXT_CENTRE, true); + float textMinX = (headerSize.Key / 2f) / MenuController.ScreenWidth; + float textMaxX = (Width - 10f) / MenuController.ScreenWidth; + float textY = MenuItemsYOffset / MenuController.ScreenHeight + (18f / MenuController.ScreenHeight) + (48f / MenuController.ScreenHeight); + font = 23; + Call((CitizenFX.Core.Native.Hash)0xADA9255D, font); + Call(_DRAW_TEXT, Call(_CREATE_VAR_STRING, 10, "LITERAL_STRING", $"{currentMenuItem.Description}"), textMinX, textY); + +#endif #endregion + +#if FIVEM #region background float descWidth = Width / MenuController.ScreenWidth; float descHeight = (textHeight + 0.005f) * lineCount + (8f / MenuController.ScreenHeight) + (2.5f / MenuController.ScreenHeight); - float descX = (Position.X + (Width / 2f)) / MenuController.ScreenWidth; + float descX = (Position.Key + (Width / 2f)) / MenuController.ScreenWidth; float descY = textY - (6f / MenuController.ScreenHeight) + (descHeight / 2f); SetScriptGfxAlign(LeftAligned ? 76 : 82, 84); @@ -1344,6 +1586,7 @@ internal async void Draw() #endregion descriptionYOffset += descY + (descHeight / 2f) - (4f / MenuController.ScreenHeight); +#endif } else { @@ -1351,9 +1594,9 @@ internal async void Draw() } } - #endregion +#if FIVEM #region Draw Weapon Stats { if (Size > 0) @@ -1388,12 +1631,12 @@ internal async void Draw() } - #region background + #region background SetScriptGfxAlign(LeftAligned ? 76 : 82, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); DrawRect(x, y, width, height, 0, 0, 0, 180); ResetScriptGfxAlign(); - #endregion + #endregion float bgStatBarWidth = (Width / 2f) / MenuController.ScreenWidth; float bgStatBarX = x + (bgStatBarWidth / 2f) - (10f / MenuController.ScreenWidth); @@ -1408,7 +1651,7 @@ internal async void Draw() float bgStatBarHeight = 10f / MenuController.ScreenHeight; float barX; float componentBarX; - #region damage bar + #region damage bar barWidth = bgStatBarWidth * WeaponStats[0]; componentBarWidth = bgStatBarWidth * WeaponComponentStats[0]; if (LeftAligned) @@ -1430,9 +1673,9 @@ internal async void Draw() // real bar DrawRect(barX, barY, barWidth, bgStatBarHeight, 255, 255, 255, 255); ResetScriptGfxAlign(); - #endregion + #endregion - #region fire rate bar + #region fire rate bar barWidth = bgStatBarWidth * WeaponStats[1]; componentBarWidth = bgStatBarWidth * WeaponComponentStats[1]; barY += 30f / MenuController.ScreenHeight; @@ -1455,9 +1698,9 @@ internal async void Draw() // real bar DrawRect(barX, barY, barWidth, bgStatBarHeight, 255, 255, 255, 255); ResetScriptGfxAlign(); - #endregion + #endregion - #region accuracy bar + #region accuracy bar barWidth = bgStatBarWidth * WeaponStats[2]; componentBarWidth = bgStatBarWidth * WeaponComponentStats[2]; barY += 30f / MenuController.ScreenHeight; @@ -1480,9 +1723,9 @@ internal async void Draw() // real bar DrawRect(barX, barY, barWidth, bgStatBarHeight, 255, 255, 255, 255); ResetScriptGfxAlign(); - #endregion + #endregion - #region range bar + #region range bar barWidth = bgStatBarWidth * WeaponStats[3]; componentBarWidth = bgStatBarWidth * WeaponComponentStats[3]; barY += 30f / MenuController.ScreenHeight; @@ -1505,9 +1748,9 @@ internal async void Draw() // real bar DrawRect(barX, barY, barWidth, bgStatBarHeight, 255, 255, 255, 255); ResetScriptGfxAlign(); - #endregion + #endregion - #region weapon stats text + #region weapon stats text float textX = LeftAligned ? x - (width / 2f) + (10f / MenuController.ScreenWidth) : GetSafeZoneSize() - ((Width - 10f) / MenuController.ScreenWidth); float textY = y - (height / 2f) + (10f / MenuController.ScreenHeight); @@ -1546,7 +1789,7 @@ internal async void Draw() textY += 30f / MenuController.ScreenHeight; EndTextCommandDisplayText(textX, textY); ResetScriptGfxAlign(); - #endregion + #endregion } } @@ -1654,8 +1897,10 @@ internal async void Draw() } #endregion +#endif SetScriptGfxDrawOrder(0); } + await Task.FromResult(0); } #endregion } diff --git a/MenuAPI/MenuAPI.csproj b/MenuAPI/MenuAPI.csproj index 386ff2e..f08976e 100644 --- a/MenuAPI/MenuAPI.csproj +++ b/MenuAPI/MenuAPI.csproj @@ -3,28 +3,33 @@ net452 embedded - $(AssemblyName).net + $(AssemblyName) Release RedM;Release FiveM;Debug RedM;Debug FiveM - + FIVEM - + REDM + + + + - + + runtime + - ..\..\..\..\citizen\clr2\lib\mono\4.5\citizenfx.core.dll + ..\dependencies\RedM\CitizenFX.Core.dll + false diff --git a/MenuAPI/MenuController.cs b/MenuAPI/MenuController.cs index eecf093..e7ab6d7 100644 --- a/MenuAPI/MenuController.cs +++ b/MenuAPI/MenuController.cs @@ -5,16 +5,25 @@ using System.Threading.Tasks; using CitizenFX.Core; using static CitizenFX.Core.Native.API; +using static CitizenFX.Core.Native.Function; +using static CitizenFX.Core.Native.Hash; namespace MenuAPI { public class MenuController : BaseScript { public static List Menus { get; protected set; } = new List(); +#if FIVEM public const string _texture_dict = "commonmenu"; public const string _header_texture = "interaction_bgd"; +#endif +#if REDM + public const string _texture_dict = "menu_textures"; + public const string _header_texture = "translate_bg_1a"; +#endif private static List menuTextureAssets = new List() { +#if FIVEM "commonmenu", "commonmenutu", "mpleaderboard", @@ -24,29 +33,61 @@ public class MenuController : BaseScript "mprankbadge", "mpcarhud", "mpcarhud2", +#endif +#if REDM + "menu_textures", + "boot_flow", + "generic_textures", +#endif }; +#if FIVEM private static float AspectRatio => GetScreenAspectRatio(false); +#endif +#if REDM + private static float AspectRatio => 16 / 9; +#endif public static float ScreenWidth => 1080 * AspectRatio; public static float ScreenHeight => 1080; public static bool DisableMenuButtons { get; set; } = false; +#if FIVEM public static bool AreMenuButtonsEnabled => Menus.Any((m) => m.Visible) && !Game.IsPaused && CitizenFX.Core.UI.Screen.Fading.IsFadedIn && !IsPlayerSwitchInProgress() && !DisableMenuButtons && !Game.Player.IsDead; +#endif +#if REDM + public static bool AreMenuButtonsEnabled => + Menus.Any((m) => m.Visible) && + !Call(IS_PAUSE_MENU_ACTIVE) && + Call(IS_SCREEN_FADED_IN) && + !DisableMenuButtons && + !Call(IS_ENTITY_DEAD, PlayerPedId()); +#endif public static bool EnableManualGCs { get; set; } = true; public static bool DontOpenAnyMenu { get; set; } = false; public static bool PreventExitingMenu { get; set; } = false; public static bool DisableBackButton { get; set; } = false; - public static Control MenuToggleKey { get; set; } = Control.InteractionMenu; + public static Control MenuToggleKey { get; set; } +#if FIVEM + = Control.InteractionMenu +#endif +#if REDM + = Control.Map +#endif + ; + public static bool EnableMenuToggleKeyOnController { get; set; } = true; internal static Dictionary MenuButtons { get; private set; } = new Dictionary(); public static Menu MainMenu { get; set; } = null; +#if FIVEM internal static int _scale = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS"); +#endif private static int ManualTimerForGC = GetGameTimer(); +#if FIVEM private static MenuAlignmentOption _alignment = MenuAlignmentOption.Left; public static MenuAlignmentOption MenuAlignment { @@ -75,11 +116,13 @@ public static MenuAlignmentOption MenuAlignment } } } + public enum MenuAlignmentOption { Left, Right } +#endif /// /// Constructor @@ -87,7 +130,9 @@ public enum MenuAlignmentOption public MenuController() { Tick += ProcessMenus; +#if FIVEM Tick += DrawInstructionalButtons; +#endif Tick += ProcessMainButtons; Tick += ProcessDirectionalButtons; Tick += ProcessToggleMenuButton; @@ -149,6 +194,7 @@ public static void AddSubmenu(Menu parent, Menu child) /// private static async Task LoadAssets() { +#if FIVEM menuTextureAssets.ForEach(asset => { if (!HasStreamedTextureDictLoaded(asset)) @@ -160,6 +206,20 @@ private static async Task LoadAssets() { await Delay(0); } +#endif +#if REDM + menuTextureAssets.ForEach(asset => + { + if (!Call(HAS_STREAMED_TEXTURE_DICT_LOADED, asset)) + { + Call(REQUEST_STREAMED_TEXTURE_DICT, asset, false); + } + }); + while (menuTextureAssets.Any(asset => { return !Call(HAS_STREAMED_TEXTURE_DICT_LOADED, asset); })) + { + await Delay(0); + } +#endif } /// @@ -167,7 +227,24 @@ private static async Task LoadAssets() /// private static void UnloadAssets() { - menuTextureAssets.ForEach(asset => { if (HasStreamedTextureDictLoaded(asset)) { SetStreamedTextureDictAsNoLongerNeeded(asset); } }); +#if FIVEM + menuTextureAssets.ForEach(asset => + { + if (HasStreamedTextureDictLoaded(asset)) + { + SetStreamedTextureDictAsNoLongerNeeded(asset); + } + }); +#endif +#if REDM + menuTextureAssets.ForEach(asset => + { + if (Call(HAS_STREAMED_TEXTURE_DICT_LOADED, asset)) + { + Call(SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED, asset); + } + }); +#endif } /// @@ -197,23 +274,41 @@ private async Task ProcessMainButtons() { if (IsAnyMenuOpen()) { +#if REDM + if (Call(IS_PAUSE_MENU_ACTIVE)) + { + return; + } +#endif var currentMenu = GetCurrentMenu(); if (currentMenu != null && !DontOpenAnyMenu) { if (PreventExitingMenu) { +#if FIVEM Game.DisableControlThisFrame(0, Control.FrontendPause); Game.DisableControlThisFrame(0, Control.FrontendPauseAlternate); +#endif +#if REDM + Call(DISABLE_CONTROL_ACTION, 0, Control.FrontendPause, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.FrontendPauseAlternate, true); +#endif } if (currentMenu.Visible && AreMenuButtonsEnabled) { // Select / Enter if ( +#if FIVEM Game.IsDisabledControlJustReleased(0, Control.FrontendAccept) || Game.IsControlJustReleased(0, Control.FrontendAccept) || Game.IsDisabledControlJustReleased(0, Control.VehicleMouseControlOverride) || Game.IsControlJustReleased(0, Control.VehicleMouseControlOverride) +#endif +#if REDM + Call(IS_DISABLED_CONTROL_JUST_RELEASED, 0, Control.FrontendAccept) || + Call(IS_CONTROL_JUST_RELEASED, 0, Control.FrontendAccept) +#endif ) { if (currentMenu.Size > 0) @@ -222,13 +317,27 @@ private async Task ProcessMainButtons() } } // Cancel / Go Back - else if (Game.IsDisabledControlJustReleased(0, Control.PhoneCancel) && !DisableBackButton) + else if ( +#if FIVEM + Game.IsDisabledControlJustReleased(0, Control.PhoneCancel) +#endif +#if REDM + Call(IS_DISABLED_CONTROL_JUST_RELEASED, 0, Control.FrontendCancel) +#endif + && !DisableBackButton) { // Wait for the next frame to make sure the "cinematic camera" button doesn't get "re-enabled" before the menu gets closed. await Delay(0); currentMenu.GoBack(); } - else if (Game.IsDisabledControlJustReleased(0, Control.PhoneCancel) && PreventExitingMenu && !DisableBackButton) + else if ( +#if FIVEM + Game.IsDisabledControlJustReleased(0, Control.PhoneCancel) +#endif +#if REDM + Call(IS_DISABLED_CONTROL_JUST_RELEASED, 0, Control.CellphoneCancel) +#endif + && PreventExitingMenu && !DisableBackButton) { // if there's a parent menu, allow going back to that, but don't allow a 'top-level' menu to be closed. if (currentMenu.ParentMenu != null) @@ -239,8 +348,9 @@ private async Task ProcessMainButtons() } } } - +#if FIVEM Game.DisableControlThisFrame(0, Control.MultiplayerInfo); +#endif } } @@ -255,7 +365,7 @@ private bool IsUpPressed() { return false; } - +#if FIVEM // when the player is holding TAB, while not in a vehicle, and when the scrollwheel is being used, return false to prevent interferring with weapon selection. if (!Game.PlayerPed.IsInVehicle()) { @@ -276,7 +386,17 @@ private bool IsUpPressed() { return true; } - +#endif +#if REDM + if (Call(IS_CONTROL_PRESSED, 0, Control.FrontendUp) || + Call(IS_DISABLED_CONTROL_PRESSED, 0, Control.FrontendUp) || + Call(IS_CONTROL_PRESSED, 0, Control.CellphoneScrollBackward) || + Call(IS_DISABLED_CONTROL_PRESSED, 0, Control.CellphoneScrollBackward) + ) + { + return true; + } +#endif // return false if none of the conditions matched. return false; } @@ -292,7 +412,7 @@ private bool IsDownPressed() { return false; } - +#if FIVEM // when the player is holding TAB, while not in a vehicle, and when the scrollwheel is being used, return false to prevent interferring with weapon selection. if (!Game.PlayerPed.IsInVehicle()) { @@ -313,6 +433,17 @@ private bool IsDownPressed() { return true; } +#endif +#if REDM + if (Call(IS_CONTROL_PRESSED, 0, Control.FrontendDown) || + Call(IS_DISABLED_CONTROL_PRESSED, 0, Control.FrontendDown) || + Call(IS_CONTROL_PRESSED, 0, Control.CellphoneScrollForward) || + Call(IS_DISABLED_CONTROL_PRESSED, 0, Control.CellphoneScrollForward) + ) + { + return true; + } +#endif // return false if none of the conditions matched. return false; @@ -324,6 +455,9 @@ private bool IsDownPressed() /// private async Task ProcessToggleMenuButton() { + +#if FIVEM + Game.DisableControlThisFrame(0, MenuToggleKey); if (!Game.IsPaused && !IsPauseMenuRestarting() && IsScreenFadedIn() && !IsPlayerSwitchInProgress() && !Game.Player.IsDead && !DisableMenuButtons) { if (IsAnyMenuOpen()) @@ -387,6 +521,15 @@ private async Task ProcessToggleMenuButton() } } } +#endif +#if REDM + Call(DISABLE_CONTROL_ACTION, 0, MenuToggleKey, true); + if (!Call(IS_PAUSE_MENU_ACTIVE) && Call(IS_SCREEN_FADED_IN) && !IsAnyMenuOpen() && !DisableMenuButtons && !Call(IS_ENTITY_DEAD, PlayerPedId()) && Call(IS_DISABLED_CONTROL_JUST_RELEASED, 0, MenuToggleKey)) + { + MainMenu.OpenMenu(); + } +#endif + await Task.FromResult(0); } /// @@ -436,6 +579,18 @@ private async Task ProcessDirectionalButtons() { delay = 150; } + if (times > 5) + { + delay = 100; + } + if (times > 25) + { + delay = 50; + } + if (times > 60) + { + delay = 25; + } // Update the currently selected item to the new one. currentMenu.GoUp(); @@ -467,6 +622,19 @@ private async Task ProcessDirectionalButtons() { delay = 150; } + if (times > 5) + { + delay = 100; + } + if (times > 25) + { + delay = 50; + } + if (times > 60) + { + delay = 25; + } + currentMenu.GoDown(); time = GetGameTimer(); @@ -476,7 +644,12 @@ private async Task ProcessDirectionalButtons() } // Check if the Go Left controls are pressed. +#if FIVEM else if (Game.IsDisabledControlJustPressed(0, Control.PhoneLeft) || Game.IsControlJustPressed(0, Control.PhoneLeft)) +#endif +#if REDM + else if (Call(IS_DISABLED_CONTROL_JUST_PRESSED, 0, Control.FrontendLeft) || Call(IS_CONTROL_JUST_PRESSED, 0, Control.FrontendLeft)) +#endif { var item = currentMenu.GetMenuItems()[currentMenu.CurrentIndex]; if (item.Enabled) @@ -485,7 +658,12 @@ private async Task ProcessDirectionalButtons() var time = GetGameTimer(); var times = 0; var delay = 200; +#if FIVEM while ((Game.IsDisabledControlPressed(0, Control.PhoneLeft) || Game.IsControlPressed(0, Control.PhoneLeft)) && GetCurrentMenu() != null && AreMenuButtonsEnabled) +#endif +#if REDM + while ((Call(IS_DISABLED_CONTROL_PRESSED, 0, Control.FrontendLeft) || Call(IS_CONTROL_PRESSED, 0, Control.FrontendLeft)) && GetCurrentMenu() != null && AreMenuButtonsEnabled) +#endif { currentMenu = GetCurrentMenu(); if (GetGameTimer() - time > delay) @@ -495,6 +673,18 @@ private async Task ProcessDirectionalButtons() { delay = 150; } + if (times > 5) + { + delay = 100; + } + if (times > 25) + { + delay = 50; + } + if (times > 60) + { + delay = 25; + } currentMenu.GoLeft(); time = GetGameTimer(); } @@ -504,7 +694,12 @@ private async Task ProcessDirectionalButtons() } // Check if the Go Right controls are pressed. +#if FIVEM else if (Game.IsDisabledControlJustPressed(0, Control.PhoneRight) || Game.IsControlJustPressed(0, Control.PhoneRight)) +#endif +#if REDM + else if (AreMenuButtonsEnabled && Call(IS_DISABLED_CONTROL_JUST_PRESSED, 0, Control.FrontendRight) || Call(IS_CONTROL_JUST_PRESSED, 0, Control.FrontendRight)) +#endif { var item = currentMenu.GetMenuItems()[currentMenu.CurrentIndex]; if (item.Enabled) @@ -513,7 +708,12 @@ private async Task ProcessDirectionalButtons() var time = GetGameTimer(); var times = 0; var delay = 200; +#if FIVEM while ((Game.IsDisabledControlPressed(0, Control.PhoneRight) || Game.IsControlPressed(0, Control.PhoneRight)) && GetCurrentMenu() != null && AreMenuButtonsEnabled) +#endif +#if REDM + while ((Call(IS_DISABLED_CONTROL_PRESSED, 0, Control.FrontendRight) || Call(IS_CONTROL_PRESSED, 0, Control.FrontendRight)) && GetCurrentMenu() != null && AreMenuButtonsEnabled) +#endif { currentMenu = GetCurrentMenu(); if (GetGameTimer() - time > delay) @@ -523,6 +723,18 @@ private async Task ProcessDirectionalButtons() { delay = 150; } + if (times > 5) + { + delay = 100; + } + if (times > 25) + { + delay = 50; + } + if (times > 60) + { + delay = 25; + } currentMenu.GoRight(); time = GetGameTimer(); } @@ -579,19 +791,27 @@ private static void DisableControls() var currentItem = currMenu.GetCurrentMenuItem(); if (currentItem != null) { +#if FIVEM if (currentItem is MenuSliderItem || currentItem is MenuListItem || currentItem is MenuDynamicListItem) { if (Game.CurrentInputMode == InputMode.GamePad) Game.DisableControlThisFrame(0, Control.SelectWeapon); } +#endif } // Close all menus when the player dies. +#if FIVEM if (Game.PlayerPed.IsDead) +#endif +#if REDM + if (Call(IS_ENTITY_DEAD, PlayerPedId())) +#endif { CloseAllMenus(); } +#if FIVEM // Disable Gamepad/Controller Specific controls: if (Game.CurrentInputMode == InputMode.GamePad) { @@ -618,8 +838,16 @@ private static void DisableControls() Game.DisableControlThisFrame(24, Control.SelectPrevWeapon); } } +#endif +#if REDM + if (Call(_IS_INPUT_DISABLED, 2)) + { + Call(DISABLE_CONTROL_ACTION, 0, Control.FrontendPauseAlternate, true); + } +#endif // Disable Shared Controls +#if FIVEM // Radio Inputs Game.DisableControlThisFrame(0, Control.RadioWheelLeftRight); Game.DisableControlThisFrame(0, Control.RadioWheelUpDown); @@ -656,6 +884,38 @@ private static void DisableControls() Game.DisableControlThisFrame(0, Control.VehicleSelectPrevWeapon); Game.DisableControlThisFrame(0, Control.VehicleCinCam); } +#endif +#if REDM + Call(DISABLE_CONTROL_ACTION, 0, Control.Attack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.Attack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.HorseAim, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.HorseAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.HorseAttack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.HorseMelee, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeBlock, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrapple, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrappleAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrappleBreakout, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrappleChoke, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrappleMountSwitch, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrappleReversal, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeGrappleStandSwitch, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeHorseAttackPrimary, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeHorseAttackSecondary, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.MeleeModifier, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehAttack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehBoatAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehBoatAttack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehCarAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehCarAttack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehDraftAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehDraftAttack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehFlyAttack, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehFlyAttack2, true); + Call(DISABLE_CONTROL_ACTION, 0, Control.VehPassengerAttack, true); +#endif } } @@ -668,7 +928,21 @@ private static void DisableControls() /// private static async Task ProcessMenus() { - if (Menus.Count > 0 && IsAnyMenuOpen() && !Game.IsPaused && !Game.Player.IsDead && IsScreenFadedIn() && !IsPlayerSwitchInProgress()) + + if (Menus.Count > 0 && + IsAnyMenuOpen() && +#if FIVEM + IsScreenFadedIn() && + !Game.IsPaused && + !Game.Player.IsDead && + !IsPlayerSwitchInProgress() +#endif +#if REDM + Call(IS_SCREEN_FADED_IN) && + !Call(IS_PAUSE_MENU_ACTIVE) && + !Call(IS_ENTITY_DEAD, PlayerPedId()) +#endif + ) { await LoadAssets(); @@ -706,6 +980,7 @@ private static async Task ProcessMenus() } } +#if FIVEM internal static async Task DrawInstructionalButtons() { if (!Game.IsPaused && !Game.Player.IsDead && IsScreenFadedIn() && !IsPlayerSwitchInProgress() && !IsWarningMessageActive() && UpdateOnscreenKeyboard() != 0) @@ -773,5 +1048,6 @@ private static void DisposeInstructionalButtonsScaleform() SetScaleformMovieAsNoLongerNeeded(ref _scale); } } +#endif } } diff --git a/MenuAPI/items/MenuCheckboxItem.cs b/MenuAPI/items/MenuCheckboxItem.cs index 3e1990c..fa47c3d 100644 --- a/MenuAPI/items/MenuCheckboxItem.cs +++ b/MenuAPI/items/MenuCheckboxItem.cs @@ -5,6 +5,8 @@ using System.Threading.Tasks; using CitizenFX.Core; using static CitizenFX.Core.Native.API; +using static CitizenFX.Core.Native.Function; +using static CitizenFX.Core.Native.Hash; namespace MenuAPI @@ -15,7 +17,9 @@ public class MenuCheckboxItem : MenuItem public CheckboxStyle Style { get; set; } = CheckboxStyle.Tick; public enum CheckboxStyle { +#if FIVEM Cross, +#endif Tick } @@ -50,9 +54,10 @@ public MenuCheckboxItem(string text, string description, bool _checked) : base(t int GetSpriteColour() { - return 255; + return Enabled ? 255 : 109; } +#if FIVEM string GetSpriteName() { if (Checked) @@ -83,12 +88,18 @@ string GetSpriteName() return "shop_box_blank"; } } +#endif float GetSpriteX() { +#if FIVEM bool leftSide = false; bool leftAligned = ParentMenu.LeftAligned; return leftSide ? (leftAligned ? (20f / MenuController.ScreenWidth) : GetSafeZoneSize() - ((Width - 20f) / MenuController.ScreenWidth)) : (leftAligned ? (Width - 20f) / MenuController.ScreenWidth : (GetSafeZoneSize() - (20f / MenuController.ScreenWidth))); +#endif +#if REDM + return (Width - 30f) / MenuController.ScreenWidth; +#endif } internal override void Draw(int offset) @@ -98,21 +109,39 @@ internal override void Draw(int offset) base.Draw(offset); +#if FIVEM SetScriptGfxAlign(76, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); +#endif float yOffset = ParentMenu.MenuItemsYOffset + 1f - (RowHeight * MathUtil.Clamp(ParentMenu.Size, 0, ParentMenu.MaxItemsOnScreen)); - +#if FIVEM string name = GetSpriteName(); - float spriteY = (ParentMenu.Position.Y + ((Index - offset) * RowHeight) + (20f) + yOffset) / MenuController.ScreenHeight; +#endif + + float spriteY = (ParentMenu.Position.Value + ((Index - offset) * RowHeight) + (20f) + yOffset) / MenuController.ScreenHeight; float spriteX = GetSpriteX(); +#if FIVEM float spriteHeight = 45f / MenuController.ScreenHeight; float spriteWidth = 45f / MenuController.ScreenWidth; +#endif int color = GetSpriteColour(); +#if FIVEM DrawSprite("commonmenu", name, spriteX, spriteY, spriteWidth, spriteHeight, 0f, color, color, color, 255); ResetScriptGfxAlign(); +#endif +#if REDM + float spriteHeight = 24f / MenuController.ScreenHeight; + float spriteWidth = 16f / MenuController.ScreenWidth; + Call(DRAW_SPRITE, "menu_textures", "SELECTION_BOX_SQUARE", spriteX, spriteY, spriteWidth, spriteHeight, 0f, color, color, color, 255); + if (Checked) + { + int[] sc = Enabled ? (Selected ? new int[3] { 255, 255, 255 } : new int[3] { 181, 17, 18 }) : (Selected ? new int[3] { 109, 109, 109 } : new int[3] { 110, 10, 10 }); + Call(DRAW_SPRITE, "generic_textures", "TICK", spriteX, spriteY, spriteWidth, spriteHeight, 0f, sc[0], sc[1], sc[2], 255); + } +#endif } } } diff --git a/MenuAPI/items/MenuItem.cs b/MenuAPI/items/MenuItem.cs index f3d01d0..405235c 100644 --- a/MenuAPI/items/MenuItem.cs +++ b/MenuAPI/items/MenuItem.cs @@ -3,17 +3,20 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Drawing; using CitizenFX.Core; using static CitizenFX.Core.Native.API; +using static CitizenFX.Core.Native.Function; +using static CitizenFX.Core.Native.Hash; namespace MenuAPI { public class MenuItem { + public enum Icon { NONE, +#if FIVEM LOCK, STAR, WARNING, @@ -192,6 +195,18 @@ public enum Icon BRAND_WESTERNMOTORCYCLE, BRAND_WILLARD, BRAND_ZIRCONIUM, +#endif +#if REDM + LOCK, + TICK, + CIRCLE, + SADDLE, + STAR, + ARROW_LEFT, + ARROW_RIGHT, + INVITE_SENT, + SELECTION_BOX +#endif } public string Text { get; set; } @@ -199,7 +214,46 @@ public enum Icon public Icon LeftIcon { get; set; } public Icon RightIcon { get; set; } public bool Enabled { get; set; } = true; - public string Description { get; set; } + public string Description + { + get + { + return _description; + } + set + { +#if FIVEM + _description = value; +#endif +#if REDM + if (value != null) + { + string text = value; + int maxLength = 50; + List lines = new List(); + while (text.Length > maxLength) + { + var substr = text.Substring(0, Math.Min(text.Length - 1, maxLength)); + var lastIndex = substr.LastIndexOf(" "); + if (lastIndex == -1) + { + lastIndex = Math.Min(text.Length - 1, maxLength); + } + lines.Add(text.Substring(0, lastIndex)); + text = text.Substring(lastIndex); + } + lines.Add(text); + text = ""; + foreach (var str in lines) + { + text += str + "\n"; + } + _description = text; + } +#endif + } + } + private string _description; public int Index { get { if (ParentMenu != null) return ParentMenu.GetMenuItems().IndexOf(this); return -1; } } //{ get; internal set; } public bool Selected { get { if (ParentMenu != null) { return ParentMenu.CurrentIndex == Index; } return false; } } public Menu ParentMenu { get; set; } @@ -231,6 +285,7 @@ protected string GetSpriteDictionary(Icon icon) { switch (icon) { +#if FIVEM case Icon.MALE: case Icon.FEMALE: case Icon.AUDIO_MUTE: @@ -391,13 +446,30 @@ protected string GetSpriteDictionary(Icon icon) return "mpcarhud2"; default: return "commonmenu"; +#endif +#if REDM + case Icon.LOCK: + case Icon.TICK: + case Icon.CIRCLE: + case Icon.SADDLE: + case Icon.STAR: + case Icon.ARROW_LEFT: + case Icon.ARROW_RIGHT: + case Icon.INVITE_SENT: + case Icon.SELECTION_BOX: + return "menu_textures"; + default: + return ""; +#endif } + } protected string GetSpriteName(Icon icon, bool selected) { switch (icon) { +#if FIVEM case Icon.AMMO: return selected ? "shop_ammo_icon_b" : "shop_ammo_icon_a"; case Icon.ARMOR: return selected ? "shop_armour_icon_b" : "shop_armour_icon_a"; case Icon.BARBER: return selected ? "shop_barber_icon_b" : "shop_barber_icon_a"; @@ -579,6 +651,27 @@ protected string GetSpriteName(Icon icon, bool selected) case Icon.BRAND_RUNE: return "rune"; default: break; +#endif +#if REDM + case Icon.LOCK: + return "MENU_ICON_LOCK"; + case Icon.TICK: + return "MENU_ICON_TICK"; + case Icon.CIRCLE: + return "MENU_ICON_CIRCLE"; + case Icon.SADDLE: + return "MENU_ICON_ON_HORSE"; + case Icon.STAR: + return "MENU_ICON_INFO_NEW"; + case Icon.ARROW_LEFT: + return "SELECTION_ARROW_LEFT"; + case Icon.ARROW_RIGHT: + return "SELECTION_ARROW_RIGHT"; + case Icon.INVITE_SENT: + return "MENU_ICON_INVITE_SENT"; + case Icon.SELECTION_BOX: + return "SELECTION_BOX_SQUARE"; +#endif } return ""; } @@ -587,6 +680,7 @@ protected float GetSpriteSize(Icon icon, bool width) { switch (icon) { +#if FIVEM case Icon.CASH: case Icon.COKE: case Icon.CROWN: @@ -747,6 +841,25 @@ protected float GetSpriteSize(Icon icon, bool width) return 22f / (width ? MenuController.ScreenWidth : MenuController.ScreenHeight); default: return 38f / (width ? MenuController.ScreenWidth : MenuController.ScreenHeight); +#endif +#if REDM + case Icon.TICK: + return width ? (16f / MenuController.ScreenWidth) : (24f / MenuController.ScreenHeight); + case Icon.CIRCLE: + return width ? (16f / MenuController.ScreenWidth) : (26f / MenuController.ScreenHeight); + case Icon.SADDLE: + return width ? (16f / MenuController.ScreenWidth) : (24f / MenuController.ScreenHeight); + case Icon.STAR: + case Icon.ARROW_LEFT: + case Icon.ARROW_RIGHT: + return width ? (14f / MenuController.ScreenWidth) : (22f / MenuController.ScreenHeight); + case Icon.SELECTION_BOX: + case Icon.INVITE_SENT: + return width ? (16f / MenuController.ScreenWidth) : (24f / MenuController.ScreenHeight); + case Icon.LOCK: + default: + return width ? (24f / MenuController.ScreenWidth) : (30f / MenuController.ScreenHeight); +#endif } } @@ -754,6 +867,7 @@ protected int[] GetSpriteColour(Icon icon, bool selected) { switch (icon) { +#if FIVEM case Icon.CROWN: case Icon.TICK: case Icon.MALE: @@ -861,16 +975,29 @@ protected int[] GetSpriteColour(Icon icon, bool selected) return Enabled ? new int[3] { 232, 207, 14 } : new int[3] { 131, 133, 12 }; default: return Enabled ? new int[3] { 255, 255, 255 } : new int[3] { 109, 109, 109 }; +#endif +#if REDM + case Icon.STAR: + return !Enabled ? new int[3] { 163, 106, 5 } : new int[3] { 237, 154, 9 }; + default: + return Enabled ? new int[3] { 255, 255, 255 } : new int[3] { 109, 109, 109 }; + //return new int[3] { 255, 255, 255 }; +#endif } } protected float GetSpriteX(Icon icon, bool leftAligned, bool leftSide) { +#if FIVEM if (icon == Icon.NONE) { return 0f; } return leftSide ? (leftAligned ? (20f / MenuController.ScreenWidth) : GetSafeZoneSize() - ((Width - 20f) / MenuController.ScreenWidth)) : (leftAligned ? (Width - 20f) / MenuController.ScreenWidth : (GetSafeZoneSize() - (20f / MenuController.ScreenWidth))); +#endif +#if REDM + return leftSide ? 30f / MenuController.ScreenWidth : ((Width - 30f) / MenuController.ScreenWidth); +#endif } protected float GetSpriteY(Icon icon) @@ -887,21 +1014,30 @@ internal virtual void Draw(int indexOffset) if (ParentMenu != null) { float yOffset = ParentMenu.MenuItemsYOffset + 1f - (RowHeight * MathUtil.Clamp(ParentMenu.Size, 0, ParentMenu.MaxItemsOnScreen)); - #region Background Rect +#if FIVEM SetScriptGfxAlign(ParentMenu.LeftAligned ? 76 : 82, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); +#endif - float x = (ParentMenu.Position.X + (Width / 2f)) / MenuController.ScreenWidth; - float y = (ParentMenu.Position.Y + ((Index - indexOffset) * RowHeight) + (20f) + yOffset) / MenuController.ScreenHeight; + float x = (ParentMenu.Position.Key + (Width / 2f)) / MenuController.ScreenWidth; + float y = (ParentMenu.Position.Value + ((Index - indexOffset) * RowHeight) + (20f) + yOffset) / MenuController.ScreenHeight; float width = Width / MenuController.ScreenWidth; float height = (RowHeight) / MenuController.ScreenHeight; if (Selected) { +#if FIVEM DrawRect(x, y, width, height, 255, 255, 255, 225); +#endif +#if REDM + Call(DRAW_SPRITE, MenuController._texture_dict, MenuController._header_texture, x, y, width, height, 0f, 181, 17, 18, 255); + //Call(DRAW_RECT, x, y, width, height, 74, 6, 7, 200); +#endif } +#if FIVEM ResetScriptGfxAlign(); +#endif #endregion #region Left Icon @@ -909,7 +1045,7 @@ internal virtual void Draw(int indexOffset) if (LeftIcon != Icon.NONE) { textXOffset = 25f; - +#if FIVEM SetScriptGfxAlign(76, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); @@ -923,18 +1059,30 @@ internal virtual void Draw(int indexOffset) DrawSprite(textureDictionary, name, spriteX, spriteY, spriteWidth, spriteHeight, 0f, spriteColor[0], spriteColor[1], spriteColor[2], 255); ResetScriptGfxAlign(); +#endif +#if REDM + string spriteName = GetSpriteName(LeftIcon, Selected); + string spriteDict = GetSpriteDictionary(LeftIcon); + float spriteX = GetSpriteX(LeftIcon, true, true); + float spriteY = y; + float spriteHeight = GetSpriteSize(LeftIcon, false); + float spriteWidth = GetSpriteSize(LeftIcon, true); + int[] spriteColor = GetSpriteColour(LeftIcon, Selected); + Call(DRAW_SPRITE, spriteDict, spriteName, spriteX, spriteY, spriteWidth, spriteHeight, 0f, spriteColor[0], spriteColor[1], spriteColor[2], 255); +#endif + } #endregion - float rightTextIconOffset = 0f; #region Right Icon + float rightTextIconOffset = 0f; if (RightIcon != Icon.NONE) { +#if FIVEM rightTextIconOffset = 25f; SetScriptGfxAlign(76, 84); SetScriptGfxAlignParams(0f, 0f, 0f, 0f); - string name = GetSpriteName(RightIcon, Selected); float spriteY = y;// GetSpriteY(RightIcon); float spriteX = GetSpriteX(RightIcon, ParentMenu.LeftAligned, false); @@ -942,63 +1090,31 @@ internal virtual void Draw(int indexOffset) float spriteWidth = GetSpriteSize(RightIcon, true); int[] spriteColor = GetSpriteColour(RightIcon, Selected); string textureDictionary = GetSpriteDictionary(RightIcon); - DrawSprite(textureDictionary, name, spriteX, spriteY, spriteWidth, spriteHeight, 0f, spriteColor[0], spriteColor[1], spriteColor[2], 255); ResetScriptGfxAlign(); +#endif +#if REDM + string spriteName = GetSpriteName(RightIcon, Selected); + string spriteDict = GetSpriteDictionary(RightIcon); + float spriteX = GetSpriteX(RightIcon, true, false); + float spriteY = y; + float spriteHeight = GetSpriteSize(RightIcon, false); + float spriteWidth = GetSpriteSize(RightIcon, true); + int[] spriteColor = GetSpriteColour(RightIcon, Selected); + Call(DRAW_SPRITE, spriteDict, spriteName, spriteX, spriteY, spriteWidth, spriteHeight, 0f, spriteColor[0], spriteColor[1], spriteColor[2], 255); +#endif } #endregion - #region Text + #region Label int font = 0; float textSize = (14f * 27f) / MenuController.ScreenHeight; - //float textSize = 0.34f; - - SetScriptGfxAlign(76, 84); - SetScriptGfxAlignParams(0f, 0f, 0f, 0f); - SetTextFont(font); - SetTextScale(textSize, textSize); - SetTextJustification(1); - BeginTextCommandDisplayText("STRING"); - AddTextComponentSubstringPlayerName(Text ?? "N/A"); - int textColor = Selected ? (Enabled ? 0 : 50) : (Enabled ? 255 : 109); - if (Selected || !Enabled) - { - SetTextColour(textColor, textColor, textColor, 255); - } - //selected ? (Enabled ? 0 : 50) : (Enabled ? 255 : 109); - //if (Selected) - //{ - // if (Enabled) - // SetTextColour(textColor, textColor, textColor, 255); - // else - // SetTextColour(textColor, textColor, textColor, 255); - //} - //else - //{ - // if (!Enabled) - // SetTextColour(textColor, textColor, textColor, 255); - //} +#if FIVEM float textMinX = (textXOffset / MenuController.ScreenWidth) + (10f / MenuController.ScreenWidth); float textMaxX = (Width - 10f) / MenuController.ScreenWidth; //float textHeight = GetTextScaleHeight(textSize, font); float textY = y - ((30f / 2f) / MenuController.ScreenHeight); - if (ParentMenu.LeftAligned) - { - SetTextWrap(textMinX, textMaxX); - EndTextCommandDisplayText(textMinX, textY); - } - else - { - textMinX = (textXOffset / MenuController.ScreenWidth) + GetSafeZoneSize() - ((Width - 10f) / MenuController.ScreenWidth); - textMaxX = GetSafeZoneSize() - (10f / MenuController.ScreenWidth); - SetTextWrap(textMinX, textMaxX); - EndTextCommandDisplayText(textMinX, textY); - } - ResetScriptGfxAlign(); - - #endregion - - #region Label + int textColor = Selected ? (Enabled ? 0 : 50) : (Enabled ? 255 : 109); if (!string.IsNullOrEmpty(Label)) { SetScriptGfxAlign(76, 84); @@ -1013,10 +1129,6 @@ internal virtual void Draw(int indexOffset) { SetTextColour(textColor, textColor, textColor, 255); } - //if (Selected) - //{ - // SetTextColour(0, 0, 0, 255); - //} if (ParentMenu.LeftAligned) { SetTextWrap(0f, ((490f - rightTextIconOffset) / MenuController.ScreenWidth)); @@ -1030,8 +1142,51 @@ internal virtual void Draw(int indexOffset) ResetScriptGfxAlign(); } +#endif #endregion + #region Text + +#if FIVEM + SetScriptGfxAlign(76, 84); + SetScriptGfxAlignParams(0f, 0f, 0f, 0f); + SetTextFont(font); + SetTextScale(textSize, textSize); + SetTextJustification(1); + BeginTextCommandDisplayText("STRING"); + AddTextComponentSubstringPlayerName(Text ?? "N/A"); + if (Selected || !Enabled) + { + SetTextColour(textColor, textColor, textColor, 255); + } + if (ParentMenu.LeftAligned) + { + SetTextWrap(textMinX, textMaxX); + EndTextCommandDisplayText(textMinX, textY); + } + else + { + textMinX = (textXOffset / MenuController.ScreenWidth) + GetSafeZoneSize() - ((Width - 10f) / MenuController.ScreenWidth); + textMaxX = GetSafeZoneSize() - (10f / MenuController.ScreenWidth); + SetTextWrap(textMinX, textMaxX); + EndTextCommandDisplayText(textMinX, textY); + } + ResetScriptGfxAlign(); +#endif +#if REDM + Call(SET_TEXT_SCALE, textSize, textSize); + + int textColor = Enabled ? 255 : 109; + Call((CitizenFX.Core.Native.Hash)0x50A41AD966910F03, textColor, textColor, textColor, 255); // _SET_TEXT_COLOUR / 0x50A41AD966910F03 + float textMinX = ((8f + textXOffset) / MenuController.ScreenWidth) + (10f / MenuController.ScreenWidth); + float textMaxX = (Width - 10f) / MenuController.ScreenWidth; + float textY = y - ((30f / 2f) / MenuController.ScreenHeight); + font = 23; + Call((CitizenFX.Core.Native.Hash)0xADA9255D, font); + + Call(_DRAW_TEXT, Call(_CREATE_VAR_STRING, 10, "LITERAL_STRING", (Text ?? "N/A") + (" " + Label ?? "")), textMinX, textY); +#endif + #endregion } diff --git a/MenuAPI/items/MenuListItem.cs b/MenuAPI/items/MenuListItem.cs index 3a1b207..4021188 100644 --- a/MenuAPI/items/MenuListItem.cs +++ b/MenuAPI/items/MenuListItem.cs @@ -8,6 +8,7 @@ namespace MenuAPI { + public class MenuListItem : MenuItem { public int ListIndex { get; set; } = 0; @@ -68,6 +69,6 @@ internal override void Draw(int indexOffset) base.Draw(indexOffset); } - } + } diff --git a/MenuAPI/items/MenuSliderItem.cs b/MenuAPI/items/MenuSliderItem.cs index 96e8ff9..ab0fba7 100644 --- a/MenuAPI/items/MenuSliderItem.cs +++ b/MenuAPI/items/MenuSliderItem.cs @@ -3,12 +3,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Drawing; using CitizenFX.Core; using static CitizenFX.Core.Native.API; namespace MenuAPI { +#if FIVEM public class MenuSliderItem : MenuItem { public int Min { get; private set; } = 0; @@ -19,8 +19,8 @@ public class MenuSliderItem : MenuItem public Icon SliderLeftIcon { get; set; } = Icon.NONE; public Icon SliderRightIcon { get; set; } = Icon.NONE; - public Color BackgroundColor { get; set; } = Color.FromArgb(255, 24, 93, 151); - public Color BarColor { get; set; } = Color.FromArgb(255, 53, 165, 223); + public System.Drawing.Color BackgroundColor { get; set; } = System.Drawing.Color.FromArgb(255, 24, 93, 151); + public System.Drawing.Color BarColor { get; set; } = System.Drawing.Color.FromArgb(255, 53, 165, 223); public MenuSliderItem(string name, int min, int max, int startPosition) : this(name, min, max, startPosition, false) { } public MenuSliderItem(string name, int min, int max, int startPosition, bool showDivider) : this(name, null, min, max, startPosition, showDivider) { } @@ -65,8 +65,8 @@ internal override void Draw(int indexOffset) float width = 150f / MenuController.ScreenWidth; float height = 10f / MenuController.ScreenHeight; - float y = (ParentMenu.Position.Y + ((Index - indexOffset) * RowHeight) + (20f) + yOffset) / MenuController.ScreenHeight; - float x = (ParentMenu.Position.X + (Width)) / MenuController.ScreenWidth - (width / 2f) - (8f / MenuController.ScreenWidth); + float y = (ParentMenu.Position.Value + ((Index - indexOffset) * RowHeight) + (20f) + yOffset) / MenuController.ScreenHeight; + float x = (ParentMenu.Position.Key + (Width)) / MenuController.ScreenWidth - (width / 2f) - (8f / MenuController.ScreenWidth); if (!ParentMenu.LeftAligned) { x = (width / 2f) - (8f / MenuController.ScreenWidth); @@ -133,4 +133,5 @@ internal override void Draw(int indexOffset) } } +#endif } diff --git a/TestMenu/ExampleMenu.cs b/TestMenu/ExampleMenu.cs index 98a4f18..74e47e0 100644 --- a/TestMenu/ExampleMenu.cs +++ b/TestMenu/ExampleMenu.cs @@ -6,7 +6,6 @@ using CitizenFX.Core; using static CitizenFX.Core.Native.API; using MenuAPI; -using System.Drawing; namespace TestMenu { @@ -14,31 +13,37 @@ public class ExampleMenu : BaseScript { public ExampleMenu() { +#if FIVEM // Setting the menu alignment to be right aligned. This can be changed at any time and it'll update instantly. // To test this, checkout one of the checkbox items in this example menu. Clicking it will toggle the menu alignment. MenuController.MenuAlignment = MenuController.MenuAlignmentOption.Right; - - MenuController.MenuToggleKey = Control.InteractionMenu; +#endif + //MenuController.MenuToggleKey = Control.InteractionMenu; // Creating the first menu. Menu menu = new Menu("Main Menu", "Subtitle"); MenuController.AddMenu(menu); // Adding a new button by directly creating one inline. You could also just store it and then add it but we don't need to do that in this example. - menu.AddMenuItem(new MenuItem("Normal Button", "This is a simple button with a simple description. Scroll down for more button types!")); - + menu.AddMenuItem(new MenuItem("Normal Button", "This is a simple button with a simple description. Scroll down for more button types!") + { + Enabled = false, + LeftIcon = MenuItem.Icon.TICK + }); +#if FIVEM // Creating 3 sliders, showing off the 3 possible variations and custom colors. MenuSliderItem slider = new MenuSliderItem("Slider", 0, 10, 5, false); MenuSliderItem slider2 = new MenuSliderItem("Slider + Bar", 0, 10, 5, true) { - BarColor = Color.FromArgb(255, 73, 233, 111), - BackgroundColor = Color.FromArgb(255, 25, 100, 43) + BarColor = System.Drawing.Color.FromArgb(255, 73, 233, 111), + BackgroundColor = System.Drawing.Color.FromArgb(255, 25, 100, 43) }; MenuSliderItem slider3 = new MenuSliderItem("Slider + Bar + Icons", "The icons are currently male/female because that's probably the most common use. But any icon can be used!", 0, 10, 5, true) { - BarColor = Color.FromArgb(255, 255, 0, 0), - BackgroundColor = Color.FromArgb(255, 100, 0, 0), + BarColor = System.Drawing.Color.FromArgb(255, 255, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(255, 100, 0, 0), + SliderLeftIcon = MenuItem.Icon.MALE, SliderRightIcon = MenuItem.Icon.FEMALE }; @@ -47,26 +52,30 @@ public ExampleMenu() menu.AddMenuItem(slider2); menu.AddMenuItem(slider3); +#endif + +#if FIVEM // Creating 3 checkboxs, 2 different styles and one has a locked icon and it's 'not enabled' (not enabled meaning you can't toggle it). MenuCheckboxItem box = new MenuCheckboxItem("Checkbox - Style 1 (click me!)", "This checkbox can toggle the menu position! Try it out.", !menu.LeftAligned) { - Style = MenuCheckboxItem.CheckboxStyle.Tick + Style = MenuCheckboxItem.CheckboxStyle.Cross }; - +#endif MenuCheckboxItem box2 = new MenuCheckboxItem("Checkbox - Style 2", "This checkbox does nothing right now.", true) { - Style = MenuCheckboxItem.CheckboxStyle.Cross + Style = MenuCheckboxItem.CheckboxStyle.Tick }; MenuCheckboxItem box3 = new MenuCheckboxItem("Checkbox (unchecked + locked)", "Make this menu right aligned. If you set this to false, then the menu will move to the left.", false) { - Style = MenuCheckboxItem.CheckboxStyle.Cross, Enabled = false, LeftIcon = MenuItem.Icon.LOCK }; // Adding the checkboxes to the menu. +#if FIVEM menu.AddMenuItem(box); +#endif menu.AddMenuItem(box2); menu.AddMenuItem(box3); @@ -79,7 +88,7 @@ string ChangeCallback(MenuDynamicListItem item, bool left) } MenuDynamicListItem dynList = new MenuDynamicListItem("Dynamic list item.", "0", new MenuDynamicListItem.ChangeItemCallback(ChangeCallback), "Description for this dynamic item. Pressing left will make the value smaller, pressing right will make the value bigger."); menu.AddMenuItem(dynList); - +#if FIVEM // List items (first the 3 special variants, then a normal one) List colorList = new List(); for (var i = 0; i < 64; i++) @@ -114,14 +123,15 @@ string ChangeCallback(MenuDynamicListItem item, bool left) ShowOpacityPanel = true }; + menu.AddMenuItem(hairColors); + menu.AddMenuItem(makeupColors); + menu.AddMenuItem(opacity); +#endif // Normal List normalList = new List() { "Item #1", "Item #2", "Item #3" }; MenuListItem normalListItem = new MenuListItem("Normal List Item", normalList, 0, "And another simple description for yet another simple (list) item. Nothing special about this one."); // Adding the lists to the menu. - menu.AddMenuItem(hairColors); - menu.AddMenuItem(makeupColors); - menu.AddMenuItem(opacity); menu.AddMenuItem(normalListItem); // Creating a submenu, adding it to the menus list, and creating and binding a button for it. @@ -130,7 +140,12 @@ string ChangeCallback(MenuDynamicListItem item, bool left) MenuItem menuButton = new MenuItem("Submenu", "This button is bound to a submenu. Clicking it will take you to the submenu.") { +#if FIVEM Label = "→→→" +#endif +#if REDM + RightIcon = MenuItem.Icon.ARROW_RIGHT +#endif }; menu.AddMenuItem(menuButton); MenuController.BindMenuItem(menu, submenu, menuButton); @@ -141,8 +156,10 @@ string ChangeCallback(MenuDynamicListItem item, bool left) var tmpItem = new MenuItem($"Icon.{Enum.GetName(typeof(MenuItem.Icon), ((MenuItem.Icon)i))}", "This menu item has a left and right sprite. Press ~r~HOME~s~ to toggle the 'enabled' state on these items.") { Label = $"(#{i})", - LeftIcon = (MenuItem.Icon)i, - RightIcon = (MenuItem.Icon)i +#if FIVEM +#endif + RightIcon = (MenuItem.Icon)i, + LeftIcon = (MenuItem.Icon)i }; //var tmpItem2 = new MenuItem($"Icon.{Enum.GetName(typeof(MenuItem.Icon), ((MenuItem.Icon)i))}", "This menu item has a left and right sprite, and it's ~h~disabled~h~."); @@ -158,13 +175,14 @@ string ChangeCallback(MenuDynamicListItem item, bool left) m.GetMenuItems().ForEach(a => a.Enabled = !a.Enabled); }), true)); +#if FIVEM // Instructional buttons setup for the second (submenu) menu. submenu.InstructionalButtons.Add(Control.CharacterWheel, "Right?!"); - submenu.InstructionalButtons.Add(Control.CreatorLS, "Buttons"); submenu.InstructionalButtons.Add(Control.CursorScrollDown, "Cool"); submenu.InstructionalButtons.Add(Control.CreatorDelete, "Out!"); submenu.InstructionalButtons.Add(Control.Cover, "This"); submenu.InstructionalButtons.Add(Control.Context, "Check"); +#endif // Create a third menu without a banner. Menu menu3 = new Menu(null, "Only a subtitle, no banner."); @@ -172,19 +190,32 @@ string ChangeCallback(MenuDynamicListItem item, bool left) // you can use AddSubmenu or AddMenu, both will work but if you want to link this menu from another menu, // you should use AddSubmenu. MenuController.AddSubmenu(menu, menu3); - MenuItem thirdSubmenuBtn = new MenuItem("Another submenu", "This is just a submenu without a banner. No big deal.") { Label = "→→→" }; + MenuItem thirdSubmenuBtn = new MenuItem("Another submenu", "This is just a submenu without a banner. No big deal. This also has a very long description to test multiple lines and see if they work properly. Let's find out if it works as intended.") + { +#if FIVEM + Label = "→→→" +#endif + +#if REDM + RightIcon = MenuItem.Icon.ARROW_RIGHT +#endif + }; menu.AddMenuItem(thirdSubmenuBtn); MenuController.BindMenuItem(menu, menu3, thirdSubmenuBtn); menu3.AddMenuItem(new MenuItem("Nothing here!")); menu3.AddMenuItem(new MenuItem("Nothing here!")); menu3.AddMenuItem(new MenuItem("Nothing here!")); - menu3.AddMenuItem(new MenuItem("Nothing here!")); + menu3.AddMenuItem(new MenuItem("Nothing here!") { LeftIcon = MenuItem.Icon.TICK }); + for (var i = 0; i < 10; i++) + { + menu.AddMenuItem(new MenuItem($"Item #{i + 1}.", "With an invisible description.")); + } /* - ######################################################## +######################################################## Event handlers - ######################################################## +######################################################## */ @@ -192,7 +223,7 @@ Event handlers { // Code in here gets executed whenever a checkbox is toggled. Debug.WriteLine($"OnCheckboxChange: [{_menu}, {_item}, {_index}, {_checked}]"); - +#if FIVEM // If the align-menu checkbox is toggled, toggle the menu alignment. if (_item == box) { @@ -205,6 +236,7 @@ Event handlers MenuController.MenuAlignment = MenuController.MenuAlignmentOption.Left; } } +#endif }; menu.OnItemSelect += (_menu, _item, _index) => @@ -231,6 +263,7 @@ Event handlers Debug.WriteLine($"OnListItemSelect: [{_menu}, {_listItem}, {_listIndex}, {_itemIndex}]"); }; +#if FIVEM menu.OnSliderPositionChange += (_menu, _sliderItem, _oldPosition, _newPosition, _itemIndex) => { // Code in here would get executed whenever the position of a slider is changed (when left/right key is pressed). @@ -242,6 +275,7 @@ Event handlers // Code in here would get executed whenever a slider item is pressed. Debug.WriteLine($"OnSliderItemSelect: [{_menu}, {_sliderItem}, {_sliderPosition}, {_itemIndex}]"); }; +#endif menu.OnMenuClose += (_menu) => { @@ -267,6 +301,19 @@ Event handlers Debug.WriteLine($"OnDynamicListItemSelect: [{_menu}, {_dynamicListItem}, {_currentItem}]"); }; + longershit(); } + + static async Task longershit() + { + Debug.WriteLine("test"); + await Delay(1000); + Debug.WriteLine("test"); + MenuController.MainMenu.OpenMenu(); + await Delay(10000); + Debug.WriteLine(MenuController.MainMenu.Visible.ToString()); + } + + } } diff --git a/TestMenu/TestMenu.csproj b/TestMenu/TestMenu.csproj index 37515ba..e6bcc83 100644 --- a/TestMenu/TestMenu.csproj +++ b/TestMenu/TestMenu.csproj @@ -7,23 +7,32 @@ Release RedM;Release FiveM;Debug RedM;Debug FiveM + + FIVEM + + + + REDM + + - + - + + runtime + - - ..\..\..\..\citizen\clr2\lib\mono\4.5\citizenfx.core.dll + + ..\dependencies\RedM\CitizenFX.Core.dll + false + + + + \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index c64c973..50ee69b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,9 @@ pull_requests: do_not_increment_build_number: false -image: Visual Studio 2017 -configuration: Release FiveM +image: Visual Studio 2019 +configuration: + - Release RedM + - Release FiveM before_build: - nuget restore build: @@ -10,30 +12,25 @@ build: include_nuget_references: true verbosity: minimal after_build: - - cmd: copy README.md .\MenuAPI\bin\Release\README.md - cmd: if %APPVEYOR_REPO_TAG%==true (appveyor SetVariable -Name VERSION_NAME -Value %APPVEYOR_REPO_TAG_NAME%) else (appveyor SetVariable -Name VERSION_NAME -Value dev) - - cmd: 7z a MenuAPI-%VERSION_NAME%.zip -r .\MenuAPI\bin\Release\* - - cmd: appveyor PushArtifact MenuAPI-%VERSION_NAME%.zip + - cmd: if "%CONFIGURATION%"=="Release FiveM" (appveyor SetVariable -Name GAME -Value "FiveM") else if "%CONFIGURATION%"=="Release RedM" (appveyor SetVariable -Name GAME -Value "RedM") + - cmd: copy "README.md" ".\MenuAPI\bin\README.md" + - cmd: 7z a MenuAPI-%VERSION_NAME%-%GAME%.zip -r ".\MenuAPI\bin\*" + - cmd: appveyor PushArtifact MenuAPI-%VERSION_NAME%-%GAME%.zip deploy: - provider: GitHub release: "[Release] MenuAPI $(VERSION_NAME)" tag: $(VERSION_NAME) - artifact: MenuAPI-$(VERSION_NAME).zip - draft: false + artifact: MenuAPI-$(VERSION_NAME)-$(GAME).zip + draft: true prerelease: false auth_token: $(github_auth) on: APPVEYOR_REPO_TAG: true - description: "MenuAPI release, version $(VERSION_NAME). For a changelog check the [docs](https://docs.vespura.com/) or checkout the recent commits on GitHub." -# before_build: -# - ps: if($env:APPVEYOR_REPO_TAG -eq $True) {Invoke-RestMethod https://raw.githubusercontent.com/TomGrobbe/appveyor-discord-webhook/master/send.ps1 -o send.ps1; ./send.ps1 start $env:WEBHOOK_URL; rm send.ps1;} + description: "MenuAPI release, version $(VERSION_NAME). For info check the [docs](https://docs.vespura.com/mapi) or checkout the recent commits on GitHub (the latter is your best bet if you want updated info about this version)." after_deploy: - - ps: if($env:APPVEYOR_REPO_TAG -eq $True) {Invoke-RestMethod https://raw.githubusercontent.com/TomGrobbe/appveyor-discord-webhook/master/send.ps1 -o send.ps1; ./send.ps1 deploy $env:WEBHOOK_URL; rm send.ps1;} + - cmd: curl -H "Content-Type:application/json" -X POST -d "{\"content\":\"^<^@^&540562517806809109^>\",\"embeds\":[{\"title\":\"%APPVEYOR_PROJECT_NAME% (%VERSION_NAME%-%GAME%)\",\"description\":\"A new version of %APPVEYOR_PROJECT_NAME% (**%VERSION_NAME%** for _%GAME%_) is available!\",\"url\":\"https://ci.appveyor.com/project/%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_SLUG%/builds/%APPVEYOR_BUILD_ID%\",\"color\":3048181,\"author\":{\"name\":\"%APPVEYOR_ACCOUNT_NAME%\",\"url\":\"https://github.com/%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_NAME%/releases/\"}}]}" -F "file=@MenuAPI-%VERSION_NAME%-%GAME%.zip" %WEBHOOK_URL% on_success: - - ps: Invoke-RestMethod https://raw.githubusercontent.com/TomGrobbe/appveyor-discord-webhook/master/send.ps1 -o send.ps1 - - ps: ./send.ps1 success $env:WEBHOOK_URL - - ps: rm send.ps1 + - cmd: curl -H "Content-Type:application/json" -X POST -d "{\"embeds\":[{\"title\":\"%APPVEYOR_PROJECT_NAME% (%VERSION_NAME%-%GAME%)\",\"description\":\"**Build passed!**\",\"url\":\"https://ci.appveyor.com/project/%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_SLUG%/builds/%APPVEYOR_BUILD_ID%\",\"color\":4502298,\"author\":{\"name\":\"%APPVEYOR_ACCOUNT_NAME%\",\"url\":\"https://github.com/%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_NAME%/\"}}]}" %WEBHOOK_URL% on_failure: - - ps: Invoke-RestMethod https://raw.githubusercontent.com/TomGrobbe/appveyor-discord-webhook/master/send.ps1 -o send.ps1 - - ps: ./send.ps1 failure $env:WEBHOOK_URL - - ps: rm send.ps1 \ No newline at end of file + - cmd: curl -H "Content-Type:application/json" -X POST -d "{\"embeds\":[{\"title\":\"%APPVEYOR_PROJECT_NAME% (%VERSION_NAME%-%GAME%)\",\"description\":\"**Build failed!**\",\"url\":\"https://ci.appveyor.com/project/%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_SLUG%/builds/%APPVEYOR_BUILD_ID%\",\"color\":13632027,\"author\":{\"name\":\"%APPVEYOR_ACCOUNT_NAME%\",\"url\":\"https://github.com/%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_NAME%/\"}}]}" %WEBHOOK_URL% \ No newline at end of file diff --git a/dependencies/RedM/CitizenFX.Core.dll b/dependencies/RedM/CitizenFX.Core.dll new file mode 100644 index 0000000..14b40ee Binary files /dev/null and b/dependencies/RedM/CitizenFX.Core.dll differ diff --git a/shared/RedM/Controls.cs b/shared/RedM/Controls.cs new file mode 100644 index 0000000..ca8148a --- /dev/null +++ b/shared/RedM/Controls.cs @@ -0,0 +1,781 @@ +#if REDM +namespace CitizenFX.Core +{ + public enum Control : uint + { + NextCamera = 0x7F8D09B8, + LookLr = 0xA987235F, + LookUd = 0xD2047988, + LookUpOnly = 0xC0651D40, + LookDownOnly = 0x8ED92E16, + LookLeftOnly = 0x08F8BC6D, + LookRightOnly = 0xA1EB1353, + CinematicSlowmo = 0x7A9093DE, + RadialMenuNavUd = 0xBA60039F, + RadialMenuNavLr = 0x390948DC, + RadialMenuSlotNavNext = 0xE71F89B8, + RadialMenuSlotNavPrev = 0x93D6723F, + SelectNextWheel = 0x77E56FB3, + SelectItemWheel = 0x1F6D95E5, + QuickSelectInspect = 0xF09866F3, + QuickSelectSetForSwap = 0xD45EC04F, + QuickShortcutAbilitiesMenu = 0x9CC7A1A4, + QuickSelectSecondaryNavNext = 0xF1421CF5, + QuickSelectSecondaryNavPrev = 0xD9F9F017, + QuickSelectToggleShortcutItem = 0xFA0B29CD, + QuickSelectPutAwayRod = 0x253FEC09, + EmotesFavorite = 0xA835261B, + EmotesManage = 0x7E75F4DC, + EmotesSlotNavNext = 0xCBB12F87, + SelectNextWeapon = 0xD0842EDF, + SelectPrevWeapon = 0xF78D7337, + SkipCutscene = 0xCDC4E4E9, + CharacterWheel = 0x972F8D1E, + MultiplayerInfo = 0xE8342FF2, + Sprint = 0x8FFC75D6, + Jump = 0xD9D0E1C0, + Enter = 0xCEFD9220, + Attack = 0x07CE1E61, + Aim = 0xF84FA74F, + LookBehind = 0x9959A6F0, + Phone = 0x4CF871D0, + SpecialAbility = 0xCEE12B50, + SpecialAbilitySecondary = 0x6328239B, + SecondarySpecialAbilitySecondary = 0x811F4A1A, + SpecialAbilityAction = 0x1ECA87D4, + MoveLr = 0x4D8FB4C1, + MoveUd = 0xFDA83190, + MoveUpOnly = 0x8FD015D8, + MoveDownOnly = 0xD27782E3, + MoveLeftOnly = 0x7065027D, + MoveRightOnly = 0xB4E465B4, + Duck = 0xDB096B85, + TwirlPistol = 0x938D4071, + ToggleHolster = 0xB238FE0B, + OpenWheelMenu = 0xAC4BD4F1, + OpenSatchelMenu = 0x4CC0E2FE, + OpenSatchelHorseMenu = 0x5966D52A, + OpenCraftingMenu = 0x734C6E39, + OpenJournal = 0xF3830D8E, + Pickup = 0xE6360A8E, + Ignite = 0xC75C27B0, + SniperZoom = 0x7ABC6A66, + SniperZoomInOnly = 0xA5BDCD3C, + SniperZoomOutOnly = 0x430593AA, + SniperZoomInSecondary = 0x6BE9C207, + SniperZoomOutSecondary = 0x8A7B8833, + ToggleWeaponScope = 0x3076E97C, + Cover = 0xDE794E3E, + CoverTransition = 0x750C8010, + Reload = 0xE30CD707, + Talk = 0x7DCA9C75, + Detonate = 0x73846677, + HudSpecial = 0x580C4473, + Arrest = 0xA4F1006B, + AccurateAim = 0x406ADFAE, + SwitchShoulder = 0x827E9EE8, + IronSight = 0x841240A9, + AimInAir = 0xD8F73058, + SwitchFiringMode = 0xEED15F18, + Context = 0xB73BCA77, + ContextSecondary = 0xF19BE385, + WeaponSpecial = 0x733901F3, + WeaponSpecialTwo = 0x50BA1A77, + Dive = 0x06052D11, + DropWeapon = 0x7DBCD016, + DropAmmo = 0x4E42696E, + ThrowGrenade = 0x0AF99998, + FocusCam = 0xE72B43F4, + Inspect = 0xA61DC630, + InspectZoom = 0x53296B75, + InspectLr = 0x1788C283, + InspectUd = 0xF9781997, + InspectOpenSatchel = 0x9B1CA8DA, + DynamicScenario = 0x2EAB0795, + PlayerMenu = 0x80F28E95, + OpenEmoteWheel = 0xE2B557A3, + OpenEmoteWheelHorse = 0x8B3FA65E, + EmoteGroupLink = 0x1C826362, + EmoteGroupLinkHorse = 0x4FD1C57B, + RevealHud = 0xCF8A4ECA, + SelectRadarMode = 0x0F39B3D4, + SimpleRadar = 0x5FEF1B6D, + ExpandRadar = 0xCF0B11DE, + RegularRadar = 0x51AA7A35, + DisableRadar = 0x70CBD78D, + Surrender = 0xDB8D69B8, + Whistle = 0x24978A28, + WhistleHorseback = 0xE7EB9185, + StopLeadingAnimal = 0x7914A3DD, + CinematicCam = 0x620A6C5E, + CinematicCamHold = 0xD7E7B375, + CinematicCamChangeShot = 0xA6C67243, + CinematicCamUd = 0x84574AE8, + CinematicCamUpOnly = 0xEFCFE6B7, + CinematicCamDownOnly = 0x23AE34A2, + CinematicCamLr = 0x6BC904FC, + ContextA = 0x5181713D, + ContextB = 0x3B24C470, + ContextX = 0xE3BF959B, + ContextY = 0xD51B784F, + ContextLt = 0xC13A6564, + ContextRt = 0x07B8BEAF, + ContextAction = 0xB28318C0, + VehMoveLr = 0xF1E2852C, + VehMoveUd = 0x8A81C00C, + VehMoveUpOnly = 0xDEBD7EF6, + VehMoveDownOnly = 0x16D73E1D, + VehMoveLeftOnly = 0x9DF54706, + VehMoveRightOnly = 0x97A8FD98, + VehSpecial = 0x493919DB, + VehGunLr = 0xB6F3E4FE, + VehGunUd = 0x482560EE, + VehAim = 0xD7CAFCEF, + VehAttack = 0xF4330038, + VehAttack2 = 0xF1C341BA, + VehAccelerate = 0x5B9FD4E2, + VehBrake = 0x6E1F639B, + VehDuck = 0x5B3690F2, + VehHeadlight = 0xF1301666, + VehExit = 0xFEFAB9B4, + VehHandbrake = 0x65D24C98, + VehLookBehind = 0xCAE9B017, + VehNextRadio = 0x22E0F7E7, + VehPrevRadio = 0x9785CE13, + VehNextRadioTrack = 0xF7FA2DDC, + VehPrevRadioTrack = 0x0A94C4FF, + VehRadioWheel = 0x4915AC0A, + VehHorn = 0x63A0D258, + VehFlyThrottleUp = 0x7232BAB3, + VehFlyThrottleDown = 0x084DFF95, + VehFlyYawLeft = 0x31589AD1, + VehFlyYawRight = 0xBD143FC6, + VehPassengerAim = 0xEE2804D0, + VehPassengerAttack = 0x27AD4433, + VehSpecialAbilityFranklin = 0x5EC33578, + VehStuntUd = 0x4AA1560E, + VehSelectNextWeapon = 0x889A626F, + VehSelectPrevWeapon = 0x0C97BAC7, + VehRoof = 0x3E7CF9A4, + VehJump = 0xAA56B926, + VehGrapplingHook = 0xB985AA5E, + VehShuffle = 0xC7083798, + VehTraversal = 0x739D6261, + VehDropProjectile = 0xC61611E6, + VehMouseControlOverride = 0x39CCABD5, + VehFlyRollLr = 0x3C8AB570, + VehFlyRollLeftOnly = 0x56F84EA0, + VehFlyRollRightOnly = 0x876B3361, + VehFlyPitchUd = 0xE67E1E57, + VehFlyPitchUpOnly = 0x6280BA1A, + VehFlyPitchDownOnly = 0x0F4E369F, + VehFlyUndercarriage = 0xFE0FE518, + VehFlyAttack = 0x1D71D7AA, + VehFlySelectNextWeapon = 0x24E94299, + VehFlySelectPrevWeapon = 0xC0D874E5, + VehFlySelectTargetLeft = 0x307FC4C1, + VehFlySelectTargetRight = 0x52F25C96, + VehFlyVerticalFlightMode = 0xE3238029, + VehFlyDuck = 0x378A10F7, + VehFlyAttackCamera = 0x2FBA3F0B, + VehFlyMouseControlOverride = 0x6C9810A5, + VehSubMouseControlOverride = 0x2CAF327E, + VehSubTurnLr = 0x627C4619, + VehSubTurnLeftOnly = 0x44E7E093, + VehSubTurnRightOnly = 0xE78A5A3C, + VehSubPitchUd = 0x469CE271, + VehSubPitchUpOnly = 0xF9EF072A, + VehSubPitchDownOnly = 0xBA2D22AA, + VehSubThrottleUp = 0xD28C446F, + VehSubThrottleDown = 0xF5B2CEFB, + VehSubAscend = 0xD7991F74, + VehSubDescend = 0x7D51DE24, + VehSubTurnHardLeft = 0x64214D49, + VehSubTurnHardRight = 0xA44C0F83, + VehPushbikePedal = 0xFD8D64A7, + VehPushbikeSprint = 0xF03EE151, + VehPushbikeFrontBrake = 0x585E942D, + VehPushbikeRearBrake = 0xF8CBAFB5, + VehDraftMoveUd = 0x23595CEA, + VehDraftTurnLr = 0xA7DFAE8A, + VehDraftMoveUpOnly = 0x29A5E51E, + VehDraftMoveDownOnly = 0x25493EB3, + VehDraftTurnLeftOnly = 0x198AFC64, + VehDraftTurnRightOnly = 0x5E371EA7, + VehDraftAccelerate = 0xE99D2B05, + VehDraftBrake = 0xD648E48D, + VehDraftAim = 0xBDD5830D, + VehDraftAttack = 0xF40AB198, + VehDraftAttack2 = 0x886F12DD, + VehDraftSwitchDrivers = 0x70B87844, + VehBoatTurnLr = 0xD8DFCAB3, + VehBoatTurnLeftOnly = 0x5BED7C91, + VehBoatTurnRightOnly = 0xF9780DFB, + VehBoatAccelerate = 0xB341E812, + VehBoatBrake = 0x428D5F39, + VehBoatAim = 0x92F5F01E, + VehBoatAttack = 0x6866FA3A, + VehBoatAttack2 = 0x876096E9, + VehCarTurnLr = 0x3BD38D43, + VehCarTurnLeftOnly = 0x07D1654C, + VehCarTurnRightOnly = 0x6E3C3649, + VehCarAccelerate = 0xB9F544B0, + VehCarBrake = 0xD1887B3F, + VehCarAim = 0x6777B840, + VehCarAttack = 0x5572F386, + VehCarAttack2 = 0x5B763AD7, + VehHandcartAccelerate = 0xFF3626FC, + VehHandcartBrake = 0x2D79D80A, + HorseMoveLr = 0x126796EB, + HorseMoveUd = 0x3BBDEFEF, + HorseMoveUpOnly = 0x699487BB, + HorseMoveDownOnly = 0x56F82045, + HorseMoveLeftOnly = 0x86D773F6, + HorseMoveRightOnly = 0x7E6B8612, + HorseSpecial = 0x70089459, + HorseGunLr = 0x3D99EEC6, + HorseGunUd = 0xBFF476F9, + HorseAttack = 0x60C81CDE, + HorseAttack2 = 0xC904196D, + HorseSprint = 0x5AA007D7, + HorseStop = 0xE16B9AAD, + HorseExit = 0xCBDB82A8, + HorseLookBehind = 0x81280569, + HorseJump = 0xE4D2CE1D, + HorseAim = 0x61470051, + HorseCollect = 0x7D5B3717, + HitchAnimal = 0xA95E1468, + HorseCommandFlee = 0x4216AF06, + HorseCommandStay = 0xAE5DFDED, + HorseCommandFollow = 0x763E4D27, + HorseMelee = 0x1A3EABBB, + MeleeHorseAttackPrimary = 0x78ED2132, + MeleeHorseAttackSecondary = 0x162AFEB8, + HorseCoverTransition = 0x2996DD15, + MeleeAttack = 0xB2F377E8, + MeleeModifier = 0x1E7D7275, + MeleeBlock = 0xB5EEEFB7, + MeleeGrapple = 0x2277FAE9, + MeleeGrappleAttack = 0xADEAF48C, + MeleeGrappleChoke = 0x018C47CF, + MeleeGrappleReversal = 0x91C9A817, + MeleeGrappleBreakout = 0xD0C1FEFF, + MeleeGrappleStandSwitch = 0xBE1F4699, + MeleeGrappleMountSwitch = 0x67ED272E, + ParachuteDeploy = 0xEBF53058, + ParachuteDetach = 0xFFBFF139, + ParachuteTurnLr = 0x8EC920BF, + ParachuteTurnLeftOnly = 0xC4CF3322, + ParachuteTurnRightOnly = 0x2BDBA378, + ParachutePitchUd = 0xF0526228, + ParachutePitchUpOnly = 0x08BFEA69, + ParachutePitchDownOnly = 0x7C3A4352, + ParachuteBrakeLeft = 0x272BD8BA, + ParachuteBrakeRight = 0x948B3EA7, + ParachuteSmoke = 0x2574FAB0, + ParachutePrecisionLanding = 0xC675B8BD, + Map = 0xE31C6A41, + SelectWeaponUnarmed = 0x1F6EEB0F, + SelectWeaponMelee = 0x109E6852, + SelectWeaponHandgun = 0x184960E3, + SelectWeaponShotgun = 0x76D3EA05, + SelectWeaponSmg = 0xCEF1BB48, + SelectWeaponAutoRifle = 0x05EEA9D0, + SelectWeaponSniper = 0x96C61FDF, + SelectWeaponHeavy = 0x3D1675C3, + SelectWeaponSpecial = 0xC41ECEF8, + SelectCharacterMichael = 0xEA9256B8, + SelectCharacterFranklin = 0x8E8B08CB, + SelectCharacterTrevor = 0xB00CC093, + SelectCharacterMultiplayer = 0xDFB2B3B8, + SaveReplayClip = 0x5B3AF9E3, + SpecialAbilityPc = 0x52E60A8B, + SelectQuickselectSidearmsLeft = 0xE6F612E4, + SelectQuickselectDualwield = 0x1CE6D9EB, + SelectQuickselectSidearmsRight = 0x4F49CC4C, + SelectQuickselectUnarmed = 0x8F9F9E58, + SelectQuickselectMeleeNoUnarmed = 0xAB62E997, + SelectQuickselectSecondaryLongarm = 0xA1FDE2A6, + SelectQuickselectThrown = 0xB03A913B, + SelectQuickselectPrimaryLongarm = 0x42385422, + CellphoneUp = 0xD2EE3B1E, + CellphoneDown = 0x82196002, + CellphoneLeft = 0x3ABBE990, + CellphoneRight = 0xD25EFDCD, + CellphoneSelect = 0xDC264018, + CellphoneCancel = 0xDD833287, + CellphoneOption = 0xD2C28BB4, + CellphoneExtraOption = 0xBE354011, + CellphoneScrollForward = 0xCB4E1798, + CellphoneScrollBackward = 0x47CD0F3B, + CellphoneCameraFocusLock = 0x5AC1805E, + CellphoneCameraGrid = 0xE18CC57A, + CellphoneCameraSelfie = 0x6A440BFE, + CellphoneCameraDof = 0x593DB489, + CellphoneCameraExpression = 0xD7E274E7, + FrontendDown = 0x05CA7C52, + FrontendUp = 0x6319DB71, + FrontendLeft = 0xA65EBAB4, + FrontendRight = 0xDEB34313, + FrontendRdown = 0x5734A944, + FrontendRup = 0xD7DE6B1E, + FrontendRleft = 0x39336A4F, + FrontendRright = 0x5B48F938, + FrontendAxisX = 0xFB56DD5B, + FrontendAxisY = 0x091178D0, + FrontendScrollAxisX = 0x3224BC55, + FrontendScrollAxisY = 0x21651AD6, + FrontendRightAxisX = 0x3D23549A, + FrontendRightAxisY = 0xEB4130DF, + FrontendPause = 0xD82E0BD2, + FrontendPauseAlternate = 0x4A903C11, + FrontendAccept = 0xC7B5340A, + FrontendCancel = 0x156F7119, + FrontendX = 0x6DB8C62F, + FrontendY = 0x7C0162C0, + FrontendLb = 0xE885EF16, + FrontendRb = 0x17BEC168, + FrontendLt = 0x51104035, + FrontendRt = 0x6FED71BC, + FrontendLs = 0x43CDA5B0, + FrontendRs = 0x7DA48D2A, + FrontendLeaderboard = 0x9EDC8D65, + FrontendSocialClub = 0x064D1698, + FrontendSocialClubSecondary = 0xBDB8D6F3, + FrontendDelete = 0x4AF4D473, + FrontendEndscreenAccept = 0x3E32FCEE, + FrontendEndscreenExpand = 0xC79BDE9F, + FrontendSelect = 0x171910DC, + FrontendPhotoMode = 0x44CD301B, + FrontendNavUp = 0x8CFFE0A1, + FrontendNavDown = 0x78114AB3, + FrontendNavLeft = 0x877F1027, + FrontendNavRight = 0x08BD758C, + FrontendMapNavUp = 0x125A70E5, + FrontendMapNavDown = 0xF8480EED, + FrontendMapNavLeft = 0xE0D75B00, + FrontendMapNavRight = 0x28725E5D, + FrontendMapZoom = 0x6B359A27, + GameMenuAccept = 0x43DBF61F, + GameMenuCancel = 0x308588E6, + GameMenuOption = 0xFBD7B3E6, + GameMenuExtraOption = 0xD596CFB0, + GameMenuUp = 0x911CB09E, + GameMenuDown = 0x4403F97F, + GameMenuLeft = 0xAD7FCC5B, + GameMenuRight = 0x65F9EC5B, + GameMenuTabLeft = 0xCBD5B26E, + GameMenuTabRight = 0x110AD1D2, + GameMenuTabLeftSecondary = 0x26E9DC00, + GameMenuTabRightSecondary = 0x8CC9CD42, + GameMenuScrollForward = 0x81457A1A, + GameMenuScrollBackward = 0x9DA42644, + GameMenuStickUp = 0x9CA97399, + GameMenuStickDown = 0x63898D36, + GameMenuStickLeft = 0x06C089D4, + GameMenuStickRight = 0x5BDBE841, + GameMenuRightStickUp = 0xF0232A03, + GameMenuRightStickDown = 0xADB78673, + GameMenuRightStickLeft = 0x71E38966, + GameMenuRightStickRight = 0xE1CECE4B, + GameMenuLs = 0xA8F6DE66, + GameMenuRs = 0x89EA3FA5, + GameMenuRightAxisX = 0x4685AA33, + GameMenuRightAxisY = 0x60C65EB4, + GameMenuLeftAxisX = 0xF431D57A, + GameMenuLeftAxisY = 0x226EB1EF, + Quit = 0x8E90C7BB, + DocumentPageNext = 0xC97792B7, + DocumentPagePrev = 0x20190AB4, + DocumentScroll = 0xAC70F311, + DocumentScrollUpOnly = 0x3D0C19EC, + DocumentScrollDownOnly = 0xD72F3E29, + Attack2 = 0x0283C582, + PrevWeapon = 0xCC1075A7, + NextWeapon = 0xFD0F0C2C, + SniperZoomIn = 0xE4568AA1, + SniperZoomOut = 0xE40CE39E, + SniperZoomInAlternate = 0x3A9897C1, + SniperZoomOutAlternate = 0xBC820489, + ReplayStartStopRecording = 0xDCA6978E, + ReplayStartStopRecordingSecondary = 0x8991A70B, + ReplayMarkerDelete = 0xC7D2C51B, + ReplayClipDelete = 0xF6734E42, + ReplayPause = 0x083137B2, + ReplayRewind = 0xC1339A31, + ReplayFfwd = 0x609A27E8, + ReplayNewmarker = 0xF7C6DA28, + ReplayRecord = 0xAD9A9C7C, + ReplayScreenshot = 0x567FAF34, + ReplayHidehud = 0x7E479C7B, + ReplayStartpoint = 0x5DAFACCF, + ReplayEndpoint = 0x4EF75BBD, + ReplayAdvance = 0x323AA450, + ReplayBack = 0x088C7CD4, + ReplayTools = 0x561A3387, + ReplayRestart = 0x81B8BC9D, + ReplayShowhotkey = 0xEBA2A41E, + ReplayCyclemarkerleft = 0x5C220959, + ReplayCyclemarkerright = 0xC69AE799, + ReplayFovincrease = 0x5925A10D, + ReplayFovdecrease = 0x2B88D701, + ReplayCameraup = 0x749EFF0C, + ReplayCameradown = 0xA1FE9E2A, + ReplaySave = 0xEBC60685, + ReplayToggletime = 0xE3FB91B3, + ReplayToggletips = 0xC8A1DE20, + ReplayPreview = 0x58AC1355, + ReplayToggleTimeline = 0xF8629909, + ReplayTimelinePickupClip = 0xD2454F90, + ReplayTimelineDuplicateClip = 0x4146A033, + ReplayTimelinePlaceClip = 0x60726F50, + ReplayCtrl = 0xD88B47E7, + ReplayTimelineSave = 0x65D70E9D, + ReplayPreviewAudio = 0x79022218, + ReplayActionReplayStart = 0xD9961107, + ReplayActionReplayCancel = 0x93776CAE, + ReplayRecordingStart = 0xFD28D0F4, + ReplayRecordingStop = 0xDB16E702, + ReplaySaveSnapshot = 0xEFEC8FDE, + VehDriveLook = 0xA2117C9A, + VehDriveLook2 = 0x55AC04E5, + VehFlyAttack2 = 0x4D83147C, + RadioWheelUd = 0x14C7291D, + RadioWheelLr = 0xF9FA6BC8, + VehSlowmoUd = 0xF1F9CD26, + VehSlowmoUpOnly = 0x2B981F4F, + VehSlowmoDownOnly = 0x642DE054, + MapPoi = 0x9BEE9213, + InteractLockon = 0xF8982F00, + InteractLockonNeg = 0x26A18F47, + InteractLockonPos = 0xF63A17F9, + InteractLockonRob = 0x9FA5AD07, + InteractLockonY = 0x09A92B8B, + InteractLockonA = 0xD10A3A36, + InteractNeg = 0x424BD2D2, + InteractPos = 0xF6BB7378, + InteractOption1 = 0x760A9C6F, + InteractOption2 = 0x84543902, + InteractAnimal = 0xA1ABB953, + InteractLockonAnimal = 0x5415BE48, + InteractLeadAnimal = 0x17D3BFF5, + InteractLockonDetachHorse = 0xF5C4701B, + InteractHorseCare = 0xB0BCE5D6, + InteractLockonCallAnimal = 0x71F89BBC, + InteractLockonTrackAnimal = 0xE2473BF0, + InteractLockonTargetInfo = 0x31219490, + InteractLockonStudyBinoculars = 0xB3F388BC, + InteractWildAnimal = 0x89F3D2E0, + InteractHorseFeed = 0x0D55A0F0, + InteractHorseBrush = 0x63A38F2C, + EmoteAction = 0x13C42BB2, + EmoteTaunt = 0x470DC190, + EmoteGreet = 0x72BAD5AA, + EmoteComm = 0x661857B3, + EmoteDance = 0xF311100C, + EmoteTwirlGunHold = 0x04FB8191, + EmoteTwirlGunVarA = 0x6990BDDF, + EmoteTwirlGunVarB = 0x52D29063, + EmoteTwirlGunVarC = 0xBC2AE312, + EmoteTwirlGunVarD = 0xAE69478F, + QuickEquipItem = 0x6070D032, + MinigameBuildingCameraNext = 0x16B0EEF8, + MinigameBuildingCameraPrev = 0x5F97B231, + MinigameBuildingHammer = 0xFA91AECD, + CursorAcceptDoubleClick = 0x1C559F2E, + CursorAcceptHold = 0xE474F150, + CursorAccept = 0x9D2AEA88, + CursorCancel = 0x27568539, + CursorCancelDoubleClick = 0x9CB4ECCE, + CursorCancelHold = 0xD7F70F36, + CursorX = 0xD6C4ECDC, + CursorY = 0xE4130778, + CursorScrollUp = 0x62800C92, + CursorScrollDown = 0x8BDE7443, + CursorScrollClick = 0x6AA8A71B, + CursorScrollDoubleClick = 0xE1B6ED6D, + CursorScrollHold = 0x5484DBDD, + CursorForwardClick = 0x11DBBAB9, + CursorForwardDoubleClick = 0x9805D715, + CursorForwardHold = 0x7630C9A1, + CursorBackwardClick = 0x9AF38793, + CursorBackwardDoubleClick = 0xA14BA1FC, + CursorBackwardHold = 0x01AA9FA1, + EnterCheatCode = 0x7BF65AC8, + InteractionMenu = 0xCC510E59, + MpTextChatAll = 0x9720FCEE, + MpTextChatTeam = 0x9098AD9D, + MpTextChatFriends = 0x7098AC73, + MpTextChatCrew = 0x8142FA92, + PushToTalk = 0x4BC9DABB, + CreatorLs = 0x339F3730, + CreatorRs = 0xD8CF0C95, + CreatorLt = 0x446258B6, + CreatorRt = 0x3C3DD371, + CreatorMenuToggle = 0x85D24405, + CreatorAccept = 0x2CD5343E, + CreatorMenuUp = 0xBCD1444B, + CreatorMenuDown = 0x97410755, + CreatorMenuLeft = 0xEC6A30AA, + CreatorMenuRight = 0x19D8334C, + CreatorMenuAccept = 0xFB9C3231, + CreatorMenuCancel = 0xBB3FC460, + CreatorMenuFunction = 0x5A03B3F3, + CreatorMenuExtraFunction = 0xE6B8F103, + CreatorMenuSelect = 0x0984E40A, + CreatorPlace = 0xD74CACAD, + CreatorDelete = 0x3F4DC0EF, + CreatorDrop = 0x414034D5, + CreatorFunction = 0xB05FDA25, + CreatorRotateRight = 0x9D75674E, + CreatorRotateLeft = 0xD41E9C2A, + CreatorGrab = 0x338A0D45, + CreatorSwitchCam = 0x16CCFEC6, + CreatorZoomIn = 0x335D8D76, + CreatorZoomOut = 0x24A42F93, + CreatorRaise = 0x0D0FB9B1, + CreatorLower = 0x1BDE2EB3, + CreatorSearch = 0xF55864CD, + CreatorMoveUd = 0x82428676, + CreatorMoveLr = 0x59753EDC, + CreatorLookUd = 0x55EA24F3, + CreatorLookLr = 0xAEB2A9C7, + CutFree = 0xD2CC4644, + Drop = 0xD2928083, + PickupCarriable = 0xEB2AC491, + PickupCarriable2 = 0xBE8593AF, + PlaceCarriableOntoParent = 0x7D326951, + PickupCarriableFromParent = 0xA1202C7B, + MercyKill = 0x956C2A0E, + Revive = 0x43F2959C, + Hogtie = 0xD9C50532, + CarriableSuicide = 0x6E9734E8, + CarriableBreakFree = 0x295175BF, + InteractHitCarriable = 0x0522B243, + Loot = 0x41AC83D1, + Loot2 = 0x399C6619, + Loot3 = 0x27D1C284, + LootVehicle = 0x14DB6C5E, + LootAmmo = 0xC23D7B9E, + BreakVehicleLock = 0x97C71B28, + LootAliveComponent = 0xFF8109D8, + FeedInteract = 0xA8E3F467, + SaddleTransfer = 0x73A8FD83, + ShopBuy = 0xDFF812F9, + ShopSell = 0x6D1319BE, + ShopSpecial = 0xEA150E72, + ShopBounty = 0xD3ECF82F, + ShopInspect = 0x5E723D8C, + ShopChangeCurrency = 0x90FA19AB, + QuickUseItem = 0xC1989F95, + PromptPageNext = 0x8CF90A9D, + FrontendTouchZoomFactor = 0xE7F89C38, + FrontendTouchZoomX = 0x16661AD0, + FrontendTouchZoomY = 0x253DB87F, + FrontendTouchDragX = 0xEC93548E, + FrontendTouchDragY = 0x9AC130EB, + FrontendTouchTapX = 0xC10E180A, + FrontendTouchTapY = 0xCF4B3484, + FrontendTouchDoubleTapX = 0x1661FAB0, + FrontendTouchDoubleTapY = 0x96E87BBF, + FrontendTouchHoldX = 0x0FF17F1D, + FrontendTouchHoldY = 0x398ED257, + FrontendTouchSwipeUpX = 0x0B71D439, + FrontendTouchSwipeUpY = 0x19CA70EA, + FrontendTouchSwipeDownX = 0xE3B30955, + FrontendTouchSwipeDownY = 0xBDFF3DEA, + FrontendTouchSwipeLeftX = 0x2545B0DE, + FrontendTouchSwipeLeftY = 0xD43D0ECE, + FrontendTouchSwipeRightX = 0xEAB68397, + FrontendTouchSwipeRightY = 0x675B7CE3, + MultiplayerInfoPlayers = 0x9C68CE34, + MultiplayerDeadSwitchRespawn = 0xB4F298BA, + MultiplayerDeadInformLaw = 0x6816A38E, + MultiplayerDeadRespawn = 0x18987353, + MultiplayerDeadDuel = 0xF875FC78, + MultiplayerDeadParley = 0x4D11FE01, + MultiplayerDeadFeud = 0xB4A11066, + MultiplayerDeadLeaderFeud = 0xCC18F960, + MultiplayerDeadPressCharges = 0xE50DCA13, + MultiplayerRaceRespawn = 0x014CA044, + MultiplayerPredatorAbility = 0xC5CF41B2, + MultiplayerSpectatePlayerNext = 0xBA065692, + MultiplayerSpectatePlayerPrev = 0x5092BF47, + MultiplayerSpectateHideHud = 0x7DBA5D49, + MultiplayerSpectatePlayerOptions = 0x4E074EE6, + MultiplayerLeaderboardScrollUd = 0xA917D24B, + MinigameQuit = 0xE9094BA0, + MinigameIncreaseBet = 0xC7CB8D5F, + MinigameDecreaseBet = 0xD3EBF425, + MinigameChangeBetAxisY = 0xBDC733EE, + MinigamePlaceBet = 0x410B0B2E, + MinigameClearBet = 0x4A21C66B, + MinigameHelp = 0x9384E0A8, + MinigameHelpPrev = 0xC5F53156, + MinigameHelpNext = 0x83608AC0, + MinigameReplay = 0x985243B7, + MinigameNewGame = 0x5D1788FF, + MinigamePokerSkip = 0x646A7792, + MinigamePokerCall = 0xDAB9EE72, + MinigamePokerFold = 0x49B4AD1E, + MinigamePokerCheck = 0x206B2087, + MinigamePokerCheckFold = 0x72A9D1F7, + MinigamePokerBet = 0xA9883369, + MinigamePokerHoleCards = 0xC2B1193A, + MinigamePokerBoardCards = 0x03753498, + MinigamePokerSkipTutorial = 0xB568BCD0, + MinigamePokerShowPossibleHands = 0x7765B9D4, + MinigamePokerYourCards = 0xF923B337, + MinigamePokerCommunityCards = 0xE402B898, + MinigamePokerCheatLr = 0x2330F517, + MinigameFishingResetCast = 0xB40A9BDB, + MinigameFishingReleaseFish = 0xF14FD435, + MinigameFishingKeepFish = 0x52C5C34A, + MinigameFishingHook = 0xA1CD103A, + MinigameFishingLeftAxisX = 0x69B10623, + MinigameFishingLeftAxisY = 0x09BF4645, + MinigameFishingRightAxisX = 0x4FD4E558, + MinigameFishingRightAxisY = 0x95F2F193, + MinigameFishingLeanLeft = 0x0D4C3ABA, + MinigameFishingLeanRight = 0x05074A9B, + MinigameFishingQuickEquip = 0x25F525CD, + MinigameFishingReelSpeedUp = 0x2FA915F5, + MinigameFishingReelSpeedDown = 0xD7AF56A0, + MinigameFishingReelSpeedAxis = 0x49C73CB2, + MinigameFishingManualReelIn = 0xA303F462, + MinigameFishingManualReelOutModifier = 0x4556642C, + MinigameCrackpotBoatShowControls = 0x524C3787, + MinigameDominoesViewDominoes = 0x88F8B6B1, + MinigameDominoesViewMoves = 0x7733CF2C, + MinigameDominoesPlayTile = 0x95F5BB7C, + MinigameDominoesSkipDeal = 0xC5E622D7, + MinigameDominoesMoveLeftOnly = 0xFDDD89D4, + MinigameDominoesMoveRightOnly = 0x7D5187C9, + MinigameDominoesMoveUpOnly = 0xC6AB8CB3, + MinigameDominoesMoveDownOnly = 0xFD9FC86D, + MinigameBlackjackHandView = 0x03F1E7CB, + MinigameBlackjackTableView = 0xADE09435, + MinigameBlackjackBetAxisY = 0x3D2EA092, + MinigameBlackjackBet = 0x661D8A31, + MinigameBlackjackDecline = 0xCD7DDF9B, + MinigameBlackjackStand = 0x31260507, + MinigameBlackjackHit = 0xA8142713, + MinigameBlackjackDouble = 0x74486CA4, + MinigameBlackjackSplit = 0x432B111F, + MinigameFffA = 0x0E717DC6, + MinigameFffB = 0x1BC81873, + MinigameFffX = 0x65F0ACDF, + MinigameFffY = 0x73AD4858, + MinigameFffZoom = 0x61E4CACC, + MinigameFffSkipTurn = 0x3073681B, + MinigameFffCycleSequenceLeft = 0x29A3550E, + MinigameFffCycleSequenceRight = 0x7B5B896D, + MinigameFffFlourishContinue = 0x6FC9DE68, + MinigameFffFlourishEnd = 0xF7750B25, + MinigameFffPractice = 0xCA379F82, + MinigameMilkingLeftAction = 0xFF4B2ADA, + MinigameMilkingRightAction = 0x30BE7CF2, + MinigameLeftTrigger = 0x7EC33553, + MinigameRightTrigger = 0xBE78B715, + MinigameActionLeft = 0x0A1EFC09, + MinigameActionRight = 0x16D70379, + MinigameActionUp = 0xF5A13A0D, + MinigameActionDown = 0xF601BCFC, + StickyFeedAccept = 0xF4DD4C67, + StickyFeedCancel = 0x0CFB963F, + StickyFeedX = 0xBD1D94A1, + StickyFeedY = 0xC85BAB1D, + CameraPutAway = 0x5FC770EA, + CameraBack = 0xA4BD74A5, + CameraTakePhoto = 0x44FA14C2, + CameraContextGallery = 0xE8337356, + CameraHandheldUse = 0x776F65E9, + CameraDof = 0x3003F9DC, + CameraSelfie = 0xAC5922EA, + CameraZoom = 0x47EC4C22, + CameraPoseNext = 0xF810FB35, + CameraPosePrev = 0x8D5BE9D1, + CameraExpressionNext = 0xCFA703D3, + CameraExpressionPrev = 0x07B6435D, + TithingIncreaseAmount = 0x24F37AB5, + TithingDecreaseAmount = 0xCEFF5C13, + BreakDoorLock = 0x77110B0A, + InterrogateQuestion = 0xA1AA2D8D, + InterrogateBeat = 0x6E1E0D62, + InterrogateKill = 0x81B2E311, + InterrogateRelease = 0x3C22EF0E, + CampBedInspect = 0xC67E13BB, + PcFreeLook = 0x8AAA0AD4, + MinigameBartenderRaiseGlass = 0xA13460F5, + MinigameBartenderRaiseBottle = 0xF0A25112, + MinigameBartenderPour = 0xCABC2460, + MinigameBartenderServe = 0xDC03B043, + PhotoMode = 0x3C0A40F2, + PhotoModePc = 0x35957F6C, + PhotoModeChangeCamera = 0x9F06B29C, + PhotoModeMoveLr = 0x4F136512, + PhotoModeMoveLeftOnly = 0x311353EB, + PhotoModeMoveRightOnly = 0x5357A7F5, + PhotoModeMoveUd = 0xEC001315, + PhotoModeMoveUpOnly = 0x315D57E6, + PhotoModeMoveDownOnly = 0x4EBCC409, + PhotoModeReset = 0xA209BD57, + PhotoModeLenseNext = 0xB138D899, + PhotoModeLensePrev = 0x06A057F8, + PhotoModeRotateLeft = 0x2EEA1D2A, + PhotoModeRotateRight = 0x96E70854, + PhotoModeToggleHud = 0x7F9055F5, + PhotoModeViewPhotos = 0xDCE96D67, + PhotoModeTakePhoto = 0xA190AAC7, + PhotoModeBack = 0x2F13EC9A, + PhotoModeSwitchMode = 0x8F32E2EB, + PhotoModeFilterIntensity = 0xFE6DD360, + PhotoModeFilterIntensityUp = 0x2286D46B, + PhotoModeFilterIntensityDown = 0xB341F407, + PhotoModeFocalLength = 0x886ABA4E, + PhotoModeFocalLengthUpOnly = 0xFAFBD66A, + PhotoModeFocalLengthDownOnly = 0x01EBFABD, + PhotoModeFilterNext = 0x699F8D08, + PhotoModeFilterPrev = 0x4F640885, + PhotoModeZoomIn = 0x5B843BC9, + PhotoModeZoomOut = 0x2354D2E6, + PhotoModeDof = 0x26B9AE6A, + PhotoModeDofUpOnly = 0x87B07940, + PhotoModeDofDownOnly = 0x047099F1, + PhotoModeExposureUp = 0xC64E2284, + PhotoModeExposureDown = 0xAD07A5A5, + PhotoModeExposureLock = 0x9DE08D71, + PhotoModeContrast = 0x483F707F, + PhotoModeContrastUpOnly = 0x5D2DD717, + PhotoModeContrastDownOnly = 0x30811620, + CraftingEat = 0xB99A9CAD, + CampSetupTent = 0x0B1BE2E8, + MinigameActionX = 0x1D927DF2, + DeprecatedAbove = 0xC1D24F92, + ScriptLeftAxisX = 0x1F8EEF84, + ScriptLeftAxisY = 0x5418D8AB, + ScriptRightAxisX = 0xA6B769E9, + ScriptRightAxisY = 0x27A5EBC0, + ScriptRup = 0x771D6E13, + ScriptRdown = 0x37933367, + ScriptRleft = 0xA4DB0458, + ScriptRright = 0x22A3B800, + ScriptLb = 0xE624C062, + ScriptRb = 0x91E9231C, + ScriptLt = 0x2B314A1E, + ScriptRt = 0x26E9CD17, + ScriptLs = 0xAADDC975, + ScriptRs = 0xD04E9FE2, + ScriptPadUp = 0x0DC15ADD, + ScriptPadDown = 0xB1DA5574, + ScriptPadLeft = 0x1AF81D9E, + ScriptPadRight = 0x82A9B758, + ScriptSelect = 0xC8722109, + ScriptedFlyUd = 0xAEB4B1DE, + ScriptedFlyLr = 0xF1111E4A, + ScriptedFlyZup = 0x639B9FC9, + ScriptedFlyZdown = 0x9C5E030C, + Count = 0x8EDFFB30, + } +} +#endif \ No newline at end of file