Exemple #1
0
        /// <summary>
        /// Creates the menu.
        /// </summary>
        private void CreateMenu()
        {
            #region create menu and menu items
            // Create the menu.
            menu = new UIMenu("BigFam Crew", "Player Options", true)
            {
                ScaleWithSafezone       = false,
                MouseControlsEnabled    = false,
                MouseEdgeEnabled        = false,
                ControlDisablingEnabled = false
            };

            // Create all checkboxes.
            UIMenuCheckboxItem playerGodModeCheckbox         = new UIMenuCheckboxItem("Godmode", PlayerGodMode, "Makes you invincible.");
            UIMenuCheckboxItem invisibleCheckbox             = new UIMenuCheckboxItem("Invisible", PlayerInvisible, "Makes you invisible to yourself and others.");
            UIMenuCheckboxItem unlimitedStaminaCheckbox      = new UIMenuCheckboxItem("Unlimited Stamina", PlayerStamina, "Allows you to run forever without slowing down or taking damage.");
            UIMenuCheckboxItem fastRunCheckbox               = new UIMenuCheckboxItem("Fast Run", PlayerFastRun, "Get ~g~Snail~s~ powers and run very fast!");
            UIMenuCheckboxItem fastSwimCheckbox              = new UIMenuCheckboxItem("Fast Swim", PlayerFastSwim, "Get ~g~Snail 2.0~s~ powers and swim super fast!");
            UIMenuCheckboxItem superJumpCheckbox             = new UIMenuCheckboxItem("Super Jump", PlayerSuperJump, "Get ~g~Snail 3.0~s~ powers and jump like a champ!");
            UIMenuCheckboxItem noRagdollCheckbox             = new UIMenuCheckboxItem("No Ragdoll", PlayerNoRagdoll, "Disables player ragdoll, makes you not fall off your bike anymore.");
            UIMenuCheckboxItem neverWantedCheckbox           = new UIMenuCheckboxItem("Never Wanted", PlayerNeverWanted, "Disables all wanted levels.");
            UIMenuCheckboxItem everyoneIgnoresPlayerCheckbox = new UIMenuCheckboxItem("Everyone Ignore Player", PlayerIsIgnored, "Everyone will leave you alone.");
            UIMenuCheckboxItem playerFrozenCheckbox          = new UIMenuCheckboxItem("Freeze Player", PlayerFrozen, "Freezes your current location, why would you do this...?");

            // Wanted level options
            List <dynamic> wantedLevelList = new List <dynamic> {
                "No Wanted Level", 1, 2, 3, 4, 5
            };
            UIMenuListItem setWantedLevel = new UIMenuListItem("Set Wanted Level", wantedLevelList, GetPlayerWantedLevel(PlayerId()), "Set your wanted level by selecting a value, and pressing enter.");

            // Player options
            List <dynamic> playerOptionsList = new List <dynamic> {
                "Max Health", "Max Armor", "Clean Player Clothes", "Player Dry", "Player Wet", "~r~Commit Suicide", "Drive To Waypoint", "Drive Around Randomly"
            };
            UIMenuListItem playerFunctions = new UIMenuListItem("Player Functions", playerOptionsList, 0, "Select an option and press enter to run/stop it.");

            // Scenarios (list can be found in the PedScenarios class)
            UIMenuListItem playerScenarios = new UIMenuListItem("Player Scenarios", PedScenarios.Scenarios, 0, "Select a scenario and hit enter to start it. Selecting another scenario will override the current scenario. If you're already playing the selected scenario, selecting it again will stop the scenario.");
            UIMenuItem     stopScenario    = new UIMenuItem("Force Stop Scenario", "This will force a playing scenario to stop immediately, without waiting for it to finish it's 'stopping' animation.");
            #endregion

            #region add items to menu based on permissions
            // Add all checkboxes to the menu. (keeping permissions in mind)
            if (cf.IsAllowed(Permission.POGod))
            {
                // menu.AddItem(playerGodModeCheckbox);
            }
            if (cf.IsAllowed(Permission.POInvisible))
            {
                // menu.AddItem(invisibleCheckbox);
            }
            if (cf.IsAllowed(Permission.POUnlimitedStamina))
            {
                menu.AddItem(unlimitedStaminaCheckbox);
            }
            if (cf.IsAllowed(Permission.POFastRun))
            {
                menu.AddItem(fastRunCheckbox);
            }
            if (cf.IsAllowed(Permission.POFastSwim))
            {
                menu.AddItem(fastSwimCheckbox);
            }
            if (cf.IsAllowed(Permission.POSuperjump))
            {
                menu.AddItem(superJumpCheckbox);
            }
            if (cf.IsAllowed(Permission.PONoRagdoll))
            {
                menu.AddItem(noRagdollCheckbox);
            }
            if (cf.IsAllowed(Permission.PONeverWanted))
            {
                menu.AddItem(neverWantedCheckbox);
            }
            if (cf.IsAllowed(Permission.POSetWanted))
            {
                menu.AddItem(setWantedLevel);
            }
            if (cf.IsAllowed(Permission.POIgnored))
            {
                menu.AddItem(everyoneIgnoresPlayerCheckbox);
            }
            if (cf.IsAllowed(Permission.POFunctions))
            {
                menu.AddItem(playerFunctions);
            }
            if (cf.IsAllowed(Permission.POFreeze))
            {
                menu.AddItem(playerFrozenCheckbox);
            }
            if (cf.IsAllowed(Permission.POScenarios))
            {
                menu.AddItem(playerScenarios);
                menu.AddItem(stopScenario);
            }
            #endregion

            #region handle all events
            // Checkbox changes.
            menu.OnCheckboxChange += (sender, item, _checked) =>
            {
                // God Mode toggled.
                if (item == playerGodModeCheckbox)
                {
                    PlayerGodMode = _checked;
                }
                // Invisibility toggled.
                else if (item == invisibleCheckbox)
                {
                    PlayerInvisible = _checked;
                }
                // Unlimited Stamina toggled.
                else if (item == unlimitedStaminaCheckbox)
                {
                    PlayerStamina = _checked;
                }
                // Fast run toggled.
                else if (item == fastRunCheckbox)
                {
                    PlayerFastRun = _checked;
                    SetRunSprintMultiplierForPlayer(PlayerId(), (_checked ? 1.49f : 1f));
                }
                // Fast swim toggled.
                else if (item == fastSwimCheckbox)
                {
                    PlayerFastSwim = _checked;
                    SetSwimMultiplierForPlayer(PlayerId(), (_checked ? 1.49f : 1f));
                }
                // Super jump toggled.
                else if (item == superJumpCheckbox)
                {
                    PlayerSuperJump = _checked;
                }
                // No ragdoll toggled.
                else if (item == noRagdollCheckbox)
                {
                    PlayerNoRagdoll = _checked;
                }
                // Never wanted toggled.
                else if (item == neverWantedCheckbox)
                {
                    PlayerNeverWanted = _checked;
                }
                // Everyone ignores player toggled.
                else if (item == everyoneIgnoresPlayerCheckbox)
                {
                    PlayerIsIgnored = _checked;
                }
                // Freeze player toggled.
                else if (item == playerFrozenCheckbox)
                {
                    PlayerFrozen = _checked;
                    if (!_checked)
                    {
                        FreezeEntityPosition(PlayerPedId(), false);
                    }
                }
            };

            // List selections
            menu.OnListSelect += (sender, listItem, index) =>
            {
                // Set wanted Level
                if (listItem == setWantedLevel)
                {
                    SetPlayerWantedLevel(PlayerId(), index, false);
                    SetPlayerWantedLevelNow(PlayerId(), false);
                }
                // Player options (healing, cleaning, armor, dry/wet, etc)
                else if (listItem == playerFunctions)
                {
                    switch (index)
                    {
                    // Max Health
                    case 0:
                        SetEntityHealth(PlayerPedId(), GetEntityMaxHealth(PlayerPedId()));
                        Subtitle.Info("Max ~g~health ~s~applied.", prefix: "Info:");
                        break;

                    // Max Armor
                    case 1:
                        SetPedArmour(PlayerPedId(), GetPlayerMaxArmour(PlayerId()));
                        Subtitle.Info("Max ~b~armor ~s~applied.", prefix: "Info:");
                        break;

                    // Clean Player Clothes
                    case 2:
                        ClearPedBloodDamage(PlayerPedId());
                        Subtitle.Info("Cleaned player clothes.", prefix: "Info:");
                        break;

                    // Make Player Dry
                    case 3:
                        ClearPedWetness(PlayerPedId());
                        Subtitle.Info("Player clothes are now ~c~dry~s~.", prefix: "Info:");
                        break;

                    // Make Player Wet
                    case 4:
                        SetPedWetnessHeight(PlayerPedId(), 2f);
                        SetPedWetnessEnabledThisFrame(PlayerPedId());
                        Subtitle.Info("Player clothes are now ~b~wet~s~.", prefix: "Info:");
                        break;

                    // Kill Player
                    case 5:
                        cf.CommitSuicide();
                        //SetEntityHealth(PlayerPedId(), 0);
                        //Subtitle.Info("You ~r~killed ~s~yourself.", prefix: "Info:");
                        break;

                    // Drive To Waypoint
                    case 6:
                        if (!Game.IsWaypointActive)
                        {
                            Subtitle.Error("You need to set a ~p~waypoint ~s~first!", prefix: "Error:");
                        }
                        else if (IsPedInAnyVehicle(PlayerPedId(), false))
                        {
                            try
                            {
                                cf.DriveToWp();
                            }
                            catch (NotImplementedException e)
                            {
                                cf.Log("\n\r[vMenu] Exception: " + e.Message + "\r\n");
                                Notify.Error(CommonErrors.UnknownError, placeholderValue: "This function is not implemented yet.");
                            }
                        }
                        else
                        {
                            Subtitle.Error("You need a ~r~vehicle ~s~first!", prefix: "Error:");
                        }
                        break;

                    // Drive Around Randomly (wander)
                    case 7:
                        if (IsPedInAnyVehicle(PlayerPedId(), false))
                        {
                            try
                            {
                                cf.DriveWander();
                            }
                            catch (NotImplementedException e)
                            {
                                cf.Log("\n\r[vMenu] Exception: " + e.Message + "\r\n");
                                Notify.Error(CommonErrors.UnknownError, placeholderValue: "This function is not implemented yet.");
                            }
                        }
                        else
                        {
                            Subtitle.Error("You need a ~r~vehicle ~s~first!", prefix: "Error:");
                        }
                        break;

                    default:
                        break;
                    }
                }
                // Player Scenarios
                else if (listItem == playerScenarios)
                {
                    cf.PlayScenario(PedScenarios.ScenarioNames[PedScenarios.Scenarios[index]]);
                }
            };

            // button presses
            menu.OnItemSelect += (sender, item, index) =>
            {
                // Force Stop Scenario button
                if (item == stopScenario)
                {
                    // Play a new scenario named "forcestop" (this scenario doesn't exist, but the "Play" function checks
                    // for the string "forcestop", if that's provided as th scenario name then it will forcefully clear the player task.
                    cf.PlayScenario("forcestop");
                }
            };
            #endregion
        }
Exemple #2
0
        /// <summary>
        /// Creates the menu.
        /// </summary>
        private void CreateMenu()
        {
            // Create the menu.
            menu = new UIMenu(GetPlayerName(PlayerId()), "Time Options", true)
            {
                ScaleWithSafezone       = false,
                MouseControlsEnabled    = false,
                MouseEdgeEnabled        = false,
                ControlDisablingEnabled = false
            };

            // Create all menu items.
            freezeTimeToggle = new UIMenuItem("Freeze/Unfreeze Time", "Enable or disable time freezing.");
            UIMenuItem earlymorning = new UIMenuItem("Early Morning", "Set the time to 06:00.");

            earlymorning.SetRightLabel("06:00");
            UIMenuItem morning = new UIMenuItem("Morning", "Set the time to 09:00.");

            morning.SetRightLabel("09:00");
            UIMenuItem noon = new UIMenuItem("Noon", "Set the time to 12:00.");

            noon.SetRightLabel("12:00");
            UIMenuItem earlyafternoon = new UIMenuItem("Early Afternoon", "Set the time to 15:00.");

            earlyafternoon.SetRightLabel("15:00");
            UIMenuItem afternoon = new UIMenuItem("Afternoon", "Set the time to 18:00.");

            afternoon.SetRightLabel("18:00");
            UIMenuItem evening = new UIMenuItem("Evening", "Set the time to 21:00.");

            evening.SetRightLabel("21:00");
            UIMenuItem midnight = new UIMenuItem("Midnight", "Set the time to 00:00.");

            midnight.SetRightLabel("00:00");
            UIMenuItem night = new UIMenuItem("Night", "Set the time to 03:00.");

            night.SetRightLabel("03:00");

            // Add all menu items to the menu.
            if (cf.IsAllowed(Permission.TOFreezeTime))
            {
                menu.AddItem(freezeTimeToggle);
            }
            if (cf.IsAllowed(Permission.TOSetTime))
            {
                menu.AddItem(earlymorning);
                menu.AddItem(morning);
                menu.AddItem(noon);
                menu.AddItem(earlyafternoon);
                menu.AddItem(afternoon);
                menu.AddItem(evening);
                menu.AddItem(midnight);
                menu.AddItem(night);
            }

            // Handle button presses.
            menu.OnItemSelect += (sender, item, index) =>
            {
                // If it's the freeze time button.
                if (item == freezeTimeToggle)
                {
                    Subtitle.Info($"Time will now {(EventManager.freezeTime ? "~y~continue" : "~o~freeze")}~s~.", prefix: "Info:");
                    cf.UpdateServerTime(EventManager.currentHours, EventManager.currentMinutes, !EventManager.freezeTime);
                }
                else
                {
                    // Set the time using the index and some math :)
                    // eg: index = 3 (12:00) ---> 3 * 3 (=9) + 3 [= 12] ---> 12:00
                    // eg: index = 8 (03:00) ---> 8 * 3 (=24) + 3 (=27, >23 so 27-24) [=3] ---> 03:00
                    var newHour = 0;
                    if (cf.IsAllowed(Permission.TOFreezeTime))
                    {
                        newHour = (((index * 3) + 3 < 23) ? (index * 3) + 3 : ((index * 3) + 3) - 24);
                    }
                    else
                    {
                        newHour = ((((index + 1) * 3) + 3 < 23) ? ((index + 1) * 3) + 3 : (((index + 1) * 3) + 3) - 24);
                    }

                    var newMinute = 0;
                    Subtitle.Info($"Time set to ~y~{(newHour < 10 ? $"0{newHour.ToString()}" : newHour.ToString())}~s~:~y~" +
                                  $"{(newMinute < 10 ? $"0{newMinute.ToString()}" : newMinute.ToString())}~s~.", prefix: "Info:");
                    cf.UpdateServerTime(newHour, newMinute, EventManager.freezeTime);
                }
            };
        }
Exemple #3
0
        /// <summary>
        /// Creates the menu.
        /// </summary>
        private void CreateMenu()
        {
            #region create main weapon options menu and add items
            // Create the menu.
            menu = new Menu(Game.Player.Name, "Weapon Options");

            MenuItem         getAllWeapons    = new MenuItem("Get All Weapons", "Get all weapons.");
            MenuItem         removeAllWeapons = new MenuItem("Remove All Weapons", "Removes all weapons in your inventory.");
            MenuCheckboxItem unlimitedAmmo    = new MenuCheckboxItem("Unlimited Ammo", "Unlimited ammonition supply.", UnlimitedAmmo);
            MenuCheckboxItem noReload         = new MenuCheckboxItem("No Reload", "Never reload.", NoReload);
            MenuItem         setAmmo          = new MenuItem("Set All Ammo Count", "Set the amount of ammo in all your weapons.");
            MenuItem         refillMaxAmmo    = new MenuItem("Refill All Ammo", "Give all your weapons max ammo.");
            MenuItem         spawnByName      = new MenuItem("Spawn Weapon By Name", "Enter a weapon mode name to spawn.");

            // Add items based on permissions
            if (IsAllowed(Permission.WPGetAll))
            {
                menu.AddMenuItem(getAllWeapons);
            }
            if (IsAllowed(Permission.WPRemoveAll))
            {
                menu.AddMenuItem(removeAllWeapons);
            }
            if (IsAllowed(Permission.WPUnlimitedAmmo))
            {
                menu.AddMenuItem(unlimitedAmmo);
            }
            if (IsAllowed(Permission.WPNoReload))
            {
                menu.AddMenuItem(noReload);
            }
            if (IsAllowed(Permission.WPSetAllAmmo))
            {
                menu.AddMenuItem(setAmmo);
                menu.AddMenuItem(refillMaxAmmo);
            }
            if (IsAllowed(Permission.WPSpawnByName))
            {
                menu.AddMenuItem(spawnByName);
            }
            #endregion

            #region addonweapons submenu
            MenuItem addonWeaponsBtn  = new MenuItem("Addon Weapons", "Equip / remove addon weapons available on this server.");
            Menu     addonWeaponsMenu = new Menu("Addon Weapons", "Equip/Remove Addon Weapons");
            menu.AddMenuItem(addonWeaponsBtn);

            #region manage creating and accessing addon weapons menu
            if (IsAllowed(Permission.WPSpawn) && AddonWeapons != null && AddonWeapons.Count > 0)
            {
                MenuController.BindMenuItem(menu, addonWeaponsMenu, addonWeaponsBtn);
                foreach (KeyValuePair <string, uint> weapon in AddonWeapons)
                {
                    string name  = weapon.Key.ToString();
                    uint   model = weapon.Value;
                    var    item  = new MenuItem(name, $"Click to add/remove this weapon ({name}) to/from your inventory.");
                    addonWeaponsMenu.AddMenuItem(item);
                    if (!IsWeaponValid(model))
                    {
                        item.Enabled     = false;
                        item.LeftIcon    = MenuItem.Icon.LOCK;
                        item.Description = "This model is not available. Please ask the server owner to verify it's being streamed correctly.";
                    }
                }
                addonWeaponsMenu.OnItemSelect += (sender, item, index) =>
                {
                    var weapon = AddonWeapons.ElementAt(index);
                    if (HasPedGotWeapon(Game.PlayerPed.Handle, weapon.Value, false))
                    {
                        RemoveWeaponFromPed(Game.PlayerPed.Handle, weapon.Value);
                    }
                    else
                    {
                        var maxAmmo = 200;
                        GetMaxAmmo(Game.PlayerPed.Handle, weapon.Value, ref maxAmmo);
                        GiveWeaponToPed(Game.PlayerPed.Handle, weapon.Value, maxAmmo, false, true);
                    }
                };
                addonWeaponsBtn.Label = "→→→";
            }
            else
            {
                addonWeaponsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                addonWeaponsBtn.Enabled     = false;
                addonWeaponsBtn.Description = "This option is not available on this server because you don't have permission to use it, or it is not setup correctly.";
            }
            #endregion
            addonWeaponsMenu.RefreshIndex();
            #endregion

            #region parachute options menu

            if (IsAllowed(Permission.WPParachute))
            {
                // main parachute options menu setup
                Menu     parachuteMenu = new Menu("Parachute Options", "Parachute Options");
                MenuItem parachuteBtn  = new MenuItem("Parachute Options", "All parachute related options can be changed here.")
                {
                    Label = "→→→"
                };

                MenuController.AddSubmenu(menu, parachuteMenu);
                menu.AddMenuItem(parachuteBtn);
                MenuController.BindMenuItem(menu, parachuteMenu, parachuteBtn);

                List <string> chutes = new List <string>()
                {
                    GetLabelText("PM_TINT0"),
                    GetLabelText("PM_TINT1"),
                    GetLabelText("PM_TINT2"),
                    GetLabelText("PM_TINT3"),
                    GetLabelText("PM_TINT4"),
                    GetLabelText("PM_TINT5"),
                    GetLabelText("PM_TINT6"),
                    GetLabelText("PM_TINT7"),

                    // broken in FiveM for some weird reason:
                    GetLabelText("PS_CAN_0"),
                    GetLabelText("PS_CAN_1"),
                    GetLabelText("PS_CAN_2"),
                    GetLabelText("PS_CAN_3"),
                    GetLabelText("PS_CAN_4"),
                    GetLabelText("PS_CAN_5")
                };
                List <string> chuteDescriptions = new List <string>()
                {
                    GetLabelText("PD_TINT0"),
                    GetLabelText("PD_TINT1"),
                    GetLabelText("PD_TINT2"),
                    GetLabelText("PD_TINT3"),
                    GetLabelText("PD_TINT4"),
                    GetLabelText("PD_TINT5"),
                    GetLabelText("PD_TINT6"),
                    GetLabelText("PD_TINT7"),

                    // broken in FiveM for some weird reason:
                    GetLabelText("PSD_CAN_0") + " ~r~For some reason this one doesn't seem to work in FiveM.",
                    GetLabelText("PSD_CAN_1") + " ~r~For some reason this one doesn't seem to work in FiveM.",
                    GetLabelText("PSD_CAN_2") + " ~r~For some reason this one doesn't seem to work in FiveM.",
                    GetLabelText("PSD_CAN_3") + " ~r~For some reason this one doesn't seem to work in FiveM.",
                    GetLabelText("PSD_CAN_4") + " ~r~For some reason this one doesn't seem to work in FiveM.",
                    GetLabelText("PSD_CAN_5") + " ~r~For some reason this one doesn't seem to work in FiveM."
                };

                MenuItem         togglePrimary       = new MenuItem("Toggle Primary Parachute", "Equip or remove the primary parachute");
                MenuItem         toggleReserve       = new MenuItem("Enable Reserve Parachute", "Enables the reserve parachute. Only works if you enabled the primary parachute first. Reserve parachute can not be removed from the player once it's activated.");
                MenuListItem     primaryChutes       = new MenuListItem("Primary Chute Style", chutes, 0, $"Primary chute: {chuteDescriptions[0]}");
                MenuListItem     secondaryChutes     = new MenuListItem("Reserve Chute Style", chutes, 0, $"Reserve chute: {chuteDescriptions[0]}");
                MenuCheckboxItem unlimitedParachutes = new MenuCheckboxItem("Unlimited Parachutes", "Enable unlimited parachutes and reserve parachutes.", UnlimitedParachutes);
                MenuCheckboxItem autoEquipParachutes = new MenuCheckboxItem("Auto Equip Parachutes", "Automatically equip a parachute and reserve parachute when entering planes/helicopters.", AutoEquipChute);

                // smoke color list
                List <string> smokeColorsList = new List <string>()
                {
                    GetLabelText("PM_TINT8"),  // no smoke
                    GetLabelText("PM_TINT9"),  // red
                    GetLabelText("PM_TINT10"), // orange
                    GetLabelText("PM_TINT11"), // yellow
                    GetLabelText("PM_TINT12"), // blue
                    GetLabelText("PM_TINT13"), // black
                };
                List <int[]> colors = new List <int[]>()
                {
                    new int[3] {
                        255, 255, 255
                    },
                    new int[3] {
                        255, 0, 0
                    },
                    new int[3] {
                        255, 165, 0
                    },
                    new int[3] {
                        255, 255, 0
                    },
                    new int[3] {
                        0, 0, 255
                    },
                    new int[3] {
                        20, 20, 20
                    },
                };

                MenuListItem smokeColors = new MenuListItem("Smoke Trail Color", smokeColorsList, 0, "Choose a smoke trail color, then press select to change it. Changing colors takes 4 seconds, you can not use your smoke while the color is being changed.");

                parachuteMenu.AddMenuItem(togglePrimary);
                parachuteMenu.AddMenuItem(toggleReserve);
                parachuteMenu.AddMenuItem(autoEquipParachutes);
                parachuteMenu.AddMenuItem(unlimitedParachutes);
                parachuteMenu.AddMenuItem(smokeColors);
                parachuteMenu.AddMenuItem(primaryChutes);
                parachuteMenu.AddMenuItem(secondaryChutes);

                parachuteMenu.OnItemSelect += (sender, item, index) =>
                {
                    if (item == togglePrimary)
                    {
                        if (HasPedGotWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), false))
                        {
                            Subtitle.Custom("Primary parachute removed.");
                            RemoveWeaponFromPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"));
                        }
                        else
                        {
                            Subtitle.Custom("Primary parachute added.");
                            GiveWeaponToPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), 0, false, false);
                        }
                    }
                    else if (item == toggleReserve)
                    {
                        SetPlayerHasReserveParachute(Game.Player.Handle);
                        Subtitle.Custom("Reserve parachute has been added.");
                    }
                };

                parachuteMenu.OnCheckboxChange += (sender, item, index, _checked) =>
                {
                    if (item == unlimitedParachutes)
                    {
                        UnlimitedParachutes = _checked;
                    }
                    else if (item == autoEquipParachutes)
                    {
                        AutoEquipChute = _checked;
                    }
                };

                bool switching = false;
                async void IndexChangedEventHandler(Menu sender, MenuListItem item, int oldIndex, int newIndex, int itemIndex)
                {
                    if (item == smokeColors && oldIndex == -1)
                    {
                        if (!switching)
                        {
                            switching = true;
                            SetPlayerCanLeaveParachuteSmokeTrail(Game.Player.Handle, false);
                            await Delay(4000);

                            int[] color = colors[newIndex];
                            SetPlayerParachuteSmokeTrailColor(Game.Player.Handle, color[0], color[1], color[2]);
                            SetPlayerCanLeaveParachuteSmokeTrail(Game.Player.Handle, newIndex != 0);
                            switching = false;
                        }
                    }
                    else if (item == primaryChutes)
                    {
                        item.Description = $"Primary chute: {chuteDescriptions[newIndex]}";
                        SetPlayerParachuteTintIndex(Game.Player.Handle, newIndex);
                    }
                    else if (item == secondaryChutes)
                    {
                        item.Description = $"Reserve chute: {chuteDescriptions[newIndex]}";
                        SetPlayerReserveParachuteTintIndex(Game.Player.Handle, newIndex);
                    }
                }

                parachuteMenu.OnListItemSelect  += (sender, item, index, itemIndex) => IndexChangedEventHandler(sender, item, -1, index, itemIndex);
                parachuteMenu.OnListIndexChange += IndexChangedEventHandler;
            }
            #endregion

            #region Create Weapon Category Submenus
            MenuItem spacer = GetSpacerMenuItem("↓ Weapon Categories ↓");
            menu.AddMenuItem(spacer);

            Menu     handGuns    = new Menu("Weapons", "Handguns");
            MenuItem handGunsBtn = new MenuItem("Handguns");

            Menu     rifles    = new Menu("Weapons", "Assault Rifles");
            MenuItem riflesBtn = new MenuItem("Assault Rifles");

            Menu     shotguns    = new Menu("Weapons", "Shotguns");
            MenuItem shotgunsBtn = new MenuItem("Shotguns");

            Menu     smgs    = new Menu("Weapons", "Sub-/Light Machine Guns");
            MenuItem smgsBtn = new MenuItem("Sub-/Light Machine Guns");

            Menu     throwables    = new Menu("Weapons", "Throwables");
            MenuItem throwablesBtn = new MenuItem("Throwables");

            Menu     melee    = new Menu("Weapons", "Melee");
            MenuItem meleeBtn = new MenuItem("Melee");

            Menu     heavy    = new Menu("Weapons", "Heavy Weapons");
            MenuItem heavyBtn = new MenuItem("Heavy Weapons");

            Menu     snipers    = new Menu("Weapons", "Sniper Rifles");
            MenuItem snipersBtn = new MenuItem("Sniper Rifles");

            MenuController.AddSubmenu(menu, handGuns);
            MenuController.AddSubmenu(menu, rifles);
            MenuController.AddSubmenu(menu, shotguns);
            MenuController.AddSubmenu(menu, smgs);
            MenuController.AddSubmenu(menu, throwables);
            MenuController.AddSubmenu(menu, melee);
            MenuController.AddSubmenu(menu, heavy);
            MenuController.AddSubmenu(menu, snipers);
            #endregion

            #region Setup weapon category buttons and submenus.
            handGunsBtn.Label = "→→→";
            menu.AddMenuItem(handGunsBtn);
            MenuController.BindMenuItem(menu, handGuns, handGunsBtn);

            riflesBtn.Label = "→→→";
            menu.AddMenuItem(riflesBtn);
            MenuController.BindMenuItem(menu, rifles, riflesBtn);

            shotgunsBtn.Label = "→→→";
            menu.AddMenuItem(shotgunsBtn);
            MenuController.BindMenuItem(menu, shotguns, shotgunsBtn);

            smgsBtn.Label = "→→→";
            menu.AddMenuItem(smgsBtn);
            MenuController.BindMenuItem(menu, smgs, smgsBtn);

            throwablesBtn.Label = "→→→";
            menu.AddMenuItem(throwablesBtn);
            MenuController.BindMenuItem(menu, throwables, throwablesBtn);

            meleeBtn.Label = "→→→";
            menu.AddMenuItem(meleeBtn);
            MenuController.BindMenuItem(menu, melee, meleeBtn);

            heavyBtn.Label = "→→→";
            menu.AddMenuItem(heavyBtn);
            MenuController.BindMenuItem(menu, heavy, heavyBtn);

            snipersBtn.Label = "→→→";
            menu.AddMenuItem(snipersBtn);
            MenuController.BindMenuItem(menu, snipers, snipersBtn);
            #endregion

            #region Loop through all weapons, create menus for them and add all menu items and handle events.
            foreach (ValidWeapon weapon in ValidWeapons.WeaponList)
            {
                uint cat = (uint)GetWeapontypeGroup(weapon.Hash);
                if (!string.IsNullOrEmpty(weapon.Name) && (IsAllowed(weapon.Perm) || IsAllowed(Permission.WPGetAll)))
                {
                    //Log($"[DEBUG LOG] [WEAPON-BUG] {weapon.Name} - {weapon.Perm} = {IsAllowed(weapon.Perm)} & All = {IsAllowed(Permission.WPGetAll)}");
                    #region Create menu for this weapon and add buttons
                    Menu     weaponMenu = new Menu("Weapon Options", weapon.Name);
                    MenuItem weaponItem = new MenuItem(weapon.Name, $"Open the options for ~y~{weapon.Name.ToString()}~s~.")
                    {
                        Label    = "→→→",
                        LeftIcon = MenuItem.Icon.GUN
                    };

                    weaponInfo.Add(weaponMenu, weapon);

                    MenuItem getOrRemoveWeapon = new MenuItem("Equip/Remove Weapon", "Add or remove this weapon to/form your inventory.")
                    {
                        LeftIcon = MenuItem.Icon.GUN
                    };
                    weaponMenu.AddMenuItem(getOrRemoveWeapon);
                    if (!IsAllowed(Permission.WPSpawn))
                    {
                        getOrRemoveWeapon.Enabled     = false;
                        getOrRemoveWeapon.Description = "You do not have permission to use this option.";
                        getOrRemoveWeapon.LeftIcon    = MenuItem.Icon.LOCK;
                    }

                    MenuItem fillAmmo = new MenuItem("Re-fill Ammo", "Get max ammo for this weapon.")
                    {
                        LeftIcon = MenuItem.Icon.AMMO
                    };
                    weaponMenu.AddMenuItem(fillAmmo);

                    List <string> tints = new List <string>();
                    if (weapon.Name.Contains(" Mk II"))
                    {
                        foreach (var tint in ValidWeapons.WeaponTintsMkII)
                        {
                            tints.Add(tint.Key);
                        }
                    }
                    else
                    {
                        foreach (var tint in ValidWeapons.WeaponTints)
                        {
                            tints.Add(tint.Key);
                        }
                    }

                    MenuListItem weaponTints = new MenuListItem("Tints", tints, 0, "Select a tint for your weapon.");
                    weaponMenu.AddMenuItem(weaponTints);
                    #endregion

                    #region Handle weapon specific list changes
                    weaponMenu.OnListIndexChange += (sender, item, oldIndex, newIndex, itemIndex) =>
                    {
                        if (item == weaponTints)
                        {
                            if (HasPedGotWeapon(Game.PlayerPed.Handle, weaponInfo[sender].Hash, false))
                            {
                                SetPedWeaponTintIndex(Game.PlayerPed.Handle, weaponInfo[sender].Hash, newIndex);
                            }
                            else
                            {
                                Notify.Error("You need to get the weapon first!");
                            }
                        }
                    };
                    #endregion

                    #region Handle weapon specific button presses
                    weaponMenu.OnItemSelect += (sender, item, index) =>
                    {
                        var  info = weaponInfo[sender];
                        uint hash = info.Hash;

                        SetCurrentPedWeapon(Game.PlayerPed.Handle, hash, true);

                        if (item == getOrRemoveWeapon)
                        {
                            if (HasPedGotWeapon(Game.PlayerPed.Handle, hash, false))
                            {
                                RemoveWeaponFromPed(Game.PlayerPed.Handle, hash);
                                Subtitle.Custom("Weapon removed.");
                            }
                            else
                            {
                                var ammo = 255;
                                GetMaxAmmo(Game.PlayerPed.Handle, hash, ref ammo);
                                GiveWeaponToPed(Game.PlayerPed.Handle, hash, ammo, false, true);
                                Subtitle.Custom("Weapon added.");
                            }
                        }
                        else if (item == fillAmmo)
                        {
                            if (HasPedGotWeapon(Game.PlayerPed.Handle, hash, false))
                            {
                                var ammo = 900;
                                GetMaxAmmo(Game.PlayerPed.Handle, hash, ref ammo);
                                SetPedAmmo(Game.PlayerPed.Handle, hash, ammo);
                            }
                            else
                            {
                                Notify.Error("You need to get the weapon first before re-filling ammo!");
                            }
                        }
                    };
                    #endregion

                    #region load components
                    if (weapon.Components != null)
                    {
                        if (weapon.Components.Count > 0)
                        {
                            foreach (var comp in weapon.Components)
                            {
                                //Log($"{weapon.Name} : {comp.Key}");
                                MenuItem compItem = new MenuItem(comp.Key, "Click to equip or remove this component.");
                                weaponComponents.Add(compItem, comp.Key);
                                weaponMenu.AddMenuItem(compItem);

                                #region Handle component button presses
                                weaponMenu.OnItemSelect += (sender, item, index) =>
                                {
                                    if (item == compItem)
                                    {
                                        var Weapon        = weaponInfo[sender];
                                        var componentHash = Weapon.Components[weaponComponents[item]];
                                        if (HasPedGotWeapon(Game.PlayerPed.Handle, Weapon.Hash, false))
                                        {
                                            SetCurrentPedWeapon(Game.PlayerPed.Handle, Weapon.Hash, true);
                                            if (HasPedGotWeaponComponent(Game.PlayerPed.Handle, Weapon.Hash, componentHash))
                                            {
                                                RemoveWeaponComponentFromPed(Game.PlayerPed.Handle, Weapon.Hash, componentHash);

                                                Subtitle.Custom("Component removed.");
                                            }
                                            else
                                            {
                                                int ammo = GetAmmoInPedWeapon(Game.PlayerPed.Handle, Weapon.Hash);

                                                int clipAmmo = GetMaxAmmoInClip(Game.PlayerPed.Handle, Weapon.Hash, false);
                                                GetAmmoInClip(Game.PlayerPed.Handle, Weapon.Hash, ref clipAmmo);

                                                GiveWeaponComponentToPed(Game.PlayerPed.Handle, Weapon.Hash, componentHash);

                                                SetAmmoInClip(Game.PlayerPed.Handle, Weapon.Hash, clipAmmo);

                                                SetPedAmmo(Game.PlayerPed.Handle, Weapon.Hash, ammo);
                                                Subtitle.Custom("Component equiped.");
                                            }
                                        }
                                        else
                                        {
                                            Notify.Error("You need to get the weapon first before you can modify it.");
                                        }
                                    }
                                };
                                #endregion
                            }
                        }
                    }
                    #endregion

                    // refresh and add to menu.
                    weaponMenu.RefreshIndex();

                    if (cat == 970310034) // 970310034 rifles
                    {
                        MenuController.AddSubmenu(rifles, weaponMenu);
                        MenuController.BindMenuItem(rifles, weaponMenu, weaponItem);
                        rifles.AddMenuItem(weaponItem);
                    }
                    else if (cat == 416676503 || cat == 690389602) // 416676503 hand guns // 690389602 stun gun
                    {
                        MenuController.AddSubmenu(handGuns, weaponMenu);
                        MenuController.BindMenuItem(handGuns, weaponMenu, weaponItem);
                        handGuns.AddMenuItem(weaponItem);
                    }
                    else if (cat == 860033945) // 860033945 shotguns
                    {
                        MenuController.AddSubmenu(shotguns, weaponMenu);
                        MenuController.BindMenuItem(shotguns, weaponMenu, weaponItem);
                        shotguns.AddMenuItem(weaponItem);
                    }
                    else if (cat == 3337201093 || cat == 1159398588) // 3337201093 sub machine guns // 1159398588 light machine guns
                    {
                        MenuController.AddSubmenu(smgs, weaponMenu);
                        MenuController.BindMenuItem(smgs, weaponMenu, weaponItem);
                        smgs.AddMenuItem(weaponItem);
                    }
                    else if (cat == 1548507267 || cat == 4257178988 || cat == 1595662460) // 1548507267 throwables // 4257178988 fire extinghuiser // jerry can
                    {
                        MenuController.AddSubmenu(throwables, weaponMenu);
                        MenuController.BindMenuItem(throwables, weaponMenu, weaponItem);
                        throwables.AddMenuItem(weaponItem);
                    }
                    else if (cat == 3566412244 || cat == 2685387236) // 3566412244 melee weapons // 2685387236 knuckle duster
                    {
                        MenuController.AddSubmenu(melee, weaponMenu);
                        MenuController.BindMenuItem(melee, weaponMenu, weaponItem);
                        melee.AddMenuItem(weaponItem);
                    }
                    else if (cat == 2725924767) // 2725924767 heavy weapons
                    {
                        MenuController.AddSubmenu(heavy, weaponMenu);
                        MenuController.BindMenuItem(heavy, weaponMenu, weaponItem);
                        heavy.AddMenuItem(weaponItem);
                    }
                    else if (cat == 3082541095) // 3082541095 sniper rifles
                    {
                        MenuController.AddSubmenu(snipers, weaponMenu);
                        MenuController.BindMenuItem(snipers, weaponMenu, weaponItem);
                        snipers.AddMenuItem(weaponItem);
                    }
                }
            }
            #endregion

            #region Disable submenus if no weapons in that category are allowed.
            if (handGuns.Size == 0)
            {
                handGunsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                handGunsBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                handGunsBtn.Enabled     = false;
            }
            if (rifles.Size == 0)
            {
                riflesBtn.LeftIcon    = MenuItem.Icon.LOCK;
                riflesBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                riflesBtn.Enabled     = false;
            }
            if (shotguns.Size == 0)
            {
                shotgunsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                shotgunsBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                shotgunsBtn.Enabled     = false;
            }
            if (smgs.Size == 0)
            {
                smgsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                smgsBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                smgsBtn.Enabled     = false;
            }
            if (throwables.Size == 0)
            {
                throwablesBtn.LeftIcon    = MenuItem.Icon.LOCK;
                throwablesBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                throwablesBtn.Enabled     = false;
            }
            if (melee.Size == 0)
            {
                meleeBtn.LeftIcon    = MenuItem.Icon.LOCK;
                meleeBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                meleeBtn.Enabled     = false;
            }
            if (heavy.Size == 0)
            {
                heavyBtn.LeftIcon    = MenuItem.Icon.LOCK;
                heavyBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                heavyBtn.Enabled     = false;
            }
            if (snipers.Size == 0)
            {
                snipersBtn.LeftIcon    = MenuItem.Icon.LOCK;
                snipersBtn.Description = "The server owner removed the permissions for all weapons in this category.";
                snipersBtn.Enabled     = false;
            }
            #endregion

            #region Handle button presses
            menu.OnItemSelect += (sender, item, index) =>
            {
                Ped ped = new Ped(Game.PlayerPed.Handle);
                if (item == getAllWeapons)
                {
                    foreach (ValidWeapon vw in ValidWeapons.WeaponList)
                    {
                        if (IsAllowed(vw.Perm))
                        {
                            GiveWeaponToPed(Game.PlayerPed.Handle, vw.Hash, vw.GetMaxAmmo, false, true);

                            int ammoInClip = GetMaxAmmoInClip(Game.PlayerPed.Handle, vw.Hash, false);
                            SetAmmoInClip(Game.PlayerPed.Handle, vw.Hash, ammoInClip);
                            int ammo = 0;
                            GetMaxAmmo(Game.PlayerPed.Handle, vw.Hash, ref ammo);
                            SetPedAmmo(Game.PlayerPed.Handle, vw.Hash, ammo);
                        }
                    }

                    SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_unarmed"), true);
                }
                else if (item == removeAllWeapons)
                {
                    ped.Weapons.RemoveAll();
                }
                else if (item == setAmmo)
                {
                    SetAllWeaponsAmmo();
                }
                else if (item == refillMaxAmmo)
                {
                    foreach (ValidWeapon vw in ValidWeapons.WeaponList)
                    {
                        if (HasPedGotWeapon(Game.PlayerPed.Handle, vw.Hash, false))
                        {
                            int ammoInClip = GetMaxAmmoInClip(Game.PlayerPed.Handle, vw.Hash, false);
                            SetAmmoInClip(Game.PlayerPed.Handle, vw.Hash, ammoInClip);
                            int ammo = 0;
                            GetMaxAmmo(Game.PlayerPed.Handle, vw.Hash, ref ammo);
                            SetPedAmmo(Game.PlayerPed.Handle, vw.Hash, ammo);
                        }
                    }
                }
                else if (item == spawnByName)
                {
                    SpawnCustomWeapon();
                }
            };
            #endregion

            #region Handle checkbox changes
            menu.OnCheckboxChange += (sender, item, index, _checked) =>
            {
                if (item == noReload)
                {
                    NoReload = _checked;
                    Subtitle.Custom($"No reload is now {(_checked ? "enabled" : "disabled")}.");
                }
                else if (item == unlimitedAmmo)
                {
                    UnlimitedAmmo = _checked;
                    Subtitle.Custom($"Unlimited ammo is now {(_checked ? "enabled" : "disabled")}.");
                }
            };
            #endregion
        }
        /// <summary>
        /// Creates the menu(s).
        /// </summary>
        private void CreateMenu()
        {
            // Create the menu.
            menu = new Menu(Game.Player.Name, "Player Appearance");
            spawnSavedPedMenu    = new Menu("Saved Peds", "Spawn Saved Ped");
            deleteSavedPedMenu   = new Menu("Saved Peds", "Delete Saved Ped");
            pedCustomizationMenu = new Menu("Ped Customization", "Customize Saved Ped");

            // Add the (submenus) to the menu pool.
            MenuController.AddSubmenu(menu, pedCustomizationMenu);
            MenuController.AddSubmenu(menu, spawnSavedPedMenu);
            MenuController.AddSubmenu(menu, deleteSavedPedMenu);

            // Create the menu items.
            MenuItem pedCustomization = new MenuItem("Ped Customization", "Modify your ped's appearance.")
            {
                Label = "→→→"
            };
            MenuItem savePed = new MenuItem("Save Current Ped", "Save your current ped and clothes.")
            {
                RightIcon = MenuItem.Icon.TICK
            };
            MenuItem spawnSavedPed = new MenuItem("Spawn Saved Ped", "Spawn one of your saved peds.")
            {
                Label = "→→→"
            };
            MenuItem deleteSavedPed = new MenuItem("Delete Saved Ped", "Delete one of your saved peds.")
            {
                Label    = "→→→",
                LeftIcon = MenuItem.Icon.WARNING
            };
            MenuItem      spawnByName = new MenuItem("Spawn Ped By Name", "Enter a model name of a custom ped you want to spawn.");
            List <string> walkstyles  = new List <string>()
            {
                "Normal", "Injured", "Tough Guy", "Femme", "Gangster", "Posh", "Sexy", "Business", "Drunk", "Hipster"
            };
            MenuListItem walkingStyle = new MenuListItem("Walking Style", walkstyles, 0, "Change the walking style of your current ped. " +
                                                         "You need to re-apply this each time you change player model or load a saved ped.");
            List <string> clothingGlowAnimations = new List <string>()
            {
                "On", "Off", "Fade", "Flash"
            };
            MenuListItem clothingGlowType = new MenuListItem("Illuminated Clothing Style", clothingGlowAnimations, ClothingAnimationType, "Set the style of the animation used on your player's illuminated clothing items.");

            // Add items to the menu.
            menu.AddMenuItem(pedCustomization);
            menu.AddMenuItem(savePed);
            menu.AddMenuItem(spawnSavedPed);
            menu.AddMenuItem(deleteSavedPed);
            menu.AddMenuItem(walkingStyle);
            menu.AddMenuItem(clothingGlowType);

            if (IsAllowed(Permission.PACustomize))
            {
                MenuController.BindMenuItem(menu, pedCustomizationMenu, pedCustomization);
            }
            else
            {
                pedCustomization.Enabled     = false;
                pedCustomization.LeftIcon    = MenuItem.Icon.LOCK;
                pedCustomization.Description = "~r~This option has been disabled by the server owner.";
            }

            if (IsAllowed(Permission.PASpawnSaved))
            {
                MenuController.BindMenuItem(menu, spawnSavedPedMenu, spawnSavedPed);
            }
            else
            {
                spawnSavedPed.Enabled     = false;
                spawnSavedPed.LeftIcon    = MenuItem.Icon.LOCK;
                spawnSavedPed.Description = "~r~This option has been disabled by the server owner.";
            }

            MenuController.BindMenuItem(menu, deleteSavedPedMenu, deleteSavedPed);

            Menu addonPeds = new Menu("Model Spawner", "Spawn Addon Ped");

            MenuItem addonPedsBtn = new MenuItem("Addon Peds", "Choose a player skin from the addons list available on this server.");

            menu.AddMenuItem(addonPedsBtn);
            MenuController.AddSubmenu(menu, addonPeds);

            if (AddonPeds != null)
            {
                if (AddonPeds.Count > 0)
                {
                    addonPedsBtn.Label = "→→→";
                    foreach (KeyValuePair <string, uint> ped in AddonPeds)
                    {
                        var button = new MenuItem(ped.Key, "Click to use this ped.");
                        addonPeds.AddMenuItem(button);
                        if (!IsModelAPed(ped.Value) || !IsModelInCdimage(ped.Value))
                        {
                            button.Enabled     = false;
                            button.LeftIcon    = MenuItem.Icon.LOCK;
                            button.Description = "This ped is not available on this server. Are you sure the model is valid?";
                        }
                    }
                    addonPeds.OnItemSelect += async(sender, item, index) =>
                    {
                        if (item.Enabled)
                        {
                            await SetPlayerSkin(AddonPeds.ElementAt(index).Value, new PedInfo()
                            {
                                version = -1
                            });
                        }
                        else
                        {
                            Notify.Error("This ped is not available. Please ask the server owner to verify this addon ped.");
                        }
                    };
                    MenuController.BindMenuItem(menu, addonPeds, addonPedsBtn);
                }
                else
                {
                    addonPedsBtn.Enabled     = false;
                    addonPedsBtn.Description = "This server does not have any addon peds available.";
                    addonPedsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                }
            }
            else
            {
                addonPedsBtn.Enabled     = false;
                addonPedsBtn.Description = "This server does not have any addon peds available.";
                addonPedsBtn.LeftIcon    = MenuItem.Icon.LOCK;
            }

            addonPeds.RefreshIndex();
            //addonPeds.UpdateScaleform();

            // Add the spawn by name button after the addon peds menu item.
            menu.AddMenuItem(spawnByName);
            if (!IsAllowed(Permission.PASpawnNew))
            {
                spawnByName.Enabled     = false;
                spawnByName.Description = "This option is disabled by the server owner or you are not allowed to use it.";
                spawnByName.LeftIcon    = MenuItem.Icon.LOCK;
            }


            // Loop through all the modelNames and create lists of max 50 ped names each.
            if (IsAllowed(Permission.PASpawnNew))
            {
                for (int i = 0; i < (modelNames.Count / 50) + 1; i++)
                {
                    List <string> pedList = new List <string>();
                    for (int ii = 0; ii < 50; ii++)
                    {
                        int index = ((i * 50) + ii);
                        if (index >= modelNames.Count)
                        {
                            break;
                        }
                        int max = ((modelNames.Count / 50) != i) ? 50 : modelNames.Count % 50;
                        pedList.Add(modelNames[index] + $" ({(ii + 1).ToString()}/{max.ToString()})");
                    }
                    MenuListItem pedl = new MenuListItem("Peds #" + (i + 1).ToString(), pedList, 0);

                    menu.AddMenuItem(pedl);
                    if (!IsAllowed(Permission.PASpawnNew))
                    {
                        pedl.Enabled     = false;
                        pedl.LeftIcon    = MenuItem.Icon.LOCK;
                        pedl.Description = "This option has been disabled by the server owner.";
                    }
                }
            }


            // Handle list selections.
            menu.OnListItemSelect += async(sender, item, listIndex, itemIndex) =>
            {
                if (item == walkingStyle)
                {
                    if (MainMenu.DebugMode)
                    {
                        Subtitle.Custom("Ped is: " + IsPedMale(Game.PlayerPed.Handle));
                    }
                    SetWalkingStyle(walkstyles[listIndex].ToString());
                }
                else if (item == clothingGlowType)
                {
                    ClothingAnimationType = item.ListIndex;
                }
                else if (IsAllowed(Permission.PASpawnNew))
                {
                    int    i         = ((itemIndex - 8) * 50) + listIndex;
                    string modelName = modelNames[i];
                    await SetPlayerSkin(modelName, new PedInfo()
                    {
                        version = -1
                    });
                }
            };

            // Handle button presses.
            menu.OnItemSelect += (sender, item, index) =>
            {
                if (item == pedCustomization)
                {
                    RefreshCustomizationMenu();
                }
                else if (item == spawnSavedPed)
                {
                    RefreshSpawnSavedPedMenu();
                }
                else if (item == deleteSavedPed)
                {
                    RefreshDeleteSavedPedMenu();
                }
                else if (item == savePed)
                {
                    SavePed();
                }
                else if (item == spawnByName)
                {
                    SpawnPedByName();
                }
            };

            // Handle saved ped spawning.
            spawnSavedPedMenu.OnItemSelect += (sender, item, idex) =>
            {
                var name = item.Text.ToString();
                LoadSavedPed(name, true);
            };

            #region ped drawable list changes
            // Manage list changes.
            pedCustomizationMenu.OnListIndexChange += (sender, item, oldListIndex, newListIndex, itemIndex) =>
            {
                if (drawablesMenuListItems.ContainsKey(item))
                {
                    int drawableID = drawablesMenuListItems[item];
                    SetPedComponentVariation(Game.PlayerPed.Handle, drawableID, newListIndex, 0, 0);
                }
                else if (propsMenuListItems.ContainsKey(item))
                {
                    int propID = propsMenuListItems[item];
                    if (newListIndex == 0)
                    {
                        SetPedPropIndex(Game.PlayerPed.Handle, propID, newListIndex - 1, 0, false);
                        ClearPedProp(Game.PlayerPed.Handle, propID);
                    }
                    else
                    {
                        SetPedPropIndex(Game.PlayerPed.Handle, propID, newListIndex - 1, 0, true);
                    }
                    if (propID == 0)
                    {
                        int component = GetPedPropIndex(Game.PlayerPed.Handle, 0);                        // helmet index
                        int texture   = GetPedPropTextureIndex(Game.PlayerPed.Handle, 0);                 // texture
                        int compHash  = GetHashNameForProp(Game.PlayerPed.Handle, 0, component, texture); // prop combination hash
                        if (N_0xd40aac51e8e4c663((uint)compHash) > 0)                                     // helmet has visor.
                        {
                            if (!IsHelpMessageBeingDisplayed())
                            {
                                BeginTextCommandDisplayHelp("TWOSTRINGS");
                                AddTextComponentSubstringPlayerName("Hold ~INPUT_SWITCH_VISOR~ to flip your helmet visor open or closed");
                                AddTextComponentSubstringPlayerName("when on foot or on a motorcycle and when vMenu is closed.");
                                EndTextCommandDisplayHelp(0, false, true, 6000);
                            }
                        }
                    }
                }
            };

            // Manage list selections.
            pedCustomizationMenu.OnListItemSelect += (sender, item, listIndex, itemIndex) =>
            {
                if (drawablesMenuListItems.ContainsKey(item)) // drawable
                {
                    int currentDrawableID   = drawablesMenuListItems[item];
                    int currentTextureIndex = GetPedTextureVariation(Game.PlayerPed.Handle, currentDrawableID);
                    int maxDrawableTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, currentDrawableID, listIndex) - 1;

                    if (currentTextureIndex == -1)
                    {
                        currentTextureIndex = 0;
                    }

                    int newTexture = currentTextureIndex < maxDrawableTextures ? currentTextureIndex + 1 : 0;

                    SetPedComponentVariation(Game.PlayerPed.Handle, currentDrawableID, listIndex, newTexture, 0);
                }
                else if (propsMenuListItems.ContainsKey(item)) // prop
                {
                    int currentPropIndex            = propsMenuListItems[item];
                    int currentPropVariationIndex   = GetPedPropIndex(Game.PlayerPed.Handle, currentPropIndex);
                    int currentPropTextureVariation = GetPedPropTextureIndex(Game.PlayerPed.Handle, currentPropIndex);
                    int maxPropTextureVariations    = GetNumberOfPedPropTextureVariations(Game.PlayerPed.Handle, currentPropIndex, currentPropVariationIndex) - 1;

                    int newPropTextureVariationIndex = currentPropTextureVariation < maxPropTextureVariations ? currentPropTextureVariation + 1 : 0;
                    SetPedPropIndex(Game.PlayerPed.Handle, currentPropIndex, currentPropVariationIndex, newPropTextureVariationIndex, true);
                }
            };
            #endregion
        }
Exemple #5
0
        /// <summary>
        /// Creates the menu.
        /// </summary>
        private void CreateMenu()
        {
            // Setup weapon dictionaries.
            weaponInfo       = new Dictionary <Menu, ValidWeapon>();
            weaponComponents = new Dictionary <MenuItem, string>();

            #region create main weapon options menu and add items
            // Create the menu.
            menu = new Menu(Game.Player.Name, "武器選單");

            MenuItem         getAllWeapons    = new MenuItem("獲得所有武器", "獲得所有武器.");
            MenuItem         removeAllWeapons = new MenuItem("移除所有武器", "移除所有武器");
            MenuCheckboxItem unlimitedAmmo    = new MenuCheckboxItem("無限子彈", "無限子彈.", UnlimitedAmmo);
            MenuCheckboxItem noReload         = new MenuCheckboxItem("永不裝彈夾", "永不裝彈夾.", NoReload);
            MenuItem         setAmmo          = new MenuItem("設置所有彈藥計數", "設置所有彈藥計數");
            MenuItem         refillMaxAmmo    = new MenuItem("所有的武器最大彈藥", "給所有的武器最大彈藥.");
            MenuItem         spawnByName      = new MenuItem("叫武器", "輸入一個武器名字來得到武器.");

            // Add items based on permissions
            if (IsAllowed(Permission.WPGetAll))
            {
                menu.AddMenuItem(getAllWeapons);
            }
            if (IsAllowed(Permission.WPRemoveAll))
            {
                menu.AddMenuItem(removeAllWeapons);
            }
            if (IsAllowed(Permission.WPUnlimitedAmmo))
            {
                menu.AddMenuItem(unlimitedAmmo);
            }
            if (IsAllowed(Permission.WPNoReload))
            {
                menu.AddMenuItem(noReload);
            }
            if (IsAllowed(Permission.WPSetAllAmmo))
            {
                menu.AddMenuItem(setAmmo);
                menu.AddMenuItem(refillMaxAmmo);
            }
            if (IsAllowed(Permission.WPSpawnByName))
            {
                menu.AddMenuItem(spawnByName);
            }
            #endregion

            #region addonweapons submenu
            MenuItem addonWeaponsBtn  = new MenuItem("附加武器", "穿戴/移除 此服務器上可用的附加武器.");
            Menu     addonWeaponsMenu = new Menu("附加武器", "穿戴/移除 附加武器");
            menu.AddMenuItem(addonWeaponsBtn);

            #region manage creating and accessing addon weapons menu
            if (IsAllowed(Permission.WPSpawn) && AddonWeapons != null && AddonWeapons.Count > 0)
            {
                MenuController.BindMenuItem(menu, addonWeaponsMenu, addonWeaponsBtn);
                foreach (KeyValuePair <string, uint> weapon in AddonWeapons)
                {
                    string name  = weapon.Key.ToString();
                    uint   model = weapon.Value;
                    var    item  = new MenuItem(name, $"點擊添加/刪除武器 ({name}).");
                    addonWeaponsMenu.AddMenuItem(item);
                    if (!IsWeaponValid(model))
                    {
                        item.Enabled     = false;
                        item.LeftIcon    = MenuItem.Icon.LOCK;
                        item.Description = "該模型不可用。 請確認伺服器是否有該資源.";
                    }
                }
                addonWeaponsMenu.OnItemSelect += (sender, item, index) =>
                {
                    var weapon = AddonWeapons.ElementAt(index);
                    if (HasPedGotWeapon(Game.PlayerPed.Handle, weapon.Value, false))
                    {
                        RemoveWeaponFromPed(Game.PlayerPed.Handle, weapon.Value);
                    }
                    else
                    {
                        var maxAmmo = 200;
                        GetMaxAmmo(Game.PlayerPed.Handle, weapon.Value, ref maxAmmo);
                        GiveWeaponToPed(Game.PlayerPed.Handle, weapon.Value, maxAmmo, false, true);
                    }
                };
                addonWeaponsBtn.Label = "→→→";
            }
            else
            {
                addonWeaponsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                addonWeaponsBtn.Enabled     = false;
                addonWeaponsBtn.Description = "該模型不可用。 請確認伺服器是否有該資源.";
            }
            #endregion
            addonWeaponsMenu.RefreshIndex();
            #endregion

            #region parachute options menu

            if (IsAllowed(Permission.WPParachute))
            {
                // main parachute options menu setup
                Menu     parachuteMenu = new Menu("降落傘選項", "降落傘選項");
                MenuItem parachuteBtn  = new MenuItem("降落傘選項", "可以在這裡更改所有與降落傘相關的選項.")
                {
                    Label = "→→→"
                };

                MenuController.AddSubmenu(menu, parachuteMenu);
                menu.AddMenuItem(parachuteBtn);
                MenuController.BindMenuItem(menu, parachuteMenu, parachuteBtn);

                List <string> chutes = new List <string>()
                {
                    GetLabelText("PM_TINT0"),
                    GetLabelText("PM_TINT1"),
                    GetLabelText("PM_TINT2"),
                    GetLabelText("PM_TINT3"),
                    GetLabelText("PM_TINT4"),
                    GetLabelText("PM_TINT5"),
                    GetLabelText("PM_TINT6"),
                    GetLabelText("PM_TINT7"),

                    // broken in FiveM for some weird reason:
                    GetLabelText("PS_CAN_0"),
                    GetLabelText("PS_CAN_1"),
                    GetLabelText("PS_CAN_2"),
                    GetLabelText("PS_CAN_3"),
                    GetLabelText("PS_CAN_4"),
                    GetLabelText("PS_CAN_5")
                };
                List <string> chuteDescriptions = new List <string>()
                {
                    GetLabelText("PD_TINT0"),
                    GetLabelText("PD_TINT1"),
                    GetLabelText("PD_TINT2"),
                    GetLabelText("PD_TINT3"),
                    GetLabelText("PD_TINT4"),
                    GetLabelText("PD_TINT5"),
                    GetLabelText("PD_TINT6"),
                    GetLabelText("PD_TINT7"),

                    // broken in FiveM for some weird reason:
                    GetLabelText("PSD_CAN_0") + " ~r~由於某種原因,這似乎不起作用.",
                    GetLabelText("PSD_CAN_1") + " ~r~由於某種原因,這似乎不起作用.",
                    GetLabelText("PSD_CAN_2") + " ~r~由於某種原因,這似乎不起作用.",
                    GetLabelText("PSD_CAN_3") + " ~r~由於某種原因,這似乎不起作用.",
                    GetLabelText("PSD_CAN_4") + " ~r~由於某種原因,這似乎不起作用.",
                    GetLabelText("PSD_CAN_5") + " ~r~由於某種原因,這似乎不起作用."
                };

                MenuItem         togglePrimary       = new MenuItem("切換主降落傘", "裝備或卸下主降落傘");
                MenuItem         toggleReserve       = new MenuItem("啟用備用降落傘", "僅在已啟用主降落傘的情況下有效,備用降落傘一旦啟動,便無法從播放器上取下.");
                MenuListItem     primaryChutes       = new MenuListItem("主要降落傘", chutes, 0, $"主要降落傘: {chuteDescriptions[0]}");
                MenuListItem     secondaryChutes     = new MenuListItem("備用降落傘", chutes, 0, $"備用降落傘: {chuteDescriptions[0]}");
                MenuCheckboxItem unlimitedParachutes = new MenuCheckboxItem("無限降落傘", "啟用後使用降落傘後並不會扣除.", UnlimitedParachutes);
                MenuCheckboxItem autoEquipParachutes = new MenuCheckboxItem("自動穿戴降落傘", "進入飛機/直升機時自動裝備降落傘並保留降落傘.", AutoEquipChute);

                // smoke color list
                List <string> smokeColorsList = new List <string>()
                {
                    GetLabelText("PM_TINT8"),  // no smoke
                    GetLabelText("PM_TINT9"),  // red
                    GetLabelText("PM_TINT10"), // orange
                    GetLabelText("PM_TINT11"), // yellow
                    GetLabelText("PM_TINT12"), // blue
                    GetLabelText("PM_TINT13"), // black
                };
                List <int[]> colors = new List <int[]>()
                {
                    new int[3] {
                        255, 255, 255
                    },
                    new int[3] {
                        255, 0, 0
                    },
                    new int[3] {
                        255, 165, 0
                    },
                    new int[3] {
                        255, 255, 0
                    },
                    new int[3] {
                        0, 0, 255
                    },
                    new int[3] {
                        20, 20, 20
                    },
                };

                MenuListItem smokeColors = new MenuListItem("煙霧顏色", smokeColorsList, 0, "選擇煙霧顏色,然後按選擇進行更改,更改顏色需要4秒鐘且無法抽煙.");

                parachuteMenu.AddMenuItem(togglePrimary);
                parachuteMenu.AddMenuItem(toggleReserve);
                parachuteMenu.AddMenuItem(autoEquipParachutes);
                parachuteMenu.AddMenuItem(unlimitedParachutes);
                parachuteMenu.AddMenuItem(smokeColors);
                parachuteMenu.AddMenuItem(primaryChutes);
                parachuteMenu.AddMenuItem(secondaryChutes);

                parachuteMenu.OnItemSelect += (sender, item, index) =>
                {
                    if (item == togglePrimary)
                    {
                        if (HasPedGotWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), false))
                        {
                            Subtitle.Custom("主要降落傘已移除.");
                            RemoveWeaponFromPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"));
                        }
                        else
                        {
                            Subtitle.Custom("主要降落傘已新增.");
                            GiveWeaponToPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), 0, false, false);
                        }
                    }
                    else if (item == toggleReserve)
                    {
                        SetPlayerHasReserveParachute(Game.Player.Handle);
                        Subtitle.Custom("備用降落傘已新增.");
                    }
                };

                parachuteMenu.OnCheckboxChange += (sender, item, index, _checked) =>
                {
                    if (item == unlimitedParachutes)
                    {
                        UnlimitedParachutes = _checked;
                    }
                    else if (item == autoEquipParachutes)
                    {
                        AutoEquipChute = _checked;
                    }
                };

                bool switching = false;
                async void IndexChangedEventHandler(Menu sender, MenuListItem item, int oldIndex, int newIndex, int itemIndex)
                {
                    if (item == smokeColors && oldIndex == -1)
                    {
                        if (!switching)
                        {
                            switching = true;
                            SetPlayerCanLeaveParachuteSmokeTrail(Game.Player.Handle, false);
                            await Delay(4000);

                            int[] color = colors[newIndex];
                            SetPlayerParachuteSmokeTrailColor(Game.Player.Handle, color[0], color[1], color[2]);
                            SetPlayerCanLeaveParachuteSmokeTrail(Game.Player.Handle, newIndex != 0);
                            switching = false;
                        }
                    }
                    else if (item == primaryChutes)
                    {
                        item.Description = $"主要降落傘: {chuteDescriptions[newIndex]}";
                        SetPlayerParachuteTintIndex(Game.Player.Handle, newIndex);
                    }
                    else if (item == secondaryChutes)
                    {
                        item.Description = $"備用降落傘: {chuteDescriptions[newIndex]}";
                        SetPlayerReserveParachuteTintIndex(Game.Player.Handle, newIndex);
                    }
                }

                parachuteMenu.OnListItemSelect  += (sender, item, index, itemIndex) => IndexChangedEventHandler(sender, item, -1, index, itemIndex);
                parachuteMenu.OnListIndexChange += IndexChangedEventHandler;
            }
            #endregion

            #region Create Weapon Category Submenus
            MenuItem spacer = GetSpacerMenuItem("↓ 武器類別 ↓");
            menu.AddMenuItem(spacer);

            Menu     handGuns    = new Menu("武器類", "手槍");
            MenuItem handGunsBtn = new MenuItem("手槍");

            Menu     rifles    = new Menu("武器類", "突襲步槍");
            MenuItem riflesBtn = new MenuItem("突襲步槍");

            Menu     shotguns    = new Menu("武器類", "散彈槍");
            MenuItem shotgunsBtn = new MenuItem("散彈槍");

            Menu     smgs    = new Menu("武器類", "輕型機槍");
            MenuItem smgsBtn = new MenuItem("輕型機槍");

            Menu     throwables    = new Menu("武器類", "投擲武器");
            MenuItem throwablesBtn = new MenuItem("投擲武器");

            Menu     melee    = new Menu("武器類", "近戰武器");
            MenuItem meleeBtn = new MenuItem("近戰武器");

            Menu     heavy    = new Menu("武器類", "重型武器");
            MenuItem heavyBtn = new MenuItem("重型武器");

            Menu     snipers    = new Menu("武器類", "狙擊步槍");
            MenuItem snipersBtn = new MenuItem("狙擊步槍");

            MenuController.AddSubmenu(menu, handGuns);
            MenuController.AddSubmenu(menu, rifles);
            MenuController.AddSubmenu(menu, shotguns);
            MenuController.AddSubmenu(menu, smgs);
            MenuController.AddSubmenu(menu, throwables);
            MenuController.AddSubmenu(menu, melee);
            MenuController.AddSubmenu(menu, heavy);
            MenuController.AddSubmenu(menu, snipers);
            #endregion

            #region Setup weapon category buttons and submenus.
            handGunsBtn.Label = "→→→";
            menu.AddMenuItem(handGunsBtn);
            MenuController.BindMenuItem(menu, handGuns, handGunsBtn);

            riflesBtn.Label = "→→→";
            menu.AddMenuItem(riflesBtn);
            MenuController.BindMenuItem(menu, rifles, riflesBtn);

            shotgunsBtn.Label = "→→→";
            menu.AddMenuItem(shotgunsBtn);
            MenuController.BindMenuItem(menu, shotguns, shotgunsBtn);

            smgsBtn.Label = "→→→";
            menu.AddMenuItem(smgsBtn);
            MenuController.BindMenuItem(menu, smgs, smgsBtn);

            throwablesBtn.Label = "→→→";
            menu.AddMenuItem(throwablesBtn);
            MenuController.BindMenuItem(menu, throwables, throwablesBtn);

            meleeBtn.Label = "→→→";
            menu.AddMenuItem(meleeBtn);
            MenuController.BindMenuItem(menu, melee, meleeBtn);

            heavyBtn.Label = "→→→";
            menu.AddMenuItem(heavyBtn);
            MenuController.BindMenuItem(menu, heavy, heavyBtn);

            snipersBtn.Label = "→→→";
            menu.AddMenuItem(snipersBtn);
            MenuController.BindMenuItem(menu, snipers, snipersBtn);
            #endregion

            #region Loop through all weapons, create menus for them and add all menu items and handle events.
            foreach (ValidWeapon weapon in ValidWeapons.WeaponList)
            {
                uint cat = (uint)GetWeapontypeGroup(weapon.Hash);
                if (!string.IsNullOrEmpty(weapon.Name) && IsAllowed(weapon.Perm))
                {
                    //Log($"[DEBUG LOG] [WEAPON-BUG] {weapon.Name} - {weapon.Perm} = {IsAllowed(weapon.Perm)} & All = {IsAllowed(Permission.WPGetAll)}");
                    #region Create menu for this weapon and add buttons
                    Menu weaponMenu = new Menu("武器選單", weapon.Name)
                    {
                        ShowWeaponStatsPanel = true
                    };
                    var stats = new Game.WeaponHudStats();
                    Game.GetWeaponHudStats(weapon.Hash, ref stats);
                    weaponMenu.SetWeaponStats((float)stats.hudDamage / 100f, (float)stats.hudSpeed / 100f, (float)stats.hudAccuracy / 100f, (float)stats.hudRange / 100f);
                    MenuItem weaponItem = new MenuItem(weapon.Name, $"打開以下選項 ~y~{weapon.Name}~s~.")
                    {
                        Label    = "→→→",
                        LeftIcon = MenuItem.Icon.GUN,
                        ItemData = stats
                    };

                    weaponInfo.Add(weaponMenu, weapon);

                    MenuItem getOrRemoveWeapon = new MenuItem("穿戴/移除武器", "")
                    {
                        LeftIcon = MenuItem.Icon.GUN
                    };
                    weaponMenu.AddMenuItem(getOrRemoveWeapon);
                    if (!IsAllowed(Permission.WPSpawn))
                    {
                        getOrRemoveWeapon.Enabled     = false;
                        getOrRemoveWeapon.Description = "您沒有權限使用此功能.";
                        getOrRemoveWeapon.LeftIcon    = MenuItem.Icon.LOCK;
                    }

                    MenuItem fillAmmo = new MenuItem("補充彈藥", "補充所有武器的最大數量.")
                    {
                        LeftIcon = MenuItem.Icon.AMMO
                    };
                    weaponMenu.AddMenuItem(fillAmmo);

                    List <string> tints = new List <string>();
                    if (weapon.Name.Contains(" Mk II"))
                    {
                        foreach (var tint in ValidWeapons.WeaponTintsMkII)
                        {
                            tints.Add(tint.Key);
                        }
                    }
                    else
                    {
                        foreach (var tint in ValidWeapons.WeaponTints)
                        {
                            tints.Add(tint.Key);
                        }
                    }

                    MenuListItem weaponTints = new MenuListItem("塗裝", tints, 0, "對您的武器做塗裝.");
                    weaponMenu.AddMenuItem(weaponTints);
                    #endregion

                    #region Handle weapon specific list changes
                    weaponMenu.OnListIndexChange += (sender, item, oldIndex, newIndex, itemIndex) =>
                    {
                        if (item == weaponTints)
                        {
                            if (HasPedGotWeapon(Game.PlayerPed.Handle, weaponInfo[sender].Hash, false))
                            {
                                SetPedWeaponTintIndex(Game.PlayerPed.Handle, weaponInfo[sender].Hash, newIndex);
                            }
                            else
                            {
                                Notify.Error("您需要一把武器!");
                            }
                        }
                    };
                    #endregion

                    #region Handle weapon specific button presses
                    weaponMenu.OnItemSelect += (sender, item, index) =>
                    {
                        var  info = weaponInfo[sender];
                        uint hash = info.Hash;

                        SetCurrentPedWeapon(Game.PlayerPed.Handle, hash, true);

                        if (item == getOrRemoveWeapon)
                        {
                            if (HasPedGotWeapon(Game.PlayerPed.Handle, hash, false))
                            {
                                RemoveWeaponFromPed(Game.PlayerPed.Handle, hash);
                                Subtitle.Custom("武器已經移除.");
                            }
                            else
                            {
                                var ammo = 255;
                                GetMaxAmmo(Game.PlayerPed.Handle, hash, ref ammo);
                                GiveWeaponToPed(Game.PlayerPed.Handle, hash, ammo, false, true);
                                Subtitle.Custom("武器已經添加.");
                            }
                        }
                        else if (item == fillAmmo)
                        {
                            if (HasPedGotWeapon(Game.PlayerPed.Handle, hash, false))
                            {
                                var ammo = 900;
                                GetMaxAmmo(Game.PlayerPed.Handle, hash, ref ammo);
                                SetPedAmmo(Game.PlayerPed.Handle, hash, ammo);
                            }
                            else
                            {
                                Notify.Error("您需要一把武器!");
                            }
                        }
                    };
                    #endregion

                    #region load components
                    if (weapon.Components != null)
                    {
                        if (weapon.Components.Count > 0)
                        {
                            foreach (var comp in weapon.Components)
                            {
                                //Log($"{weapon.Name} : {comp.Key}");
                                MenuItem compItem = new MenuItem(comp.Key, "點擊來進行配備整理.");
                                weaponComponents.Add(compItem, comp.Key);
                                weaponMenu.AddMenuItem(compItem);

                                #region Handle component button presses
                                weaponMenu.OnItemSelect += (sender, item, index) =>
                                {
                                    if (item == compItem)
                                    {
                                        var Weapon        = weaponInfo[sender];
                                        var componentHash = Weapon.Components[weaponComponents[item]];
                                        if (HasPedGotWeapon(Game.PlayerPed.Handle, Weapon.Hash, false))
                                        {
                                            SetCurrentPedWeapon(Game.PlayerPed.Handle, Weapon.Hash, true);
                                            if (HasPedGotWeaponComponent(Game.PlayerPed.Handle, Weapon.Hash, componentHash))
                                            {
                                                RemoveWeaponComponentFromPed(Game.PlayerPed.Handle, Weapon.Hash, componentHash);

                                                Subtitle.Custom("配件已經刪除.");
                                            }
                                            else
                                            {
                                                int ammo = GetAmmoInPedWeapon(Game.PlayerPed.Handle, Weapon.Hash);

                                                int clipAmmo = GetMaxAmmoInClip(Game.PlayerPed.Handle, Weapon.Hash, false);
                                                GetAmmoInClip(Game.PlayerPed.Handle, Weapon.Hash, ref clipAmmo);

                                                GiveWeaponComponentToPed(Game.PlayerPed.Handle, Weapon.Hash, componentHash);

                                                SetAmmoInClip(Game.PlayerPed.Handle, Weapon.Hash, clipAmmo);

                                                SetPedAmmo(Game.PlayerPed.Handle, Weapon.Hash, ammo);
                                                Subtitle.Custom("配件已經裝備.");
                                            }
                                        }
                                        else
                                        {
                                            Notify.Error("您需要一把武器.");
                                        }
                                    }
                                };
                                #endregion
                            }
                        }
                    }
                    #endregion

                    // refresh and add to menu.
                    weaponMenu.RefreshIndex();

                    if (cat == 970310034) // 970310034 rifles
                    {
                        MenuController.AddSubmenu(rifles, weaponMenu);
                        MenuController.BindMenuItem(rifles, weaponMenu, weaponItem);
                        rifles.AddMenuItem(weaponItem);
                    }
                    else if (cat == 416676503 || cat == 690389602) // 416676503 hand guns // 690389602 stun gun
                    {
                        MenuController.AddSubmenu(handGuns, weaponMenu);
                        MenuController.BindMenuItem(handGuns, weaponMenu, weaponItem);
                        handGuns.AddMenuItem(weaponItem);
                    }
                    else if (cat == 860033945) // 860033945 shotguns
                    {
                        MenuController.AddSubmenu(shotguns, weaponMenu);
                        MenuController.BindMenuItem(shotguns, weaponMenu, weaponItem);
                        shotguns.AddMenuItem(weaponItem);
                    }
                    else if (cat == 3337201093 || cat == 1159398588) // 3337201093 sub machine guns // 1159398588 light machine guns
                    {
                        MenuController.AddSubmenu(smgs, weaponMenu);
                        MenuController.BindMenuItem(smgs, weaponMenu, weaponItem);
                        smgs.AddMenuItem(weaponItem);
                    }
                    else if (cat == 1548507267 || cat == 4257178988 || cat == 1595662460) // 1548507267 throwables // 4257178988 fire extinghuiser // jerry can
                    {
                        MenuController.AddSubmenu(throwables, weaponMenu);
                        MenuController.BindMenuItem(throwables, weaponMenu, weaponItem);
                        throwables.AddMenuItem(weaponItem);
                    }
                    else if (cat == 3566412244 || cat == 2685387236) // 3566412244 melee weapons // 2685387236 knuckle duster
                    {
                        MenuController.AddSubmenu(melee, weaponMenu);
                        MenuController.BindMenuItem(melee, weaponMenu, weaponItem);
                        melee.AddMenuItem(weaponItem);
                    }
                    else if (cat == 2725924767) // 2725924767 heavy weapons
                    {
                        MenuController.AddSubmenu(heavy, weaponMenu);
                        MenuController.BindMenuItem(heavy, weaponMenu, weaponItem);
                        heavy.AddMenuItem(weaponItem);
                    }
                    else if (cat == 3082541095) // 3082541095 sniper rifles
                    {
                        MenuController.AddSubmenu(snipers, weaponMenu);
                        MenuController.BindMenuItem(snipers, weaponMenu, weaponItem);
                        snipers.AddMenuItem(weaponItem);
                    }
                }
            }
            #endregion

            #region Disable submenus if no weapons in that category are allowed.
            if (handGuns.Size == 0)
            {
                handGunsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                handGunsBtn.Description = "無法使用因為伺服器尚未載入該資源";
                handGunsBtn.Enabled     = false;
            }
            if (rifles.Size == 0)
            {
                riflesBtn.LeftIcon    = MenuItem.Icon.LOCK;
                riflesBtn.Description = "無法使用因為伺服器尚未載入該資源";
                riflesBtn.Enabled     = false;
            }
            if (shotguns.Size == 0)
            {
                shotgunsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                shotgunsBtn.Description = "無法使用因為伺服器尚未載入該資源";
                shotgunsBtn.Enabled     = false;
            }
            if (smgs.Size == 0)
            {
                smgsBtn.LeftIcon    = MenuItem.Icon.LOCK;
                smgsBtn.Description = "無法使用因為伺服器尚未載入該資源";
                smgsBtn.Enabled     = false;
            }
            if (throwables.Size == 0)
            {
                throwablesBtn.LeftIcon    = MenuItem.Icon.LOCK;
                throwablesBtn.Description = "無法使用因為伺服器尚未載入該資源";
                throwablesBtn.Enabled     = false;
            }
            if (melee.Size == 0)
            {
                meleeBtn.LeftIcon    = MenuItem.Icon.LOCK;
                meleeBtn.Description = "無法使用因為伺服器尚未載入該資源";
                meleeBtn.Enabled     = false;
            }
            if (heavy.Size == 0)
            {
                heavyBtn.LeftIcon    = MenuItem.Icon.LOCK;
                heavyBtn.Description = "無法使用因為伺服器尚未載入該資源";
                heavyBtn.Enabled     = false;
            }
            if (snipers.Size == 0)
            {
                snipersBtn.LeftIcon    = MenuItem.Icon.LOCK;
                snipersBtn.Description = "無法使用因為伺服器尚未載入該資源";
                snipersBtn.Enabled     = false;
            }
            #endregion

            #region Handle button presses
            menu.OnItemSelect += (sender, item, index) =>
            {
                Ped ped = new Ped(Game.PlayerPed.Handle);
                if (item == getAllWeapons)
                {
                    foreach (ValidWeapon vw in ValidWeapons.WeaponList)
                    {
                        if (IsAllowed(vw.Perm))
                        {
                            GiveWeaponToPed(Game.PlayerPed.Handle, vw.Hash, vw.GetMaxAmmo, false, true);

                            int ammoInClip = GetMaxAmmoInClip(Game.PlayerPed.Handle, vw.Hash, false);
                            SetAmmoInClip(Game.PlayerPed.Handle, vw.Hash, ammoInClip);
                            int ammo = 0;
                            GetMaxAmmo(Game.PlayerPed.Handle, vw.Hash, ref ammo);
                            SetPedAmmo(Game.PlayerPed.Handle, vw.Hash, ammo);
                        }
                    }

                    SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_unarmed"), true);
                }
                else if (item == removeAllWeapons)
                {
                    ped.Weapons.RemoveAll();
                }
                else if (item == setAmmo)
                {
                    SetAllWeaponsAmmo();
                }
                else if (item == refillMaxAmmo)
                {
                    foreach (ValidWeapon vw in ValidWeapons.WeaponList)
                    {
                        if (HasPedGotWeapon(Game.PlayerPed.Handle, vw.Hash, false))
                        {
                            int ammoInClip = GetMaxAmmoInClip(Game.PlayerPed.Handle, vw.Hash, false);
                            SetAmmoInClip(Game.PlayerPed.Handle, vw.Hash, ammoInClip);
                            int ammo = 0;
                            GetMaxAmmo(Game.PlayerPed.Handle, vw.Hash, ref ammo);
                            SetPedAmmo(Game.PlayerPed.Handle, vw.Hash, ammo);
                        }
                    }
                }
                else if (item == spawnByName)
                {
                    SpawnCustomWeapon();
                }
            };
            #endregion

            #region Handle checkbox changes
            menu.OnCheckboxChange += (sender, item, index, _checked) =>
            {
                if (item == noReload)
                {
                    NoReload = _checked;
                    Subtitle.Custom($"永不裝彈夾 {(_checked ? "啟用" : "禁用")}.");
                }
                else if (item == unlimitedAmmo)
                {
                    UnlimitedAmmo = _checked;
                    Subtitle.Custom($"無限彈藥已 {(_checked ? "啟用" : "禁用")}.");
                }
            };
            #endregion

            void OnIndexChange(Menu m, MenuItem i)
            {
                if (i.ItemData is Game.WeaponHudStats stats)
                {
                    m.SetWeaponStats((float)stats.hudDamage / 100f, (float)stats.hudSpeed / 100f, (float)stats.hudAccuracy / 100f, (float)stats.hudRange / 100f);
                    m.ShowWeaponStatsPanel = true;
                }
                else
                {
                    m.ShowWeaponStatsPanel = false;
                }
            }

            handGuns.OnIndexChange   += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            rifles.OnIndexChange     += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            shotguns.OnIndexChange   += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            smgs.OnIndexChange       += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            throwables.OnIndexChange += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            melee.OnIndexChange      += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            heavy.OnIndexChange      += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };
            snipers.OnIndexChange    += (sender, oldItem, newItem, oldIndex, newIndex) => { OnIndexChange(sender, newItem); };

            handGuns.OnMenuOpen   += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            rifles.OnMenuOpen     += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            shotguns.OnMenuOpen   += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            smgs.OnMenuOpen       += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            throwables.OnMenuOpen += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            melee.OnMenuOpen      += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            heavy.OnMenuOpen      += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
            snipers.OnMenuOpen    += (sender) => { OnIndexChange(sender, sender.GetCurrentMenuItem()); };
        }