/// <summary>
        /// Creates a preset for the <paramref name="vehicle"/> to edit it locally
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        /// <returns></returns>
        private VStancerPreset CreatePreset(int vehicle)
        {
            if (debug && IsVehicleDamaged(vehicle))
            {
                Screen.ShowNotification($"~o~Warning~w~: You are creating a vstancer preset for a damaged vehicle, default position and rotation of the wheels might be wrong");
            }

            int wheelsCount = GetVehicleNumberOfWheels(vehicle);
            int frontCount  = VStancerPreset.CalculateFrontWheelsCount(wheelsCount);

            // Get default values first
            float off_f_def         = DecorExistOn(vehicle, DefaultFrontOffsetID) ? DecorGetFloat(vehicle, DefaultFrontOffsetID) : GetVehicleWheelXOffset(vehicle, 0);
            float rot_f_def         = DecorExistOn(vehicle, DefaultFrontRotationID) ? DecorGetFloat(vehicle, DefaultFrontRotationID) : GetVehicleWheelYRotation(vehicle, 0);
            float off_r_def         = DecorExistOn(vehicle, DefaultRearOffsetID) ? DecorGetFloat(vehicle, DefaultRearOffsetID) : GetVehicleWheelXOffset(vehicle, frontCount);
            float rot_r_def         = DecorExistOn(vehicle, DefaultRearRotationID) ? DecorGetFloat(vehicle, DefaultRearRotationID) : GetVehicleWheelYRotation(vehicle, frontCount);
            float steering_lock_def = DecorExistOn(vehicle, DefaultSteeringLockID) ? DecorGetFloat(vehicle, DefaultSteeringLockID) : GetVehicleHandlingFloat(vehicle, "CHandlingData", "fSteeringLock");
            float susp_height_def   = DecorExistOn(vehicle, DefaultSuspensionHeightID) ? DecorGetFloat(vehicle, DefaultSuspensionHeightID) : GetVehicleHandlingFloat(vehicle, "CHandlingData", "fSuspensionRaise");;

            float off_f         = DecorExistOn(vehicle, FrontOffsetID) ? DecorGetFloat(vehicle, FrontOffsetID) : off_f_def;
            float rot_f         = DecorExistOn(vehicle, FrontRotationID) ? DecorGetFloat(vehicle, FrontRotationID) : rot_f_def;
            float off_r         = DecorExistOn(vehicle, RearOffsetID) ? DecorGetFloat(vehicle, RearOffsetID) : off_r_def;
            float rot_r         = DecorExistOn(vehicle, RearRotationID) ? DecorGetFloat(vehicle, RearRotationID) : rot_r_def;
            float steering_lock = DecorExistOn(vehicle, SteeringLockID) ? DecorGetFloat(vehicle, SteeringLockID) : steering_lock_def;
            float susp_height   = DecorExistOn(vehicle, SuspensionHeightID) ? DecorGetFloat(vehicle, SuspensionHeightID) : susp_height_def;

            return(new VStancerPreset(wheelsCount, off_f, rot_f, off_r, rot_r, steering_lock, susp_height, off_f_def, rot_f_def, off_r_def, rot_r_def, steering_lock_def, susp_height_def));
        }
        /// <summary>
        /// Updates the decorators on the <paramref name="vehicle"/> with updated values from the <paramref name="preset"/>
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        /// <param name="preset">The preset for this vehicle</param>
        private void UpdateVehicleDecorators(int vehicle, VStancerPreset preset)
        {
            float[] DefaultOffsetX          = preset.DefaultOffsetX;
            float[] DefaultRotationY        = preset.DefaultRotationY;
            float[] OffsetX                 = preset.OffsetX;
            float[] RotationY               = preset.RotationY;
            float   SteeringLock            = preset.SteeringLock;
            float   DefaultSteeringLock     = preset.DefaultSteeringLock;
            float   SuspensionHeight        = preset.SuspensionHeight;
            float   DefaultSuspensionHeight = preset.DefaultSuspensionHeight;
            int     frontCount              = preset.FrontWheelsCount;

            UpdateFloatDecorator(vehicle, DefaultFrontOffsetID, DefaultOffsetX[0], OffsetX[0]);
            UpdateFloatDecorator(vehicle, DefaultFrontRotationID, DefaultRotationY[0], RotationY[0]);
            UpdateFloatDecorator(vehicle, DefaultRearOffsetID, DefaultOffsetX[frontCount], OffsetX[frontCount]);
            UpdateFloatDecorator(vehicle, DefaultRearRotationID, DefaultRotationY[frontCount], RotationY[frontCount]);
            UpdateFloatDecorator(vehicle, DefaultSteeringLockID, DefaultSteeringLock, SteeringLock);
            UpdateFloatDecorator(vehicle, DefaultSuspensionHeightID, DefaultSuspensionHeight, SuspensionHeight);

            UpdateFloatDecorator(vehicle, FrontOffsetID, OffsetX[0], DefaultOffsetX[0]);
            UpdateFloatDecorator(vehicle, FrontRotationID, RotationY[0], DefaultRotationY[0]);
            UpdateFloatDecorator(vehicle, RearOffsetID, OffsetX[frontCount], DefaultOffsetX[frontCount]);
            UpdateFloatDecorator(vehicle, RearRotationID, RotationY[frontCount], DefaultRotationY[frontCount]);
            UpdateFloatDecorator(vehicle, SteeringLockID, SteeringLock, DefaultSteeringLock);
            UpdateFloatDecorator(vehicle, SuspensionHeightID, SuspensionHeight, DefaultSuspensionHeight);
        }
        /// <summary>
        /// Refreshes the <paramref name="vehicle"/> with values from the <paramref name="preset"/>
        /// </summary>
        private void RefreshVehicleUsingPreset(int vehicle, VStancerPreset preset)
        {
            if (!DoesEntityExist(vehicle) || preset == null)
            {
                return;
            }

            int wheelsCount = preset.WheelsCount;

            for (int index = 0; index < wheelsCount; index++)
            {
                SetVehicleWheelXOffset(vehicle, index, preset.OffsetX[index]);
                SetVehicleWheelYRotation(vehicle, index, preset.RotationY[index]);
            }
        }
        /// <summary>
        /// Refreshes the <paramref name="vehicle"/> with values from the <paramref name="preset"/>
        /// </summary>
        private void RefreshVehicleUsingPreset(int vehicle, VStancerPreset preset)
        {
            if (!DoesEntityExist(vehicle) || preset == null)
            {
                return;
            }

            int wheelsCount = preset.WheelsCount;

            for (int index = 0; index < wheelsCount; index++)
            {
                SetVehicleWheelXOffset(vehicle, index, preset.OffsetX[index]);
                SetVehicleWheelYRotation(vehicle, index, preset.RotationY[index]);
            }
            SetVehicleHandlingFloat(vehicle, "CHandlingData", "fSteeringLock", preset.SteeringLock);
            SetVehicleHandlingFloat(vehicle, "CHandlingData", "fSuspensionRaise", preset.SuspensionHeight);
        }
        /// <summary>
        /// Updates the decorators on the <paramref name="vehicle"/> with updated values from the <paramref name="preset"/>
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        /// <param name="preset">The preset for this vehicle</param>
        private void UpdateVehicleDecorators(int vehicle, VStancerPreset preset)
        {
            float[] DefaultOffsetX   = preset.DefaultOffsetX;
            float[] DefaultRotationY = preset.DefaultRotationY;
            float[] OffsetX          = preset.OffsetX;
            float[] RotationY        = preset.RotationY;
            int     frontCount       = preset.FrontWheelsCount;

            UpdateFloatDecorator(vehicle, DefaultFrontOffsetID, DefaultOffsetX[0], OffsetX[0]);
            UpdateFloatDecorator(vehicle, DefaultFrontRotationID, DefaultRotationY[0], RotationY[0]);
            UpdateFloatDecorator(vehicle, DefaultRearOffsetID, DefaultOffsetX[frontCount], OffsetX[frontCount]);
            UpdateFloatDecorator(vehicle, DefaultRearRotationID, DefaultRotationY[frontCount], RotationY[frontCount]);

            UpdateFloatDecorator(vehicle, FrontOffsetID, OffsetX[0], DefaultOffsetX[0]);
            UpdateFloatDecorator(vehicle, FrontRotationID, RotationY[0], DefaultRotationY[0]);
            UpdateFloatDecorator(vehicle, RearOffsetID, OffsetX[frontCount], DefaultOffsetX[frontCount]);
            UpdateFloatDecorator(vehicle, RearRotationID, RotationY[frontCount], DefaultRotationY[frontCount]);
        }
        /// <summary>
        /// Updates the <see cref="currentVehicle"/> and the <see cref="currentPreset"/>
        /// </summary>
        /// <returns></returns>
        private async Task GetCurrentVehicle()
        {
            playerPed = PlayerPedId();

            if (IsPedInAnyVehicle(playerPed, false))
            {
                int vehicle = GetVehiclePedIsIn(playerPed, false);

                if (IsThisModelACar((uint)GetEntityModel(vehicle)) && GetPedInVehicleSeat(vehicle, -1) == playerPed && IsVehicleDriveable(vehicle, false))
                {
                    // Update current vehicle and get its preset
                    if (vehicle != currentVehicle)
                    {
                        currentPreset  = CreatePreset(vehicle);
                        currentVehicle = vehicle;
                        PresetChanged?.Invoke(this, EventArgs.Empty);
                        Tick += UpdateCurrentVehicle;
                    }
                }
                else
                {
                    if (CurrentPresetIsValid)
                    {
                        // If current vehicle isn't a car or player isn't driving current vehicle or vehicle is dead
                        currentPreset  = null;
                        currentVehicle = -1;
                        Tick          -= UpdateCurrentVehicle;
                    }
                }
            }
            else
            {
                if (CurrentPresetIsValid)
                {
                    // If player isn't in any vehicle
                    currentPreset  = null;
                    currentVehicle = -1;
                    Tick          -= UpdateCurrentVehicle;
                }
            }

            await Task.FromResult(0);
        }
        /// <summary>
        /// Refreshes the <paramref name="vehicle"/> with values from its decorators (if exist)
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        private void RefreshVehicleUsingDecorators(int vehicle)
        {
            int wheelsCount = GetVehicleNumberOfWheels(vehicle);
            int frontCount  = VStancerPreset.CalculateFrontWheelsCount(wheelsCount);

            if (DecorExistOn(vehicle, FrontOffsetID))
            {
                float value = DecorGetFloat(vehicle, FrontOffsetID);

                for (int index = 0; index < frontCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelXOffset(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelXOffset(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, FrontRotationID))
            {
                float value = DecorGetFloat(vehicle, FrontRotationID);

                for (int index = 0; index < frontCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelYRotation(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelYRotation(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, RearOffsetID))
            {
                float value = DecorGetFloat(vehicle, RearOffsetID);

                for (int index = frontCount; index < wheelsCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelXOffset(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelXOffset(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, RearRotationID))
            {
                float value = DecorGetFloat(vehicle, RearRotationID);

                for (int index = frontCount; index < wheelsCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelYRotation(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelYRotation(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, SteeringLockID))
            {
                float value = DecorGetFloat(vehicle, SteeringLockID);
                SetVehicleHandlingFloat(vehicle, "CHandlingData", "fSteeringLock", value);
            }

            if (DecorExistOn(vehicle, SuspensionHeightID))
            {
                float value = DecorGetFloat(vehicle, SuspensionHeightID);
                SetVehicleHandlingFloat(vehicle, "CHandlingData", "fSuspensionRaise", value);
            }
        }
        /// <summary>
        /// Loads a Vstancer preset for the <paramref name="vehicle"/> with the specified values.
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        /// <param name="frontOffset">The front offset value</param>
        /// <param name="frontRotation">The front rotation value</param>
        /// <param name="rearOffset">The rear offset value</param>
        /// <param name="rearRotation">The rear rotation value</param>
        /// <param name="steeringLock">Steering lock value</param>
        /// <param name="suspensionHeight">Suspension height value</param>
        /// <param name="defaultFrontOffset">The default front offset value</param>
        /// <param name="defaultFrontRotation">The default front rotation value</param>
        /// <param name="defaultRearOffset">The default rear offset value</param>
        /// <param name="defaultRearRotation">The default rear rotation value</param>
        /// <param name="defaultSteeringLock">The default steering lock value</param>
        /// <param name="defaultSuspensionHeight">The default suspension height value</param>
        public void SetVstancerPreset(int vehicle, float frontOffset, float frontRotation, float rearOffset, float rearRotation, float steeringLock, float suspensionHeight, object defaultFrontOffset = null, object defaultFrontRotation = null, object defaultRearOffset = null, object defaultRearRotation = null, object defaultSteeringLock = null, object defaultSuspensionHeight = null)
        {
            if (debug)
            {
                Debug.WriteLine($"{ScriptName}: SetVstancerPreset parameters {frontOffset} {frontRotation} {rearOffset} {rearRotation} {steeringLock} {suspensionHeight} {defaultFrontOffset} {defaultFrontRotation} {defaultRearOffset} {defaultRearRotation} {defaultSteeringLock} {defaultSuspensionHeight}");
            }

            if (!DoesEntityExist(vehicle))
            {
                return;
            }

            int wheelsCount = GetVehicleNumberOfWheels(vehicle);
            int frontCount  = VStancerPreset.CalculateFrontWheelsCount(wheelsCount);

            float off_f_def, rot_f_def, off_r_def, rot_r_def, steering_lock_def, susp_height_def;

            if (defaultFrontOffset != null && defaultFrontOffset is float)
            {
                off_f_def = (float)defaultFrontOffset;
            }
            else
            {
                off_f_def = DecorExistOn(vehicle, DefaultFrontOffsetID) ? DecorGetFloat(vehicle, DefaultFrontOffsetID) : GetVehicleWheelXOffset(vehicle, 0);
            }

            if (defaultFrontRotation != null && defaultFrontRotation is float)
            {
                rot_f_def = (float)defaultFrontRotation;
            }
            else
            {
                rot_f_def = DecorExistOn(vehicle, DefaultFrontRotationID) ? DecorGetFloat(vehicle, DefaultFrontRotationID) : GetVehicleWheelYRotation(vehicle, 0);
            }

            if (defaultRearOffset != null && defaultRearOffset is float)
            {
                off_r_def = (float)defaultRearOffset;
            }
            else
            {
                off_r_def = DecorExistOn(vehicle, DefaultRearOffsetID) ? DecorGetFloat(vehicle, DefaultRearOffsetID) : GetVehicleWheelXOffset(vehicle, frontCount);
            }

            if (defaultRearRotation != null && defaultRearRotation is float)
            {
                rot_r_def = (float)defaultRearRotation;
            }
            else
            {
                rot_r_def = DecorExistOn(vehicle, DefaultRearRotationID) ? DecorGetFloat(vehicle, DefaultRearRotationID) : GetVehicleWheelYRotation(vehicle, frontCount);
            }

            if (defaultSteeringLock != null && defaultSteeringLock is float)
            {
                steering_lock_def = (float)defaultSteeringLock;
            }
            else
            {
                steering_lock_def = DecorExistOn(vehicle, DefaultSteeringLockID) ? DecorGetFloat(vehicle, DefaultSteeringLockID) : GetVehicleHandlingFloat(vehicle, "CHandlingData", "fSteeringLock");
            }

            if (defaultSuspensionHeight != null && defaultSuspensionHeight is float)
            {
                susp_height_def = (float)defaultSuspensionHeight;
            }
            else
            {
                susp_height_def = DecorExistOn(vehicle, DefaultSuspensionHeightID) ? DecorGetFloat(vehicle, DefaultSuspensionHeightID) : GetVehicleHandlingFloat(vehicle, "CHandlingData", "fSuspensionRaise");
            }

            if (vehicle == currentVehicle)
            {
                currentPreset = new VStancerPreset(wheelsCount, frontOffset, frontRotation, rearOffset, rearRotation, steeringLock, suspensionHeight, off_f_def, rot_f_def, off_r_def, rot_r_def, steering_lock_def, susp_height_def);
                PresetChanged?.Invoke(this, EventArgs.Empty);
            }
            else
            {
                UpdateFloatDecorator(vehicle, DefaultFrontOffsetID, off_f_def, frontOffset);
                UpdateFloatDecorator(vehicle, DefaultFrontRotationID, rot_f_def, frontRotation);
                UpdateFloatDecorator(vehicle, DefaultRearOffsetID, off_r_def, rearOffset);
                UpdateFloatDecorator(vehicle, DefaultRearRotationID, rot_r_def, rearRotation);
                UpdateFloatDecorator(vehicle, DefaultSteeringLockID, steering_lock_def, steeringLock);
                UpdateFloatDecorator(vehicle, DefaultSuspensionHeightID, susp_height_def, suspensionHeight);

                UpdateFloatDecorator(vehicle, FrontOffsetID, frontOffset, off_f_def);
                UpdateFloatDecorator(vehicle, FrontRotationID, frontRotation, rot_f_def);
                UpdateFloatDecorator(vehicle, RearOffsetID, rearOffset, off_r_def);
                UpdateFloatDecorator(vehicle, RearRotationID, rearRotation, rot_r_def);
                UpdateFloatDecorator(vehicle, SteeringLockID, steeringLock, steering_lock_def);
                UpdateFloatDecorator(vehicle, SuspensionHeightID, suspensionHeight, susp_height_def);
            }
        }
        /// <summary>
        /// Returns the preset as an array of floats containing in order:
        /// frontOffset, frontRotation, rearOffset, rearRotation, defaultFrontOffset, defaultFrontRotation, defaultRearOffset, defaultRearRotation
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        /// <returns>The float array</returns>
        public float[] GetVstancerPreset(int vehicle)
        {
            VStancerPreset preset = (vehicle == currentVehicle && CurrentPresetIsValid) ? currentPreset : CreatePreset(vehicle);

            return(preset.ToArray());
        }
        public VStancerEditor()
        {
            // If the resource name is not the expected one ...
            if (GetCurrentResourceName() != ResourceName)
            {
                CitizenFX.Core.Debug.WriteLine($"{ScriptName}: Invalid resource name, be sure the resource name is {ResourceName}");
                return;
            }

            lastTime       = GetGameTimer();
            currentVehicle = -1;
            currentPreset  = null;
            vehicles       = Enumerable.Empty <int>();

            RegisterDecorators();
            LoadConfig();

            #region Register Commands

            RegisterCommand("vstancer_range", new Action <int, dynamic>((source, args) =>
            {
                if (args.Count < 1)
                {
                    Debug.WriteLine($"{ScriptName}: Missing float argument");
                    return;
                }

                if (float.TryParse(args[0], out float value))
                {
                    ScriptRange = value;
                    Debug.WriteLine($"{ScriptName}: Received new {nameof(ScriptRange)} value {value}");
                }
                else
                {
                    Debug.WriteLine($"{ScriptName}: Error parsing {args[0]} as float");
                }
            }), false);

            RegisterCommand("vstancer_debug", new Action <int, dynamic>((source, args) =>
            {
                if (args.Count < 1)
                {
                    Debug.WriteLine($"{ScriptName}: Missing bool argument");
                    return;
                }

                if (bool.TryParse(args[0], out bool value))
                {
                    debug = value;
                    Debug.WriteLine($"{ScriptName}: Received new {nameof(debug)} value {value}");
                }
                else
                {
                    Debug.WriteLine($"{ScriptName}: Error parsing {args[0]} as bool");
                }
            }), false);

            RegisterCommand("vstancer_decorators", new Action <int, dynamic>((source, args) =>
            {
                if (args.Count < 1)
                {
                    PrintDecoratorsInfo(currentVehicle);
                }
                else
                {
                    if (int.TryParse(args[0], out int value))
                    {
                        PrintDecoratorsInfo(value);
                    }
                    else
                    {
                        Debug.WriteLine($"{ScriptName}: Error parsing entity handle {args[0]} as int");
                    }
                }
            }), false);

            RegisterCommand("vstancer_preset", new Action <int, dynamic>((source, args) =>
            {
                if (currentPreset != null)
                {
                    Debug.WriteLine(currentPreset.ToString());
                }
                else
                {
                    Debug.WriteLine($"{ScriptName}: Current preset doesn't exist");
                }
            }), false);

            RegisterCommand("vstancer_print", new Action <int, dynamic>((source, args) =>
            {
                PrintVehiclesWithDecorators(vehicles);
            }), false);

            #endregion


            if (exposeCommand)
            {
                RegisterCommand("vstancer", new Action <int, dynamic>((source, args) =>
                {
                    ToggleMenuVisibility?.Invoke(this, EventArgs.Empty);
                }), false);
            }

            if (exposeEvent)
            {
                EventHandlers.Add("vstancer:toggleMenu", new Action(() =>
                {
                    ToggleMenuVisibility?.Invoke(this, EventArgs.Empty);
                }));
            }


            Exports.Add("SetVstancerPreset", new Action <int, float, float, float, float, float, float, object, object, object, object, object, object>(SetVstancerPreset));
            Exports.Add("GetVstancerPreset", new Func <int, float[]>(GetVstancerPreset));

            // Create a script for the menu ...
            vstancerMenu = new VStancerMenu(this);

            if (vstancerMenu != null)
            {
                // Actually only required to have its Tick event triggered
                // TODO: Workaround this and avoid to register the script
                RegisterScript(vstancerMenu);
            }

            vstancerMenu.MenuResetPresetButtonPressed += (sender, args) => OnMenuResetPresetButtonPressed();
            vstancerMenu.MenuPresetValueChanged       += OnMenuPresetValueChanged;

            Tick += GetCurrentVehicle;
            Tick += UpdateCurrentVehicle;
            Tick += UpdateWorldVehicles;
            Tick += UpdateCurrentVehicleDecorators;
        }
        /// <summary>
        /// Refreshes the <paramref name="vehicle"/> with values from its decorators (if exist)
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        private void RefreshVehicleUsingDecorators(int vehicle)
        {
            int wheelsCount = GetVehicleNumberOfWheels(vehicle);
            int frontCount  = VStancerPreset.CalculateFrontWheelsCount(wheelsCount);

            if (DecorExistOn(vehicle, FrontOffsetID))
            {
                float value = DecorGetFloat(vehicle, FrontOffsetID);

                for (int index = 0; index < frontCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelXOffset(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelXOffset(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, FrontRotationID))
            {
                float value = DecorGetFloat(vehicle, FrontRotationID);

                for (int index = 0; index < frontCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelYRotation(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelYRotation(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, RearOffsetID))
            {
                float value = DecorGetFloat(vehicle, RearOffsetID);

                for (int index = frontCount; index < wheelsCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelXOffset(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelXOffset(vehicle, index, -value);
                    }
                }
            }

            if (DecorExistOn(vehicle, RearRotationID))
            {
                float value = DecorGetFloat(vehicle, RearRotationID);

                for (int index = frontCount; index < wheelsCount; index++)
                {
                    if (index % 2 == 0)
                    {
                        SetVehicleWheelYRotation(vehicle, index, value);
                    }
                    else
                    {
                        SetVehicleWheelYRotation(vehicle, index, -value);
                    }
                }
            }
        }
        /// <summary>
        /// Loads a Vstancer preset for the <paramref name="vehicle"/> with the specified values.
        /// </summary>
        /// <param name="vehicle">The handle of the entity</param>
        /// <param name="frontOffset">The front offset value</param>
        /// <param name="frontRotation">The front rotation value</param>
        /// <param name="rearOffset">The rear offset value</param>
        /// <param name="rearRotation">The rear rotation value</param>
        /// <param name="defaultFrontOffset">The default front offset value</param>
        /// <param name="defaultFrontRotation">The default front rotation value</param>
        /// <param name="defaultRearOffset">The default rear offset value</param>
        /// <param name="defaultRearRotation">The default rear rotation value</param>
        public void SetVstancerPreset(int vehicle, float frontOffset, float frontRotation, float rearOffset, float rearRotation, object defaultFrontOffset = null, object defaultFrontRotation = null, object defaultRearOffset = null, object defaultRearRotation = null)
        {
            if (debug)
            {
                Debug.WriteLine($"{ScriptName}: SetVstancerPreset parameters {frontOffset} {frontRotation} {rearOffset} {rearRotation} {defaultFrontOffset} {defaultFrontRotation} {defaultRearOffset} {defaultRearRotation}");
            }

            if (!DoesEntityExist(vehicle))
            {
                return;
            }

            int wheelsCount = GetVehicleNumberOfWheels(vehicle);
            int frontCount  = VStancerPreset.CalculateFrontWheelsCount(wheelsCount);

            float off_f_def, rot_f_def, off_r_def, rot_r_def;

            if (defaultFrontOffset != null && defaultFrontOffset is float)
            {
                off_f_def = (float)defaultFrontOffset;
            }
            else
            {
                off_f_def = DecorExistOn(vehicle, DefaultFrontOffsetID) ? DecorGetFloat(vehicle, DefaultFrontOffsetID) : GetVehicleWheelXOffset(vehicle, 0);
            }

            if (defaultFrontRotation != null && defaultFrontRotation is float)
            {
                rot_f_def = (float)defaultFrontRotation;
            }
            else
            {
                rot_f_def = DecorExistOn(vehicle, DefaultFrontRotationID) ? DecorGetFloat(vehicle, DefaultFrontRotationID) : GetVehicleWheelYRotation(vehicle, 0);
            }

            if (defaultRearOffset != null && defaultRearOffset is float)
            {
                off_r_def = (float)defaultRearOffset;
            }
            else
            {
                off_r_def = DecorExistOn(vehicle, DefaultRearOffsetID) ? DecorGetFloat(vehicle, DefaultRearOffsetID) : GetVehicleWheelXOffset(vehicle, frontCount);
            }

            if (defaultRearRotation != null && defaultRearRotation is float)
            {
                rot_r_def = (float)defaultRearRotation;
            }
            else
            {
                rot_r_def = DecorExistOn(vehicle, DefaultRearRotationID) ? DecorGetFloat(vehicle, DefaultRearRotationID) : GetVehicleWheelYRotation(vehicle, frontCount);
            }

            if (vehicle == currentVehicle)
            {
                currentPreset = new VStancerPreset(wheelsCount, frontOffset, frontRotation, rearOffset, rearRotation, off_f_def, rot_f_def, off_r_def, rot_r_def);
                PresetChanged?.Invoke(this, EventArgs.Empty);
            }
            else
            {
                UpdateFloatDecorator(vehicle, DefaultFrontOffsetID, off_f_def, frontOffset);
                UpdateFloatDecorator(vehicle, DefaultFrontRotationID, rot_f_def, frontRotation);
                UpdateFloatDecorator(vehicle, DefaultRearOffsetID, off_r_def, rearOffset);
                UpdateFloatDecorator(vehicle, DefaultRearRotationID, rot_r_def, rearRotation);

                UpdateFloatDecorator(vehicle, FrontOffsetID, frontOffset, off_f_def);
                UpdateFloatDecorator(vehicle, FrontRotationID, frontRotation, rot_f_def);
                UpdateFloatDecorator(vehicle, RearOffsetID, rearOffset, off_r_def);
                UpdateFloatDecorator(vehicle, RearRotationID, rearRotation, rot_r_def);
            }
        }