/// <summary> /// Main OnTick task runs every game tick and handles all the menu stuff. /// </summary> /// <returns></returns> private async Task OnTick() { #region FirstTick // Only run this the first tick. if (firstTick) { firstTick = false; // Clear all previous pause menu info/brief messages on resource start. ClearBrief(); // Request the permissions data from the server. TriggerServerEvent("vMenu:RequestPermissions", PlayerId()); TriggerServerEvent("vMenu:RequestBanList", PlayerId()); // Wait until the data is received and the player's name is loaded correctly. while (!permissionsSetupDone || !optionsSetupDone || GetPlayerName(PlayerId()) == "**Invalid**" || GetPlayerName(PlayerId()) == "** Invalid **" || !addonCarsLoaded || !addonPedsLoaded || !addonWeaponsLoaded) { await Delay(0); } // Create the main menu. Menu = new UIMenu(GetPlayerName(PlayerId()), "Main Menu", true) { ScaleWithSafezone = false, MouseControlsEnabled = false, MouseEdgeEnabled = false, ControlDisablingEnabled = false }; // Add the main menu to the menu pool. Mp.Add(Menu); Menu.RefreshIndex(); Menu.UpdateScaleform(); // Create all (sub)menus. CreateSubmenus(); } #endregion // If the setup (permissions) is done, and it's not the first tick, then do this: if (permissionsSetupDone && optionsSetupDone && !firstTick) { #region Handle Opening/Closing of the menu. // If menus can be opened. if (!DontOpenMenus && !IsPauseMenuActive()) { // If the player is using Keyboard & Mouse and they pressed the M key (interaction menu button) then... if (Game.CurrentInputMode == InputMode.MouseAndKeyboard && (Game.IsControlJustPressed(0, (Control)MenuToggleKey) || Game.IsDisabledControlJustPressed(0, (Control)MenuToggleKey))) { // If any menu is already open: close all menus. if (Mp.IsAnyMenuOpen()) { Mp.CloseAllMenus(); } // Otherwise: toggle the main menu (to be safe, only open it if no other menus are open.) else { Menu.Visible = !Mp.IsAnyMenuOpen(); } } // If the player is using a controller, and no menus are currently open. else if (!Mp.IsAnyMenuOpen() && Game.CurrentInputMode == InputMode.GamePad) { // Create a timer and set it to the current game timer value. 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)) { // If debugging is enabled, show the progress using a timerbar. if (DebugMode) { bt.Draw(0); float percent = ((GetGameTimer() - timer) / 350f); bt.Percentage = percent; } // If 900ms in real time have passed. if (GetGameTimer() - timer > 350) { Menu.Visible = !Mp.IsAnyMenuOpen(); // Break the loop (resetting the timer). break; } // Wait for the next game tick. await Delay(0); } } if (Game.CurrentInputMode == InputMode.MouseAndKeyboard) { if (Game.IsControlJustPressed(0, (Control)NoClipKey) && Cf.IsAllowed(Permission.NoClip)) { if (IsPedInAnyVehicle(PlayerPedId(), false)) { if (GetPedInVehicleSeat(Cf.GetVehicle(), -1) == PlayerPedId()) { NoClipEnabled = !Mp.IsAnyMenuOpen(); } else { NoClipEnabled = false; Notify.Error("You need to be the driver of this vehicle to enable noclip!"); } } else { NoClipEnabled = !Mp.IsAnyMenuOpen(); } } } } // If the pause menu is active or all menus should be closed, close all menus. else { await Delay(1); Mp.CloseAllMenus(); } #endregion // Menu toggle button. Game.DisableControlThisFrame(0, (Control)MenuToggleKey); #region Disable Inputs when any menu is open. if (Mp.IsAnyMenuOpen()) { // Close all menus when the player dies. if (Game.PlayerPed.IsDead) { Mp.CloseAllMenus(); } // Disable Gamepad/Controller Specific controls: if (Game.CurrentInputMode == InputMode.GamePad) { Game.DisableControlThisFrame(0, Control.MultiplayerInfo); // when in a vehicle. if (IsPedInAnyVehicle(PlayerPedId(), false)) { Game.DisableControlThisFrame(0, Control.VehicleHeadlight); Game.DisableControlThisFrame(0, Control.VehicleDuck); } } // Disable Shared Controls // Radio Inputs Game.DisableControlThisFrame(0, Control.RadioWheelLeftRight); Game.DisableControlThisFrame(0, Control.RadioWheelUpDown); Game.DisableControlThisFrame(0, Control.VehicleNextRadio); Game.DisableControlThisFrame(0, Control.VehicleRadioWheel); Game.DisableControlThisFrame(0, Control.VehiclePrevRadio); // Phone / Arrows Inputs Game.DisableControlThisFrame(0, Control.Phone); Game.DisableControlThisFrame(0, Control.PhoneCancel); Game.DisableControlThisFrame(0, Control.PhoneDown); Game.DisableControlThisFrame(0, Control.PhoneLeft); Game.DisableControlThisFrame(0, Control.PhoneRight); // Attack Controls Game.DisableControlThisFrame(0, Control.Attack); Game.DisableControlThisFrame(0, Control.Attack2); Game.DisableControlThisFrame(0, Control.MeleeAttack1); Game.DisableControlThisFrame(0, Control.MeleeAttack2); Game.DisableControlThisFrame(0, Control.MeleeAttackAlternate); Game.DisableControlThisFrame(0, Control.MeleeAttackHeavy); Game.DisableControlThisFrame(0, Control.MeleeAttackLight); Game.DisableControlThisFrame(0, Control.VehicleAttack); Game.DisableControlThisFrame(0, Control.VehicleAttack2); Game.DisableControlThisFrame(0, Control.VehicleFlyAttack); Game.DisableControlThisFrame(0, Control.VehiclePassengerAttack); Game.DisableControlThisFrame(0, Control.Aim); // When in a vehicle if (IsPedInAnyVehicle(PlayerPedId(), false)) { Game.DisableControlThisFrame(0, Control.VehicleSelectNextWeapon); Game.DisableControlThisFrame(0, Control.VehicleSelectPrevWeapon); Game.DisableControlThisFrame(0, Control.VehicleCinCam); } } #endregion // 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; if (Mp.IsAnyMenuOpen()) { Mp.Draw(); } } }