public override void Refresh()
            {
                var _menuItems           = new List <MenuItem>();
                var ped                  = Game.PlayerPed;
                int selectedPedHashIndex = PedHashValues.Contains((PedHash)ped.Model.Hash) ? PedHashValues.IndexOf((PedHash)ped.Model.Hash) : PedHashValues.IndexOf(PedHash.FreemodeMale01);

                if (Game.PlayerPed.Exists())
                {
                    _menuItems.Add(new MenuItemHorNamedSelector
                    {
                        Title       = $"Skin",
                        Description = "Activate to replace your current skin.",
                        state       = menuItems[0] is MenuItemHorNamedSelector ? (menuItems[0] as MenuItemHorNamedSelector).state : selectedPedHashIndex,
                        Type        = MenuItemHorizontalSelectorType.NumberAndBar,
                        wrapAround  = true,
                        optionList  = PedHashNames,
                        OnActivate  = new Action <int, string, MenuItemHorNamedSelector>(async(selectedAlternative, selName, menuItem) => { await ReplaceCurrentPedModelByIndex(selectedAlternative); componentSettings.Clear(); propSettings.Clear(); })
                    });
                    if ((PedHash)ped.Model.Hash == PedHash.FreemodeMale01 || (PedHash)ped.Model.Hash == PedHash.FreemodeFemale01)
                    {
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = $@"Face: Father's appearance",
                            state      = (blendHeadA >= 0 && blendHeadA <= 45) ? blendHeadA : 0,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 45,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { blendHeadA = selectedAlternative; Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, ped.Handle, blendHeadA, blendHeadB, 0, blendSkinA, blendSkinB, 0, blendHeadAmount, blendSkinAmount, 0f, false); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = $@"Face: Mother's appearance",
                            state      = (blendHeadB >= 0 && blendHeadB <= 45) ? blendHeadB : 0,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 45,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { blendHeadB = selectedAlternative; Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, ped.Handle, blendHeadA, blendHeadB, 0, blendSkinA, blendSkinB, 0, blendHeadAmount, blendSkinAmount, 0f, false); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <float>
                        {
                            Title      = $@"Face: Father/Mother Gene Weight",
                            state      = blendHeadAmount,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0f,
                            maxState   = 1f,
                            stepSize   = 0.05f,
                            OnChange   = new Action <float, MenuItemHorSelector <float> >((selectedAlternative, menuItem) => { blendHeadAmount = selectedAlternative; Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, ped.Handle, blendHeadA, blendHeadB, 0, blendSkinA, blendSkinB, 0, blendHeadAmount, blendSkinAmount, 0f, false); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = $@"Skin color: Father's appearance",
                            state      = (blendSkinA >= 0 && blendSkinA <= 45) ? blendSkinA : 0,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 45,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { blendSkinA = selectedAlternative; Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, ped.Handle, blendHeadA, blendHeadB, 0, blendSkinA, blendSkinB, 0, blendHeadAmount, blendSkinAmount, 0f, false); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = $@"Skin color: Mother's appearance",
                            state      = (blendSkinB >= 0 && blendSkinB <= 45) ? blendSkinB : 0,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 45,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { blendSkinB = selectedAlternative; Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, ped.Handle, blendHeadA, blendHeadB, 0, blendSkinA, blendSkinB, 0, blendHeadAmount, blendSkinAmount, 0f, false); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <float>
                        {
                            Title      = $@"Skin color: Father/Mother Gene Weight",
                            state      = blendSkinAmount,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0f,
                            maxState   = 1f,
                            stepSize   = 0.05f,
                            OnChange   = new Action <float, MenuItemHorSelector <float> >((selectedAlternative, menuItem) => { blendSkinAmount = selectedAlternative; Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, ped.Handle, blendHeadA, blendHeadB, 0, blendSkinA, blendSkinB, 0, blendHeadAmount, blendSkinAmount, 0f, false); })
                        });
                        overlays.ForEach(o =>
                        {
                            _menuItems.Add(new MenuItemHorNamedSelector
                            {
                                Title      = o.Name,
                                state      = o.OptionValues.IndexOf(Function.Call <int>(Hash._GET_PED_HEAD_OVERLAY_VALUE, ped.Handle, o.ID)),
                                Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                                wrapAround = true,
                                optionList = o.OptionNames,
                                OnChange   = new Action <int, string, MenuItemHorNamedSelector>((selectedAlternative, selName, menuItem) => { Function.Call(Hash.SET_PED_HEAD_OVERLAY, ped.Handle, o.ID, o.OptionValues[selectedAlternative], 1f); }) // Setting default opacity of 1f
                            });
                            if (o.colorType != 0)
                            {
                                if (!overlayColors.ContainsKey(o.ID))
                                {
                                    overlayColors[o.ID] = 0;
                                }
                                _menuItems.Add(new MenuItemHorSelector <int>
                                {
                                    Title      = $"{o.Name}: Color",
                                    state      = overlayColors[o.ID],
                                    Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                                    wrapAround = true,
                                    minState   = 0,
                                    maxState   = 63,
                                    OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { overlayColors[o.ID] = selectedAlternative; Function.Call(Hash._SET_PED_HEAD_OVERLAY_COLOR, ped.Handle, o.ID, o.colorType, selectedAlternative, selectedAlternative); })
                                });
                            }
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = "Eye Color",
                            state      = EyeColor,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 63,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { EyeColor = selectedAlternative; Function.Call(Hash._SET_PED_EYE_COLOR, ped.Handle, selectedAlternative); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = "Primary Hair Color",
                            state      = HairColorPrimary,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 63,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { HairColorPrimary = selectedAlternative; Function.Call(Hash._SET_PED_HAIR_COLOR, ped.Handle, selectedAlternative, HairColorHighlights); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = "Highlight Hair Color",
                            state      = HairColorHighlights,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 63,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { HairColorHighlights = selectedAlternative; Function.Call(Hash._SET_PED_HAIR_COLOR, ped.Handle, HairColorPrimary, selectedAlternative); })
                        });
                        _menuItems.Add(new MenuItemHorSelector <int>
                        {
                            Title      = "Facial Morph: Feature Index",
                            state      = MorphIndex,
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = 0,
                            maxState   = 20,
                            OnChange   = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { MorphIndex = selectedAlternative; })
                        });
                        if (!MorphStatus.ContainsKey(MorphIndex))
                        {
                            MorphStatus[MorphIndex] = 0f;
                        }
                        _menuItems.Add(new MenuItemHorSelector <float>
                        {
                            Title      = "Facial Morph: Morph Stage",
                            state      = MorphStatus[MorphIndex],
                            Type       = MenuItemHorizontalSelectorType.NumberAndBar,
                            wrapAround = true,
                            minState   = -2f,
                            maxState   = 2f,
                            stepSize   = 0.5f,
                            OnChange   = new Action <float, MenuItemHorSelector <float> >((selectedAlternative, menuItem) => { MorphStatus[MorphIndex] = selectedAlternative; Function.Call(Hash._SET_PED_FACE_FEATURE, ped.Handle, MorphIndex, selectedAlternative); })
                        });
                    }


                    PedComponent[] components = Game.PlayerPed.Style.GetAllComponents();
                    PedProp[]      props      = Game.PlayerPed.Style.GetAllProps();

                    components.ToList().ForEach(c =>
                    {
                        try
                        {
                            if (!(c.ToString() == "Face") || (!((PedHash)ped.Model.Hash == PedHash.FreemodeMale01) && !((PedHash)ped.Model.Hash == PedHash.FreemodeFemale01))) // Since Face doesn't work on freemode characters (if you use the blending/morphing option anyway, which everybody should be)
                            {
                                if (!componentSettings.ContainsKey(c.ToString()))
                                {
                                    componentSettings.Add(c.ToString(), new Tuple <int, int>(0, 0));
                                }
                                if (componentSettings[c.ToString()].Item1 <0 || componentSettings[c.ToString()].Item1> c.Count - 1)
                                {
                                    componentSettings[c.ToString()] = new Tuple <int, int>(0, componentSettings[c.ToString()].Item2);
                                }
                                if (componentSettings[c.ToString()].Item2 <0 || componentSettings[c.ToString()].Item2> c.TextureCount - 1)
                                {
                                    componentSettings[c.ToString()] = new Tuple <int, int>(componentSettings[c.ToString()].Item1, 0);
                                }
                                if (c.Count > 1)
                                {
                                    _menuItems.Add(new MenuItemHorSelector <int>
                                    {
                                        Title              = $@"{(componentAndPropRenamings.ContainsKey(c.ToString()) ? componentAndPropRenamings[c.ToString()] : c.ToString())}",
                                        state              = componentSettings[c.ToString()].Item1,
                                        Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                        wrapAround         = true,
                                        minState           = 0,
                                        maxState           = c.Count - 1,
                                        overrideDetailWith = $"{componentSettings[c.ToString()].Item1+1}/{c.Count}",
                                        OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) =>
                                        {
                                            componentSettings[c.ToString()] = new Tuple <int, int>(selectedAlternative, 0);
                                            Function.Call(Hash.SET_PED_COMPONENT_VARIATION, ped.Handle, Enum.GetNames(typeof(PedComponents)).ToList().IndexOf(c.ToString()), selectedAlternative, 0, 0);
                                        })
                                    });
                                }
                                if (c.TextureCount > 1)
                                {
                                    _menuItems.Add(new MenuItemHorSelector <int>
                                    {
                                        Title              = $@"{(componentAndPropRenamings.ContainsKey(c.ToString()) ? componentAndPropRenamings[c.ToString()] : c.ToString())}: Variants",
                                        state              = componentSettings[c.ToString()].Item2,
                                        Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                        wrapAround         = true,
                                        minState           = 0,
                                        maxState           = c.TextureCount - 1,
                                        overrideDetailWith = $"{componentSettings[c.ToString()].Item2+1}/{c.TextureCount}",
                                        OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { componentSettings[c.ToString()] = new Tuple <int, int>(componentSettings[c.ToString()].Item1, selectedAlternative);
                                                                                                                                               Function.Call(Hash.SET_PED_COMPONENT_VARIATION, ped.Handle, Enum.GetNames(typeof(PedComponents)).ToList().IndexOf(c.ToString()), componentSettings[c.ToString()].Item1, selectedAlternative, 0); })
                                    });
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"[PEDTESTMENU] Exception in ped components code; {ex.Message}");
                        }
                    });

                    props.ToList().ForEach(p =>
                    {
                        try
                        {
                            if (!propSettings.ContainsKey(p.ToString()))
                            {
                                propSettings.Add(p.ToString(), new Tuple <int, int>(0, 0));
                            }
                            if (propSettings[p.ToString()].Item1 <-1 || propSettings[p.ToString()].Item1> p.Count - 1)
                            {
                                componentSettings[p.ToString()] = new Tuple <int, int>(0, propSettings[p.ToString()].Item2);
                            }
                            if (propSettings[p.ToString()].Item2 <0 || propSettings[p.ToString()].Item2> p.TextureCount - 1)
                            {
                                propSettings[p.ToString()] = new Tuple <int, int>(propSettings[p.ToString()].Item1, 0);
                            }
                            if (p.Count > 1)
                            {
                                _menuItems.Add(new MenuItemHorSelector <int>
                                {
                                    Title              = $@"{(componentAndPropRenamings.ContainsKey(p.ToString()) ? componentAndPropRenamings[p.ToString()] : p.ToString())}",
                                    state              = propSettings[p.ToString()].Item1,
                                    Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                    wrapAround         = true,
                                    minState           = -1,
                                    maxState           = p.Count - 1,
                                    overrideDetailWith = $"{propSettings[p.ToString()].Item1 + 2}/{p.Count + 1}",
                                    OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { propSettings[p.ToString()] = new Tuple <int, int>(selectedAlternative, 0);
                                                                                                                                           if (selectedAlternative == -1)
                                                                                                                                           {
                                                                                                                                               Function.Call(Hash.CLEAR_PED_PROP, ped.Handle, Enum.GetNames(typeof(PedProps)).ToList().IndexOf(p.ToString()));
                                                                                                                                           }
                                                                                                                                           else
                                                                                                                                           {
                                                                                                                                               Function.Call(Hash.SET_PED_PROP_INDEX, ped.Handle, Enum.GetNames(typeof(PedProps)).ToList().IndexOf(p.ToString()), selectedAlternative, 0, false);
                                                                                                                                           } })
                                });
                            }
                            if (p.TextureCount > 1)
                            {
                                _menuItems.Add(new MenuItemHorSelector <int>
                                {
                                    Title              = $"{(componentAndPropRenamings.ContainsKey(p.ToString()) ? componentAndPropRenamings[p.ToString()] : p.ToString())}: Variants",
                                    state              = propSettings[p.ToString()].Item2,
                                    Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                    wrapAround         = true,
                                    minState           = 0,
                                    maxState           = p.TextureCount - 1,
                                    overrideDetailWith = $"{propSettings[p.ToString()].Item2 + 1}/{p.TextureCount}",
                                    OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => { propSettings[p.ToString()] = new Tuple <int, int>(propSettings[p.ToString()].Item1, selectedAlternative);
                                                                                                                                           Function.Call(Hash.SET_PED_PROP_INDEX, ped.Handle, Enum.GetNames(typeof(PedProps)).ToList().IndexOf(p.ToString()), propSettings[p.ToString()].Item1, selectedAlternative, false); })
                                });
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"[PEDTESTMENU] Exception in ped props code; {ex.Message}");
                        }
                    });
                }

                _menuItems.Add(new MenuItemHorNamedSelector
                {
                    Title              = $"Walking Style",
                    state              = walkingStyleIndex,
                    Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                    wrapAround         = true,
                    optionList         = walkingStyles,
                    overrideDetailWith = walkingStyles[walkingStyleIndex].Replace("move_m@", "").Replace("move_f@", "").Replace("@", " ").AddSpacesToCamelCase().Replace("_", " ").ToTitleCase(),
                    OnChange           = new Action <int, string, MenuItemHorNamedSelector>(async(selectedAlternative, selName, menuItem) => {
                        walkingStyleIndex = selectedAlternative;
                        if (walkingStyleIndex == 0)
                        {
                            Function.Call(Hash.RESET_PED_MOVEMENT_CLIPSET, Game.PlayerPed.Handle);
                        }
                        else
                        {
                            Function.Call(Hash.REQUEST_CLIP_SET, walkingStyles[selectedAlternative]);
                            Function.Call(Hash.SET_PED_MOVEMENT_CLIPSET, ped.Handle, walkingStyles[selectedAlternative], 0.25f);
                            await BaseScript.Delay(1000);
                            if (walkingStyleIndex == selectedAlternative)
                            {
                                Function.Call(Hash.SET_PED_MOVEMENT_CLIPSET, ped.Handle, walkingStyles[selectedAlternative], 0.25f);
                            }
                        }
                    })
                });

                visibleItems  = _menuItems.Slice(visibleItems.IndexOf(menuItems.First()), visibleItems.IndexOf(menuItems.Last()));
                menuItems     = _menuItems;
                SelectedIndex = SelectedIndex; // refreshes state
            }
Ejemplo n.º 2
0
            public override void Refresh()
            {
                var _menuItems           = new List <MenuItem>();
                var ped                  = Game.PlayerPed;
                int selectedPedHashIndex = PedHashValues.Contains((PedHash)ped.Model.Hash) ? PedHashValues.IndexOf((PedHash)ped.Model.Hash) : 0;

                if (Game.PlayerPed.Exists())
                {
                    /*_menuItems.Add(new MenuItemHorNamedSelector
                     * {
                     *  Title = $"Skin",
                     *  Description = "Activate to replace your current skin.",
                     *  state = menuItems[0] is MenuItemHorNamedSelector ? (menuItems[0] as MenuItemHorNamedSelector).state : selectedPedHashIndex,
                     *  Type = MenuItemHorizontalSelectorType.NumberAndBar,
                     *  wrapAround = true,
                     *  optionList = PedHashNames,
                     *  OnActivate = new Action<int, string, MenuItemHorNamedSelector>(async (selectedAlternative, selName, menuItem) => {
                     *      await ReplaceCurrentPedModelByIndex(selectedAlternative); componentSettings.Clear(); propSettings.Clear();
                     *  })
                     * });*/

                    PedComponent[] components = Game.PlayerPed.Style.GetAllComponents();
                    PedProp[]      props      = Game.PlayerPed.Style.GetAllProps();

                    components.ToList().ForEach(c =>
                    {
                        try
                        {
                            if (!(c.ToString() == "Face") || (!((PedHash)ped.Model.Hash == PedHash.FreemodeMale01) && !((PedHash)ped.Model.Hash == PedHash.FreemodeFemale01))) // Since Face doesn't work on freemode characters (if you use the blending/morphing option anyway, which everybody should be)
                            {
                                if (!componentSettings.ContainsKey(c.ToString()))
                                {
                                    componentSettings.Add(c.ToString(), new Tuple <int, int>(0, 0));
                                }
                                if (componentSettings[c.ToString()].Item1 <0 || componentSettings[c.ToString()].Item1> c.Count - 1)
                                {
                                    componentSettings[c.ToString()] = new Tuple <int, int>(0, componentSettings[c.ToString()].Item2);
                                }
                                if (componentSettings[c.ToString()].Item2 <0 || componentSettings[c.ToString()].Item2> c.TextureCount - 1)
                                {
                                    componentSettings[c.ToString()] = new Tuple <int, int>(componentSettings[c.ToString()].Item1, 0);
                                }
                                if (c.Count > 1)
                                {
                                    _menuItems.Add(new MenuItemHorSelector <int>
                                    {
                                        Title              = $@"{(componentAndPropRenamings.ContainsKey(c.ToString()) ? componentAndPropRenamings[c.ToString()] : c.ToString())}",
                                        state              = componentSettings[c.ToString()].Item1,
                                        Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                        wrapAround         = true,
                                        minState           = 0,
                                        maxState           = c.Count - 1,
                                        overrideDetailWith = $"{componentSettings[c.ToString()].Item1 + 1}/{c.Count}",
                                        OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) =>
                                        {
                                            componentSettings[c.ToString()] = new Tuple <int, int>(selectedAlternative, 0);
                                            Function.Call(Hash.SET_PED_COMPONENT_VARIATION, ped.Handle, Enum.GetNames(typeof(PedComponents)).ToList().IndexOf(c.ToString()), selectedAlternative, 0, 0);
                                        })
                                    });
                                }
                                if (c.TextureCount > 1)
                                {
                                    _menuItems.Add(new MenuItemHorSelector <int>
                                    {
                                        Title              = $@"{(componentAndPropRenamings.ContainsKey(c.ToString()) ? componentAndPropRenamings[c.ToString()] : c.ToString())}: Variants",
                                        state              = componentSettings[c.ToString()].Item2,
                                        Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                        wrapAround         = true,
                                        minState           = 0,
                                        maxState           = c.TextureCount - 1,
                                        overrideDetailWith = $"{componentSettings[c.ToString()].Item2 + 1}/{c.TextureCount}",
                                        OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => {
                                            componentSettings[c.ToString()] = new Tuple <int, int>(componentSettings[c.ToString()].Item1, selectedAlternative);
                                            Function.Call(Hash.SET_PED_COMPONENT_VARIATION, ped.Handle, Enum.GetNames(typeof(PedComponents)).ToList().IndexOf(c.ToString()), componentSettings[c.ToString()].Item1, selectedAlternative, 0);
                                        })
                                    });
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"[POLICEPEDMENU] Exception in ped components code; {ex.Message}");
                        }
                    });

                    props.ToList().ForEach(p =>
                    {
                        try
                        {
                            if (!propSettings.ContainsKey(p.ToString()))
                            {
                                propSettings.Add(p.ToString(), new Tuple <int, int>(0, 0));
                            }
                            if (propSettings[p.ToString()].Item1 <-1 || propSettings[p.ToString()].Item1> p.Count - 1)
                            {
                                componentSettings[p.ToString()] = new Tuple <int, int>(0, propSettings[p.ToString()].Item2);
                            }
                            if (propSettings[p.ToString()].Item2 <0 || propSettings[p.ToString()].Item2> p.TextureCount - 1)
                            {
                                propSettings[p.ToString()] = new Tuple <int, int>(propSettings[p.ToString()].Item1, 0);
                            }
                            if (p.Count > 1)
                            {
                                _menuItems.Add(new MenuItemHorSelector <int>
                                {
                                    Title              = $@"{(componentAndPropRenamings.ContainsKey(p.ToString()) ? componentAndPropRenamings[p.ToString()] : p.ToString())}",
                                    state              = propSettings[p.ToString()].Item1,
                                    Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                    wrapAround         = true,
                                    minState           = -1,
                                    maxState           = p.Count - 1,
                                    overrideDetailWith = $"{propSettings[p.ToString()].Item1 + 2}/{p.Count + 1}",
                                    OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => {
                                        propSettings[p.ToString()] = new Tuple <int, int>(selectedAlternative, 0);
                                        if (selectedAlternative == -1)
                                        {
                                            Function.Call(Hash.CLEAR_PED_PROP, ped.Handle, Enum.GetNames(typeof(PedProps)).ToList().IndexOf(p.ToString()));
                                        }
                                        else
                                        {
                                            Function.Call(Hash.SET_PED_PROP_INDEX, ped.Handle, Enum.GetNames(typeof(PedProps)).ToList().IndexOf(p.ToString()), selectedAlternative, 0, false);
                                        }
                                    })
                                });
                            }
                            if (p.TextureCount > 1)
                            {
                                _menuItems.Add(new MenuItemHorSelector <int>
                                {
                                    Title              = $"{(componentAndPropRenamings.ContainsKey(p.ToString()) ? componentAndPropRenamings[p.ToString()] : p.ToString())}: Variants",
                                    state              = propSettings[p.ToString()].Item2,
                                    Type               = MenuItemHorizontalSelectorType.NumberAndBar,
                                    wrapAround         = true,
                                    minState           = 0,
                                    maxState           = p.TextureCount - 1,
                                    overrideDetailWith = $"{propSettings[p.ToString()].Item2 + 1}/{p.TextureCount}",
                                    OnChange           = new Action <int, MenuItemHorSelector <int> >((selectedAlternative, menuItem) => {
                                        propSettings[p.ToString()] = new Tuple <int, int>(propSettings[p.ToString()].Item1, selectedAlternative);
                                        Function.Call(Hash.SET_PED_PROP_INDEX, ped.Handle, Enum.GetNames(typeof(PedProps)).ToList().IndexOf(p.ToString()), propSettings[p.ToString()].Item1, selectedAlternative, false);
                                    })
                                });
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"[POLICEPEDMENU] Exception in ped props code; {ex.Message}");
                        }
                    });
                }

                visibleItems  = _menuItems.Slice(visibleItems.IndexOf(menuItems.First()), visibleItems.IndexOf(menuItems.Last()));
                menuItems     = _menuItems;
                SelectedIndex = SelectedIndex; // refreshes state
            }