/// <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); } }