diff --git a/NativeUI.dll b/NativeUI.dll
index 9cbf7231..5b866a7c 100644
Binary files a/NativeUI.dll and b/NativeUI.dll differ
diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs
index afe2ce6a..d0408449 100644
--- a/vMenu/MainMenu.cs
+++ b/vMenu/MainMenu.cs
@@ -76,7 +76,8 @@ public MainMenu()
else
{
Tick += OnTick;
- Tick += ProcessMenus;
+ Tick += ProcessMainButtons;
+ Tick += ProcessDirectionalButtons;
}
}
@@ -101,7 +102,11 @@ public static void SetPermissions(dynamic dict)
permissionsSetupDone = true;
}
#endregion
-
+ #region set settings
+ ///
+ /// Sets the settings received from the server.
+ ///
+ ///
public static void SetOptions(dynamic options)
{
MenuOptions = new Dictionary();
@@ -116,19 +121,196 @@ public static void SetOptions(dynamic options)
MenuToggleKey = int.Parse(MenuOptions["menuKey"].ToString());
optionsSetupDone = true;
}
+ #endregion
+ #region Process Menu Buttons
///
- /// This has to be separated from the "draw" function to fix the fast scrolling bug.
+ /// Process the select & go back/cancel buttons.
///
///
- private async Task ProcessMenus()
+ private async Task ProcessMainButtons()
{
- await Mp.ProcessControlAsync();
- Mp.WidthOffset = 50;
+ UIMenu currentMenu = Cf.GetOpenMenu();
+ if (currentMenu != null)
+ {
+ // Select / Enter
+ if (Game.IsDisabledControlJustReleased(0, Control.FrontendAccept) || Game.IsControlJustReleased(0, Control.FrontendAccept))
+ {
+ currentMenu.SelectItem();
+ if (DebugMode)
+ {
+ Subtitle.Custom("select");
+ }
+ }
+ // Cancel / Go Back
+ else if (Game.IsDisabledControlJustReleased(0, Control.PhoneCancel))
+ {
+ // 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();
+ if (DebugMode)
+ {
+
+ Subtitle.Custom("cancel");
+ }
+ }
+ }
+ else
+ {
+ await Delay(0);
+ }
}
///
- /// OnTick runs every game tick.
+ /// Process left/right/up/down buttons (also holding down buttons will speed up after 3 iterations)
+ ///
+ ///
+ private async Task ProcessDirectionalButtons()
+ {
+ // Get the currently open menu.
+ UIMenu currentMenu = Cf.GetOpenMenu();
+ // If it exists.
+ if (currentMenu != null)
+ {
+ // Check if the Go Up controls are pressed.
+ if (Game.IsDisabledControlJustPressed(0, Control.Phone) || Game.IsControlJustPressed(0, Control.SniperZoomInSecondary))
+ {
+ // Update the currently selected item to the new one.
+ currentMenu.GoUp();
+ currentMenu.GoUpOverflow();
+
+ // Get the current game time.
+ var time = GetGameTimer();
+ var times = 0;
+ var delay = 200;
+
+ // Do the following as long as the controls are being pressed.
+ while (Game.IsDisabledControlPressed(0, Control.Phone) && Cf.GetOpenMenu() != null)
+ {
+ // Update the current menu.
+ currentMenu = Cf.GetOpenMenu();
+
+ // Check if the game time has changed by "delay" amount.
+ if (GetGameTimer() - time > delay)
+ {
+ // Increment the "changed indexes" counter
+ times++;
+
+ // If the controls are still being held down after moving 3 indexes, reduce the delay between index changes.
+ if (times > 2)
+ {
+ delay = 150;
+ }
+
+ // Update the currently selected item to the new one.
+ currentMenu.GoUp();
+ currentMenu.GoUpOverflow();
+
+ // Reset the time to the current game timer.
+ time = GetGameTimer();
+ }
+
+ // Wait for the next game tick.
+ await Delay(0);
+ }
+ // If debugging is enabled, a subtitle will be shown when this control is pressed.
+ if (DebugMode)
+ {
+ Subtitle.Custom("up");
+ }
+ }
+
+ // Check if the Go Left controls are pressed.
+ else if (Game.IsDisabledControlJustPressed(0, Control.PhoneLeft))
+ {
+ currentMenu.GoLeft();
+ var time = GetGameTimer();
+ var times = 0;
+ var delay = 200;
+ while (Game.IsDisabledControlPressed(0, Control.PhoneLeft) && Cf.GetOpenMenu() != null)
+ {
+ currentMenu = Cf.GetOpenMenu();
+ if (GetGameTimer() - time > delay)
+ {
+ times++;
+ if (times > 2)
+ {
+ delay = 150;
+ }
+ currentMenu.GoLeft();
+ time = GetGameTimer();
+ }
+ await Delay(0);
+ }
+ if (DebugMode)
+ {
+ Subtitle.Custom("left");
+ }
+ }
+
+ // Check if the Go Right controls are pressed.
+ else if (Game.IsDisabledControlJustPressed(0, Control.PhoneRight))
+ {
+ currentMenu.GoRight();
+ var time = GetGameTimer();
+ var times = 0;
+ var delay = 200;
+ while (Game.IsDisabledControlPressed(0, Control.PhoneRight) && Cf.GetOpenMenu() != null)
+ {
+ currentMenu = Cf.GetOpenMenu();
+ if (GetGameTimer() - time > delay)
+ {
+ times++;
+ if (times > 2)
+ {
+ delay = 150;
+ }
+ currentMenu.GoRight();
+ time = GetGameTimer();
+ }
+ await Delay(0);
+ }
+ if (DebugMode)
+ {
+ Subtitle.Custom("right");
+ }
+ }
+
+ // Check if the Go Down controls are pressed.
+ else if (Game.IsDisabledControlJustPressed(0, Control.PhoneDown) || Game.IsControlJustPressed(0, Control.SniperZoomOutSecondary))
+ {
+ currentMenu.GoDown();
+ currentMenu.GoDownOverflow();
+ var time = GetGameTimer();
+ var times = 0;
+ var delay = 200;
+ while (Game.IsDisabledControlPressed(0, Control.PhoneDown) && Cf.GetOpenMenu() != null)
+ {
+ currentMenu = Cf.GetOpenMenu();
+ if (GetGameTimer() - time > delay)
+ {
+ times++;
+ if (times > 2)
+ {
+ delay = 150;
+ }
+ currentMenu.GoDown();
+ currentMenu.GoDownOverflow();
+ time = GetGameTimer();
+ }
+ await Delay(0);
+ }
+ if (DebugMode)
+ {
+ Subtitle.Custom("down");
+ }
+ }
+ }
+ }
+ #endregion
+
+ ///
+ /// Main OnTick task runs every game tick and handles all the menu stuff.
///
///
private async Task OnTick()
@@ -171,7 +353,7 @@ private async Task OnTick()
#endregion
// If the setup (permissions) is done, and it's not the first tick, then do this:
- if (permissionsSetupDone && !firstTick)
+ if (permissionsSetupDone && optionsSetupDone && !firstTick)
{
#region Handle Opening/Closing of the menu.
// If menus can be opened.
@@ -196,25 +378,23 @@ private async Task OnTick()
else if (!Mp.IsAnyMenuOpen() && Game.CurrentInputMode == InputMode.GamePad)
{
// Create a timer and set it to 0.
- float timer = 0f;
+ //float timer = 0f;
+ int timer = GetGameTimer();
// While (and only if) the player keeps using only the controller, and keeps holding down the interactionmenu button (select on controller).
while (Game.CurrentInputMode == InputMode.GamePad && Game.IsControlPressed(0, Control.InteractionMenu))
{
- // Increment the timer.
- timer++;
-
// If debugging is enabled, show the progress using a timerbar.
if (DebugMode)
{
bt.Draw(0);
- float percent = (timer / 60f);
+ float percent = ((GetGameTimer() - timer) / 900f);
bt.Percentage = percent;
- Subtitle.Success(percent.ToString(), 0, true, "Progress:");
+ //Subtitle.Success(percent.ToString(), 0, true, "Progress:");
}
- // If the timer has reached 60, open the menu. (60 is +/- 1 second, so the player is holding down the button for at least 1 second).
- if (timer > 59)
+ // If 900ms in real time have passed.
+ if (GetGameTimer() - timer > 900)
{
Menu.Visible = !Mp.IsAnyMenuOpen();
// Break the loop (resetting the timer).
@@ -288,7 +468,7 @@ private async Task OnTick()
Game.DisableControlThisFrame(0, (Control)MenuToggleKey);
// When in a vehicle
- if (IsPedInAnyVehicle(PlayerPedId(), false))
+ //if (IsPedInAnyVehicle(PlayerPedId(), false))
{
Game.DisableControlThisFrame(0, Control.VehicleSelectNextWeapon);
Game.DisableControlThisFrame(0, Control.VehicleSelectPrevWeapon);
@@ -296,12 +476,13 @@ private async Task OnTick()
}
}
#endregion
- // Only draw the menu each frame, control handling is done in another Tick task because that needs delays.
+
+ // Process the menu. Draw it and reset the menu width offset to make sure any newly generated menus always have the right width offset.
+ Mp.WidthOffset = 50;
Mp.Draw();
}
}
-
#region Add Menu Function
///
/// Add the menu to the menu pool and set it up correctly.