From 211e7e4a7d19d6933249db98405fcbc4975d4888 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Wed, 16 Aug 2023 20:48:02 -0400 Subject: [PATCH 01/49] Starting work on FH4 speed o meter Intergration --- vMenu/MainMenu.cs | 2 +- vMenu/menus/PluginsMenu.cs | 29 +++++++++++++++++++++++--- vMenuServer/plugin-config.lua | 2 ++ vMenuServer/plugins/fh4speedometer.lua | 5 +++++ 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 vMenuServer/plugins/fh4speedometer.lua diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index ddab6177..4d6c47d4 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -895,7 +895,7 @@ private static void CreateSubmenus() { PluginSettingsMenu = new PluginSettings(); var menu = PluginSettingsMenu.GetMenu(); - var button = new MenuItem("Plugins Menu", "Miscellaneous vMenu options/settings can be configured here. You can also save your settings in this menu.") + var button = new MenuItem("Plugins Menu", "Plugins settings/status.") { Label = "→→→" }; diff --git a/vMenu/menus/PluginsMenu.cs b/vMenu/menus/PluginsMenu.cs index 3648b61c..e1ab4467 100644 --- a/vMenu/menus/PluginsMenu.cs +++ b/vMenu/menus/PluginsMenu.cs @@ -21,7 +21,7 @@ public class PluginSettings public bool EDPBool { get; private set; } public bool WMBool { get; private set; } - + public bool FH4Bool { get; private set; } private static readonly LanguageManager Lm = new LanguageManager(); @@ -35,13 +35,18 @@ private void CreateMenu() Label = "(~g~Plugin~s~) →→→" }; - menu = new Menu(Game.Player.Name, "Plugins Menu"); + MenuItem wmstatus = new MenuItem("Wheelie Manager", "Wheelie Manager Status.") { Label = "(~g~Plugin~s~)" }; + MenuItem fh4status = new MenuItem("FH4 Speed O' Meter", "FH4 Speed O' Meter Status.") + { + Label = "(~g~Plugin~s~)" + }; + #region EasyDriftPlusMenu = Lm.GetMenu(new Menu("Easy Drift Plus Menu", "Easy Drift Plus Menu")); @@ -106,9 +111,27 @@ private void CreateMenu() wmstatus.Label = "(~r~Plugin~s~)"; } + + TriggerEvent("vMenu:FH4SpeedOMeter", new Action((Bool) => + { + FH4Bool = Bool; + })); + if (FH4Bool) + { + menu.AddMenuItem(fh4status); + } + else + { + menu.AddMenuItem(fh4status); + + fh4status.Enabled = false; + fh4status.LeftIcon = MenuItem.Icon.LOCK; + fh4status.Description = "This plugin isn't enabled."; + fh4status.Label = "(~r~Plugin~s~)"; + + } - #endregion #region Easy Drift Plus Submenu diff --git a/vMenuServer/plugin-config.lua b/vMenuServer/plugin-config.lua index 9da23798..dbe7ffc5 100644 --- a/vMenuServer/plugin-config.lua +++ b/vMenuServer/plugin-config.lua @@ -24,3 +24,5 @@ ConfigShared.vehiclelistwm = { -- per vehicle config } +-- fh4 speedometer config +ConfigShared.FH4SpeedOMeter = true -- toggle the FH4 Speed O' Meter plugin diff --git a/vMenuServer/plugins/fh4speedometer.lua b/vMenuServer/plugins/fh4speedometer.lua new file mode 100644 index 00000000..9d57a597 --- /dev/null +++ b/vMenuServer/plugins/fh4speedometer.lua @@ -0,0 +1,5 @@ +AddEventHandler("vMenu:FH4SpeedOMeter", function(cb) + TriggerEvent("FH4:FH4SpeedOMeter", function(Val) + cb(Val and ConfigShared.FH4SpeedOMeter) + end) +end) \ No newline at end of file From 81346abeffdf40ebfe129dc8f7722d72e14dad5a Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Fri, 18 Aug 2023 13:31:30 -0400 Subject: [PATCH 02/49] Updates Fixed Client time/weather, added commit from main, added name entry for the 6/6 engine mod, and removed Spanish from default languages. --- vMenu/EventManager.cs | 47 ++++++++++++++++--------- vMenu/FunctionsController.cs | 7 ++-- vMenu/menus/PlayerTimeWeatherOptions.cs | 12 +++++++ vMenu/menus/VehicleOptions.cs | 4 +++ vMenuServer/fxmanifest.lua | 2 +- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/vMenu/EventManager.cs b/vMenu/EventManager.cs index 321f1a25..06fe3195 100644 --- a/vMenu/EventManager.cs +++ b/vMenu/EventManager.cs @@ -52,12 +52,12 @@ public EventManager() EventHandlers.Add("vMenu:PrivateMessage", new Action(PrivateMessage)); EventHandlers.Add("vMenu:UpdateTeleportLocations", new Action(UpdateTeleportLocations)); - if (GetSettingsBool(Setting.vmenu_enable_weather_sync)) + if (!((!GetSettingsBool(Setting.vmenu_enable_weather_sync))||( false ))) { Tick += WeatherSync; } - if (GetSettingsBool(Setting.vmenu_enable_time_sync)) + if (!((!GetSettingsBool(Setting.vmenu_enable_time_sync))||( false ))) { Tick += TimeSync; } @@ -275,15 +275,22 @@ private async Task UpdateWeatherParticles() /// private async Task WeatherSync() { - await UpdateWeatherParticles(); - SetArtificialLightsState(IsBlackoutEnabled); - SetArtificialLightsStateAffectsVehicles(false); - if (GetNextWeatherType() != GetHashKey(GetServerWeather)) - { - SetWeatherTypeOvertimePersist(GetServerWeather, (float)WeatherChangeTime); - await Delay((WeatherChangeTime * 1000) + 2000); - TriggerEvent("vMenu:WeatherChangeComplete", GetServerWeather); + if (MainMenu.PlayerTimeWeatherOptionsMenu != null) + { + if (!MainMenu.PlayerTimeWeatherOptionsMenu.ClientWeatherTimeBool) + { + await UpdateWeatherParticles(); + SetArtificialLightsState(IsBlackoutEnabled); + SetArtificialLightsStateAffectsVehicles(false); + if (GetNextWeatherType() != GetHashKey(GetServerWeather)) + { + SetWeatherTypeOvertimePersist(GetServerWeather, (float)WeatherChangeTime); + await Delay((WeatherChangeTime * 1000) + 2000); + + TriggerEvent("vMenu:WeatherChangeComplete", GetServerWeather); + } + } } await Delay(1000); } @@ -294,14 +301,20 @@ private async Task WeatherSync() /// private async Task TimeSync() { - NetworkOverrideClockTime(GetServerHours, GetServerMinutes, 0); - if (IsServerTimeFrozen || IsServerTimeSyncedWithMachineTime) + if (MainMenu.PlayerTimeWeatherOptionsMenu != null) { - await Delay(5); - } - else - { - await Delay(MathUtil.Clamp(GetServerMinuteDuration, 100, 2000)); + if (!MainMenu.PlayerTimeWeatherOptionsMenu.ClientWeatherTimeBool) + { + NetworkOverrideClockTime(GetServerHours, GetServerMinutes, 0); + if (IsServerTimeFrozen || IsServerTimeSyncedWithMachineTime) + { + await Delay(5); + } + else + { + await Delay(MathUtil.Clamp(GetServerMinuteDuration, 100, 2000)); + } + } } } diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index 8c9483b8..46f54cbd 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -2318,12 +2318,12 @@ private async Task PlayerOverheadNamesControl() } else { - gamerTags[p] = CreateMpGamerTag(p.Character.Handle, p.Name + $" [{p.ServerId}]", false, false, "", 0); + gamerTags[p] = CreateMpGamerTag(p.Character.Handle, $" #{p.ServerId} | " + p.Name, false, false, "", 0); } } else if (closeEnough) { - gamerTags.Add(p, CreateMpGamerTag(p.Character.Handle, p.Name + $" [{p.ServerId}]", false, false, "", 0)); + gamerTags.Add(p, CreateMpGamerTag(p.Character.Handle, $" #{p.ServerId} | " + p.Name, false, false, "", 0)); } if (closeEnough && gamerTags.ContainsKey(p)) { @@ -3242,5 +3242,4 @@ public async Task TeleportOptions() } } } -} - +} \ No newline at end of file diff --git a/vMenu/menus/PlayerTimeWeatherOptions.cs b/vMenu/menus/PlayerTimeWeatherOptions.cs index c61ebfc0..812b0d48 100644 --- a/vMenu/menus/PlayerTimeWeatherOptions.cs +++ b/vMenu/menus/PlayerTimeWeatherOptions.cs @@ -26,6 +26,8 @@ public class PlayerTimeWeatherOptions public List weatherListData = new List() { "Clear", "ExtraSunny", "Clouds", "Overcast", "Rain", "Clearing", "Thunder", "Smog", "Foggy", "Xmas", "Snowlight", "Blizzard", "Snow", "Halloween", "Neutral" }; public MenuListItem weatherList; + public bool ClientWeatherTimeBool; + /// /// Creates the menu. /// @@ -46,6 +48,16 @@ private void CreateMenu() weatherList = new MenuListItem("Change Weather", weatherListData, 0, "Select weather."); menu.AddMenuItem(weatherList); + + + + menu.OnCheckboxChange += (_menu, _item, _index, _checked) => { + if (_item == clientSidedEnabled) + { + //Debug.WriteLine($"{_checked}"); + ClientWeatherTimeBool = _checked; + } + }; } /// diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index c8753856..271ff783 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1847,6 +1847,10 @@ public void UpdateMods(int selectedIndex = 0) // Create the name (again, converting to proper case), then add the name. name = mod.GetLocalizedModName(x) != "" ? $"{ToProperString(mod.GetLocalizedModName(x))} {currentItem}" : $"{typeName} #{x} {currentItem}"; + + if (name == "Engine #4 [6/6]") + modlist.Add("EMS Upgrade, Level 5 [6/6]"); + else modlist.Add(name); } diff --git a/vMenuServer/fxmanifest.lua b/vMenuServer/fxmanifest.lua index 136bf129..290cedea 100644 --- a/vMenuServer/fxmanifest.lua +++ b/vMenuServer/fxmanifest.lua @@ -15,7 +15,7 @@ ui_page 'storage.html' default_language "English" -- Add the names of the jsons added to config/languages here in the current format -languages 'English, Spanish' +languages 'English' -- Adds additional logging, useful when debugging issues. client_debug_mode 'false' From d80127b665055fa418d2722b5a56411eb61ea98d Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Fri, 18 Aug 2023 16:16:13 -0400 Subject: [PATCH 03/49] Added RGB/Color Finish sliders --- vMenu/menus/VehicleOptions.cs | 199 +++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 3 deletions(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 271ff783..cd3a2403 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -57,6 +57,14 @@ public class VehicleOptions public float VehicleTorqueMultiplierAmount { get; private set; } = 2f; public float VehiclePowerMultiplierAmount { get; private set; } = 2f; public bool isCorrectVehicleType { get; private set; } + public int RedPrimary { get; private set; } = 0; + public int GreenPrimary { get; private set; } = 0; + public int BluePrimary { get; private set; } = 0; + public int FinishPrimary { get; private set; } = 0; + public int RedSecondary { get; private set; } = 0; + public int GreenSecondary { get; private set; } = 0; + public int BlueSecondary { get; private set; } = 0; + public int FinishSecondary { get; private set; } = 0; private static readonly LanguageManager Lm = new LanguageManager(); @@ -987,7 +995,15 @@ private void CreateMenu() var secondaryColorsBtn = new MenuItem("Secondary Color") { Label = "→→→" }; VehicleColorsMenu.AddMenuItem(secondaryColorsBtn); MenuController.BindMenuItem(VehicleColorsMenu, secondaryColorsMenu, secondaryColorsBtn); - + var ColorFInishes = new List() + { + "Normal", + "Metallic", + "Pearl", + "Matte", + "Metal", + "Chrome", + }; // color lists var classic = new List(); var matte = new List(); @@ -1063,6 +1079,7 @@ private void CreateMenu() { if (item == chrome) { + ClearVehicleCustomPrimaryColour(veh.Handle); SetVehicleColours(veh.Handle, 120, 120); // chrome is index 120 } } @@ -1086,7 +1103,6 @@ private void CreateMenu() Notify.Error("You need to be the driver of a driveable vehicle to change this slider."); } }; - VehicleColorsMenu.AddMenuItem(dashColorList); VehicleColorsMenu.AddMenuItem(intColorList); VehicleColorsMenu.AddMenuItem(wheelColorsList); @@ -1147,7 +1163,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in SetVehicleModKit(veh.Handle, 0); } } - + ClearVehicleCustomPrimaryColour(veh.Handle); SetVehicleColours(veh.Handle, primaryColor, secondaryColor); } else if (sender == secondaryColorsMenu) @@ -1174,6 +1190,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in secondaryColor = VehicleData.WornColors[newIndex].id; break; } + ClearVehicleCustomPrimaryColour(veh.Handle); SetVehicleColours(veh.Handle, primaryColor, secondaryColor); } else if (sender == VehicleColorsMenu) @@ -1259,6 +1276,182 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in secondaryColorsMenu.OnListIndexChange += HandleListIndexChanges; } } + + var primaryColorsMenuRGB = Lm.GetMenu(new Menu("Vehicle Colors RGB", "Primary Colors RGB")); + MenuController.AddSubmenu(primaryColorsMenu, primaryColorsMenuRGB); + + var primaryColorsRGBBtn = new MenuItem("Primary Color RGB") { Label = "→→→" }; + primaryColorsMenu.AddMenuItem(primaryColorsRGBBtn); + MenuController.BindMenuItem(primaryColorsMenu, primaryColorsMenuRGB, primaryColorsRGBBtn); + MenuSliderItem RedSliderPrimary = new MenuSliderItem($"Red Color {RedPrimary}", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + + MenuSliderItem GreenSliderPrimary = new MenuSliderItem($"Green Color {GreenPrimary}", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + + MenuSliderItem BlueSliderPrimary = new MenuSliderItem($"Blue Color {BluePrimary}", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + MenuSliderItem FinishSliderPrimary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + + primaryColorsMenuRGB.AddMenuItem(RedSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(GreenSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); + + primaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => + { + if (sliderItem == RedSliderPrimary) + { + RedPrimary = newPosition; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + RedSliderPrimary.Text = $"Red Color {RedPrimary}"; + + + } + if (sliderItem == GreenSliderPrimary) + { + GreenPrimary = newPosition; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.Text = $"Green Color {GreenPrimary}"; + + } + if (sliderItem == BlueSliderPrimary) + { + BluePrimary = newPosition; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.Text = $"Blue Color {BluePrimary}"; + + } + + if (sliderItem == FinishSliderPrimary) + { + FinishPrimary = newPosition; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[FinishPrimary]}"; + + } + if ((sliderItem == RedSliderPrimary) || (sliderItem == GreenSliderPrimary) || (sliderItem == BlueSliderPrimary) || (sliderItem == FinishSliderPrimary)) + { + var veh = GetVehicle(); + SetVehicleModColor_1(veh.Handle, FinishPrimary, 0, 0); + SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); + + } + }; + var SecondaryColorsMenuRGB = Lm.GetMenu(new Menu("Vehicle Colors RGB", "Secondary Colors RGB")); + MenuController.AddSubmenu(secondaryColorsMenu, SecondaryColorsMenuRGB); + + var SecondaryColorsRGBBtn = new MenuItem("Secondary Color RGB") { Label = "→→→" }; + secondaryColorsMenu.AddMenuItem(SecondaryColorsRGBBtn); + MenuController.BindMenuItem(secondaryColorsMenu, SecondaryColorsMenuRGB, SecondaryColorsRGBBtn); + MenuSliderItem RedSliderSecondary = new MenuSliderItem($"Red Color {RedSecondary}", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + + MenuSliderItem GreenSliderSecondary = new MenuSliderItem($"Green Color {GreenSecondary}", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + + MenuSliderItem BlueSliderSecondary = new MenuSliderItem($"Blue Color {BlueSecondary}", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + MenuSliderItem FinishSliderSecondary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + + }; + + SecondaryColorsMenuRGB.AddMenuItem(RedSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(GreenSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(BlueSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(FinishSliderSecondary); + + SecondaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => + { + if (sliderItem == RedSliderSecondary) + { + RedSecondary = newPosition; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + RedSliderSecondary.Text = $"Red Color {RedSecondary}"; + + + } + if (sliderItem == GreenSliderSecondary) + { + GreenSecondary = newPosition; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; + + } + if (sliderItem == BlueSliderSecondary) + { + BlueSecondary = newPosition; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; + + } + + if (sliderItem == FinishSliderSecondary) + { + FinishSecondary = newPosition; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; + + } + if ((sliderItem == RedSliderSecondary) || (sliderItem == GreenSliderSecondary) || (sliderItem == BlueSliderSecondary) || (sliderItem == FinishSliderSecondary)) + { + var veh = GetVehicle(); + SetVehicleModColor_2(veh.Handle, FinishSecondary, 0); + SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); + + } + + }; #endregion #region Vehicle Doors Submenu Stuff From aec7a28dceb49bf211801ad6fbe3352855f78d59 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Fri, 18 Aug 2023 17:22:36 -0400 Subject: [PATCH 04/49] added saving for custom colors might still be janks needs more testing --- vMenu/CommonFunctions.cs | 83 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 70371749..2a098552 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -1438,8 +1438,33 @@ private static async void ApplyVehicleModsDelayed(Vehicle vehicle, VehicleInfo v ToggleVehicleMod(vehicle.Handle, 20, vehicleInfo.tyreSmoke); ToggleVehicleMod(vehicle.Handle, 22, vehicleInfo.xenonHeadlights); SetVehicleLivery(vehicle.Handle, vehicleInfo.livery); - + Debug.WriteLine($"{vehicleInfo.colors["primary"] == 1100110}"); + if (!(vehicleInfo.colors["primary"] == 1100110)) + { + if (vehicleInfo.colors["secondary"] == 1100110) + { + SetVehicleColours(vehicle.Handle, vehicleInfo.colors["primary"], 0); + SetVehicleCustomSecondaryColour(vehicle.Handle, vehicleInfo.colors["secondaryr"], vehicleInfo.colors["secondaryg"] , vehicleInfo.colors["secondaryb"]); + SetVehicleModColor_2(vehicle.Handle, vehicleInfo.colors["secondaryf"], 0); + } + else SetVehicleColours(vehicle.Handle, vehicleInfo.colors["primary"], vehicleInfo.colors["secondary"]); + } + else + { + if (vehicleInfo.colors["secondary"] == 1100110) + { + SetVehicleColours(vehicle.Handle, 0, 0); + SetVehicleCustomSecondaryColour(vehicle.Handle, vehicleInfo.colors["secondaryr"], vehicleInfo.colors["secondaryg"] , vehicleInfo.colors["secondaryb"]); + SetVehicleModColor_2(vehicle.Handle, vehicleInfo.colors["secondaryf"], 0); + } + else + SetVehicleColours(vehicle.Handle, 0, vehicleInfo.colors["secondary"]); + + SetVehicleModColor_1(vehicle.Handle, vehicleInfo.colors["primaryf"], 0, 0); + SetVehicleCustomPrimaryColour(vehicle.Handle, vehicleInfo.colors["primaryr"], vehicleInfo.colors["primaryg"] , vehicleInfo.colors["primaryb"]); + } + SetVehicleInteriorColour(vehicle.Handle, vehicleInfo.colors["trim"]); SetVehicleDashboardColour(vehicle.Handle, vehicleInfo.colors["dash"]); @@ -1541,17 +1566,73 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul #region colors var colors = new Dictionary(); var primaryColor = 0; + var primaryColorred = 0; + var primaryColorgreen = 0; + var primaryColorblue = 0; + var primaryFinish = 0; + var primaryFinishUseless = 0; + var primaryFinishUseless2 = 0; + var secondaryColor = 0; + var secondaryColorred = 0; + var secondaryColorgreen = 0; + var secondaryColorblue = 0; + var secondaryFinish = 0; + var secondaryFinishUseless = 0; + var pearlescentColor = 0; var wheelColor = 0; var dashColor = 0; var trimColor = 0; GetVehicleExtraColours(veh.Handle, ref pearlescentColor, ref wheelColor); + GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); + GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + Debug.WriteLine($"{((primaryColorred +primaryColorgreen + primaryColorblue) == 0 + primaryFinish ) }"); + if (!(!((primaryColorred +primaryColorgreen + primaryColorblue ) == 0 ) || !(primaryFinish == 0))) + { GetVehicleColours(veh.Handle, ref primaryColor, ref secondaryColor); + } + else + { + GetVehicleColours(veh.Handle, ref primaryColor, ref secondaryColor); + primaryColor = 1100110; + } + + GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); + GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + Debug.WriteLine($"{((secondaryColorred +secondaryColorgreen + secondaryColorblue) == 0 + secondaryFinish ) }"); + if (!(!((secondaryColorred +secondaryColorgreen + secondaryColorblue ) == 0 ) || !(secondaryFinish == 0))) + { + GetVehicleColours(veh.Handle, ref secondaryColor, ref secondaryColor); + } + else + { + if (primaryColor == 1100110) + { + secondaryColor = 1100110; + primaryColor = 1100110; + } + else + { + GetVehicleColours(veh.Handle, ref secondaryColor, ref secondaryColor); + secondaryColor = 1100110; + } + } + GetVehicleDashboardColour(veh.Handle, ref dashColor); GetVehicleInteriorColour(veh.Handle, ref trimColor); colors.Add("primary", primaryColor); + colors.Add("primaryr", primaryColorred); + colors.Add("primaryg", primaryColorgreen); + colors.Add("primaryb", primaryColorblue); + colors.Add("primaryf", primaryFinish); + colors.Add("secondary", secondaryColor); + colors.Add("secondaryr", secondaryColorred); + colors.Add("secondaryg", secondaryColorgreen); + colors.Add("secondaryb", secondaryColorblue); + colors.Add("secondaryf", secondaryFinish); + colors.Add("pearlescent", pearlescentColor); colors.Add("wheels", wheelColor); colors.Add("dash", dashColor); From ef3868a09fe3ea2808046ae8cd50f9074f1162dd Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Fri, 18 Aug 2023 21:48:05 -0400 Subject: [PATCH 05/49] Update VehicleOptions.cs --- vMenu/menus/VehicleOptions.cs | 117 ++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 27 deletions(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index cd3a2403..d26c3440 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1309,20 +1309,49 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; - primaryColorsMenuRGB.AddMenuItem(RedSliderPrimary); primaryColorsMenuRGB.AddMenuItem(GreenSliderPrimary); primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); + primaryColorsMenu.OnItemSelect += (sender, item, index) => + { + var veh = GetVehicle(); + var primaryColorred = 0; + var primaryColorgreen = 0; + var primaryColorblue = 0; + var primaryFinish = 0; + var primaryFinishUseless = 0; + var primaryFinishUseless2 = 0; + GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); + GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + RedSliderPrimary.Position = primaryColorred; + GreenSliderPrimary.Position = primaryColorgreen; + BlueSliderPrimary.Position = primaryColorblue; + FinishSliderPrimary.Position = primaryFinish; + RedPrimary = primaryColorred; + GreenPrimary = primaryColorgreen; + BluePrimary = primaryColorblue; + FinishPrimary = primaryFinish; + RedSliderPrimary.Text = $"Red Color {primaryColorred}"; + GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; + BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; + FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[primaryFinish]}"; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + }; + primaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => { if (sliderItem == RedSliderPrimary) { RedPrimary = newPosition; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); RedSliderPrimary.Text = $"Red Color {RedPrimary}"; @@ -1330,18 +1359,20 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if (sliderItem == GreenSliderPrimary) { GreenPrimary = newPosition; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); GreenSliderPrimary.Text = $"Green Color {GreenPrimary}"; } if (sliderItem == BlueSliderPrimary) { BluePrimary = newPosition; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); BlueSliderPrimary.Text = $"Blue Color {BluePrimary}"; } @@ -1349,10 +1380,10 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if (sliderItem == FinishSliderPrimary) { FinishPrimary = newPosition; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); - FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(155, RedPrimary, GreenPrimary, BluePrimary); + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[FinishPrimary]}"; } @@ -1397,6 +1428,35 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in }; + secondaryColorsMenu.OnItemSelect += (sender, item, index) => + { + var veh = GetVehicle(); + var secondaryColorred = 0; + var secondaryColorgreen = 0; + var secondaryColorblue = 0; + var secondaryFinish = 0; + var secondaryFinishUseless = 0; + GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); + GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + RedSliderSecondary.Position = secondaryColorred; + GreenSliderSecondary.Position = secondaryColorgreen; + BlueSliderSecondary.Position = secondaryColorblue; + FinishSliderSecondary.Position = secondaryFinish; + RedSecondary = secondaryColorred; + GreenSecondary = secondaryColorgreen; + BlueSecondary = secondaryColorblue; + FinishSecondary = secondaryFinish; + RedSliderSecondary.Text = $"Red Color {RedSecondary}"; + GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; + BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; + FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[secondaryFinish]}"; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + }; + + SecondaryColorsMenuRGB.AddMenuItem(RedSliderSecondary); SecondaryColorsMenuRGB.AddMenuItem(GreenSliderSecondary); SecondaryColorsMenuRGB.AddMenuItem(BlueSliderSecondary); @@ -1407,9 +1467,10 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if (sliderItem == RedSliderSecondary) { RedSecondary = newPosition; - RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); RedSliderSecondary.Text = $"Red Color {RedSecondary}"; @@ -1417,18 +1478,20 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if (sliderItem == GreenSliderSecondary) { GreenSecondary = newPosition; - RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; } if (sliderItem == BlueSliderSecondary) { BlueSecondary = newPosition; - RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; } @@ -1436,10 +1499,10 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if (sliderItem == FinishSliderSecondary) { FinishSecondary = newPosition; - RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); - FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(155, RedSecondary, GreenSecondary, BlueSecondary); + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; } From d4e50fe66ae497a2eb3fb976d85ed073385115cc Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Fri, 18 Aug 2023 21:54:02 -0400 Subject: [PATCH 06/49] Update VehicleOptions.cs --- vMenu/menus/VehicleOptions.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index d26c3440..7d477b97 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1080,6 +1080,7 @@ private void CreateMenu() if (item == chrome) { ClearVehicleCustomPrimaryColour(veh.Handle); + ClearVehicleCustomSecondaryColour(veh.Handle); SetVehicleColours(veh.Handle, 120, 120); // chrome is index 120 } } @@ -1163,6 +1164,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in SetVehicleModKit(veh.Handle, 0); } } + ClearVehicleCustomSecondaryColour(veh.Handle); ClearVehicleCustomPrimaryColour(veh.Handle); SetVehicleColours(veh.Handle, primaryColor, secondaryColor); } @@ -1190,6 +1192,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in secondaryColor = VehicleData.WornColors[newIndex].id; break; } + ClearVehicleCustomSecondaryColour(veh.Handle); ClearVehicleCustomPrimaryColour(veh.Handle); SetVehicleColours(veh.Handle, primaryColor, secondaryColor); } @@ -1449,7 +1452,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in RedSliderSecondary.Text = $"Red Color {RedSecondary}"; GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; - FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[secondaryFinish]}"; + FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); From ebcea5fa8d44c7e53a9758d4f817da0b1dffbf82 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Fri, 18 Aug 2023 23:23:46 -0400 Subject: [PATCH 07/49] RGB hex for secondary and primary --- vMenu/menus/VehicleOptions.cs | 88 ++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 7d477b97..9510b40b 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1306,6 +1306,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; + var HexColorPrimary = new MenuItem("Primary Hex", "Set primary color with hex code."); MenuSliderItem FinishSliderPrimary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), @@ -1315,6 +1316,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in primaryColorsMenuRGB.AddMenuItem(RedSliderPrimary); primaryColorsMenuRGB.AddMenuItem(GreenSliderPrimary); primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(HexColorPrimary); primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); primaryColorsMenu.OnItemSelect += (sender, item, index) => { @@ -1327,6 +1329,10 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var primaryFinishUseless2 = 0; GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + + if (primaryFinish > 5) + primaryFinish = 0; + RedSliderPrimary.Position = primaryColorred; GreenSliderPrimary.Position = primaryColorgreen; BlueSliderPrimary.Position = primaryColorblue; @@ -1343,8 +1349,45 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + HexColorPrimary.Label = $"{hexValue}"; }; + primaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => + { + if (item == HexColorPrimary) + { + var result = await GetUserInput(windowTitle: "Enter Color Hex"); + if (!string.IsNullOrEmpty(result)) + { + Debug.WriteLine($"{result}"); + int RGBint = Convert.ToInt32(result, 16); + byte Red = (byte)((RGBint >> 16) & 255); + byte Green = (byte)((RGBint >> 8) & 255); + byte Blue = (byte)(RGBint & 255); + Debug.WriteLine($"{Red} {Green} {Blue}"); + RedSliderPrimary.Text = $"Red Color {Red}"; + GreenSliderPrimary.Text = $"Green Color {Green}"; + BlueSliderPrimary.Text = $"Blue Color {Blue}"; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + RedSliderPrimary.Position = Red; + GreenSliderPrimary.Position = Green; + BlueSliderPrimary.Position = Blue; + RedPrimary = Red; + GreenPrimary = Green; + BluePrimary = Blue; + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + Debug.WriteLine($"{hexValue}"); + HexColorPrimary.Label = $"{hexValue}"; + var veh = GetVehicle(); + SetVehicleCustomPrimaryColour(veh.Handle, Red, Green, Blue); + } + + } + }; primaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => { @@ -1393,6 +1436,8 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if ((sliderItem == RedSliderPrimary) || (sliderItem == GreenSliderPrimary) || (sliderItem == BlueSliderPrimary) || (sliderItem == FinishSliderPrimary)) { var veh = GetVehicle(); + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + HexColorPrimary.Label = $"{hexValue}"; SetVehicleModColor_1(veh.Handle, FinishPrimary, 0, 0); SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); @@ -1424,6 +1469,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; + var HexColorSecondary = new MenuItem("Primary Hex", "Set primary color with hex code."); MenuSliderItem FinishSliderSecondary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), @@ -1441,6 +1487,8 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var secondaryFinishUseless = 0; GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + if (secondaryFinish > 5) + secondaryFinish = 0; RedSliderSecondary.Position = secondaryColorred; GreenSliderSecondary.Position = secondaryColorgreen; BlueSliderSecondary.Position = secondaryColorblue; @@ -1457,12 +1505,49 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + HexColorSecondary.Label = $"{hexValue}"; }; + SecondaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => + { + if (item == HexColorSecondary) + { + var result = await GetUserInput(windowTitle: "Enter Color Hex"); + if (!string.IsNullOrEmpty(result)) + { + Debug.WriteLine($"{result}"); + int RGBint = Convert.ToInt32(result, 16); + byte Red = (byte)((RGBint >> 16) & 255); + byte Green = (byte)((RGBint >> 8) & 255); + byte Blue = (byte)(RGBint & 255); + Debug.WriteLine($"{Red} {Green} {Blue}"); + RedSliderSecondary.Text = $"Red Color {Red}"; + GreenSliderSecondary.Text = $"Green Color {Green}"; + BlueSliderSecondary.Text = $"Blue Color {Blue}"; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + RedSliderSecondary.Position = Red; + GreenSliderSecondary.Position = Green; + BlueSliderSecondary.Position = Blue; + RedSecondary = Red; + GreenSecondary = Green; + BlueSecondary = Blue; + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + Debug.WriteLine($"{hexValue}"); + HexColorSecondary.Label = $"{hexValue}"; + var veh = GetVehicle(); + SetVehicleCustomSecondaryColour(veh.Handle, Red, Green, Blue); + } + } + }; SecondaryColorsMenuRGB.AddMenuItem(RedSliderSecondary); SecondaryColorsMenuRGB.AddMenuItem(GreenSliderSecondary); SecondaryColorsMenuRGB.AddMenuItem(BlueSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(HexColorSecondary); SecondaryColorsMenuRGB.AddMenuItem(FinishSliderSecondary); SecondaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => @@ -1514,7 +1599,8 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var veh = GetVehicle(); SetVehicleModColor_2(veh.Handle, FinishSecondary, 0); SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); - + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + HexColorSecondary.Label = $"{hexValue}"; } }; From a2b7030702a59737c31215c287a97958b51bb27d Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 19 Aug 2023 00:32:11 -0400 Subject: [PATCH 08/49] Fixed saving issue and name of secondary hex color --- vMenu/CommonFunctions.cs | 4 +++- vMenu/menus/VehicleOptions.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 2a098552..c6b47042 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -1618,7 +1618,9 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul secondaryColor = 1100110; } } - + GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + GetVehicleDashboardColour(veh.Handle, ref dashColor); GetVehicleInteriorColour(veh.Handle, ref trimColor); colors.Add("primary", primaryColor); diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 9510b40b..9b64c9d1 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1469,7 +1469,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; - var HexColorSecondary = new MenuItem("Primary Hex", "Set primary color with hex code."); + var HexColorSecondary = new MenuItem("Secondary Hex", "Set secondary color with hex code."); MenuSliderItem FinishSliderSecondary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), From e21f54965968b9d6cb5e639d165a78e3cf4ed3b9 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 19 Aug 2023 01:07:50 -0400 Subject: [PATCH 09/49] Added match to primary/secondary button --- vMenu/menus/VehicleOptions.cs | 90 ++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 9b64c9d1..0d028fab 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1313,11 +1313,14 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; + var SecondaryMatchColorPrimary = new MenuItem("Match To Secondary", "Copys color data from secondary."); primaryColorsMenuRGB.AddMenuItem(RedSliderPrimary); primaryColorsMenuRGB.AddMenuItem(GreenSliderPrimary); primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); primaryColorsMenuRGB.AddMenuItem(HexColorPrimary); primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(SecondaryMatchColorPrimary); + primaryColorsMenu.OnItemSelect += (sender, item, index) => { var veh = GetVehicle(); @@ -1360,12 +1363,12 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var result = await GetUserInput(windowTitle: "Enter Color Hex"); if (!string.IsNullOrEmpty(result)) { - Debug.WriteLine($"{result}"); + int RGBint = Convert.ToInt32(result, 16); byte Red = (byte)((RGBint >> 16) & 255); byte Green = (byte)((RGBint >> 8) & 255); byte Blue = (byte)(RGBint & 255); - Debug.WriteLine($"{Red} {Green} {Blue}"); + RedSliderPrimary.Text = $"Red Color {Red}"; GreenSliderPrimary.Text = $"Green Color {Green}"; BlueSliderPrimary.Text = $"Blue Color {Blue}"; @@ -1380,11 +1383,46 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenPrimary = Green; BluePrimary = Blue; string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - Debug.WriteLine($"{hexValue}"); + HexColorPrimary.Label = $"{hexValue}"; var veh = GetVehicle(); SetVehicleCustomPrimaryColour(veh.Handle, Red, Green, Blue); } + } + if (item == SecondaryMatchColorPrimary) + { + var veh = GetVehicle(); + var primaryColorred = 0; + var primaryColorgreen = 0; + var primaryColorblue = 0; + var secondaryFinish = 0; + var secondaryFinishUseless = 0; + + GetVehicleCustomSecondaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); + GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + + if (secondaryFinish > 5) + secondaryFinish = 0; + RedSliderPrimary.Position = primaryColorred; + GreenSliderPrimary.Position = primaryColorgreen; + BlueSliderPrimary.Position = primaryColorblue; + FinishSliderPrimary.Position = secondaryFinish; + RedPrimary = primaryColorred; + GreenPrimary = primaryColorgreen; + BluePrimary = primaryColorblue; + FinishPrimary = secondaryFinish; + RedSliderPrimary.Text = $"Red Color {primaryColorred}"; + GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; + BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; + FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[secondaryFinish]}"; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + HexColorPrimary.Label = $"{hexValue}"; + SetVehicleModColor_1(veh.Handle, secondaryFinish, 0, 0); + SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); } }; @@ -1476,6 +1514,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; + var PrimaryMatchColorSecondary = new MenuItem("Match To Primary", "Copys color data from primary."); secondaryColorsMenu.OnItemSelect += (sender, item, index) => { @@ -1515,12 +1554,12 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var result = await GetUserInput(windowTitle: "Enter Color Hex"); if (!string.IsNullOrEmpty(result)) { - Debug.WriteLine($"{result}"); + int RGBint = Convert.ToInt32(result, 16); byte Red = (byte)((RGBint >> 16) & 255); byte Green = (byte)((RGBint >> 8) & 255); byte Blue = (byte)(RGBint & 255); - Debug.WriteLine($"{Red} {Green} {Blue}"); + RedSliderSecondary.Text = $"Red Color {Red}"; GreenSliderSecondary.Text = $"Green Color {Green}"; BlueSliderSecondary.Text = $"Blue Color {Blue}"; @@ -1534,14 +1573,49 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in RedSecondary = Red; GreenSecondary = Green; BlueSecondary = Blue; - string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - Debug.WriteLine($"{hexValue}"); + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); HexColorSecondary.Label = $"{hexValue}"; var veh = GetVehicle(); SetVehicleCustomSecondaryColour(veh.Handle, Red, Green, Blue); } } + if (item == PrimaryMatchColorSecondary) + { + var veh = GetVehicle(); + var secondaryColorred = 0; + var secondaryColorgreen = 0; + var secondaryColorblue = 0; + var primaryFinish = 0; + var primaryFinishUseless = 0; + var primaryFinishUseless2 = 0; + GetVehicleCustomPrimaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); + GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + + if (primaryFinish > 5) + primaryFinish = 0; + RedSliderSecondary.Position = secondaryColorred; + GreenSliderSecondary.Position = secondaryColorgreen; + BlueSliderSecondary.Position = secondaryColorblue; + FinishSliderSecondary.Position = primaryFinish; + RedSecondary = secondaryColorred; + GreenSecondary = secondaryColorgreen; + BlueSecondary = secondaryColorblue; + FinishSecondary = primaryFinish; + RedSliderSecondary.Text = $"Red Color {RedSecondary}"; + GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; + BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; + FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[primaryFinish]}"; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + HexColorSecondary.Label = $"{hexValue}"; + SetVehicleModColor_2(veh.Handle, primaryFinish, 0); + SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); + + } }; SecondaryColorsMenuRGB.AddMenuItem(RedSliderSecondary); @@ -1550,6 +1624,8 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in SecondaryColorsMenuRGB.AddMenuItem(HexColorSecondary); SecondaryColorsMenuRGB.AddMenuItem(FinishSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(PrimaryMatchColorSecondary); + SecondaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => { if (sliderItem == RedSliderSecondary) From 2d94dd22fc875b95229b72963ad0226d3e4ebaf1 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 19 Aug 2023 01:57:58 -0400 Subject: [PATCH 10/49] Added Hex detection to try to prevent errors in console --- vMenu/menus/VehicleOptions.cs | 77 +++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 0d028fab..f6423449 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using CitizenFX.Core; @@ -1360,10 +1361,11 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in { if (item == HexColorPrimary) { - var result = await GetUserInput(windowTitle: "Enter Color Hex"); + var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorPrimary.Label , maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { - + if (IsHex(result)) + { int RGBint = Convert.ToInt32(result, 16); byte Red = (byte)((RGBint >> 16) & 255); byte Green = (byte)((RGBint >> 8) & 255); @@ -1387,6 +1389,9 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in HexColorPrimary.Label = $"{hexValue}"; var veh = GetVehicle(); SetVehicleCustomPrimaryColour(veh.Handle, Red, Green, Blue); + } + else + Notify.Error($"{result} is not a valid hex code"); } } if (item == SecondaryMatchColorPrimary) @@ -1551,32 +1556,37 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in { if (item == HexColorSecondary) { - var result = await GetUserInput(windowTitle: "Enter Color Hex"); + var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorSecondary.Label , maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { - - int RGBint = Convert.ToInt32(result, 16); - byte Red = (byte)((RGBint >> 16) & 255); - byte Green = (byte)((RGBint >> 8) & 255); - byte Blue = (byte)(RGBint & 255); - - RedSliderSecondary.Text = $"Red Color {Red}"; - GreenSliderSecondary.Text = $"Green Color {Green}"; - BlueSliderSecondary.Text = $"Blue Color {Blue}"; - RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - RedSliderSecondary.Position = Red; - GreenSliderSecondary.Position = Green; - BlueSliderSecondary.Position = Blue; - RedSecondary = Red; - GreenSecondary = Green; - BlueSecondary = Blue; - string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; - var veh = GetVehicle(); - SetVehicleCustomSecondaryColour(veh.Handle, Red, Green, Blue); + if (IsHex(result)) + { + int RGBint = Convert.ToInt32(result, 16); + byte Red = (byte)((RGBint >> 16) & 255); + byte Green = (byte)((RGBint >> 8) & 255); + byte Blue = (byte)(RGBint & 255); + + RedSliderSecondary.Text = $"Red Color {Red}"; + GreenSliderSecondary.Text = $"Green Color {Green}"; + BlueSliderSecondary.Text = $"Blue Color {Blue}"; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + RedSliderSecondary.Position = Red; + GreenSliderSecondary.Position = Green; + BlueSliderSecondary.Position = Blue; + RedSecondary = Red; + GreenSecondary = Green; + BlueSecondary = Blue; + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + HexColorSecondary.Label = $"{hexValue}"; + var veh = GetVehicle(); + SetVehicleCustomSecondaryColour(veh.Handle, Red, Green, Blue); + } + else + Notify.Error($"{result} is not a valid hex code"); + } } @@ -2635,7 +2645,20 @@ internal static void SetHeadlightsColorForVehicle(Vehicle veh, int newIndex) } } } - + private bool IsHex(IEnumerable chars) + { + bool isHex; + foreach(var c in chars) + { + isHex = ((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')); + + if(!isHex) + return false; + } + return true; + } internal static int GetHeadlightsColorForVehicle(Vehicle vehicle) { if (vehicle != null && vehicle.Exists()) From 00dc04b633e839bc9980377a7728019592f7181d Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 21 Aug 2023 06:28:05 -0400 Subject: [PATCH 11/49] fixing broken native with bandage but should work better --- vMenu/CommonFunctions.cs | 25 +- vMenu/menus/VehicleOptions.cs | 410 +++++++++++++++++------------ vMenuServer/PaintMaterialServer.cs | 116 ++++++++ 3 files changed, 377 insertions(+), 174 deletions(-) create mode 100644 vMenuServer/PaintMaterialServer.cs diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index c6b47042..5fc8cde2 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -1445,7 +1445,7 @@ private static async void ApplyVehicleModsDelayed(Vehicle vehicle, VehicleInfo v { SetVehicleColours(vehicle.Handle, vehicleInfo.colors["primary"], 0); SetVehicleCustomSecondaryColour(vehicle.Handle, vehicleInfo.colors["secondaryr"], vehicleInfo.colors["secondaryg"] , vehicleInfo.colors["secondaryb"]); - SetVehicleModColor_2(vehicle.Handle, vehicleInfo.colors["secondaryf"], 0); + SetMaterial.SetSecondaryMaterial(vehicle.Handle, vehicleInfo.colors["secondaryf"]); } else SetVehicleColours(vehicle.Handle, vehicleInfo.colors["primary"], vehicleInfo.colors["secondary"]); @@ -1456,12 +1456,14 @@ private static async void ApplyVehicleModsDelayed(Vehicle vehicle, VehicleInfo v { SetVehicleColours(vehicle.Handle, 0, 0); SetVehicleCustomSecondaryColour(vehicle.Handle, vehicleInfo.colors["secondaryr"], vehicleInfo.colors["secondaryg"] , vehicleInfo.colors["secondaryb"]); - SetVehicleModColor_2(vehicle.Handle, vehicleInfo.colors["secondaryf"], 0); + SetMaterial.SetSecondaryMaterial(vehicle.Handle, vehicleInfo.colors["secondaryf"]); + } else SetVehicleColours(vehicle.Handle, 0, vehicleInfo.colors["secondary"]); - SetVehicleModColor_1(vehicle.Handle, vehicleInfo.colors["primaryf"], 0, 0); + SetMaterial.SetPrimaryMaterial(vehicle.Handle, vehicleInfo.colors["primaryf"]); + SetVehicleCustomPrimaryColour(vehicle.Handle, vehicleInfo.colors["primaryr"], vehicleInfo.colors["primaryg"] , vehicleInfo.colors["primaryb"]); } @@ -1569,24 +1571,23 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul var primaryColorred = 0; var primaryColorgreen = 0; var primaryColorblue = 0; - var primaryFinish = 0; - var primaryFinishUseless = 0; - var primaryFinishUseless2 = 0; + var primaryFinish = await GetMaterial.GetPrimaryMaterialAsync(veh.Handle); var secondaryColor = 0; var secondaryColorred = 0; var secondaryColorgreen = 0; var secondaryColorblue = 0; - var secondaryFinish = 0; - var secondaryFinishUseless = 0; + var secondaryFinish = await GetMaterial.GetSecondaryMaterialAsync(veh.Handle); + var pearlescentColor = 0; var wheelColor = 0; var dashColor = 0; var trimColor = 0; + GetVehicleExtraColours(veh.Handle, ref pearlescentColor, ref wheelColor); GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); - GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + Debug.WriteLine($"{((primaryColorred +primaryColorgreen + primaryColorblue) == 0 + primaryFinish ) }"); if (!(!((primaryColorred +primaryColorgreen + primaryColorblue ) == 0 ) || !(primaryFinish == 0))) { @@ -1599,7 +1600,7 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul } GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); - GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + Debug.WriteLine($"{((secondaryColorred +secondaryColorgreen + secondaryColorblue) == 0 + secondaryFinish ) }"); if (!(!((secondaryColorred +secondaryColorgreen + secondaryColorblue ) == 0 ) || !(secondaryFinish == 0))) { @@ -1618,8 +1619,8 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul secondaryColor = 1100110; } } - GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); - GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); + + GetVehicleDashboardColour(veh.Handle, ref dashColor); GetVehicleInteriorColour(veh.Handle, ref trimColor); diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index f6423449..aa777b3e 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text.RegularExpressions; +using System.Threading.Tasks; using CitizenFX.Core; @@ -14,6 +14,7 @@ using static vMenuShared.ConfigManager; using static vMenuShared.PermissionsManager; + namespace vMenuClient.menus { public class VehicleOptions @@ -1004,7 +1005,7 @@ private void CreateMenu() "Matte", "Metal", "Chrome", - }; + }; // color lists var classic = new List(); var matte = new List(); @@ -1282,7 +1283,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in } var primaryColorsMenuRGB = Lm.GetMenu(new Menu("Vehicle Colors RGB", "Primary Colors RGB")); - MenuController.AddSubmenu(primaryColorsMenu, primaryColorsMenuRGB); + MenuController.AddSubmenu(primaryColorsMenu, primaryColorsMenuRGB); var primaryColorsRGBBtn = new MenuItem("Primary Color RGB") { Label = "→→→" }; primaryColorsMenu.AddMenuItem(primaryColorsRGBBtn); @@ -1307,7 +1308,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; - var HexColorPrimary = new MenuItem("Primary Hex", "Set primary color with hex code."); + var HexColorPrimary = new MenuItem("Primary Hex", "Set primary color with hex code."); MenuSliderItem FinishSliderPrimary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), @@ -1322,112 +1323,113 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); primaryColorsMenuRGB.AddMenuItem(SecondaryMatchColorPrimary); - primaryColorsMenu.OnItemSelect += (sender, item, index) => + primaryColorsMenu.OnItemSelect += async (sender, item, index) => { - var veh = GetVehicle(); - var primaryColorred = 0; - var primaryColorgreen = 0; - var primaryColorblue = 0; - var primaryFinish = 0; - var primaryFinishUseless = 0; - var primaryFinishUseless2 = 0; - GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); - GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); - - if (primaryFinish > 5) - primaryFinish = 0; - - RedSliderPrimary.Position = primaryColorred; - GreenSliderPrimary.Position = primaryColorgreen; - BlueSliderPrimary.Position = primaryColorblue; - FinishSliderPrimary.Position = primaryFinish; - RedPrimary = primaryColorred; - GreenPrimary = primaryColorgreen; - BluePrimary = primaryColorblue; - FinishPrimary = primaryFinish; - RedSliderPrimary.Text = $"Red Color {primaryColorred}"; - GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; - BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; - FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[primaryFinish]}"; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - HexColorPrimary.Label = $"{hexValue}"; + var veh = GetVehicle(); + var primaryColorred = 0; + var primaryColorgreen = 0; + var primaryColorblue = 0; + var primaryPaintFinish = await GetMaterial.GetPrimaryMaterialAsync(veh.Handle); + + + GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); + + +; + if (primaryPaintFinish > 5) + primaryPaintFinish = 0; + + RedSliderPrimary.Position = primaryColorred; + GreenSliderPrimary.Position = primaryColorgreen; + BlueSliderPrimary.Position = primaryColorblue; + FinishSliderPrimary.Position = primaryPaintFinish; + RedPrimary = primaryColorred; + GreenPrimary = primaryColorgreen; + BluePrimary = primaryColorblue; + FinishPrimary = primaryPaintFinish; + RedSliderPrimary.Text = $"Red Color {primaryColorred}"; + GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; + BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; + FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[primaryPaintFinish]}"; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + HexColorPrimary.Label = $"{hexValue}"; }; primaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => { if (item == HexColorPrimary) { - var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorPrimary.Label , maxInputLength: 6); + var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorPrimary.Label, maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { if (IsHex(result)) { - int RGBint = Convert.ToInt32(result, 16); - byte Red = (byte)((RGBint >> 16) & 255); - byte Green = (byte)((RGBint >> 8) & 255); - byte Blue = (byte)(RGBint & 255); - - RedSliderPrimary.Text = $"Red Color {Red}"; - GreenSliderPrimary.Text = $"Green Color {Green}"; - BlueSliderPrimary.Text = $"Blue Color {Blue}"; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); - RedSliderPrimary.Position = Red; - GreenSliderPrimary.Position = Green; - BlueSliderPrimary.Position = Blue; - RedPrimary = Red; - GreenPrimary = Green; - BluePrimary = Blue; - string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - - HexColorPrimary.Label = $"{hexValue}"; - var veh = GetVehicle(); - SetVehicleCustomPrimaryColour(veh.Handle, Red, Green, Blue); + int RGBint = Convert.ToInt32(result, 16); + byte Red = (byte)((RGBint >> 16) & 255); + byte Green = (byte)((RGBint >> 8) & 255); + byte Blue = (byte)(RGBint & 255); + + RedSliderPrimary.Text = $"Red Color {Red}"; + GreenSliderPrimary.Text = $"Green Color {Green}"; + BlueSliderPrimary.Text = $"Blue Color {Blue}"; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + RedSliderPrimary.Position = Red; + GreenSliderPrimary.Position = Green; + BlueSliderPrimary.Position = Blue; + RedPrimary = Red; + GreenPrimary = Green; + BluePrimary = Blue; + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + + HexColorPrimary.Label = $"{hexValue}"; + var veh = GetVehicle(); + + SetVehicleCustomPrimaryColour(veh.Handle, Red, Green, Blue); } else - Notify.Error($"{result} is not a valid hex code"); - } + Notify.Error($"{result} is not a valid hex code"); + } } if (item == SecondaryMatchColorPrimary) { - var veh = GetVehicle(); - var primaryColorred = 0; - var primaryColorgreen = 0; - var primaryColorblue = 0; - var secondaryFinish = 0; - var secondaryFinishUseless = 0; - - GetVehicleCustomSecondaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); - GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); - - if (secondaryFinish > 5) - secondaryFinish = 0; - RedSliderPrimary.Position = primaryColorred; - GreenSliderPrimary.Position = primaryColorgreen; - BlueSliderPrimary.Position = primaryColorblue; - FinishSliderPrimary.Position = secondaryFinish; - RedPrimary = primaryColorred; - GreenPrimary = primaryColorgreen; - BluePrimary = primaryColorblue; - FinishPrimary = secondaryFinish; - RedSliderPrimary.Text = $"Red Color {primaryColorred}"; - GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; - BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; - FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[secondaryFinish]}"; - RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); - string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - HexColorPrimary.Label = $"{hexValue}"; - SetVehicleModColor_1(veh.Handle, secondaryFinish, 0, 0); - SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); + var veh = GetVehicle(); + var primaryColorred = 0; + var primaryColorgreen = 0; + var primaryColorblue = 0; + var secondaryFinish = await GetMaterial.GetSecondaryMaterialAsync(veh.Handle); + + GetVehicleCustomSecondaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); + + + if (secondaryFinish > 5) + secondaryFinish = 0; + RedSliderPrimary.Position = primaryColorred; + GreenSliderPrimary.Position = primaryColorgreen; + BlueSliderPrimary.Position = primaryColorblue; + FinishSliderPrimary.Position = secondaryFinish; + RedPrimary = primaryColorred; + GreenPrimary = primaryColorgreen; + BluePrimary = primaryColorblue; + FinishPrimary = secondaryFinish; + RedSliderPrimary.Text = $"Red Color {primaryColorred}"; + GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; + BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; + FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[secondaryFinish]}"; + RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); + string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); + HexColorPrimary.Label = $"{hexValue}"; + SetMaterial.SetPrimaryMaterial(veh.Handle, secondaryFinish); + SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); } }; @@ -1443,7 +1445,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); RedSliderPrimary.Text = $"Red Color {RedPrimary}"; - + } if (sliderItem == GreenSliderPrimary) { @@ -1463,7 +1465,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); BlueSliderPrimary.Text = $"Blue Color {BluePrimary}"; - + } if (sliderItem == FinishSliderPrimary) @@ -1481,13 +1483,15 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var veh = GetVehicle(); string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); HexColorPrimary.Label = $"{hexValue}"; - SetVehicleModColor_1(veh.Handle, FinishPrimary, 0, 0); + + SetMaterial.SetPrimaryMaterial(veh.Handle, FinishPrimary); + SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); } }; var SecondaryColorsMenuRGB = Lm.GetMenu(new Menu("Vehicle Colors RGB", "Secondary Colors RGB")); - MenuController.AddSubmenu(secondaryColorsMenu, SecondaryColorsMenuRGB); + MenuController.AddSubmenu(secondaryColorsMenu, SecondaryColorsMenuRGB); var SecondaryColorsRGBBtn = new MenuItem("Secondary Color RGB") { Label = "→→→" }; secondaryColorsMenu.AddMenuItem(SecondaryColorsRGBBtn); @@ -1521,42 +1525,43 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in }; var PrimaryMatchColorSecondary = new MenuItem("Match To Primary", "Copys color data from primary."); - secondaryColorsMenu.OnItemSelect += (sender, item, index) => + secondaryColorsMenu.OnItemSelect += async (sender, item, index) => { - var veh = GetVehicle(); - var secondaryColorred = 0; - var secondaryColorgreen = 0; - var secondaryColorblue = 0; - var secondaryFinish = 0; - var secondaryFinishUseless = 0; - GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); - GetVehicleModColor_2(veh.Handle, ref secondaryFinish, ref secondaryFinishUseless); - if (secondaryFinish > 5) + var veh = GetVehicle(); + var secondaryColorred = 0; + var secondaryColorgreen = 0; + var secondaryColorblue = 0; + var secondaryFinish = await GetMaterial.GetSecondaryMaterialAsync(veh.Handle); + + + GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); + + if (secondaryFinish > 5) secondaryFinish = 0; - RedSliderSecondary.Position = secondaryColorred; - GreenSliderSecondary.Position = secondaryColorgreen; - BlueSliderSecondary.Position = secondaryColorblue; - FinishSliderSecondary.Position = secondaryFinish; - RedSecondary = secondaryColorred; - GreenSecondary = secondaryColorgreen; - BlueSecondary = secondaryColorblue; - FinishSecondary = secondaryFinish; - RedSliderSecondary.Text = $"Red Color {RedSecondary}"; - GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; - BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; - FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; - RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; + RedSliderSecondary.Position = secondaryColorred; + GreenSliderSecondary.Position = secondaryColorgreen; + BlueSliderSecondary.Position = secondaryColorblue; + FinishSliderSecondary.Position = secondaryFinish; + RedSecondary = secondaryColorred; + GreenSecondary = secondaryColorgreen; + BlueSecondary = secondaryColorblue; + FinishSecondary = secondaryFinish; + RedSliderSecondary.Text = $"Red Color {RedSecondary}"; + GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; + BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; + FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; + RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + HexColorSecondary.Label = $"{hexValue}"; }; SecondaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => { if (item == HexColorSecondary) { - var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorSecondary.Label , maxInputLength: 6); + var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorSecondary.Label, maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { if (IsHex(result)) @@ -1565,7 +1570,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in byte Red = (byte)((RGBint >> 16) & 255); byte Green = (byte)((RGBint >> 8) & 255); byte Blue = (byte)(RGBint & 255); - + RedSliderSecondary.Text = $"Red Color {Red}"; GreenSliderSecondary.Text = $"Green Color {Green}"; BlueSliderSecondary.Text = $"Blue Color {Blue}"; @@ -1579,15 +1584,16 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in RedSecondary = Red; GreenSecondary = Green; BlueSecondary = Blue; - string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); HexColorSecondary.Label = $"{hexValue}"; - var veh = GetVehicle(); + var veh = GetVehicle(); + SetVehicleCustomSecondaryColour(veh.Handle, Red, Green, Blue); } else - Notify.Error($"{result} is not a valid hex code"); + Notify.Error($"{result} is not a valid hex code"); - } + } } if (item == PrimaryMatchColorSecondary) @@ -1596,34 +1602,36 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in var secondaryColorred = 0; var secondaryColorgreen = 0; var secondaryColorblue = 0; - var primaryFinish = 0; - var primaryFinishUseless = 0; - var primaryFinishUseless2 = 0; + var primaryFinish2 = await GetMaterial.GetPrimaryMaterialAsync(veh.Handle); + + GetVehicleCustomPrimaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); - GetVehicleModColor_1(veh.Handle, ref primaryFinish, ref primaryFinishUseless, ref primaryFinishUseless2); + - if (primaryFinish > 5) - primaryFinish = 0; + if (primaryFinish2 > 5) + primaryFinish2 = 0; RedSliderSecondary.Position = secondaryColorred; GreenSliderSecondary.Position = secondaryColorgreen; BlueSliderSecondary.Position = secondaryColorblue; - FinishSliderSecondary.Position = primaryFinish; + FinishSliderSecondary.Position = primaryFinish2; RedSecondary = secondaryColorred; GreenSecondary = secondaryColorgreen; BlueSecondary = secondaryColorblue; - FinishSecondary = primaryFinish; + FinishSecondary = primaryFinish2; RedSliderSecondary.Text = $"Red Color {RedSecondary}"; GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; - FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[primaryFinish]}"; + FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[primaryFinish2]}"; RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); HexColorSecondary.Label = $"{hexValue}"; - SetVehicleModColor_2(veh.Handle, primaryFinish, 0); - SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); + + SetMaterial.SetSecondaryMaterial(veh.Handle, primaryFinish2); + + SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); } }; @@ -1647,7 +1655,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); RedSliderSecondary.Text = $"Red Color {RedSecondary}"; - + } if (sliderItem == GreenSliderSecondary) { @@ -1667,7 +1675,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; - + } if (sliderItem == FinishSliderSecondary) @@ -1678,17 +1686,18 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; - + } if ((sliderItem == RedSliderSecondary) || (sliderItem == GreenSliderSecondary) || (sliderItem == BlueSliderSecondary) || (sliderItem == FinishSliderSecondary)) { var veh = GetVehicle(); - SetVehicleModColor_2(veh.Handle, FinishSecondary, 0); - SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); - string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; + SetMaterial.SetSecondaryMaterial(veh.Handle, FinishSecondary); + + SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); + string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); + HexColorSecondary.Label = $"{hexValue}"; } - + }; #endregion @@ -2278,11 +2287,11 @@ public void UpdateMods(int selectedIndex = 0) // Create the name (again, converting to proper case), then add the name. name = mod.GetLocalizedModName(x) != "" ? $"{ToProperString(mod.GetLocalizedModName(x))} {currentItem}" : $"{typeName} #{x} {currentItem}"; - + if (name == "Engine #4 [6/6]") - modlist.Add("EMS Upgrade, Level 5 [6/6]"); + modlist.Add("EMS Upgrade, Level 5 [6/6]"); else - modlist.Add(name); + modlist.Add(name); } // Create the MenuListItem for this mod type. @@ -2511,7 +2520,7 @@ public void UpdateMods(int selectedIndex = 0) else if (item2 == vehicleWheelType) { var vehicleClass = GetVehicleClass(veh.Handle); - var isBikeOrOpenWheel = (newIndex == 6 && veh.Model.IsBike) ; + var isBikeOrOpenWheel = (newIndex == 6 && veh.Model.IsBike); var isNotBikeNorOpenWheel = newIndex != 6 && !veh.Model.IsBike; var isCorrectVehicleType = isBikeOrOpenWheel || isNotBikeNorOpenWheel; if (!isCorrectVehicleType) @@ -2647,14 +2656,14 @@ internal static void SetHeadlightsColorForVehicle(Vehicle veh, int newIndex) } private bool IsHex(IEnumerable chars) { - bool isHex; - foreach(var c in chars) + bool isHex; + foreach (var c in chars) { - isHex = ((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f') || + isHex = ((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); - - if(!isHex) + + if (!isHex) return false; } return true; @@ -2743,4 +2752,81 @@ private int GetIndexFromColor() } #endregion } -} \ No newline at end of file + public static class SetMaterial + { + public static void SetSecondaryMaterial(int vehicle, int material) + { + SetVehicleModColor_2(vehicle, material, 0); + + + TriggerServerEvent("vMenu:SetSecondaryMaterial_Sync", VehToNet(vehicle), material); + } + public static void SetPrimaryMaterial(int vehicle, int material) + { + SetVehicleModColor_1(vehicle, material, 0, 0); + + + TriggerServerEvent("vMenu:SetPrimaryMaterial_Sync", VehToNet(vehicle), material); + } + }; + public static class GetMaterial + { + public static int argSecondary { get; private set; } + public static bool EventSecondaryran { get; private set; } + + public static async Task GetSecondaryMaterialAsync(int vehicle) + { + + + return await GetSecondaryMaterial_1Async(vehicle); + } + public static async Task GetSecondaryMaterial_1Async(int vehicle) + { + EventSecondaryran = false; + TriggerServerEvent("vMenu:GetSecondaryMaterial_Sync", VehToNet(vehicle), new Action((matargSecondary) => + { + argSecondary = matargSecondary; + + + EventSecondaryran = true; + + })); + while (!EventSecondaryran) + { + + await Delay(0); + } + + return argSecondary; + + } + + public static int argPrimary { get; private set; } + public static bool EventPrimaryran { get; private set; } + + public static async Task GetPrimaryMaterialAsync(int vehicle) + { + + + return await GetPrimaryMaterial_1Async(vehicle); + } + public static async Task GetPrimaryMaterial_1Async(int vehicle) + { + EventPrimaryran = false; + TriggerServerEvent("vMenu:GetPrimaryMaterial_Sync", VehToNet(vehicle), new Action((matargPrimary) => + { + argPrimary = matargPrimary; + + + EventPrimaryran = true; + + })); + while (!EventPrimaryran) + { + + await Delay(0); + } + return argPrimary; + + } + }} \ No newline at end of file diff --git a/vMenuServer/PaintMaterialServer.cs b/vMenuServer/PaintMaterialServer.cs new file mode 100644 index 00000000..f6acef9c --- /dev/null +++ b/vMenuServer/PaintMaterialServer.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Threading.Tasks; + +using CitizenFX.Core; +using CitizenFX.Core.Native; + +namespace vMenuServer +{ + public class SetPrimaryMaterial_Server : BaseScript + + { + + public SetPrimaryMaterial_Server() + { + var VehicleMaterialListPrimary = new Dictionary(); + + EventHandlers["vMenu:GetPrimaryMaterial_Sync"] += new Action(PrimaryEvent); + + void PrimaryEvent(int vehicle, NetworkCallbackDelegate SecondarynetworkCB) + { + + foreach ( var vehiclel in VehicleMaterialListPrimary) + { + + if (vehiclel.Key == vehicle) + hasvaluePrimary = true; + } + if (hasvaluePrimary) + { + SecondarynetworkCB.Invoke(VehicleMaterialListPrimary[vehicle]); + hasvaluePrimary = false; + } + else + { + SecondarynetworkCB.Invoke(0); + hasvaluePrimary = false; + } + + } + + EventHandlers["vMenu:SetPrimaryMaterial_Sync"] += new Action(PrimarySave); + void PrimarySave(int vehicle, int material) + { + VehicleMaterialListPrimary[vehicle] = material; + foreach ( var vehiclel in new Dictionary(VehicleMaterialListPrimary)) + { + + if (!API.DoesEntityExist(API.NetworkGetEntityFromNetworkId(vehiclel.Key))) + { + + VehicleMaterialListPrimary.Remove(vehiclel.Key); + }; + } + } + + + } + + public bool hasvaluePrimary { get; private set; } + } + public class SetSecondaryMaterial_Server : BaseScript + + { + + public SetSecondaryMaterial_Server() + { + var VehicleMaterialListSecondary = new Dictionary(); + + EventHandlers["vMenu:GetSecondaryMaterial_Sync"] += new Action(SecondaryEvent); + + void SecondaryEvent(int vehicle, NetworkCallbackDelegate PrimarynetworkCB) + { + + foreach ( var vehiclel in VehicleMaterialListSecondary) + { + if (vehiclel.Key == vehicle) + hasvalueSecondary = true; + } + if (hasvalueSecondary) + { + PrimarynetworkCB.Invoke(VehicleMaterialListSecondary[vehicle]); + hasvalueSecondary = false; + } + else + { + PrimarynetworkCB.Invoke(0); + hasvalueSecondary = false; + } + + } + + EventHandlers["vMenu:SetSecondaryMaterial_Sync"] += new Action(SecondarySave); + void SecondarySave(int vehicle, int material) + { + + VehicleMaterialListSecondary[vehicle] = material; + foreach ( var vehiclel in new Dictionary(VehicleMaterialListSecondary)) + { + + if (!API.DoesEntityExist(API.NetworkGetEntityFromNetworkId(vehiclel.Key))) + { + + VehicleMaterialListSecondary.Remove(vehiclel.Key); + }; + } + } + + + } + + public bool hasvalueSecondary { get; private set; } + } +} \ No newline at end of file From 6cf8c0964c9035da26676519a7de5b273cea0e3b Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 21 Aug 2023 16:01:24 -0400 Subject: [PATCH 12/49] Added Pearlescent to custom colors --- vMenu/menus/VehicleOptions.cs | 44 ++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index aa777b3e..809d8448 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1308,6 +1308,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; + var pearlescentListPrimary = new MenuListItem("Pearlescent", classic, 0); var HexColorPrimary = new MenuItem("Primary Hex", "Set primary color with hex code."); MenuSliderItem FinishSliderPrimary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) { @@ -1321,6 +1322,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); primaryColorsMenuRGB.AddMenuItem(HexColorPrimary); primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(pearlescentListPrimary); primaryColorsMenuRGB.AddMenuItem(SecondaryMatchColorPrimary); primaryColorsMenu.OnItemSelect += async (sender, item, index) => @@ -1359,6 +1361,19 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in HexColorPrimary.Label = $"{hexValue}"; }; + primaryColorsMenuRGB.OnListIndexChange += (sender, item, oldIndex, newIndex, itemIndex) => + { + if (item == pearlescentListPrimary) + { + var veh = GetVehicle(); + var pearlColorReset = 0; + var wheelColorReset = 0; + GetVehicleExtraColours(veh.Handle, ref pearlColorReset, ref wheelColorReset); + SetVehicleExtraColours(veh.Handle, VehicleData.ClassicColors[newIndex].id, wheelColorReset); + + } + }; + primaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => { if (item == HexColorPrimary) @@ -2754,24 +2769,47 @@ private int GetIndexFromColor() } public static class SetMaterial { + public static int lastSecondaryMaterial { get; private set; } + public static int lastSecondaryVehicle { get; private set; } + public static void SetSecondaryMaterial(int vehicle, int material) { + var pearlColorReset = 0; + var wheelColorReset = 0; + GetVehicleExtraColours(vehicle, ref pearlColorReset, ref wheelColorReset); SetVehicleModColor_2(vehicle, material, 0); - + SetVehicleExtraColours(vehicle, pearlColorReset, wheelColorReset); + if (!(material == lastSecondaryMaterial) || !(vehicle == lastSecondaryVehicle)) + { TriggerServerEvent("vMenu:SetSecondaryMaterial_Sync", VehToNet(vehicle), material); + lastSecondaryMaterial = material; + lastSecondaryVehicle = vehicle; + } } + public static int lastPrimaryMaterial { get; private set; } + public static int lastPrimaryVehicle { get; private set; } + public static void SetPrimaryMaterial(int vehicle, int material) { + var pearlColorReset = 0; + var wheelColorReset = 0; + GetVehicleExtraColours(vehicle, ref pearlColorReset, ref wheelColorReset); SetVehicleModColor_1(vehicle, material, 0, 0); - - + SetVehicleExtraColours(vehicle, pearlColorReset, wheelColorReset); + + if (!(material == lastPrimaryMaterial) || !(vehicle == lastPrimaryVehicle)) + { TriggerServerEvent("vMenu:SetPrimaryMaterial_Sync", VehToNet(vehicle), material); + lastPrimaryMaterial = material; + lastPrimaryVehicle = vehicle; + } } }; public static class GetMaterial { public static int argSecondary { get; private set; } + public static bool EventSecondaryran { get; private set; } public static async Task GetSecondaryMaterialAsync(int vehicle) From f39c0a652fadfa81595c6f952db2b9315d322c9d Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 21 Aug 2023 17:28:35 -0400 Subject: [PATCH 13/49] removed debug info --- vMenu/CommonFunctions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 5fc8cde2..322cfdf5 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -1438,7 +1438,7 @@ private static async void ApplyVehicleModsDelayed(Vehicle vehicle, VehicleInfo v ToggleVehicleMod(vehicle.Handle, 20, vehicleInfo.tyreSmoke); ToggleVehicleMod(vehicle.Handle, 22, vehicleInfo.xenonHeadlights); SetVehicleLivery(vehicle.Handle, vehicleInfo.livery); - Debug.WriteLine($"{vehicleInfo.colors["primary"] == 1100110}"); + if (!(vehicleInfo.colors["primary"] == 1100110)) { if (vehicleInfo.colors["secondary"] == 1100110) @@ -1588,7 +1588,7 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul GetVehicleExtraColours(veh.Handle, ref pearlescentColor, ref wheelColor); GetVehicleCustomPrimaryColour(veh.Handle, ref primaryColorred, ref primaryColorgreen, ref primaryColorblue); - Debug.WriteLine($"{((primaryColorred +primaryColorgreen + primaryColorblue) == 0 + primaryFinish ) }"); + if (!(!((primaryColorred +primaryColorgreen + primaryColorblue ) == 0 ) || !(primaryFinish == 0))) { GetVehicleColours(veh.Handle, ref primaryColor, ref secondaryColor); @@ -1601,7 +1601,7 @@ public static async void SaveVehicle(string updateExistingSavedVehicleName = nul GetVehicleCustomSecondaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); - Debug.WriteLine($"{((secondaryColorred +secondaryColorgreen + secondaryColorblue) == 0 + secondaryFinish ) }"); + if (!(!((secondaryColorred +secondaryColorgreen + secondaryColorblue ) == 0 ) || !(secondaryFinish == 0))) { GetVehicleColours(veh.Handle, ref secondaryColor, ref secondaryColor); From 1be24f52c6942994f9d545978ad6b846e3a3f4a6 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Mon, 21 Aug 2023 18:59:51 -0400 Subject: [PATCH 14/49] Fixes to make RGB colours prettier, description for Player Time & Weather Options should give you the idea yeah Co-Authored-By: Ricky Merc <65817116+RickyB505@users.noreply.github.com> --- vMenu/menus/PlayerTimeWeatherOptions.cs | 4 +- vMenu/menus/VehicleOptions.cs | 146 +++++++++++++----------- 2 files changed, 79 insertions(+), 71 deletions(-) diff --git a/vMenu/menus/PlayerTimeWeatherOptions.cs b/vMenu/menus/PlayerTimeWeatherOptions.cs index 812b0d48..fdbfe117 100644 --- a/vMenu/menus/PlayerTimeWeatherOptions.cs +++ b/vMenu/menus/PlayerTimeWeatherOptions.cs @@ -33,9 +33,9 @@ public class PlayerTimeWeatherOptions /// private void CreateMenu() { - menu = new Menu("Time & Weather Options", "Time & Weather Options"); + menu = new Menu("Time & Weather", "Time & Weather Options"); - clientSidedEnabled = new MenuCheckboxItem("Client-Sided Time & Weather", "Enable or disable client-sided time and weather changes.", false); + clientSidedEnabled = new MenuCheckboxItem("Client-Sided Time & Weather", "Enable or disable client-sided time and weather changes. \n\nPlease do note that this menu will be revamped in a future update, to replicate the World Related Options menu.", false); menu.AddMenuItem(clientSidedEnabled); List timeData = new List(); diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 809d8448..657fd121 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -130,7 +130,7 @@ private void CreateMenu() { Label = "→→→" }; - var colorsMenuBtn = new MenuItem("Vehicle Colors", "Style your vehicle even further by giving it some ~g~Snailsome ~s~colors!") + var colorsMenuBtn = new MenuItem("Vehicle Colours", "Style your vehicle even further by giving it an ~g~awesome ~s~paint job!") { Label = "→→→" }; @@ -230,7 +230,7 @@ private void CreateMenu() VehicleWindowsMenu = Lm.GetMenu(new Menu("Vehicle Windows", "Vehicle Windows Management")); VehicleComponentsMenu = Lm.GetMenu(new Menu("Vehicle Extras", "Vehicle Extras/Components")); VehicleLiveriesMenu = Lm.GetMenu(new Menu("Vehicle Liveries", "Vehicle Liveries")); - VehicleColorsMenu = Lm.GetMenu(new Menu("Vehicle Colors", "Vehicle Colors")); + VehicleColorsMenu = Lm.GetMenu(new Menu("Vehicle Colours", "Vehicle Colours")); DeleteConfirmMenu = Lm.GetMenu(new Menu("Confirm Action", "Delete Vehicle, are you sure?")); VehicleUnderglowMenu = Lm.GetMenu(new Menu("Vehicle Neon Kits", "Vehicle Neon Underglow Options")); @@ -981,20 +981,20 @@ private void CreateMenu() }; #endregion - #region Vehicle Colors Submenu Stuff + #region Vehicle Colours Submenu Stuff // primary menu - var primaryColorsMenu = Lm.GetMenu(new Menu("Vehicle Colors", "Primary Colors")); + var primaryColorsMenu = Lm.GetMenu(new Menu("Vehicle Colours", "Primary Colours")); MenuController.AddSubmenu(VehicleColorsMenu, primaryColorsMenu); - var primaryColorsBtn = new MenuItem("Primary Color") { Label = "→→→" }; + var primaryColorsBtn = new MenuItem("Primary Colour") { Label = "→→→" }; VehicleColorsMenu.AddMenuItem(primaryColorsBtn); MenuController.BindMenuItem(VehicleColorsMenu, primaryColorsMenu, primaryColorsBtn); // secondary menu - var secondaryColorsMenu = Lm.GetMenu(new Menu("Vehicle Colors", "Secondary Colors")); + var secondaryColorsMenu = Lm.GetMenu(new Menu("Vehicle Colours", "Secondary Colours")); MenuController.AddSubmenu(VehicleColorsMenu, secondaryColorsMenu); - var secondaryColorsBtn = new MenuItem("Secondary Color") { Label = "→→→" }; + var secondaryColorsBtn = new MenuItem("Secondary Colour") { Label = "→→→" }; VehicleColorsMenu.AddMenuItem(secondaryColorsBtn); MenuController.BindMenuItem(VehicleColorsMenu, secondaryColorsMenu, secondaryColorsBtn); var ColorFInishes = new List() @@ -1065,9 +1065,9 @@ private void CreateMenu() wheelColors.AddRange(classic); } - var wheelColorsList = new MenuListItem("Wheel Color", wheelColors, 0); - var dashColorList = new MenuListItem("Dashboard Color", classic, 0); - var intColorList = new MenuListItem("Interior / Trim Color", classic, 0); + var wheelColorsList = new MenuListItem("Wheel Colour", wheelColors, 0); + var dashColorList = new MenuListItem("Dashboard Colour", classic, 0); + var intColorList = new MenuListItem("Interior / Trim Colour", classic, 0); var vehicleEnveffScale = new MenuSliderItem("Vehicle Enveff Scale", "This works on certain vehicles only, like the besra for example. It 'fades' certain paint layers.", 0, 20, 10, true); var chrome = new MenuItem("Chrome"); @@ -1231,7 +1231,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in } else { - Notify.Error("You need to be the driver of a vehicle in order to change the vehicle colors."); + Notify.Error("You need to be the driver of a vehicle in order to change the vehicle colours."); } } @@ -1282,41 +1282,45 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in } } - var primaryColorsMenuRGB = Lm.GetMenu(new Menu("Vehicle Colors RGB", "Primary Colors RGB")); + var primaryColorsMenuRGB = Lm.GetMenu(new Menu("Primary RGB Colours", "Primary RGB Colours")); MenuController.AddSubmenu(primaryColorsMenu, primaryColorsMenuRGB); - var primaryColorsRGBBtn = new MenuItem("Primary Color RGB") { Label = "→→→" }; + var primaryColorsRGBBtn = new MenuItem("Primary Colour RGB") { Label = "→→→" }; primaryColorsMenu.AddMenuItem(primaryColorsRGBBtn); MenuController.BindMenuItem(primaryColorsMenu, primaryColorsMenuRGB, primaryColorsRGBBtn); - MenuSliderItem RedSliderPrimary = new MenuSliderItem($"Red Color {RedPrimary}", 0, 255, 0, false) + MenuSliderItem RedSliderPrimary = new MenuSliderItem($"Red Colour ({RedPrimary})", 0, 255, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~r~Red~r~ ~w~colour.~w~", }; - MenuSliderItem GreenSliderPrimary = new MenuSliderItem($"Green Color {GreenPrimary}", 0, 255, 0, false) + MenuSliderItem GreenSliderPrimary = new MenuSliderItem($"Green Colour ({GreenPrimary})", 0, 255, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~g~Green~g~ ~w~colour.~w~", }; - MenuSliderItem BlueSliderPrimary = new MenuSliderItem($"Blue Color {BluePrimary}", 0, 255, 0, false) + MenuSliderItem BlueSliderPrimary = new MenuSliderItem($"Blue Colour ({BluePrimary})", 0, 255, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~b~Blue~b~ ~w~colour.~w~", }; var pearlescentListPrimary = new MenuListItem("Pearlescent", classic, 0); - var HexColorPrimary = new MenuItem("Primary Hex", "Set primary color with hex code."); - MenuSliderItem FinishSliderPrimary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) + var HexColorPrimary = new MenuItem("Primary Hex", "Set primary colour with hex code."); + MenuSliderItem FinishSliderPrimary = new MenuSliderItem($"Colour Finish (Normal)", 0, 5, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Select a paint finish for your Primary paint job.", }; - var SecondaryMatchColorPrimary = new MenuItem("Match To Secondary", "Copys color data from secondary."); + var SecondaryMatchColorPrimary = new MenuItem("Match from Secondary", "Copies the Secondary Colour's colour data."); primaryColorsMenuRGB.AddMenuItem(RedSliderPrimary); primaryColorsMenuRGB.AddMenuItem(GreenSliderPrimary); primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); @@ -1349,16 +1353,16 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenPrimary = primaryColorgreen; BluePrimary = primaryColorblue; FinishPrimary = primaryPaintFinish; - RedSliderPrimary.Text = $"Red Color {primaryColorred}"; - GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; - BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; - FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[primaryPaintFinish]}"; + RedSliderPrimary.Text = $"Red Colour ({primaryColorred})"; + GreenSliderPrimary.Text = $"Green Colour ({primaryColorgreen})"; + BlueSliderPrimary.Text = $"Blue Colour ({primaryColorblue})"; + FinishSliderPrimary.Text = $"Colour Finish ({ColorFInishes[primaryPaintFinish]})"; RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - HexColorPrimary.Label = $"{hexValue}"; + HexColorPrimary.Label = $"#{hexValue}"; }; primaryColorsMenuRGB.OnListIndexChange += (sender, item, oldIndex, newIndex, itemIndex) => @@ -1378,7 +1382,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in { if (item == HexColorPrimary) { - var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorPrimary.Label, maxInputLength: 6); + var result = await GetUserInput(windowTitle: "Enter Colour Hex", defaultText: (HexColorPrimary.Label).Replace("#", ""), maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { if (IsHex(result)) @@ -1388,9 +1392,9 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in byte Green = (byte)((RGBint >> 8) & 255); byte Blue = (byte)(RGBint & 255); - RedSliderPrimary.Text = $"Red Color {Red}"; - GreenSliderPrimary.Text = $"Green Color {Green}"; - BlueSliderPrimary.Text = $"Blue Color {Blue}"; + RedSliderPrimary.Text = $"Red Colour ({Red})"; + GreenSliderPrimary.Text = $"Green Colour ({Green})"; + BlueSliderPrimary.Text = $"Blue Colour ({Blue})"; RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); @@ -1403,13 +1407,13 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in BluePrimary = Blue; string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - HexColorPrimary.Label = $"{hexValue}"; + HexColorPrimary.Label = $"#{hexValue}"; var veh = GetVehicle(); SetVehicleCustomPrimaryColour(veh.Handle, Red, Green, Blue); } else - Notify.Error($"{result} is not a valid hex code"); + Notify.Error($"#{result} is not a valid hex code!"); } } if (item == SecondaryMatchColorPrimary) @@ -1433,16 +1437,16 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenPrimary = primaryColorgreen; BluePrimary = primaryColorblue; FinishPrimary = secondaryFinish; - RedSliderPrimary.Text = $"Red Color {primaryColorred}"; - GreenSliderPrimary.Text = $"Green Color {primaryColorgreen}"; - BlueSliderPrimary.Text = $"Blue Color {primaryColorblue}"; - FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[secondaryFinish]}"; + RedSliderPrimary.Text = $"Red Colour ({primaryColorred})"; + GreenSliderPrimary.Text = $"Green Colour ({primaryColorgreen})"; + BlueSliderPrimary.Text = $"Blue Colour ({primaryColorblue})"; + FinishSliderPrimary.Text = $"Colour Finish ({ColorFInishes[secondaryFinish]})"; RedSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, primaryColorred, primaryColorgreen, primaryColorblue); string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - HexColorPrimary.Label = $"{hexValue}"; + HexColorPrimary.Label = $"#{hexValue}"; SetMaterial.SetPrimaryMaterial(veh.Handle, secondaryFinish); SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); @@ -1458,7 +1462,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); - RedSliderPrimary.Text = $"Red Color {RedPrimary}"; + RedSliderPrimary.Text = $"Red Colour ({RedPrimary})"; } @@ -1469,7 +1473,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); - GreenSliderPrimary.Text = $"Green Color {GreenPrimary}"; + GreenSliderPrimary.Text = $"Green Colour ({GreenPrimary})"; } if (sliderItem == BlueSliderPrimary) @@ -1479,7 +1483,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); - BlueSliderPrimary.Text = $"Blue Color {BluePrimary}"; + BlueSliderPrimary.Text = $"Blue Colour ({BluePrimary})"; } @@ -1490,14 +1494,14 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); BlueSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); FinishSliderPrimary.BarColor = System.Drawing.Color.FromArgb(255, RedPrimary, GreenPrimary, BluePrimary); - FinishSliderPrimary.Text = $"Color Finish {ColorFInishes[FinishPrimary]}"; + FinishSliderPrimary.Text = $"Colour Finish ({ColorFInishes[FinishPrimary]})"; } if ((sliderItem == RedSliderPrimary) || (sliderItem == GreenSliderPrimary) || (sliderItem == BlueSliderPrimary) || (sliderItem == FinishSliderPrimary)) { var veh = GetVehicle(); string hexValue = RedPrimary.ToString("X2") + GreenPrimary.ToString("X2") + BluePrimary.ToString("X2"); - HexColorPrimary.Label = $"{hexValue}"; + HexColorPrimary.Label = $"#{hexValue}"; SetMaterial.SetPrimaryMaterial(veh.Handle, FinishPrimary); @@ -1505,40 +1509,44 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in } }; - var SecondaryColorsMenuRGB = Lm.GetMenu(new Menu("Vehicle Colors RGB", "Secondary Colors RGB")); + var SecondaryColorsMenuRGB = Lm.GetMenu(new Menu("Secondary RGB Colours", "Secondary RGB Colours")); MenuController.AddSubmenu(secondaryColorsMenu, SecondaryColorsMenuRGB); - var SecondaryColorsRGBBtn = new MenuItem("Secondary Color RGB") { Label = "→→→" }; + var SecondaryColorsRGBBtn = new MenuItem("Secondary Colour RGB") { Label = "→→→" }; secondaryColorsMenu.AddMenuItem(SecondaryColorsRGBBtn); MenuController.BindMenuItem(secondaryColorsMenu, SecondaryColorsMenuRGB, SecondaryColorsRGBBtn); - MenuSliderItem RedSliderSecondary = new MenuSliderItem($"Red Color {RedSecondary}", 0, 255, 0, false) + MenuSliderItem RedSliderSecondary = new MenuSliderItem($"Red Colour ({RedSecondary})", 0, 255, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~r~Red~r~ ~w~colour.~w~", }; - MenuSliderItem GreenSliderSecondary = new MenuSliderItem($"Green Color {GreenSecondary}", 0, 255, 0, false) + MenuSliderItem GreenSliderSecondary = new MenuSliderItem($"Green Colour ({GreenSecondary})", 0, 255, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~g~Green~g~ ~w~colour.~w~", }; - MenuSliderItem BlueSliderSecondary = new MenuSliderItem($"Blue Color {BlueSecondary}", 0, 255, 0, false) + MenuSliderItem BlueSliderSecondary = new MenuSliderItem($"Blue Colour ({BlueSecondary})", 0, 255, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~b~Blue~b~ ~w~colour.~w~", }; - var HexColorSecondary = new MenuItem("Secondary Hex", "Set secondary color with hex code."); - MenuSliderItem FinishSliderSecondary = new MenuSliderItem($"Color Finish Normal", 0, 5, 0, false) + var HexColorSecondary = new MenuItem("Secondary Hex", "Set secondary colour with hex code."); + MenuSliderItem FinishSliderSecondary = new MenuSliderItem($"Colour Finish (Normal)", 0, 5, 0, false) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Select a paint finish for your Secondary paint job.", }; - var PrimaryMatchColorSecondary = new MenuItem("Match To Primary", "Copys color data from primary."); + var PrimaryMatchColorSecondary = new MenuItem("Match from Primary Colour", "Copies the Primary Colour's colour data."); secondaryColorsMenu.OnItemSelect += async (sender, item, index) => { @@ -1561,22 +1569,22 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSecondary = secondaryColorgreen; BlueSecondary = secondaryColorblue; FinishSecondary = secondaryFinish; - RedSliderSecondary.Text = $"Red Color {RedSecondary}"; - GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; - BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; - FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; + RedSliderSecondary.Text = $"Red Colour ({RedSecondary})"; + GreenSliderSecondary.Text = $"Green Colour ({GreenSecondary})"; + BlueSliderSecondary.Text = $"Blue Colour ({BlueSecondary})"; + FinishSliderSecondary.Text = $"Colour Finish ({ColorFInishes[FinishSecondary]})"; RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; + HexColorSecondary.Label = $"#{hexValue}"; }; SecondaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => { if (item == HexColorSecondary) { - var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: HexColorSecondary.Label, maxInputLength: 6); + var result = await GetUserInput(windowTitle: "Enter Colour Hex", defaultText: (HexColorSecondary.Label).Replace("#", ""), maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { if (IsHex(result)) @@ -1586,9 +1594,9 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in byte Green = (byte)((RGBint >> 8) & 255); byte Blue = (byte)(RGBint & 255); - RedSliderSecondary.Text = $"Red Color {Red}"; - GreenSliderSecondary.Text = $"Green Color {Green}"; - BlueSliderSecondary.Text = $"Blue Color {Blue}"; + RedSliderSecondary.Text = $"Red Colour ({Red})"; + GreenSliderSecondary.Text = $"Green Colour ({Green})"; + BlueSliderSecondary.Text = $"Blue Colour ({Blue})"; RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); @@ -1600,13 +1608,13 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSecondary = Green; BlueSecondary = Blue; string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; + HexColorSecondary.Label = $"#{hexValue}"; var veh = GetVehicle(); SetVehicleCustomSecondaryColour(veh.Handle, Red, Green, Blue); } else - Notify.Error($"{result} is not a valid hex code"); + Notify.Error($"{result} is not a valid hex code!"); } @@ -1633,16 +1641,16 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSecondary = secondaryColorgreen; BlueSecondary = secondaryColorblue; FinishSecondary = primaryFinish2; - RedSliderSecondary.Text = $"Red Color {RedSecondary}"; - GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; - BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; - FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[primaryFinish2]}"; + RedSliderSecondary.Text = $"Red Colour ({RedSecondary})"; + GreenSliderSecondary.Text = $"Green Colour ({GreenSecondary})"; + BlueSliderSecondary.Text = $"Blue Colour ({BlueSecondary})"; + FinishSliderSecondary.Text = $"Colour Finish ({ColorFInishes[primaryFinish2]})"; RedSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; + HexColorSecondary.Label = $"#{hexValue}"; SetMaterial.SetSecondaryMaterial(veh.Handle, primaryFinish2); @@ -1668,7 +1676,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - RedSliderSecondary.Text = $"Red Color {RedSecondary}"; + RedSliderSecondary.Text = $"Red Colour ({RedSecondary})"; } @@ -1679,7 +1687,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - GreenSliderSecondary.Text = $"Green Color {GreenSecondary}"; + GreenSliderSecondary.Text = $"Green Colour ({GreenSecondary})"; } if (sliderItem == BlueSliderSecondary) @@ -1689,7 +1697,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - BlueSliderSecondary.Text = $"Blue Color {BlueSecondary}"; + BlueSliderSecondary.Text = $"Blue Colour ({BlueSecondary})"; } @@ -1700,7 +1708,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in GreenSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); BlueSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); FinishSliderSecondary.BarColor = System.Drawing.Color.FromArgb(255, RedSecondary, GreenSecondary, BlueSecondary); - FinishSliderSecondary.Text = $"Color Finish {ColorFInishes[FinishSecondary]}"; + FinishSliderSecondary.Text = $"Colour Finish ({ColorFInishes[FinishSecondary]})"; } if ((sliderItem == RedSliderSecondary) || (sliderItem == GreenSliderSecondary) || (sliderItem == BlueSliderSecondary) || (sliderItem == FinishSliderSecondary)) @@ -1710,7 +1718,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); string hexValue = RedSecondary.ToString("X2") + GreenSecondary.ToString("X2") + BlueSecondary.ToString("X2"); - HexColorSecondary.Label = $"{hexValue}"; + HexColorSecondary.Label = $"#{hexValue}"; } }; From b4df4aa67b935516c78d4b5bd77bf23fb09881ef Mon Sep 17 00:00:00 2001 From: Tristen <87451201+tristencommunity@users.noreply.github.com> Date: Mon, 21 Aug 2023 19:29:55 -0500 Subject: [PATCH 15/49] Inverted the Spawn as Default permission convar https://github.com/ProjectFairnessLabs/PF-vMenu/issues/51 Upon Ricky testing the permission, he forgot to invert it which caused the person above to create that ticket. This resolves the issue. --- vMenu/EventManager.cs | 2 +- vMenu/FunctionsController.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vMenu/EventManager.cs b/vMenu/EventManager.cs index 06fe3195..f5041402 100644 --- a/vMenu/EventManager.cs +++ b/vMenu/EventManager.cs @@ -91,7 +91,7 @@ private async void SetAppearanceOnFirstSpawn() if (firstSpawn) { firstSpawn = false; - if (MainMenu.MiscSettingsMenu != null && MainMenu.MpPedCustomizationMenu != null && MainMenu.MiscSettingsMenu.MiscRespawnDefaultCharacter && !string.IsNullOrEmpty(GetResourceKvpString("vmenu_default_character")) && !IsAllowed(Permission.PASpawnAsDefault)) + if (MainMenu.MiscSettingsMenu != null && MainMenu.MpPedCustomizationMenu != null && MainMenu.MiscSettingsMenu.MiscRespawnDefaultCharacter && !string.IsNullOrEmpty(GetResourceKvpString("vmenu_default_character")) && IsAllowed(Permission.PASpawnAsDefault)) { await MainMenu.MpPedCustomizationMenu.SpawnThisCharacter(GetResourceKvpString("vmenu_default_character"), false); } diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index 46f54cbd..42982db2 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -107,7 +107,7 @@ public void SetupTickFunctions() } // Configuration based - if (!IsAllowed(Permission.PASpawnAsDefault)) + if (IsAllowed(Permission.PASpawnAsDefault)) { Tick += RestorePlayerAfterBeingDead; } From 0c907d35fa9488fabab1286d946a0b1fa1627435 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 21 Aug 2023 20:46:30 -0400 Subject: [PATCH 16/49] Removed useless Chrome button --- vMenu/menus/VehicleOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 657fd121..73cafb3c 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1071,7 +1071,7 @@ private void CreateMenu() var vehicleEnveffScale = new MenuSliderItem("Vehicle Enveff Scale", "This works on certain vehicles only, like the besra for example. It 'fades' certain paint layers.", 0, 20, 10, true); var chrome = new MenuItem("Chrome"); - VehicleColorsMenu.AddMenuItem(chrome); + //VehicleColorsMenu.AddMenuItem(chrome); VehicleColorsMenu.AddMenuItem(vehicleEnveffScale); VehicleColorsMenu.OnItemSelect += (sender, item, index) => From 001a63c3300153494f228dad6ac60639cddb7e4a Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 21 Aug 2023 22:41:43 -0400 Subject: [PATCH 17/49] Smoother time change --- vMenuServer/MainServer.cs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/vMenuServer/MainServer.cs b/vMenuServer/MainServer.cs index e084e141..2b74d469 100644 --- a/vMenuServer/MainServer.cs +++ b/vMenuServer/MainServer.cs @@ -739,11 +739,35 @@ internal void UpdateWeatherCloudsType(bool removeClouds) /// /// [EventHandler("vMenu:UpdateServerTime")] - internal void UpdateTime(int newHours, int newMinutes, bool freezeTimeNew) + internal async void UpdateTime(int newHours, int newMinutes, bool freezeTimeNew) { + CurrentHours = CurrentHours; + CurrentMinutes = CurrentMinutes; + + while (newHours != CurrentHours) + { + if ((CurrentMinutes + 1) > 59) + { + CurrentMinutes = 0; + if ((CurrentHours + 1) > 23) + { + CurrentHours = 0; + } + else + { + CurrentHours ++; + } + } + else + { + CurrentMinutes=CurrentMinutes+5; + } + await Delay(1); + } CurrentHours = newHours; CurrentMinutes = newMinutes; FreezeTime = freezeTimeNew; + } #endregion From 16233b31001ab5b5590ab8cd34f6eb6b086e9185 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Tue, 22 Aug 2023 01:37:52 -0400 Subject: [PATCH 18/49] RGB underglow --- vMenu/FunctionsController.cs | 3 +- vMenu/menus/VehicleOptions.cs | 236 +++++++++++++++++++++++++++++++--- vMenuServer/MainServer.cs | 4 +- 3 files changed, 218 insertions(+), 25 deletions(-) diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index 42982db2..a8e55efa 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -567,8 +567,7 @@ private async Task VehicleOptions() MainMenu.VehicleOptionsMenu.VehicleComponentsMenu, MainMenu.VehicleOptionsMenu.VehicleDoorsMenu, MainMenu.VehicleOptionsMenu.VehicleLiveriesMenu, - MainMenu.VehicleOptionsMenu.VehicleModMenu, - MainMenu.VehicleOptionsMenu.VehicleUnderglowMenu, + MainMenu.VehicleOptionsMenu.VehicleModMenu, MainMenu.VehicleOptionsMenu.VehicleWindowsMenu, }; foreach (var m in subMenus) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 73cafb3c..965a19d5 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -32,7 +32,7 @@ public class VehicleOptions public Menu VehicleLiveriesMenu { get; private set; } public Menu VehicleColorsMenu { get; private set; } public Menu DeleteConfirmMenu { get; private set; } - public Menu VehicleUnderglowMenu { get; private set; } + public Menu UnderglowColorsMenu { get; private set; } // Public variables (getters only), return the private variables. public bool VehicleGodMode { get; private set; } = UserDefaults.VehicleGodMode; @@ -67,6 +67,9 @@ public class VehicleOptions public int GreenSecondary { get; private set; } = 0; public int BlueSecondary { get; private set; } = 0; public int FinishSecondary { get; private set; } = 0; + public object RedUnderglow { get; private set; } + public object GreenUnderglow { get; private set; } + public object BlueUnderglow { get; private set; } private static readonly LanguageManager Lm = new LanguageManager(); @@ -134,10 +137,10 @@ private void CreateMenu() { Label = "→→→" }; - var underglowMenuBtn = new MenuItem("Vehicle Neon Kits", "Make your vehicle shine with some fancy neon underglow!") - { - Label = "→→→" - }; + //var underglowMenuBtn = new MenuItem("Vehicle Neon Kits", "Make your vehicle shine with some fancy neon underglow!") + //{ + // Label = "→→→" + //}; var vehicleInvisible = new MenuItem("Toggle Vehicle Visibility", "Makes your vehicle visible/invisible. ~r~Your vehicle will be made visible again as soon as you leave the vehicle. Otherwise you would not be able to get back in."); var flipVehicle = new MenuItem("Flip Vehicle", "Sets your current vehicle on all 4 wheels."); var vehicleAlarm = new MenuItem("Toggle Vehicle Alarm", "Starts/stops your vehicle's alarm."); @@ -232,7 +235,7 @@ private void CreateMenu() VehicleLiveriesMenu = Lm.GetMenu(new Menu("Vehicle Liveries", "Vehicle Liveries")); VehicleColorsMenu = Lm.GetMenu(new Menu("Vehicle Colours", "Vehicle Colours")); DeleteConfirmMenu = Lm.GetMenu(new Menu("Confirm Action", "Delete Vehicle, are you sure?")); - VehicleUnderglowMenu = Lm.GetMenu(new Menu("Vehicle Neon Kits", "Vehicle Neon Underglow Options")); + //VehicleUnderglowMenu = Lm.GetMenu(new Menu("Vehicle Neon Kits", "Vehicle Neon Underglow Options")); MenuController.AddSubmenu(menu, VehicleModMenu); MenuController.AddSubmenu(menu, VehicleDoorsMenu); @@ -241,7 +244,7 @@ private void CreateMenu() MenuController.AddSubmenu(menu, VehicleLiveriesMenu); MenuController.AddSubmenu(menu, VehicleColorsMenu); MenuController.AddSubmenu(menu, DeleteConfirmMenu); - MenuController.AddSubmenu(menu, VehicleUnderglowMenu); + #endregion #region Add items to the menu. @@ -318,8 +321,8 @@ private void CreateMenu() } if (IsAllowed(Permission.VOUnderglow)) // UNDERGLOW EFFECTS { - menu.AddMenuItem(underglowMenuBtn); - MenuController.BindMenuItem(menu, VehicleUnderglowMenu, underglowMenuBtn); + // menu.AddMenuItem(underglowMenuBtn); + // MenuController.BindMenuItem(menu, VehicleUnderglowMenu, underglowMenuBtn); } if (IsAllowed(Permission.VOLiveries)) // LIVERIES MENU { @@ -1110,6 +1113,40 @@ private void CreateMenu() VehicleColorsMenu.AddMenuItem(intColorList); VehicleColorsMenu.AddMenuItem(wheelColorsList); + // Underglow menu + var UnderglowColorsMenu = Lm.GetMenu(new Menu("Underglow Colours", "Underglow Colours")); + MenuController.AddSubmenu(VehicleColorsMenu, UnderglowColorsMenu); + + var UnderglowColorsBtn = new MenuItem("Underglow Colour") { Label = "→→→" }; + VehicleColorsMenu.AddMenuItem(UnderglowColorsBtn); + MenuController.BindMenuItem(VehicleColorsMenu, UnderglowColorsMenu, UnderglowColorsBtn); + + MenuSliderItem RedSliderUnderglow = new MenuSliderItem($"Red Colour ({RedUnderglow})", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~r~Red~r~ ~w~colour.~w~", + + }; + + MenuSliderItem GreenSliderUnderglow = new MenuSliderItem($"Green Colour ({GreenUnderglow})", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~g~Green~g~ ~w~colour.~w~", + + }; + + MenuSliderItem BlueSliderUnderglow = new MenuSliderItem($"Blue Colour ({BlueUnderglow})", 0, 255, 0, false) + { + BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), + BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), + Description = "Use the slider to pick a ~b~Blue~b~ ~w~colour.~w~", + + }; + + + VehicleColorsMenu.OnListIndexChange += HandleListIndexChanges; void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, int newIndex, int itemIndex) @@ -1331,6 +1368,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in primaryColorsMenu.OnItemSelect += async (sender, item, index) => { + var veh = GetVehicle(); var primaryColorred = 0; var primaryColorgreen = 0; @@ -2074,21 +2112,118 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in { underglowColorsList.Add(GetLabelText($"CMOD_NEONCOL_{i}")); } - var underglowColor = new MenuListItem(GetLabelText("CMOD_NEON_1"), underglowColorsList, 0, "Select the color of the neon underglow."); + var underglowColor = new MenuListItem("Underglow preset", underglowColorsList, 0, "Preset underglow colors."); + var HexColorUnderglow = new MenuItem("Underglow Hex", "Set Underglow colour with hex code."); + var syncprimaryUnderglow = new MenuItem("Sync With Primary", "Sync Underglow colour with Secondary Paint."); + var syncsecondaryUnderglow = new MenuItem("Sync With Secondary", "Sync Underglow colour with Secondary Paint."); + UnderglowColorsMenu.AddMenuItem(underglowFront); + UnderglowColorsMenu.AddMenuItem(underglowBack); + UnderglowColorsMenu.AddMenuItem(underglowLeft); + UnderglowColorsMenu.AddMenuItem(underglowRight); + + UnderglowColorsMenu.AddMenuItem(underglowColor); + + UnderglowColorsMenu.AddMenuItem(RedSliderUnderglow); + UnderglowColorsMenu.AddMenuItem(GreenSliderUnderglow); + UnderglowColorsMenu.AddMenuItem(BlueSliderUnderglow); + UnderglowColorsMenu.AddMenuItem(HexColorUnderglow); + UnderglowColorsMenu.AddMenuItem(syncprimaryUnderglow); + UnderglowColorsMenu.AddMenuItem(syncsecondaryUnderglow); + UnderglowColorsMenu.OnItemSelect += async (sender, item, index) => + { + if (item == HexColorUnderglow) + { + var result = await GetUserInput(windowTitle: "Enter Colour Hex", defaultText: (HexColorUnderglow.Label).Replace("#", ""), maxInputLength: 6); + if (!string.IsNullOrEmpty(result)) + { + if (IsHex(result)) + { + int RGBint = Convert.ToInt32(result, 16); + byte Red = (byte)((RGBint >> 16) & 255); + byte Green = (byte)((RGBint >> 8) & 255); + byte Blue = (byte)(RGBint & 255); - VehicleUnderglowMenu.AddMenuItem(underglowFront); - VehicleUnderglowMenu.AddMenuItem(underglowBack); - VehicleUnderglowMenu.AddMenuItem(underglowLeft); - VehicleUnderglowMenu.AddMenuItem(underglowRight); - VehicleUnderglowMenu.AddMenuItem(underglowColor); + var veh = GetVehicle(); + RedSliderUnderglow.Position = Red; + GreenSliderUnderglow.Position = Green; + BlueSliderUnderglow.Position = Blue; + RedSliderUnderglow.Text = $"Red Colour ({Red})"; + GreenSliderUnderglow.Text = $"Green Colour ({Green})"; + BlueSliderUnderglow.Text = $"Blue Colour ({Blue})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + string hexValue = Red.ToString("X2") + Green.ToString("X2") + Blue.ToString("X2"); + HexColorUnderglow.Label = $"#{hexValue}"; + SetVehicleNeonLightsColour(veh.Handle, RedSliderUnderglow.Position, GreenSliderUnderglow.Position, BlueSliderUnderglow.Position); - menu.OnItemSelect += (sender, item, index) => + } + else + Notify.Error($"#{result} is not a valid hex code!"); + } + } + if (item == syncprimaryUnderglow) + { + var Red = 0; + var Green = 0; + var Blue = 0; + var veh = GetVehicle(); + GetVehicleCustomPrimaryColour(veh.Handle, ref Red, ref Green, ref Blue); + RedSliderUnderglow.Position = Red; + GreenSliderUnderglow.Position = Green; + BlueSliderUnderglow.Position = Blue; + RedSliderUnderglow.Text = $"Red Colour ({Red})"; + GreenSliderUnderglow.Text = $"Green Colour ({Green})"; + BlueSliderUnderglow.Text = $"Blue Colour ({Blue})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + string hexValue = Red.ToString("X2") + Green.ToString("X2") + Blue.ToString("X2"); + HexColorUnderglow.Label = $"#{hexValue}"; + SetVehicleNeonLightsColour(veh.Handle, RedSliderUnderglow.Position, GreenSliderUnderglow.Position, BlueSliderUnderglow.Position); + } + if (item == syncsecondaryUnderglow) + { + var Red = 0; + var Green = 0; + var Blue = 0; + var veh = GetVehicle(); + GetVehicleCustomSecondaryColour(veh.Handle, ref Red, ref Green, ref Blue); + RedSliderUnderglow.Position = Red; + GreenSliderUnderglow.Position = Green; + BlueSliderUnderglow.Position = Blue; + RedSliderUnderglow.Text = $"Red Colour ({Red})"; + GreenSliderUnderglow.Text = $"Green Colour ({Green})"; + BlueSliderUnderglow.Text = $"Blue Colour ({Blue})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, Red, Green, Blue); + string hexValue = Red.ToString("X2") + Green.ToString("X2") + Blue.ToString("X2"); + HexColorUnderglow.Label = $"#{hexValue}"; + SetVehicleNeonLightsColour(veh.Handle, RedSliderUnderglow.Position, GreenSliderUnderglow.Position, BlueSliderUnderglow.Position); + } + }; + + VehicleColorsMenu.OnItemSelect += (sender, item, index) => { #region reset checkboxes state when opening the menu. - if (item == underglowMenuBtn) - { var veh = GetVehicle(); + var redneon = 0; + var greenneon = 0; + var blueneon = 0; + GetVehicleNeonLightsColour(veh.Handle, ref redneon, ref greenneon, ref blueneon); + RedSliderUnderglow.Position = redneon; + GreenSliderUnderglow.Position = greenneon; + BlueSliderUnderglow.Position = blueneon; + RedSliderUnderglow.Text = $"Red Colour ({redneon})"; + GreenSliderUnderglow.Text = $"Green Colour ({greenneon})"; + BlueSliderUnderglow.Text = $"Blue Colour ({blueneon})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, redneon, greenneon, blueneon); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, redneon, greenneon, blueneon); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, redneon, greenneon, blueneon); + string hexValue = redneon.ToString("X2") + greenneon.ToString("X2") + blueneon.ToString("X2"); + HexColorUnderglow.Label = $"#{hexValue}"; if (veh != null) { if (veh.Mods.HasNeonLights) @@ -2145,11 +2280,11 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in } underglowColor.ListIndex = GetIndexFromColor(); - } + #endregion }; // handle item selections - VehicleUnderglowMenu.OnCheckboxChange += (sender, item, index, _checked) => + UnderglowColorsMenu.OnCheckboxChange += (sender, item, index, _checked) => { if (Game.PlayerPed.IsInVehicle()) { @@ -2177,7 +2312,7 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in } }; - VehicleUnderglowMenu.OnListIndexChange += (sender, item, oldIndex, newIndex, itemIndex) => + UnderglowColorsMenu.OnListIndexChange += (sender, item, oldIndex, newIndex, itemIndex) => { if (item == underglowColor) { @@ -2187,10 +2322,69 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in if (veh.Mods.HasNeonLights) { veh.Mods.NeonLightsColor = GetColorFromIndex(newIndex); + var redneon = 0; + var greenneon = 0; + var blueneon = 0; + GetVehicleNeonLightsColour(veh.Handle, ref redneon, ref greenneon, ref blueneon); + + RedSliderUnderglow.Position = redneon; + GreenSliderUnderglow.Position = greenneon; + BlueSliderUnderglow.Position = blueneon; + RedSliderUnderglow.Text = $"Red Colour ({redneon})"; + GreenSliderUnderglow.Text = $"Green Colour ({greenneon})"; + BlueSliderUnderglow.Text = $"Blue Colour ({blueneon})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, redneon, greenneon, blueneon); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, redneon, greenneon, blueneon); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, redneon, greenneon, blueneon); + string hexValue = redneon.ToString("X2") + greenneon.ToString("X2") + blueneon.ToString("X2"); + HexColorUnderglow.Label = $"#{hexValue}"; } } } }; + UnderglowColorsMenu.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => + { + var red = 0; + var green = 0; + var blue = 0; + if (sliderItem == RedSliderUnderglow) + { + //RedSliderUnderglow.Position; + RedSliderUnderglow.Text = $"Red Colour ({newPosition})"; + red = newPosition; + green = GreenSliderUnderglow.Position; + blue = BlueSliderUnderglow.Position; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, newPosition, GreenSliderUnderglow.Position, BlueSliderUnderglow.Position); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, newPosition, GreenSliderUnderglow.Position, BlueSliderUnderglow.Position); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, newPosition, GreenSliderUnderglow.Position, BlueSliderUnderglow.Position); + } + if (sliderItem == GreenSliderUnderglow) + { + red = RedSliderUnderglow.Position; + green = newPosition; + blue = BlueSliderUnderglow.Position; + //GreenSliderUnderglow.Position = newPosition; + GreenSliderUnderglow.Text = $"Green Colour ({newPosition})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, RedSliderUnderglow.Position, newPosition, BlueSliderUnderglow.Position); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, RedSliderUnderglow.Position, newPosition, BlueSliderUnderglow.Position); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, RedSliderUnderglow.Position, newPosition, BlueSliderUnderglow.Position); + } + if (sliderItem == BlueSliderUnderglow) + { + red = RedSliderUnderglow.Position; + green = GreenSliderUnderglow.Position; + blue = newPosition; + // BlueSliderUnderglow.Position = newPosition; + BlueSliderUnderglow.Text = $"Blue Colour ({newPosition})"; + RedSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, RedSliderUnderglow.Position, GreenSliderUnderglow.Position, newPosition); + GreenSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, RedSliderUnderglow.Position, GreenSliderUnderglow.Position, newPosition); + BlueSliderUnderglow.BarColor = System.Drawing.Color.FromArgb(255, RedSliderUnderglow.Position, GreenSliderUnderglow.Position, newPosition); + } + Vehicle veh = GetVehicle(); + string hexValue = red.ToString("X2") + green.ToString("X2") + blue.ToString("X2"); + HexColorUnderglow.Label = $"#{hexValue}"; + SetVehicleNeonLightsColour(veh.Handle, red, green, blue); + }; #endregion #region Handle menu-opening refreshing license plate diff --git a/vMenuServer/MainServer.cs b/vMenuServer/MainServer.cs index 2b74d469..b24e12d2 100644 --- a/vMenuServer/MainServer.cs +++ b/vMenuServer/MainServer.cs @@ -743,7 +743,7 @@ internal async void UpdateTime(int newHours, int newMinutes, bool freezeTimeNew) { CurrentHours = CurrentHours; CurrentMinutes = CurrentMinutes; - + FreezeTime = true; while (newHours != CurrentHours) { if ((CurrentMinutes + 1) > 59) @@ -762,7 +762,7 @@ internal async void UpdateTime(int newHours, int newMinutes, bool freezeTimeNew) { CurrentMinutes=CurrentMinutes+5; } - await Delay(1); + await Delay(0); } CurrentHours = newHours; CurrentMinutes = newMinutes; From 196b186fb6b13421df7cc722eb4e046938f359a1 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Wed, 23 Aug 2023 02:45:40 -0400 Subject: [PATCH 19/49] Fixed Toggle NoClip button not showing when in noclip --- vMenu/Noclip.cs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/vMenu/Noclip.cs b/vMenu/Noclip.cs index 753b9215..e9067d06 100644 --- a/vMenu/Noclip.cs +++ b/vMenu/Noclip.cs @@ -43,7 +43,35 @@ internal static bool IsNoclipActive() { return NoclipActive; } - + static string HashString(string command) + { + uint hash = 0; + string str = command.ToLower(); + + for (int i = 0; i < str.Length; i++) + { + uint letter = (uint)str[i]; + hash = hash + letter; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + hash += (hash << 3); + if (hash < 0) + { + hash = (uint)((int)hash); + } + + hash ^= (hash >> 11); + hash += (hash << 15); + + if (hash < 0) + { + hash = (uint)((int)hash); + } + + return hash.ToString("X"); + } private async Task NoClipHandler() { if (NoclipActive) @@ -105,7 +133,7 @@ private async Task NoClipHandler() BeginScaleformMovieMethod(Scale, "SET_DATA_SLOT"); ScaleformMovieMethodAddParamInt(6); - PushScaleformMovieMethodParameterString("~INPUT_F975668C~"); + PushScaleformMovieMethodParameterString($"~INPUT_{HashString($"{vMenuShared.ConfigManager.GetSettingsString(vMenuShared.ConfigManager.Setting.vmenu_individual_server_id)}vMenu:NoClip")}~"); PushScaleformMovieMethodParameterString($"Toggle NoClip"); EndScaleformMovieMethod(); From b9592a5ddb7e124fcd9c038d996d41ac9faa93a3 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Wed, 23 Aug 2023 12:34:27 -0400 Subject: [PATCH 20/49] Update addons.json --- vMenuServer/config/addons.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenuServer/config/addons.json b/vMenuServer/config/addons.json index 67ec28aa..073b44a0 100644 --- a/vMenuServer/config/addons.json +++ b/vMenuServer/config/addons.json @@ -215,7 +215,7 @@ "TANKERCAR", "CABLECAR", "AVENGER3", - "AVENGER4", + "AVENGER4" ] } \ No newline at end of file From 41ceebe77898b7fd5c6ba42609d6a367acf2b73e Mon Sep 17 00:00:00 2001 From: Ricky Merc <65817116+RickyB505@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:39:59 -0400 Subject: [PATCH 21/49] Update README.md --- README.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 28708afa..46c01ac5 100644 --- a/README.md +++ b/README.md @@ -19,20 +19,32 @@ The original vMenu was lacking on options and new content. I made this version a If you want to help out provide translations to vMenu, you can [click here](https://github.com/ProjectFairnessLabs/GroupTranslationDB) and do a pull request! -------- -# Credits +# Developers +- Ribbitpoison/Venom +- RickyB505 - TristenCommunity -- DeckardCain000 +- 1Mosheba - QuadrupleTurbo -- Lincoln HUX - Starman0620 -- 1Mosheba -- AvarianKnight -- Wildbrick142 -- MichaelCoding25 +- UnsayingCheetah +- DeckardCain000 +- Shrimpy +- L'kid & Proky0 - AlexR32 - Freedy69 +- MichaelCoding25 +- ChatGGS/gg781 +- AvarianKnight - AvaNOX +- Wildbrick142 +- Lincoln HUX + + +# Feature Suggestions - TayMcKenzieNZ +- zwrks + +# Original Author - Vespura -------- # Discord From 8111505107acc4a7b7f7a90f0b587260235b7cb3 Mon Sep 17 00:00:00 2001 From: Ricky Merc <65817116+RickyB505@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:40:26 -0400 Subject: [PATCH 22/49] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 46c01ac5..0abd10ef 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ The original vMenu was lacking on options and new content. I made this version a If you want to help out provide translations to vMenu, you can [click here](https://github.com/ProjectFairnessLabs/GroupTranslationDB) and do a pull request! -------- -# Developers +# Credits +## Developers - Ribbitpoison/Venom - RickyB505 - TristenCommunity @@ -40,11 +41,11 @@ If you want to help out provide translations to vMenu, you can [click here](http - Lincoln HUX -# Feature Suggestions +## Feature Suggestions - TayMcKenzieNZ - zwrks -# Original Author +## Original Author - Vespura -------- # Discord From 57a855c2009e9d018e18e425be6fe1395f5d68f2 Mon Sep 17 00:00:00 2001 From: Ricky Merc <65817116+RickyB505@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:41:26 -0400 Subject: [PATCH 23/49] Update README.md --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0abd10ef..7184fbc0 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,8 @@ The original vMenu was lacking on options and new content. I made this version a If you want to help out provide translations to vMenu, you can [click here](https://github.com/ProjectFairnessLabs/GroupTranslationDB) and do a pull request! -------- -# Credits -## Developers -- Ribbitpoison/Venom +# Developers +- Ribbitpoison - RickyB505 - TristenCommunity - 1Mosheba @@ -41,11 +40,11 @@ If you want to help out provide translations to vMenu, you can [click here](http - Lincoln HUX -## Feature Suggestions +# Feature Suggestions - TayMcKenzieNZ - zwrks -## Original Author +# Original Author - Vespura -------- # Discord From e1412c4bb07535561535510c01d68b2ea3bfc4eb Mon Sep 17 00:00:00 2001 From: Ricky Merc <65817116+RickyB505@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:47:53 -0400 Subject: [PATCH 24/49] Update README.md --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7184fbc0..3f5fe94d 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,34 @@ The vMenu for Project Fairness and other affiliated servers. All actions are sub # Description The original vMenu was lacking on options and new content. I made this version as a way for people to still get the latest updates, while of course, adding new things so it feels more like the vMenu on other servers (such as RSM, Impulse99, etc) while also improving upon the original. +# DISCLAIMER +- If you are going to use this version of PF-vMenu, make sure you set "vmenu_individual_server_id" in your permission.cfg file. Otherwise, vMenu will fail to start. This value can be any ASCII character and no spaces (ie. the name of the server, random string of letters and numbers). +- Make sure you also update your "vmenu_menu_toggle_key" and "vmenu_noclip_toggle_key". If you're an existing vMenu/PF-vMenu user, these have been changed to use [Keyboard Controls](https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/) +- This release is also based on the v3.6.0 release of vMenu. We had to do a whole bunch of porting from our v3.5.1 pre-release into this. + # What's New - Chameleon Color by Wildbrick142 - [Download Chameleon Colors here](https://cdn.discordapp.com/attachments/1099903046701559828/1102708906234478712/pzn_chameleoncolor.7z), [Source](https://www.gta5-mods.com/misc/chameleon-paint-add-on) -- Content Updated up to v2802 +- Content Updated up to v2802 & v2944 - Mosh_Notify embedded Support for vMenu's NoClip - [Download Mosh_Notify here](https://forum.cfx.re/t/release-free-mosh-notify-fivem-custom-notifications-with-loadbar/2614951) - Los Santos Tuners goodies such as Vehicle Stance and Drift Tires (it's useless since we have vStancer and Handling Editor, but hey, it works) - Moved Teleport Options to the front (Now, you no longer have to go to Misc Settings to teleport to your favorite place!) - PMA-Voice Support -- Custom language support (22/06/2023) - (WIP) Local Time & Weather Options - (WIP) Car Brands on Addon Vehicles menu +- Multi-Language Support [(Looking for contributors!)](https://github.com/ProjectFairnessLabs/GroupTranslationDB) +- Labels for Vehicle Extras +- Plugins menu created, added Wheelie Manager and Easy Drift Plus as default plugins +- Enhanced Camera Menu added (thank you Shrimpy) +- Enhanced version of the add-on vehicle spawner, the old version was deprecated. No need to add extra categories! +- Default vehicle blacklist was added and located within addons.json (for those RP server players... 😉) +- Allowed all non-bike vehicles to use Open-Wheel tires (now make a ridiculous car!) +- Noclip lets you go up and down by looking with your camera! Look up to go up! + +# What's been changed +- Changed "vmenu_enable_animals_spawn_menu" to a new ace permission "vMenu.PlayerAppearance.AnimalPeds" +- Changed "vmenu_disable_spawning_as_default_character" to a new ace permission "vMenu.PlayerAppearance.SpawnAsDefault" +- Changed vMenu toggle and noclip to RegisterKeyMapping so it can now be changed within key binds in settings + -------- # Translations If you want to help out provide translations to vMenu, you can [click here](https://github.com/ProjectFairnessLabs/GroupTranslationDB) and do a pull request! From 9afc23149b1572c1a0dd679074313d79307d5f0e Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 03:12:59 -0400 Subject: [PATCH 25/49] Slightly Large update Updated fxmanifest to say PF Team instead of ribbitpoison. Made it so personal vehicle blip disappears if your in that vehicle. Updated the about menu so it says PF-vMenu version and added a download link. Made it so when you set a personal vehicle the menu shows up in the main menu along side its default location. --- vMenu/FunctionsController.cs | 36 ++++++ vMenu/MainMenu.cs | 215 ++++++++++++++++++++++++++++++++- vMenu/menus/About.cs | 2 +- vMenu/menus/PersonalVehicle.cs | 5 +- vMenuServer/config/addons.json | 1 - vMenuServer/fxmanifest.lua | 2 +- 6 files changed, 256 insertions(+), 5 deletions(-) diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index a8e55efa..edeed76a 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -176,6 +176,10 @@ public void SetupTickFunctions() { Tick += PersonalVehicleOptions; } + if (IsAllowed(Permission.PVAddBlip)) + { + Tick += PersonalVehicleBlip; + } if (IsAllowed(Permission.PAAnimalPeds)) { Tick += AnimalPedCameraChangeBlocker; @@ -2895,6 +2899,38 @@ private async Task PersonalVehicleOptions() } #endregion + #region personal vehicle blip + /// + /// tick to check if player is in personal vehicle and remove blip + /// + /// + + private async Task PersonalVehicleBlip() + { + if (MainMenu.PersonalVehicleMenu.enableBlip.Checked) + { + if (Game.PlayerPed.IsInVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle)) + { + if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle != null && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Exists() && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip != null && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) + { + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Delete(); + } + } + else + { + if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip == null || !MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) + { + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachBlip(); + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Sprite = BlipSprite.PersonalVehicleCar; + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Name = "Personal Vehicle"; + } + } + } + await Delay(1000); + await Task.FromResult(0); + } + #endregion + #region animation functions /// /// This triggers a helmet visor/goggles toggle if available. diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 4d6c47d4..bb1382ec 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -624,7 +624,207 @@ private static void AddMenu(Menu parentMenu, Menu submenu, MenuItem menuButton, Lm.GetMenu(submenu); } #endregion + #region + public static void RecreateMenus() + { + Menu.ClearMenuItems(true); + Menu.RefreshIndex(); + if (IsAllowed(Permission.PVMenu)) + { + var menu = PersonalVehicleMenu.GetMenu(); + var button = new MenuItem("~r~~h~Personal Vehicle~h~~s~ ", "Settings for your set personal vehicle, and control some things about that vehicle when you're not inside.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + if (IsAllowed(Permission.OPMenu)) + { + + var menu = OnlinePlayersMenu.GetMenu(); + var button = new MenuItem("Online Players", "All currently connected players.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + Menu.OnItemSelect += async (sender, item, index) => + { + if (item == button) + { + PlayersList.RequestPlayerList(); + + await OnlinePlayersMenu.UpdatePlayerlist(); + menu.RefreshIndex(); + } + }; + } + if (IsAllowed(Permission.OPUnban) || IsAllowed(Permission.OPViewBannedPlayers)) + { + var menu = BannedPlayersMenu.GetMenu(); + var button = new MenuItem("Banned Players", "View and manage all banned players in this menu.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + Menu.OnItemSelect += (sender, item, index) => + { + if (item == button) + { + TriggerServerEvent("vMenu:RequestBanList", Game.Player.Handle); + menu.RefreshIndex(); + } + }; + } + + var playerSubmenuBtn = new MenuItem("Player Related Options", "Open this submenu for player related subcategories.") { Label = "→→→" }; + Menu.AddMenuItem(playerSubmenuBtn); + + + + var vehicleSubmenuBtn = new MenuItem("Vehicle Related Options", "Open this submenu for vehicle related subcategories.") { Label = "→→→" }; + Menu.AddMenuItem(vehicleSubmenuBtn); + // Add the vehicle options Menu. + + + var worldSubmenuBtn = new MenuItem("World Related Options", "Open this submenu for world related subcategories.") { Label = "→→→" }; + Menu.AddMenuItem(worldSubmenuBtn); + + { + var menu2 = PlayerTimeWeatherOptionsMenu.GetMenu(); + var button2 = new MenuItem("Time & Weather Options", "Change all time & weather related options here.") + { + Label = "→→→" + }; + AddMenu(Menu, menu2, button2); + } + + // Add Teleport Menu. + if (IsAllowed(Permission.TPMenu)) + { + //TeleportOptionsMenu = new TeleportOptions(); + var menu = TeleportOptionsMenu.GetMenu(); + var button = new MenuItem("Teleport Related Options", "Open this submenu for teleport options.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + + + // Add Voice Chat Menu. + if (IsAllowed(Permission.VCMenu)) + { + var menu = VoiceChatSettingsMenu.GetMenu(); + var button = new MenuItem("Voice Chat Settings", "Change Voice Chat options here.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + + { + var menu = RecordingMenu.GetMenu(); + var button = new MenuItem("Recording Options", "In-game recording options.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + + // Add a Spacer Here + var spacer = GetSpacerMenuItem("~y~↓ Miscellaneous ↓"); + Menu.AddMenuItem(spacer); + + // Add enhanced camera menu. + if (IsAllowed(Permission.ECMenu)) + { + var menu = EnhancedCameraMenu.GetMenu(); + var button = new MenuItem("Enhanced Camera", "Opens the enhanced camera menu.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + + // Add Plugin Settings Menu + if (IsAllowed(Permission.PNMenu)) + { + var menu = PluginSettingsMenu.GetMenu(); + var button = new MenuItem("Plugins Menu", "Plugins settings/status.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + + // Add misc settings menu. + { + var menu = MiscSettingsMenu.GetMenu(); + var button = new MenuItem("Misc Settings", "Miscellaneous vMenu options/settings can be configured here. You can also save your settings in this menu.") + { + Label = "→→→" + }; + AddMenu(Menu, menu, button); + } + Menu.OnIndexChange += (_menu, _oldItem, _newItem, _oldIndex, _newIndex) => + { + if (spacer == _newItem) + { + if (_oldIndex < _newIndex) + { + Menu.GoDown(); + } + else + { + Menu.GoUp(); + } + } + }; + // Add About Menu. + var sub = AboutMenu.GetMenu(); + var btn = new MenuItem("About vMenu", "Information about vMenu.") + { + Label = "→→→" + }; + AddMenu(Menu, sub, btn); + if (!GetSettingsBool(Setting.vmenu_use_permissions)) + { + Notify.Alert("vMenu is set up to ignore permissions, default permissions will be used."); + } + + if (PlayerSubmenu.Size > 0) + { + MenuController.BindMenuItem(Menu, PlayerSubmenu, playerSubmenuBtn); + } + else + { + Menu.RemoveMenuItem(playerSubmenuBtn); + } + + if (VehicleSubmenu.Size > 0) + { + MenuController.BindMenuItem(Menu, VehicleSubmenu, vehicleSubmenuBtn); + } + else + { + Menu.RemoveMenuItem(vehicleSubmenuBtn); + } + if (WorldSubmenu.Size > 0) + { + MenuController.BindMenuItem(Menu, WorldSubmenu, worldSubmenuBtn); + } + else + { + Menu.RemoveMenuItem(worldSubmenuBtn); + } + + if (MiscSettingsMenu != null) + { + MenuController.EnableMenuToggleKeyOnController = !MiscSettingsMenu.MiscDisableControllerSupport; + } + } + #endregion #region Create Submenus /// /// Creates all the submenus depending on the permissions of the user. @@ -912,7 +1112,20 @@ private static void CreateSubmenus() }; AddMenu(Menu, menu, button); } - + Menu.OnIndexChange += (_menu, _oldItem, _newItem, _oldIndex, _newIndex) => + { + if (spacer == _newItem) + { + if (_oldIndex < _newIndex) + { + Menu.GoDown(); + } + else + { + Menu.GoUp(); + } + } + }; // Add About Menu. AboutMenu = new About(); var sub = AboutMenu.GetMenu(); diff --git a/vMenu/menus/About.cs b/vMenu/menus/About.cs index bc5a4374..f4f9604c 100644 --- a/vMenu/menus/About.cs +++ b/vMenu/menus/About.cs @@ -13,7 +13,7 @@ private void CreateMenu() menu = new Menu("vMenu", "About PF-vMenu"); // Create menu items. - var version = new MenuItem("vMenu Version", $"This server is using vMenu ~b~~h~{MainMenu.Version}~h~~s~.") + var version = new MenuItem("PF-vMenu Version", $"This server is using PF-vMenu ~b~~h~{MainMenu.Version}~h~~s~. \n\nDownload PF-vMenu: ~b~~h~github.com/ProjectFairnessLabs/PF-vMenu~h~~s~") { Label = $"~h~{MainMenu.Version}~h~" }; diff --git a/vMenu/menus/PersonalVehicle.cs b/vMenu/menus/PersonalVehicle.cs index a7386ea3..1bca6f75 100644 --- a/vMenu/menus/PersonalVehicle.cs +++ b/vMenu/menus/PersonalVehicle.cs @@ -24,6 +24,8 @@ public PersonalVehicle() { } public Menu VehicleDoorsMenu { get; internal set; } = null; + public MenuCheckboxItem enableBlip; + private static readonly LanguageManager Lm = new LanguageManager(); @@ -50,7 +52,7 @@ private void CreateMenu() }; var soundHorn = new MenuItem("Sound Horn", "Sounds the horn of the vehicle."); var toggleAlarm = new MenuItem("Toggle Alarm Sound", "Toggles the vehicle alarm sound on or off. This does not set an alarm. It only toggles the current sounding status of the alarm."); - var enableBlip = new MenuCheckboxItem("Add Blip For Personal Vehicle", "Enables or disables the blip that gets added when you mark a vehicle as your personal vehicle.", EnableVehicleBlip) { Style = MenuCheckboxItem.CheckboxStyle.Cross }; + enableBlip = new MenuCheckboxItem("Add Blip For Personal Vehicle", "Enables or disables the blip that gets added when you mark a vehicle as your personal vehicle.", EnableVehicleBlip) { Style = MenuCheckboxItem.CheckboxStyle.Cross }; var exclusiveDriver = new MenuCheckboxItem("Exclusive Driver", "If enabled, then you will be the only one that can enter the drivers seat. Other players will not be able to drive the car, however, they can still be passengers.", false) { Style = MenuCheckboxItem.CheckboxStyle.Cross }; //submenu VehicleDoorsMenu = Lm.GetMenu(new Menu("Vehicle Doors", "Vehicle Doors Management")); @@ -262,6 +264,7 @@ private void CreateMenu() name = veh.DisplayName; } item.Label = $"Current Vehicle: {name}"; + MainMenu.RecreateMenus(); } else { diff --git a/vMenuServer/config/addons.json b/vMenuServer/config/addons.json index 67ec28aa..bba4c4e0 100644 --- a/vMenuServer/config/addons.json +++ b/vMenuServer/config/addons.json @@ -39,7 +39,6 @@ "KURUMA2", "PARAGON2", "SCHAFTER5", - "ZR350", "ZR380", "ZR3802", "ZR3803", diff --git a/vMenuServer/fxmanifest.lua b/vMenuServer/fxmanifest.lua index 290cedea..73d79558 100644 --- a/vMenuServer/fxmanifest.lua +++ b/vMenuServer/fxmanifest.lua @@ -7,7 +7,7 @@ games {'gta5'} name 'PF-vMenu' description 'A fork of vMenu, a server sided menu for FiveM with custom permissions.' version 'v1.1.3' -author 'ribbitpoison/Tom Grobbe' +author 'PF Team/Tom Grobbe' url 'https://github.com/ProjectFairnessLabs/PF-vMenu/' ui_page 'storage.html' From a8a3c6da67bd75f549526c505090ea5fd6e3b301 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 04:34:53 -0400 Subject: [PATCH 26/49] Suppress warnings and changed main menu personal vehicle text --- vMenu/MainMenu.cs | 2 +- vMenu/menus/EnhancedCamera.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index bb1382ec..2bec7e43 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -632,7 +632,7 @@ public static void RecreateMenus() if (IsAllowed(Permission.PVMenu)) { var menu = PersonalVehicleMenu.GetMenu(); - var button = new MenuItem("~r~~h~Personal Vehicle~h~~s~ ", "Settings for your set personal vehicle, and control some things about that vehicle when you're not inside.") + var button = new MenuItem("~r~~h~Personal Vehicle Options~h~~s~ ", "Settings for your set personal vehicle.") { Label = "→→→" }; diff --git a/vMenu/menus/EnhancedCamera.cs b/vMenu/menus/EnhancedCamera.cs index 31ef35b7..6743d830 100644 --- a/vMenu/menus/EnhancedCamera.cs +++ b/vMenu/menus/EnhancedCamera.cs @@ -21,9 +21,11 @@ public class EnhancedCamera public Menu EnhancedCameraMenu { get; private set; } // Menu variable, will be defined in CreateMenu() +#pragma warning disable CS0649 // remove warnings private static MenuCheckboxItem leadCam; private static MenuCheckboxItem chaseCam; private static MenuCheckboxItem droneCam; +#pragma warning restore CS0649 // remove warnings private static Control MenuToggleControl; private static bool chaseCameraConfigEnabled; private static bool droneCameraConfigEnabled; From 082cba51a890dbfb27ff1b34660d81049b76ff27 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 11:10:22 -0400 Subject: [PATCH 27/49] Update MainMenu.cs Cosmetic changes --- vMenu/MainMenu.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 2bec7e43..3e59e5af 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -632,7 +632,7 @@ public static void RecreateMenus() if (IsAllowed(Permission.PVMenu)) { var menu = PersonalVehicleMenu.GetMenu(); - var button = new MenuItem("~r~~h~Personal Vehicle Options~h~~s~ ", "Settings for your set personal vehicle.") + var button = new MenuItem("~g~Personal Vehicle Options~s~", "Opens the personal vehicle submenu.") { Label = "→→→" }; From 04a500eb325c517acd1bdc195f16f1dd536e4f61 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 16:42:59 -0400 Subject: [PATCH 28/49] fix for error in console --- vMenu/FunctionsController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index edeed76a..db65bb77 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -2907,7 +2907,7 @@ private async Task PersonalVehicleOptions() private async Task PersonalVehicleBlip() { - if (MainMenu.PersonalVehicleMenu.enableBlip.Checked) + if (MainMenu.PersonalVehicleMenu.enableBlip.Checked && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle != null) { if (Game.PlayerPed.IsInVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle)) { From ab21c49807e43029e3927a292f39f2435585bfe7 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 19:04:33 -0400 Subject: [PATCH 29/49] update so ribbit will shutup --- vMenu/FunctionsController.cs | 2 +- vMenu/data/BlipInfo.cs | 3 ++- vMenu/menus/PersonalVehicle.cs | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index db65bb77..f7866aa1 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -2921,7 +2921,7 @@ private async Task PersonalVehicleBlip() if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip == null || !MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) { MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachBlip(); - MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Sprite = BlipSprite.PersonalVehicleCar; + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Sprite = (BlipSprite)BlipInfo.GetBlipSpriteForVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Handle); MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Name = "Personal Vehicle"; } } diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index bfff5917..47f2e329 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -42,7 +42,7 @@ public static int GetBlipSpriteForVehicle(int vehicle) // { (uint)GetHashKey("apc"), 558 }, { (uint)GetHashKey("oppressor"), 559 }, - { (uint)GetHashKey("oppressor2"), 559 }, + { (uint)GetHashKey("oppressor2"), 639 }, { (uint)GetHashKey("halftrack"), 560 }, { (uint)GetHashKey("dune3"), 561 }, { (uint)GetHashKey("tampa3"), 562 }, @@ -74,6 +74,7 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("barrage"), 601 }, { (uint)GetHashKey("akula"), 602 }, { (uint)GetHashKey("chernobog"), 603 }, + { (uint)GetHashKey("buffalo4"), 825 }, }; if (sprites.ContainsKey(model)) diff --git a/vMenu/menus/PersonalVehicle.cs b/vMenu/menus/PersonalVehicle.cs index 1bca6f75..09c19d0b 100644 --- a/vMenu/menus/PersonalVehicle.cs +++ b/vMenu/menus/PersonalVehicle.cs @@ -189,7 +189,7 @@ private void CreateMenu() { CurrentPersonalVehicle.AttachBlip(); } - CurrentPersonalVehicle.AttachedBlip.Sprite = BlipSprite.PersonalVehicleCar; + CurrentPersonalVehicle.AttachedBlip.Sprite = (BlipSprite)data.BlipInfo.GetBlipSpriteForVehicle(CurrentPersonalVehicle.Handle); CurrentPersonalVehicle.AttachedBlip.Name = "Personal Vehicle"; } else @@ -246,6 +246,8 @@ private void CreateMenu() { if (Game.PlayerPed == veh.Driver) { + if (CurrentPersonalVehicle != null) + CurrentPersonalVehicle.AttachedBlip.Delete(); CurrentPersonalVehicle = veh; veh.PreviouslyOwnedByPlayer = true; veh.IsPersistent = true; @@ -255,7 +257,7 @@ private void CreateMenu() { veh.AttachBlip(); } - veh.AttachedBlip.Sprite = BlipSprite.PersonalVehicleCar; + veh.AttachedBlip.Sprite = (BlipSprite)data.BlipInfo.GetBlipSpriteForVehicle(CurrentPersonalVehicle.Handle); veh.AttachedBlip.Name = "Personal Vehicle"; } var name = GetLabelText(veh.DisplayName); From e58f24c2732160e1ab6569ab66b30132ee0ce2cd Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 19:33:58 -0400 Subject: [PATCH 30/49] Update BlipInfo.cs - Arena Wars thx ricky you daft cunt --- vMenu/data/BlipInfo.cs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 47f2e329..10bd2bf8 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -74,6 +74,44 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("barrage"), 601 }, { (uint)GetHashKey("akula"), 602 }, { (uint)GetHashKey("chernobog"), 603 }, + // + { (uint)GetHashKey("bruiser"), 658 }, + { (uint)GetHashKey("bruiser2"), 658 }, + { (uint)GetHashKey("bruiser3"), 658 }, + { (uint)GetHashKey("brutus"), 659 }, + { (uint)GetHashKey("brutus2"), 659 }, + { (uint)GetHashKey("brutus3"), 659 }, + { (uint)GetHashKey("cerberus"), 660 }, + { (uint)GetHashKey("cerberus2"), 660 }, + { (uint)GetHashKey("cerberus3"), 660 }, + { (uint)GetHashKey("deathbike"), 661 }, + { (uint)GetHashKey("deathbike2"), 661 }, + { (uint)GetHashKey("deathbike3"), 661 }, + { (uint)GetHashKey("dominator4"), 662 }, + { (uint)GetHashKey("dominator5"), 662 }, + { (uint)GetHashKey("dominator6"), 662 }, + { (uint)GetHashKey("impaler2"), 663 }, + { (uint)GetHashKey("impaler3"), 663 }, + { (uint)GetHashKey("impaler4"), 663 }, + { (uint)GetHashKey("imperator"), 664 }, + { (uint)GetHashKey("imperator2"), 664 }, + { (uint)GetHashKey("imperator3"), 664 }, + { (uint)GetHashKey("issi4"), 665 }, + { (uint)GetHashKey("issi5"), 665 }, + { (uint)GetHashKey("issi6"), 665 }, + { (uint)GetHashKey("monster3"), 666 }, + { (uint)GetHashKey("monster4"), 666 }, + { (uint)GetHashKey("monster5"), 666 }, + { (uint)GetHashKey("scarab"), 667 }, + { (uint)GetHashKey("scarab2"), 667 }, + { (uint)GetHashKey("scarab3"), 667 }, + { (uint)GetHashKey("slamvan4"), 668 }, + { (uint)GetHashKey("slamvan5"), 668 }, + { (uint)GetHashKey("slamvan6"), 668 }, + { (uint)GetHashKey("zr380"), 668 }, + { (uint)GetHashKey("zr3802"), 669 }, + { (uint)GetHashKey("zr383"), 669 }, + // { (uint)GetHashKey("buffalo4"), 825 }, }; From 1aa46d2af6c2ba2cef244468e71f009602dee3be Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 19:36:52 -0400 Subject: [PATCH 31/49] fixed error --- vMenu/menus/PersonalVehicle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenu/menus/PersonalVehicle.cs b/vMenu/menus/PersonalVehicle.cs index 09c19d0b..830f82db 100644 --- a/vMenu/menus/PersonalVehicle.cs +++ b/vMenu/menus/PersonalVehicle.cs @@ -246,7 +246,7 @@ private void CreateMenu() { if (Game.PlayerPed == veh.Driver) { - if (CurrentPersonalVehicle != null) + if (CurrentPersonalVehicle != null && DoesEntityExist(CurrentPersonalVehicle.Handle)) CurrentPersonalVehicle.AttachedBlip.Delete(); CurrentPersonalVehicle = veh; veh.PreviouslyOwnedByPlayer = true; From a5d107c761523fbb75da1763620f9eeb9a91182d Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 19:53:00 -0400 Subject: [PATCH 32/49] Update BlipInfo.cs - Diamond Casino Heist Vehicles --- vMenu/data/BlipInfo.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 10bd2bf8..9ec8197a 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -112,6 +112,11 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("zr3802"), 669 }, { (uint)GetHashKey("zr383"), 669 }, // + { (uint)GetHashKey("everon"), 734 }, + { (uint)GetHashKey("outlaw"), 735 }, + { (uint)GetHashKey("everon"), 736 }, + { (uint)GetHashKey("zhaba"), 737 }, + // { (uint)GetHashKey("buffalo4"), 825 }, }; From ed80ed5532e4f8bdc5de37f78bdb1eacb102521e Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 19:57:09 -0400 Subject: [PATCH 33/49] oversight --- vMenu/data/BlipInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 9ec8197a..b600e3fd 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -114,7 +114,7 @@ public static int GetBlipSpriteForVehicle(int vehicle) // { (uint)GetHashKey("everon"), 734 }, { (uint)GetHashKey("outlaw"), 735 }, - { (uint)GetHashKey("everon"), 736 }, + { (uint)GetHashKey("vagrant"), 736 }, { (uint)GetHashKey("zhaba"), 737 }, // { (uint)GetHashKey("buffalo4"), 825 }, From 828e803983aa099fd25fa1d14b4ab87737385a9f Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 20:12:54 -0400 Subject: [PATCH 34/49] Update BlipInfo.cs - The Cayo Perico Heist --- vMenu/data/BlipInfo.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index b600e3fd..5c251a29 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -116,6 +116,24 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("outlaw"), 735 }, { (uint)GetHashKey("vagrant"), 736 }, { (uint)GetHashKey("zhaba"), 737 }, + { (uint)GetHashKey("minitank"), 742 }, + // + { (uint)GetHashKey("winky"), 745 }, + { (uint)GetHashKey("avisa"), 746 }, + { (uint)GetHashKey("veto"), 747 }, + { (uint)GetHashKey("veto2"), 748 }, + { (uint)GetHashKey("verus"), 749 }, + { (uint)GetHashKey("vetir"), 750 }, + { (uint)GetHashKey("seasparrow2"), 751 }, + { (uint)GetHashKey("seasparrow3"), 751 }, + { (uint)GetHashKey("dinghy5"), 754 }, + { (uint)GetHashKey("patrolboat"), 755 }, + { (uint)GetHashKey("toreador"), 756 }, + { (uint)GetHashKey("squaddie"), 757 }, + { (uint)GetHashKey("alkonost"), 758 }, + { (uint)GetHashKey("annihilator2"), 759 }, + { (uint)GetHashKey("annihilator2"), 759 }, + { (uint)GetHashKey("kosatka"), 760 }, // { (uint)GetHashKey("buffalo4"), 825 }, }; From 79e22a060ece4f582178dc844759d6370b08dd3f Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 20:14:24 -0400 Subject: [PATCH 35/49] Update BlipInfo.cs --- vMenu/data/BlipInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 5c251a29..32eec7b7 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -124,8 +124,8 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("veto2"), 748 }, { (uint)GetHashKey("verus"), 749 }, { (uint)GetHashKey("vetir"), 750 }, - { (uint)GetHashKey("seasparrow2"), 751 }, - { (uint)GetHashKey("seasparrow3"), 751 }, + { (uint)GetHashKey("seasparrow2"), 753 }, + { (uint)GetHashKey("seasparrow3"), 753 }, { (uint)GetHashKey("dinghy5"), 754 }, { (uint)GetHashKey("patrolboat"), 755 }, { (uint)GetHashKey("toreador"), 756 }, From 5f71ba3d0e149ebca38f0eb01a3d46cd6f078964 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 20:15:43 -0400 Subject: [PATCH 36/49] Update BlipInfo.cs --- vMenu/data/BlipInfo.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 32eec7b7..8448553d 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -132,7 +132,6 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("squaddie"), 757 }, { (uint)GetHashKey("alkonost"), 758 }, { (uint)GetHashKey("annihilator2"), 759 }, - { (uint)GetHashKey("annihilator2"), 759 }, { (uint)GetHashKey("kosatka"), 760 }, // { (uint)GetHashKey("buffalo4"), 825 }, From 7acab01fc72b1280398e0198cc6e8390bf04f2ba Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sat, 26 Aug 2023 20:32:17 -0400 Subject: [PATCH 37/49] The Contract Blips (for now) --- vMenu/data/BlipInfo.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 8448553d..fd606fe5 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -134,6 +134,11 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("annihilator2"), 759 }, { (uint)GetHashKey("kosatka"), 760 }, // + { (uint)GetHashKey("patriot3"), 818 }, + { (uint)GetHashKey("jubilee"), 820 }, + { (uint)GetHashKey("granger2"), 821 }, + { (uint)GetHashKey("deity"), 823 }, + { (uint)GetHashKey("champion"), 824 }, { (uint)GetHashKey("buffalo4"), 825 }, }; From d2d3dc963b3ecf90f3d84af5ec62dd58e0a21d29 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 21:27:17 -0400 Subject: [PATCH 38/49] Reset index can be used to stream decks --- SharedClasses/PermissionsManager.cs | 6 ++++++ vMenu/MainMenu.cs | 12 ++++++++++++ vMenu/menus/MiscSettings.cs | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/SharedClasses/PermissionsManager.cs b/SharedClasses/PermissionsManager.cs index 9d4250a6..c5768cc0 100644 --- a/SharedClasses/PermissionsManager.cs +++ b/SharedClasses/PermissionsManager.cs @@ -397,6 +397,12 @@ public enum Permission #region bug prevention BPCarlaunch, #endregion + + #region reset index + // ResetIndex Permission + ResetIndex, + #endregion + } public static Dictionary Permissions { get; private set; } = new Dictionary(); public static bool ArePermissionsSetup { get; set; } = false; diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 3e59e5af..77a3beae 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Threading.Tasks; using CitizenFX.Core; @@ -1126,6 +1127,17 @@ private static void CreateSubmenus() } } }; + Menu.OnMenuClose += (sender) => + { + if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) + { + Menu.RefreshIndex(); + MenuController.Menus.ForEach(delegate (Menu m) + { + m.RefreshIndex(); + }); + } + }; // Add About Menu. AboutMenu = new About(); var sub = AboutMenu.GetMenu(); diff --git a/vMenu/menus/MiscSettings.cs b/vMenu/menus/MiscSettings.cs index 6b26ce10..b06f2afa 100644 --- a/vMenu/menus/MiscSettings.cs +++ b/vMenu/menus/MiscSettings.cs @@ -51,6 +51,8 @@ public class MiscSettings public bool MiscDisablePrivateMessages { get; private set; } = UserDefaults.MiscDisablePrivateMessages; public bool MiscDisableControllerSupport { get; private set; } = UserDefaults.MiscDisableControllerSupport; + public MenuCheckboxItem ResetIndex; + internal bool TimecycleEnabled { get; private set; } = false; internal int LastTimeCycleModifierIndex { get; private set; } = UserDefaults.MiscLastTimeCycleModifierIndex; internal int LastTimeCycleModifierStrength { get; private set; } = UserDefaults.MiscLastTimeCycleModifierStrength; @@ -153,6 +155,8 @@ private void CreateMenu() var clearArea = new MenuItem("Clear Area", "Clears the area around your player (100 meters). Damage, dirt, peds, props, vehicles, etc. Everything gets cleaned up, fixed and reset to the default world state."); var lockCamX = new MenuCheckboxItem("Lock Camera Horizontal Rotation", "Locks your camera horizontal rotation. Could be useful in helicopters I guess.", false); var lockCamY = new MenuCheckboxItem("Lock Camera Vertical Rotation", "Locks your camera vertical rotation. Could be useful in helicopters I guess.", false); + + ResetIndex = new MenuCheckboxItem("Reset Index", "Resets index once you go to main menu.", false); // Entity spawner var spawnNewEntity = new MenuItem("Spawn New Entity", "Spawns entity into the world and lets you set its position and rotation"); @@ -662,6 +666,10 @@ private void CreateMenu() menu.AddMenuItem(hideHud); menu.AddMenuItem(lockCamX); menu.AddMenuItem(lockCamY); + if (IsAllowed(Permission.ResetIndex)) + { + menu.AddMenuItem(ResetIndex); + } if (MainMenu.EnableExperimentalFeatures) { menu.AddMenuItem(exportData); From f1c6de017226610b001db33f1d6cd1792236674b Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 21:30:00 -0400 Subject: [PATCH 39/49] Reset index can be used for stream decks --- SharedClasses/PermissionsManager.cs | 6 ++++++ vMenu/MainMenu.cs | 12 ++++++++++++ vMenu/menus/MiscSettings.cs | 8 ++++++++ vMenuServer/config/permissions.cfg | 1 + 4 files changed, 27 insertions(+) diff --git a/SharedClasses/PermissionsManager.cs b/SharedClasses/PermissionsManager.cs index 9d4250a6..c5768cc0 100644 --- a/SharedClasses/PermissionsManager.cs +++ b/SharedClasses/PermissionsManager.cs @@ -397,6 +397,12 @@ public enum Permission #region bug prevention BPCarlaunch, #endregion + + #region reset index + // ResetIndex Permission + ResetIndex, + #endregion + } public static Dictionary Permissions { get; private set; } = new Dictionary(); public static bool ArePermissionsSetup { get; set; } = false; diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 3e59e5af..77a3beae 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Threading.Tasks; using CitizenFX.Core; @@ -1126,6 +1127,17 @@ private static void CreateSubmenus() } } }; + Menu.OnMenuClose += (sender) => + { + if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) + { + Menu.RefreshIndex(); + MenuController.Menus.ForEach(delegate (Menu m) + { + m.RefreshIndex(); + }); + } + }; // Add About Menu. AboutMenu = new About(); var sub = AboutMenu.GetMenu(); diff --git a/vMenu/menus/MiscSettings.cs b/vMenu/menus/MiscSettings.cs index 6b26ce10..b06f2afa 100644 --- a/vMenu/menus/MiscSettings.cs +++ b/vMenu/menus/MiscSettings.cs @@ -51,6 +51,8 @@ public class MiscSettings public bool MiscDisablePrivateMessages { get; private set; } = UserDefaults.MiscDisablePrivateMessages; public bool MiscDisableControllerSupport { get; private set; } = UserDefaults.MiscDisableControllerSupport; + public MenuCheckboxItem ResetIndex; + internal bool TimecycleEnabled { get; private set; } = false; internal int LastTimeCycleModifierIndex { get; private set; } = UserDefaults.MiscLastTimeCycleModifierIndex; internal int LastTimeCycleModifierStrength { get; private set; } = UserDefaults.MiscLastTimeCycleModifierStrength; @@ -153,6 +155,8 @@ private void CreateMenu() var clearArea = new MenuItem("Clear Area", "Clears the area around your player (100 meters). Damage, dirt, peds, props, vehicles, etc. Everything gets cleaned up, fixed and reset to the default world state."); var lockCamX = new MenuCheckboxItem("Lock Camera Horizontal Rotation", "Locks your camera horizontal rotation. Could be useful in helicopters I guess.", false); var lockCamY = new MenuCheckboxItem("Lock Camera Vertical Rotation", "Locks your camera vertical rotation. Could be useful in helicopters I guess.", false); + + ResetIndex = new MenuCheckboxItem("Reset Index", "Resets index once you go to main menu.", false); // Entity spawner var spawnNewEntity = new MenuItem("Spawn New Entity", "Spawns entity into the world and lets you set its position and rotation"); @@ -662,6 +666,10 @@ private void CreateMenu() menu.AddMenuItem(hideHud); menu.AddMenuItem(lockCamX); menu.AddMenuItem(lockCamY); + if (IsAllowed(Permission.ResetIndex)) + { + menu.AddMenuItem(ResetIndex); + } if (MainMenu.EnableExperimentalFeatures) { menu.AddMenuItem(exportData); diff --git a/vMenuServer/config/permissions.cfg b/vMenuServer/config/permissions.cfg index 061acd07..0c2363b9 100644 --- a/vMenuServer/config/permissions.cfg +++ b/vMenuServer/config/permissions.cfg @@ -553,6 +553,7 @@ add_ace builtin.everyone "vMenu.MiscSettings.RestoreWeapons" allow add_ace builtin.everyone "vMenu.MiscSettings.DriftMode" allow add_ace group.moderator "vMenu.MiscSettings.EntitySpawner" allow # Probably not the best idea to give this feature for everyone add_ace group.admin "vMenu.MiscSettings.DevTools" allow +#add_ace builtin.everyone "vMenu.ResetIndex" allow #################################### From 54e94abb84315b9d1aa6de3684b3921656b14adc Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Sat, 26 Aug 2023 22:34:22 -0400 Subject: [PATCH 40/49] added missing section for reset index --- vMenu/MainMenu.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 77a3beae..a032328d 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -781,6 +781,17 @@ public static void RecreateMenus() } } }; + Menu.OnMenuClose += (sender) => + { + if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) + { + Menu.RefreshIndex(); + MenuController.Menus.ForEach(delegate (Menu m) + { + m.RefreshIndex(); + }); + } + }; // Add About Menu. var sub = AboutMenu.GetMenu(); var btn = new MenuItem("About vMenu", "Information about vMenu.") From b9a8a7019affc78040d54c09c92bd7885e78afe2 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sun, 27 Aug 2023 01:10:56 -0400 Subject: [PATCH 41/49] Update BlipInfo.cs Added missing Blips from Southern San Andreas Super Sport Series, After Hours, fixed error with Nightmare ZR380 (zr3803) --- vMenu/data/BlipInfo.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index fd606fe5..b2a52fc5 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -42,7 +42,6 @@ public static int GetBlipSpriteForVehicle(int vehicle) // { (uint)GetHashKey("apc"), 558 }, { (uint)GetHashKey("oppressor"), 559 }, - { (uint)GetHashKey("oppressor2"), 639 }, { (uint)GetHashKey("halftrack"), 560 }, { (uint)GetHashKey("dune3"), 561 }, { (uint)GetHashKey("tampa3"), 562 }, @@ -75,6 +74,20 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("akula"), 602 }, { (uint)GetHashKey("chernobog"), 603 }, // + { (uint)GetHashKey("seasparrow"), 612 }, + { (uint)GetHashKey("caracara"), 613 }, + // + { (uint)GetHashKey("pbus2"), 631 }, + { (uint)GetHashKey("terbyte"), 632 }, + { (uint)GetHashKey("menacer"), 633 }, + { (uint)GetHashKey("scramjet"), 634 }, + { (uint)GetHashKey("pounder2"), 635 }, + { (uint)GetHashKey("mule4"), 636 }, + { (uint)GetHashKey("speedo4"), 637 }, + { (uint)GetHashKey("blimp3"), 638 }, + { (uint)GetHashKey("oppressor2"), 639 }, + { (uint)GetHashKey("strikeforce"), 640 }, + // { (uint)GetHashKey("bruiser"), 658 }, { (uint)GetHashKey("bruiser2"), 658 }, { (uint)GetHashKey("bruiser3"), 658 }, @@ -110,7 +123,7 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("slamvan6"), 668 }, { (uint)GetHashKey("zr380"), 668 }, { (uint)GetHashKey("zr3802"), 669 }, - { (uint)GetHashKey("zr383"), 669 }, + { (uint)GetHashKey("zr3803"), 669 }, // { (uint)GetHashKey("everon"), 734 }, { (uint)GetHashKey("outlaw"), 735 }, From eb94d3e771a28757a0f1afb1b97002d91d8a6312 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sun, 27 Aug 2023 01:15:00 -0400 Subject: [PATCH 42/49] yet another oversight, whoops --- vMenu/data/BlipInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index b2a52fc5..35829967 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -121,7 +121,7 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("slamvan4"), 668 }, { (uint)GetHashKey("slamvan5"), 668 }, { (uint)GetHashKey("slamvan6"), 668 }, - { (uint)GetHashKey("zr380"), 668 }, + { (uint)GetHashKey("zr380"), 669 }, { (uint)GetHashKey("zr3802"), 669 }, { (uint)GetHashKey("zr3803"), 669 }, // From 35a9495174361cb21ac06d370f9a7aced3839ee9 Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Sun, 27 Aug 2023 01:32:58 -0400 Subject: [PATCH 43/49] Update BlipInfo.cs Changes to the 3 Avengers, update to San Andreas Mercenaries (v2944) update n added some of that update's vehicles blips they didn't have....CFX, please update your fucking documentation and ban Scully kthxbai --- vMenu/data/BlipInfo.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 35829967..fd886bb5 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -63,6 +63,7 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("tula"), 585 }, // { (uint)GetHashKey("avenger"), 589 }, + { (uint)GetHashKey("avenger2"), 589 }, // { (uint)GetHashKey("stromberg"), 595 }, { (uint)GetHashKey("deluxo"), 596 }, @@ -153,6 +154,12 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("deity"), 823 }, { (uint)GetHashKey("champion"), 824 }, { (uint)GetHashKey("buffalo4"), 825 }, + // + { (uint)GetHashKey("avenger3"), 589 }, + { (uint)GetHashKey("avenger4"), 589 }, + { (uint)GetHashKey("raiju"), 861 }, + { (uint)GetHashKey("conada2"), 862 }, + { (uint)GetHashKey("streamer216"), 865 }, }; if (sprites.ContainsKey(model)) From 0a191b9a7c84619d71158b50cbf589e383428015 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 28 Aug 2023 02:14:46 -0400 Subject: [PATCH 44/49] updated vMenu you use the new MenuAPI functions --- dependencies/client/MenuAPI.dll | Bin 0 -> 101888 bytes vMenu/MainMenu.cs | 14 +++----------- vMenu/vMenuClient.csproj | 8 +++++++- 3 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 dependencies/client/MenuAPI.dll diff --git a/dependencies/client/MenuAPI.dll b/dependencies/client/MenuAPI.dll new file mode 100644 index 0000000000000000000000000000000000000000..91574402d196330ef87a344977cc3acf73ad0a7a GIT binary patch literal 101888 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
  • GIX#?+6}l*+5^k*;##e)W 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

    1&a#2sfU zg@m_mrn z1>NSB-NlKvq$MDKhK6OJ+KVAWW4!o`C$*1*|JUaUa>8aPFS6PwI!gG=3?l=@O*WmnDqKN10`eQYgmXelq15Wo zAkjsU*V|8Ztyae#t3$oC1x9S}!RqAL94yBa(y%B$hEJcmbh5`7E+ONMZ+tTih967OV?$DT z9_!(F`VScsTUZ==XgAe4@;Lk)73pwO|DaMk+~hB|zAKx=9>W$B7XrIl8=GTGD$Z1h z{tnea{xgfoKBr8;({+Uw+GM7I)&ftgR`?NgdRak9PJTR&G%b0wTY~Kf3y?RkpzN+Y z_*_NAnR*>Q6!39umuP7HFSLg1OrLsk9XEw=nb-3KUEPp(bvnhV>pD*YT*B4!sEwc= z-}%HpbN#6TD?&?=y~m+Ct=~}wu~E{n7`5=_SuHCyA34Cr@(sd6ts>EZr=^&B%AL$qWdyDd#NLg(nC(S3UJb8~6wT>aA+(hkCrX5Y%DJ>W8Vv z$1p+@K1{TQjpl~WLNLc(p8*}Hgg+KCTsW*@F7qw%fQPpoRX;b24klE`X-*wXD{c0W zcF{?x7-5kkr0B+D9%UlQyHnl6BHoJi4v?@Kz>k5%Fy-Ri!hdYSjHJVuw$ap?KQ{rI z&zNcWrJV2uRvdr!o)<(|Ux|z~3m&7UJc|Yo_Q!F=#A;P0#i})pHDWuH=?kp35~owx z0mg)b{E%GzlNHg29;R^$i4?l6NLhvOwF^Q1AdGOJqY~HTn38c#bx9^30kLw74x$(UOnO>f;p8}*mTL&QN=hmTOA4~N|R#L z5fef?Rt0su96|Y}SREh7Lc0!=@=WVUlb8W=bIT&So%s|xg+uPK-N@l71gaark-D=i zLWv)fU%{g`Cr&42^s)6MBqeyE_Ncbt*HR z=sDTc&b(I&Qfi~kB+T#`h9_$YqbUd`%v1(Jc`2gWpTaPxnkgB{@hnifTunGZG1oni z<$m>8h>h>5@gQWS>$)gw+zT@v$8W8;J6GsXoUXf@iNUBC13CApzmw_eS3z{&SXaHnW_$AWm{043$<{ya9S**Xl8;Jv5T z+v(yFx&G9XcJReqadDg)8Os^{^bULc*kEylu%^?H{xp0fwJ+Yzz`Uj*AJf>vPJv7k z;OZmrnO7iuN#d1GlJ?06F%)G_#QPiccyELO?~#aSv3S1(-q_MV4sT%4f`@1PSqkFM zfK)Q)Xt}%!{)s$PI{Y)aUpjmcwrvsWwh%cq;bfO#AE zXq7gPD_sed(2GLkgF@&QL_6BRhBzq|Ax>*;JyNQ9#P=iV9GHs8&vDW`@bZh1$YaQLrW-LYOzw>>&5dwNY#xio98kc`TV!I8k0g? zeVzHr<8c{zJy92!Mz9^ zYELQ$>)|X-4)nkR2|Ad<7GV8y{Ew3Vo~nh{5Njjki`v(Q6ouYhhE!eiGZrl*^y)&M zqk1jxlAnK*M1HzC%a{ipG9$f0+_USK@PCr4+d}!MPwGEZYxVNy(n5_%QCy9+5QQO| zNNqvyb#wFuY9q3-uKlA3c_7Uz<*nVAo-`&!E#{1$r11W)`lb0lBoIeOp(JEeb9tRm zkDwBm@n#^{5pK^6+~zv`^Wclaw#SCGq2z_!zFGf8k0~{(d)GEDLdYEOjPNV0Uk;Zx zZd?wfaT&kNh^GwkkfxF)a!rdkSU;j1q{;O(z$LB5<&c)kh~*eToiVw#a|u#6p-#x! zJ0-Y1b0H=R1$V$8NgxL>` z>`u8d#7g-=)TBVfJBw4WPQA8WF}L=#QU6_Z*tXyvVju z&$2=PazT~yk(BzR5qdXPESEzY1PeI!U;3S6R?&FR6y}9!$v%yZB@T%?wJO?cM~&2- z8$fG%G!`5687c{lIOV*YjY(2nP)#?Ucj}K+o2*-7aR{jh^G|4aqjJSahcrf*jj_Is z#Yb|~K4jI&_K7XtXl;>i#X8k$YaJe~ zTTl)c`)1)9M0SZRx?=>Sk_bJ+!21hXS>(GZ<<5*hvd*keV`GXDdP#QH!Yz5JP%Gj8 zi!`N4+C!<6rDEOwmr%j~qa51&e~K@ZvB>&%(xLaxF_mT+j`7QY5>xB4@c$kTGsuDe zH5ATAQ9ES2F*^4Duc61GWk_R@-~Sx;S%jjV`~QuS@{qk43u)3zsyXJK4L6NBG;5~uiL4!J z1fj`x&{#~?gL#o#)PKZ;{Xs|y{fcJA7}vc>uN-L$b7iuHd|uI%+%(JNBYOai*fg)9 zSI*;Q^re4={m|o{gV0=&6O!-Zm}>{Qm&{JEFc$gll2oc zgwO1n(M*J_4DnEYPpT8rc-EBah2~{sD_IMgk-85#{(vuEK)^-5)eUGt(6Q2n7T0;skq zR%#2%BhtnW3eE7SjcHzh-I!*?5%xv+>P21zAF5BXLsS~-)zoIpQ<#Myw@qmdM|PRF zlAnd=)XHsv1!*z4I8rsEyATJp8H1Z<9fFNVz4*}_kMc_U0lYj-iDTim7A3%Jh}w-t zcA*}Gy&dXBlPK@4gc$?b0owhedZm_Sc$2x%w&X&7{blwaL7M6$kGt&4_m72YKvV*G=Q4&_`V6%m_m{qxRr?W&xAnwjy>K zwZ!?YpR0}-XmplS`Z=g~$~*Ny)`seeX5CI3Y{1(UAuC}`)3H-W`+ayj1HwA?4|U+t zeqS2KZVm2pv<`R>yZ$HIQVUYF>f_$UAmiGZ72bMhfaQ8E;LU z##pau$iJ}TTDRV5|5b;-BuLZFD`eYDMj5B#-Lk>JKwH-Zymz9=7@E3gr(NZ zz(u-2dO~$isilHKd$ny`jO-n2bm>eq7d0z2G~U96 z%2IQc&ETALEO{xkU?3e+M=~t5>6J&uEI`8*LWNo~@E8&?P1Ev@NLBwIQgZV|gBno( z6h=_@Iw}__C~`khmAi9Q9ggw|>KurY2wU?)KFI*v@ETd>rK>Fgj&qi}c~%_zYR`}z zwxamO*00VmS)fFsaKjOZI|x5Na{9OjN+mu(FjO8ufBQV)w#H2^Q7GgdQmNEODisK+ zx73X>?`Cp^w~sgeDO&g?Nxi+@nUqACOhQZ#=BB_u55Z3s$O0rj%nON-r#E>a4hdqH zLedBSWOAvG4~16v_(;Jgh7{rb$4mTukuyaABaT!qck@&FDSgDdw?c5YS9l_Qe|wFe z{b#w{9eG5K<=zVXiT|WBhJsTry}gMP5<^DZYppO71=7_*d8 z@+(CkMCFdM_(##77nAzie-r+D`%2t8Fy9V%n{WpvYa;QFBC!GVN3H?nilIMp#gI!& zf8^4VD~|ri6-TZ_`Xg5&xl-wmT&d*Bpg(eDkZU;ok!v`)M$;d;Mw2Ux{>YWp0;Lq% z$Q6BkB@%LXU@iRZf8$27zNmZDLz6%r0M(_C!}kk`e>+r|6wS-f_FQ402vEoX=nN#v zrG8U=;O7HBMCq3++zJ(Po`k=zOpdsl`bwm=sR<3CkP7XgP*5cPzW(i?(*cOqTdsi1 z7nQCceUfp~1H}TX3EB?1ngKC)xzxW{ioo_+2#r>iO4_wEYBk?QrE0p@>`{k2Pc%eod0Z|!#g`Rfg?9 zDl|h%Wt@n*vG0|5!)$N@A(aw|1e!s$JCP#vw=YA+pO6P|E%OnTOhKK21N0bLjtG6w z7U*<9bVl?#AD?#Z+EI_De^PHDpf@@O&l}a2kV}8xmhxs?sE(vm+F9NPb>xj?@Xtr+ zb?tqi+#H1X+?k|3PZL62<$;K`xicyuKB_9@wY`EmutM5a-ioA%NB#m*X95FxmnwXk zvL+IqCUF%|6Nwa`){-cE`5#qVi92RT_AOLLCGLUD-@Y7D+=L+t=0C#^LVi^t2NiG3$n_QMh%QB@8Ls)D9MPpzx*La0ML)FB?jT28MO z4Jj1@IcU$lj&iS~oIcL!weJ%<0XXexK9tb9yzWS95wJr#C{crN|Sd;5VZa z_u0;UwsX3Q(^b?152FVvOLMCWzL(&RIdJ6xEZIKWvj^egg@C0GHh=T+a zLTvU5Pv(JflKy!%kx*_RgU-e8G#0|cSI#wDh-kJ;;Mu-%cLlmN()IDTzf@ZxWHyQC zC6=8$>xeFdsEg;qI-ZN`dM>Wx`C47i*Xnq_S=aN;0J*2ahZnz6p}?IA&TH0(#!igv z^bbRTP_oJZxfcdV)Q{j^?OIQ(n`87Q8{qJL-_`g1=JF=w#nW0V-fQc4tyqEFccW{# zjrC*Q?CQI@UWT^2dTwuuy5}+ObY<_PE;I|XqX3Ky4hzp&7!#l^KK|60JX{ssT*Fqm zD$D`yOA=hTwlD|kXu~1YsH6T4`QnR2g7nvQ!+h;6mkD`2>LP!%PE5yLe2y!&O&UG4 zO<46D#m2#g>3-ig=_h0Co(9lb-JF)z^&hS2@bA-P1jHv6Bm`0d*bjUGlmPaK$vg<; z1PTI-Xc)r?ya>DrniBXBG$ZgO@FVai2q0)q(1M^PK`VmR1Z@bOAZSa_j-Wk32Lk&1 zgDjAs6Ty=Noe8=SbR~F-pc_GV0!*rztS3P)g5Csu2(Y$bvc3dZRx=q^&`gHKGLvDQ z%Vc2$;RF!`^z9}YeHcm>P0){^KLLFvN;Z&S5W!%A7y=c6nm|LKCD0M*39vK4WN`%X z1Vae0j%G5fNSG{%0E<~BOCd-lc$y%M01F)^!=jPNG6{wfV13DC^dTx4){IOxl3)}8 zeU?gwFM2T97y<)97J-oKL@nLkpV>dB=s&m-3qnTMbK2N3y9 zz!qn~Bq2<~$#)ASM}t1UV?s>KT_RH<^YFLZDIJ=k@pQ;IbAl#1h?#Oj6KNkY2vtuY zE?-&-OJx}QySsxT^EqeMYN5|K8;1-&@YP{=F4}GWh!U_Mvb}9!^POw5Flt z0`XB}P~`OSQ+fnSfl}POal;~~y@KD}$SL&-#26_qSepc5xrn(r{*Vn&o=8aH?TbG- zP4uz&R3KhXG@-l*EHBEAK=K@w@*I`QiA__EKzDwZa)LOXfgZ>|2x8G38w+{Lc@)P1 z9Ah|YImU5J2rvZ!UZ=K0~W zAjMGL$Q{Mg&fgmZFS)<3r&x3ZrkNnk=s1g0B8#dF6~q;lnt)obJue&~?Nv}a(bfX; zTD$D?_Z24pg1S+?QI#MjC=@21w17gZFd-l9Jekl0{-9{}MJg?0%x|hYJp86MA*QhO z^x~2N4GHK67=rK=E@xhjdNcrH) zMFP)9;UqEXaud1e2~a(MZ>(=+{zlyWOT;e+HAf}h0SC^i9_uxX$N z_XG)FhYKwVmrtOa`@uy{&p zraiW%9BoSkZ&5e;Vm!XOhsg@sl-OcBDv$^LUKv?7++AbE~ECPIlaZVq70l678D*7f=GOt*LsRS5TKu~Hm6X5wLXDd zx|xJE$*>d!##$}e*(Q9)QNq0V8%zTE_eOB8f^YoQzO*LLDH<4}436p(qQn=ESTMf9 zr!of`b0-+hIi}n|dbU3hFZvF|Yj}is0yUij@svG(N0luITYxA{aFCMz@a-%KbLS3$ zPoe28;rN0lYbrV%xrqWR%~VV;!?ak-Gp&VP^GiyKZTiuRZa~ zMii$n{Yt=CT+kO^Rg|!fVq8IV@Aa4uMo<&9X(;6QkO%7{VclK5#oy-Q*V(-qe#V7` zOPI1TX~$3b@YKEd6H!V8-^pNuBrLkIP~vaI5vaj0PgM@m@8zXz=Q z1_>SxbL#&)T-`TR@Nj4!jf4&Q_w>lO_SY75e#6h>zy$u^G(#w?>x(cb6uyGR`b$_u zV<{6~R3!1ItHLkQd04bo&2k&*Z%U9BBw8R{cFpU^y7YEEd)l^ zloHmfv8>^TD7C-L5&}R~{#yX3$bSm}-S}?-pcMZt0J`aa3jmdY^>_X=Zv6TflO&}| z!Rms`Zjmti(@qJZ0&sQ1wHkh_UHrhpHwhd0hY`pRUOPe=`wHQ{Lb$YaZTgVxzn^%o zYJS{vg9cnR%>3a{wC}Sl+UwLv<*)ti zM{Mkz>d_BtjH9+-1|?WEa*J$9D#tKQQ7 z%nv{Oxuoy0^=;1%{_fn%_y2b5-(k;tcei$1aWLYW?Z1EX?R>?)*zmSly{kIge^L~8 zj0vgk%LXWvF}hE_*B-$46Ya}zs@B}?B{n`%AtzSU;?K{m$iPRqa($zOD`D_?yj*}lAI=T>f` zJ+Jk$zrp59esWWKU-PfJ&A#{1pJKQA?K@;*CmC|>UA+ye(?LG5Lv^@)8yh6+K3~x} z9NRdPnU8dI6Q!(pU{w(-a~t4u&97?lA?08BiLLMYSBA8_$0j~e9cnMmYyD%hg)QV$ zr5T@T{+T#yqs;yD^}g~0$@W}(qJ4lp7$3m=o_&W;U>3Un;B`%I?>eVR8;{~{vlfNe zud{T?yKY~*50`ChSLt5aKFh7DrM*4A-ukO#w5+&I)%VOG{o$FKF7B0WD&^J7FBYf0 z=AV4x-Gz@5rbk#Oyf|;PTd}-qKfXdcMRBctOyURgwoAU0{4QC-*2;!AE$&m*haHq$ zahs^9?qMG+-RW~}n0=3AisahBn2E2?)4Fw$ORu?JuSEb++3mq$t7To&=M7n&uHops+H?Dgf2qKhN!2MXJ+asNSH+`eicPLYwJ z_^s8K-|NsedWqMK!<%0Au}{8Hbn)b@qbItnQi48S)Z0GA{-k|~{S$njc8S|&w%M&v z_Cu460a>l8?&4FnLGtY$)gJcK_@?akj@6y)-6Uh!#HQ6r_S=#{k~{v@lkKl%_m6hV zimcMGt^WJ|9%`Di{ACbfH=9yG<@`7_$1;*4N+ex#%tB z&>%~<*n>ZQk`w9n1nUT2C{=8d}4!E4|_^^q+{Zv;l# zFWmbjVY^#p%s#K^*P_-RiA%V@s`upuTaO+beo5DI(nqt#Jo)zve~su_b7*de=U~Y` zLr_h#=k^ZoRFk=}P0y|mynpb{^go+)^xZ8ltUVXy+40EU1B=*GaoYple)hQ3<6+k- zt!G(GSp2?o9& z{qt8EvQ`>^xhp${L58lW>bnM~xOKxrW=;(ssm-c*obi+v{mmsOj>d; za@3`5!!K<^bX$*FHXWUwv$Er+qn2$)uWmfLVAQ3uk(bIwTq;Yrp=+}{cHjQ$2mh?A zSk-63hKf~>ekp4??Mz;e>3b@EbsG>^v;ExjUE3ASJC_i3WkrDh{H@>2^gpXRIyd+H za@H*VPK5o1uI+B0=LUxxqm-@xB8kcPd!>x4TJJGL0 z`8%w7QPXx%#V+kiA8oRy1Q%~^v0_ni;ni}_lZty6)W7u|d1?CMYg3OO7{5N#zDIT^ zW9IyRzneT4WXR64JFDyqR!LV#?u0Cy6;x%AOj+`DhpCGEY*2vK5x2 z-@b6STh-Dwcm7h&Sm7D9=g&5Go~;`EWIgKa_eT+3vR2 zmcD;&#FM+_*9Jd5e()r>Yg6@;qu$#S7xmV#ZsVWv{>kIoyA>B6PWehby=`*ovWN34 zR_(s`VMWf}vOa&G+qC)7?u-t%Ps*44)p6vP({oo&FI@TPu=>%CSr6yTdbnoR!)9Lp ztY~>JujRd8Ti$Ec^4`*x_lC8+ce3TZ$d>o^^uB57bMtENn^(I|d;8%7)xK{}JbZfJ z(;fYuJ%8zVrT?J$m0vH5I{Wv&F71{lzgTgh{E48N_Xih-l?<5R8C#x#2HK<9cY{6I z6^Xu`zE~Y*<{pb8h9prLsHaX_JFI z58nI2fBu7nmy4%(ENXJ+uE)bJF;7(Ace^Las;F2M+T)ph-+u9Gr<(0!mbIL;WY(3f z)j#^r|8)&a%*(}ZrmS~|{=YeWw|n1(#fy)qJ!7Z6w7B>seSFlZabFdb_{N?)Ji>qe z?s>2J&%eF*DbGi(-yZ5YSaxsnyyJt`pBw3U@P6WsiVJu5B=38A#rkb8ZAjm@prU5^ zX9sSi#wJ9aGQRJBiz+VKlD_ZTt$!tKm;SoHvf`ZV+YX+2-bZo+9<|lp?>Z%1 z+iLi!{#|Mg27apDH=S)y+;^lV@2xops~)`2Ws1Kxw#yWEZEV*mifRwf4PghW+XXdg zJMmt#=HJbXYCCOP(+ltIRF8T0(q!$p@AX@6O#1b&kt_Vi^;{AJrc|->d%%mAgJ!vQ2qt)TnPp#r={qaoINet`}~M`0>z_w+8q4 zqI$IUgD(#b{mPcSX|t@*fV5ntx%{mz7Z;%$;3&B1+x1LQTYwo=cDUJ=neM3){uBMLP}s zuMYe9pMDefJUw9W>%Shn_F(v1S1 z{Mj9!yLSGLQL*R64dW{oovrAk$m`~#nV5GzzJrg>xM#m_hm=8{Mst%npBHxzdh@}P zrQK(wcN)D^|H{OE%N8tp;Y#yAk&!RjJW+9Stheg@u|AsZoo{rhD9b&u`uRosMJvDpqNZa?1ix9RHqZs!)Ch?z8EL_kF! z-&1q8CCx%e>)kt`Q^w?GM~lEE5dqpi>}f3D$_)*%kF+KdCJBr zjho7p6%{u>@jdm0?$s_w^yYP4a`wglFg!%xwPWVX!9IU&_~5BSKlWemX?<6HDKO#S z@`^VP9(?)j;=h)TH!IQ)o{SkDIZd(ev;G2e?j2hUkNYti{0s}s8pPJGJb<3I2nPwS!MPaP_^e5qW0b$LJU z-#YvDJM__-D}NRLWuCWVbk{QEvf20f3vc`#*3|meEZ?x7H!oVa>FrxxE`I&tx;2V! zb4tTo^t|hPY~z+co>#s%O<_H2-#k-$V$qO=nTkwnuL>WlVQRp|#KQdN+NJDQuHL48 z|CL)FWi9?Z_uG}8uWDC*yl&jr%fn0$KFDl;X5HcTyWUxS`1I*d7vD5rD!6(hsO!|T z>!#XH?^yE6lJI#`4^Q24cwj>OxUyfLzY=6wS~XHxm94M&WnDsf+pk`VSYn)GdebBR zSj{tMBG;{&nzVG=y!YCkKD~4Gho5|x@M-^3OTx+u|N86gd6)Ah$M^Lpy8Pj=Md3TY z2t9TB-iap;zgSY7A$>J=Y;#4It=Bd#FDc&^HmU#4byLr79WnK6@}I9BT=&MLNzZxa z&v>u@smb>*e*MYW^-1k42djpiK6CQqnfR^JnX@fV-}d-;>n9(s+kaZK^@Pee`?J(P zKJEYMvCE`#;Z$ z?!3@zb->JZ8&ADC^O>Tv>kf^4x$2cSChh$D^17&*zjRokOo{({T$vwq zaD>e~^|I%$mXm+$410>dfA@u;?R#qG?>O^9Hb_s@2pzjjyHUx(juD?2yw;>xGb_5JdG;JRO4eEQtiDHCo@Szdng`EO!(UwNZ^ z`d6pU_381?SNeTVd{8v*)cq6YXXgx8?o#|3UbMIO4!;*}l*Y%bHLu%NIyK?;(9!qL zpBQt0M8=#F(=VT{m|Q$${N85YF1R(|`qK}$% zr)ItS$JD^Hm)F_6M}+(lx#Q}J=?PQ5nHhOv`JJsd2R`aMV9%cNMYxBYb2R5tMX zf%&D|F3w981-b-n!T?QIK84~vXvP9B-IeoOL)-S_l6e>HPKvko0~EqC3oyzzOY zq5ssh-X~u9)a&?^A9tPK|D*iGmSeahe0LubXN z%pdUZS--qd#nyYH%hJvt${X{|inn_W9Q!`WmWG6e|V+%_VTr(C(Zch$E#!Cx_f@`z-S3;tD&4kr?%La13rAjf>+J3y`=31V^W_iM_UzmD zt&U$6Kr@wuF=?X*U_@UP$n?;*T+y7ZOFz4Ct-Mt2ld^F+K2fts)Gn_fse$U_^ z7jDSP+4SkqvQcmR_-BW+qe{MCw_wV|@8^`t&C}kyd~@lEXF~3;O!;Ndo}S|hf4nNU zojm#5j)=J*y=+~7`_zmVbTig|dH$o%-qE%A?B^CgX9m1@aDjPUeo>!sy^8*x^v0+! zUq3i>OZd_yOXuAfx@71}8+wilx-s9fzI&hcgSRd#2`gLo^2j{$2FL@nM^H@A`0F>sQYF^li->-<{oZ_H@L1yWWv+yZ`+BUv__g zX5jMNkxMt2_dj*a?bXx$cOAR-d8=Xb*RAat)O14Y)$@9-XS%IVWcV%{G%kMsPr-jT z-7+_CcJZr+_O=)qRb<}Z=0>Zxo>%m4tN;0(4}a-9Iy}d?f3vQsSMaLyi(l%QpnqqJ z_U9g5Kln2Fiylj@Rj++G?&{2$AB?+q?EI%!I#|X(6Wc%k(fO_OeYOX9FMsq~&$NJ) z*B4!x^z+f*2A>#nD@%zSwE-=4-Jaqck zN59n@`kF@#@_zbb&$jJ+I$M@c{q^w4Xg3DZsk^lfK_~A24o^_hy@B!M0W>cTMa! zdqkY!!C7&7n`#it@z0ZAf@5}qF`K&p6?X&kj z>#TkDc{8)Vdm$&N;BYCqtkPI{8lM3+b|JM*NEhGEUc&V@=<5}XUC^fuFclwkPko5O zNHCf47aKh+U#6TmQCnN?>?DJNlFxd{e=4=+z9pZ)Grl%5@r=yQL|p@U7u_W~ucMp_ z^+1Zx4nH`WU5M)YnKw!~A}jego}GOp5%4t>0arrd9oF@?^6r?W(Dazf3NrRg)h_75 z2-rqNIC1B+%|k~Dhx*+4&M~9}s8Rv?CX&~3dNZ`2azP^Ffz3SQA@KG9Gg=Y{VUo@= z0A9f%x;m> z1bPR}6($5Te_$>)3JSAo0QMYB{RW-=xvsow?j{Td)|;?onI&%hLigdIGT zqn3AQpRm#Qlx#SVn=QVj>3zyR3hmCcA+%zYxLfe%%2d|KQufue#6Vjd!7z!3kErtG ztg*O|q|sce>m{k8V;=8QKFZ6QlJgHzN)Kr0_2%+4iqY`77ArjmQb4K&U*rzlqqtv~ z60A}ZN~DJf_~4{o=yYI^*$o|ez%zj~9mc-yEjsSXak*oP?(h-Wl% zg_dbxKZVwMXHqBMsF}dqwid0ab0h>RL}d4kF|>=`1;@N27T4ilxL}f(Ox%-Nd{l0U zR8(cqBGQdcI(4psAGR`Bssh@ywC}mI5$IEj442gaX@-35vREDui9CM}UZv>49jn73 zMkE+rZwN1AF>gopjmprm@9#6R3wEbU9rvr4=r#4o*>`2;i*^WRh!9!G4q4WX@2|5z zML@jOcWpVYk2$1AE7M9j4ZFpOuAUp+<|tO;?pf3r!DH2pi$GT5@Jx(*eF_jMPdM3I z@@!)sTYFhLYYxYG52NeQZDcZ$O}FFWPn#&NDHDFk0isEoO}j@r2UcHBw{r!>M-A1; zQy98ZRJt&vD_KdgD<826z2HqX407a{i0~KyF(96E7^;1UaX3niiQ?B_(~|gt5deYh zb_;sqiQ}3;Ed>bs(vqSbfkOG}_R>8SsS(kXzBmUUJr1b47~QBEHROpcNP(H5hEA{9 zQV6fx?Q6vxX@KKwt(SDMl@E?=t-LJV6Z2FGgJl?ON?{AppicEj*kn-tM zp(IA2tb1@o+G1GZ@hbgRd-J$cL9 zC|vybbKy1DR(Q+_BxC$!(MY(4Od}0Z5pztQeC1R^VbEc!@X-R7Ij@oy2VptT9BaZD zDIW{>DxqtW6e`$IKp<8Q-{SBntzvb8eJ?<|-p=RW8X&b&tYU`q{as3Rx#I5epJ^T1 zI-Qwg;4py$-=to9%UIe|O4Zy?6M(mj#4#kb(8{br<$LvVz-c@?{;eS4aL;r~&6BvA zhePTsc>39-gZSfNce|jyC4@5(c;-|OSdkr;B9R?qrtDRDpYBy}IN@9mV?5Q4?n>Ko zHM(M~QdGSZTn02EH~>W|$GExR1<* z;z53Xa93&W#|i5v>0D_%J+X;Dd8KZJ*$l`Chy>eoJj5~56t=Zk1d_Vy%i=81g5GtJ zE7A{6Tkp7d^$H>?wn^_Y(NEw}6naGhi-!`3;BLN%do$ghoJOl0p6nl3jf+)y?$7Pp zbOJ?WRMO^+%HiGVy6KkWC2=?%6SfXdna0E4^O56C*fAOMZM_CO$CVUp^DlBJf@zAF z3HL%xD5w~0KOW%l-CXkn!mKds)=6VpBG>f2bl*j(y^yj!nzw{4f;Pkfl_ko^XBt9H@*IB z?}NS2!79XbD@Q4sFRZzTNIaOHd<8EhdFrEwT%;}vpkq!#7m06C_*UV8ktDQEl9lf1 zGvKE(f=Qh+i7%B-F?vS*!D%em6d7LWF=HJQWkn8+;7Ve(B+54wksW0#i&zcy4@Ckr z+{AYr5E3|_J^fgHLitP;b&qM99<+gX4{MpCjzcVOcKq$`Ffk6`Ns<6{f7%Xo3JmYd!-Y}hI#82O2TgU9@ z70(dVqL}Ox2pZ;QoacX>CH{~)M`UL33I5{@hIg*1hmyW(oN(!fGEIR%zayY9S6v1( zzO;_YV-d!A57CP;O{j=5*;CjSEGy1xi!ls8d2BsV@YD`EzVwx`{9dD#q=}9XHjm2i zQ(e;;+JXARij$@U<16z~Ym-`Xi@2tlCV*rnG&s*!+SY<+IVqH#Szx((K*Rd(GO5OO zj4}BsZRQU1SFh%;nar_krMnROKKkss>~&D`+T23D=ON_8+3r9S&o4JI;eB$g8Yn2H z&7eu}=&+aQBv;aCktPXn7Tqg%i|!D~V(u7PtC_gBjCK7pA9fwwlmsTYC-#ij` zzC7Md*)Pa?B*P(g*$UAq*sMt>sW+^6JF8DYj6Jn13c9Z!YPO&ycQC62Aha-#Xf$Ip zO?#M?uVx9bZdAsdxr5P~L$#E^cHct|k3l%DgFerVB|>G_M5MP+pHWqAI{hRUmdJj0 zl*i^(=8D-klcBWl{6UMS@Ze-Nn~y(Zz$J}hV`!oU znbl;sDW@7V5+R^a0Bj9)RyaBQu+hi+je>T6hUSLlBo}0PGkuFz_FcMjFvCIk#v)#! z`_yw_fZFYW6iqh?8?MX&A^}JOiA}_J>IJC$5oN8)QqgH%@P|E|$1Xfo_MEs+;ZSMT zj6h#~e4=VYrANsfI&-v6tGun%E?3{xn|@rmb?EnL6xXCW%{=xSpqU0D4AxYplQS)M zsTRL51Q3Nkz5(I8dMPQ!_->Sn-VcmAOB@>AALfFl`x z*i$m{n>EIdPVAom?+S9T>xMfxKi?5HwRWvZkv^*krypLzLcD=U`-|QvQqwF0VxqS@ z$Xg8NgMAYny8$h<^~=~@<0p5?V^kf9aYemr%{N{Xt4usubQ_e>ajW9#+|dHd zkYza&ixBrJt*I|1ymBwaoNAie=f}xt(^Y;)`4urf64>W0Tbh1cB}$ym$-^tLM$DZ@ zL^xnydiLw%s~4Y z4}Ye*Z@H4}=4r*X$np9}Yo))p_$(hb?~ldyqgM3|B_9mzcu*m{3H8fQ;ISO;t7$V< z&W+p9E=?mc5xiEKd0#^~7_ZGYPNQVbi?O!$)24~ z4nPxm2!8--CSY{kGNo9?2NO^7G!cj|M%)%eR&c^Fu|zfTAGwy4-^=y*)j1%V;lW*T!aTWM5ymjtj#&4;11iiU zBN>mBoT*j?8Q{p?7`3$L?s_}nhjj_MIni7VsMFA_VA=A8zC#FVYi#nr{gud>=K`@~ zw$(KkO%uxS7dg*6OLHlqUdh$1rh;gdw&ZQ;RD>m-A6B*#KNEA(APhYIu))V>nl(+e zdW(*#=bJY7&Kj3+(?H{QjmM*AG;{FrFDh0?^Twb(&)Q!gJNAUvxA*lbN(b@GZFzT} zSWfxBjf}hmEDa#nyJPc{Y)KW4#KdcQ=eq@a0)$+bi(XM)J<_i|WB)adVY;4fsO(2b zaDN(*JKt{-S}N+RsINSAC+IoC4zq6Jrf^fZT+DM|jSZXalSOe#OT~%A>5#b5Rp9Im z?M`?y+3F~!5K~jW9yq`rvRBgzJ=b$a4%;|?`L3nfAWI)`rLy}>y#7HwR*oavPggK0 zqK;%C)oMRf#}QK@<1&gN2v8gdvP*294y>KVUHj$Ub!aDD7zrv&q**7`VUA_C{BF;)J)< z_?47U+cZ}-nM;Xm;+&`;-rhIKymKEN;T`j;&*kTMRf_soS`%+ZBeiAV2B)FAr+bAL zEXDX4W7zNJ@MoE@cl-zBjFDzItE4pp4tJ#@i&W@>Y{i zVSHQ^^B1#9%zKHJwNY0NSA*`?{iHM6&$DW2Bjn1Wp5|%L2XV;hf#(2aNqdHdDj$sb ztS>n0-1SprNhJ!+9LLGT*%J3jYkGnO>u~bEEYLcA`YA?KCQIgghZMpHC^88+=9ri~ z^fA7ZAkPxwC1LwELbwhIr{PIi?kBEk$63g=eXUlqE*6_|J6G37Q`5; z3cW4p#OO~?ELU?s(&H}Y*#zQtbk;kmS&(n*1e=~!V_G%hDciA7^e2|%g3>GI+4gKQ z!D5K!M)jSRZH1O?&z2DWg;vOJTh#7NJaZF?UV{$&M0&g&c;);>aS$)O^!;A>`*w#A z8~;6zz+KbE3n}@1I@$fAYYp7Eq205BkyXUBrI)MCaKmkE}A@r^ul(dz*?d2-N%DJIn`0Vp%)04M!WM?s=}0M#OoFJpMQ%9=?`;$G9S zLzpC;Pjo+q?~{2bEyv z#$RsXMK6@vx+*M6(=|}4c{+4eoD+O-0y$((y!Yjxb9pE z*Ttx7FS1v(GRcF#NjvdNE@QaxXvw()SeiaPUW4%%Hz;_{Uur` zq4;S!pg=mSd(noAHMLUNhVue10Jga&lHGstlmAsu+lY=K7%ZKy1+H}09m-^(nNwk+ z@+~K*-Vd#5)|J&h)BotX|31VS z@D1~>vf5?_-k{=m$0;96rcc%)_Gb=94!C17@-z%9^f8{es)Q|8nxU|(Bl2|(h+)^k zaj4wBZro>hC6OBfxWYH`#{_PH5DNpBl8^cjD?DB*)Vyi?y2zH9`6!XcRl?;&4A~%d zBMK8NVq*w@wJE2#2>GpRsIqJhepxVmv}NL>{nrT?#+{zH*mMk`!Hg6fV;!+GatPTO zBq@l-{ykTXP4dup>#+NBbB_r`AA^8!uyO!!@p5s@5T;Cur%r3i2R3^0p&>bXao=6D zNZk(SMNGoI=jZg=dcDo~vq6iwFhsK@nAMsTj0{*)iZQ!Sb=Qq0CuBC}qYRt>N1|8L z^cv|+5^~Sgj$dvfMP&9FWcJyaLKAltVt21|6GAhCUEPt&J=?w=`rr%vE z@kBw+w)c{%T<>`SVE1J@89mq0t1aT#N5hQq-(qttt+{VIrl?L|pl13|%u zmS3{K_y)SrI@tRxvra{w{&whz6-Fyzc>9o|A9;?xkwxp)K?os(l*W-!dBPGmowvgG zrSTl3cuPNmJ{h^rTM8(+$|&|}HmtI7YF6RG-C5;p%hYvJ^9e%u9xjsz_a4l}@gUCk zUvt0Z^XK+<*%I6IqTlHV`kYncC!kQx1Nb6l{XE$BhNt7PK9~IFx88}Zk&^~&-Pd;z z-U6`?jfu)AE-kgczvl1kqaaH!zm#26HT0)FRe8k6s9Ezkg|Fw~?-}%{$A;=}K?)9Q+pw zVfH?^NOY;zA35*O^CC>S~nxH5c&Q z2|qz{4y3g1iW{$s{Zt!Kh@7lJ3XnXA=dx#z?CW~%EanaE6tL5@bmTMqgvS>OB?MCY)V3J_|_Wv6Zr(uRc3~ z5AF#BnhG0Ljq5)KEP23shdufCBRHz4S{0DiL5587dfnxp{cmQFQwc`GzYeYhuVKuW zf{UcV`o7hh?;zFgck-{x;n#Gd`BI`hfa_1uytL76_d@5af&u!qjze1FpA-rMwjoYhr@u9ji=Zq(A;q3m;)FBFV4Ul$~XPxVoM#`>2&tNw18r1c{SLOxi)^} zhgL`IYfG>?fheZVD$iJspO&&2fQ{nqPFLoQE%=*T6m<6xSE9EK05>8$JgvEg=0^q* zFywXzw(iX=sMpKi9qhTO3wCnU4i}V!4&ry+OfCS8+H|?_3b1}6W7e(tPsQl*vramQ zE^8W6RxcOXNO8s1!m5QW80bw3hK~~9;cexLu{Bz1Awgx*8@|hCxggW+wRGF5&vBl! zHw?7_S0AP+cKUHbBM5X9F3MK}$yNgv*=!fd+$1l-O&SI;BQJ}$*VsN7e4s@+33xx= zoBbaxIIE2$6JM)X$IrW%=D*?czs>7p6T_}Ed=df@NiYOBf^JSHY_Y!j*fg>xfYK7D zES9zzRV>%?s!qs!n-yIuWTiD4*1f^cLKPSYT(Re7kTm%=v5_q0>01b7rA7lKna4_| z5WuAz*isB`6YHOf&HoeYDv~w))EhKd%)k8KE?b(%?|}aapeF~wp6flu;+9o@fleM@~LzUQkWT|pBJ8e zN0xxMIuxu_OQ9G^bi$lLN_fDo?>x%Sp;S26%z7ugiH5bkJU?vD=QlaJ&lE3tdNbUoXaQl;kABO2yz!x2(r%AP{=* zC=5?OM{m?dUBCBQ|I_D&6E({1MU;Wc0{gA#`kQ|!+D5Y;{wmrgMkyL~fo40P1(i>P zf&VW>+tDc1Ln#T`KnW@l8bvw8KqZ^}5j4#K-RAH4ZUl(L`{EofFnBTB!c4V0kr zurbg`1v9jP6144#Qgj_!{`!tSqGbc6sVF5w8z@2B=xhA7(RKeL|F;pq{GGc-i%NO> z_Yu&k)2OVv|E3<@?jA}lk(d}h*l6pI_+X<_2{Fu3XvaT{Q)5)=58Ck$h*1NTj)Rs~ zoV{x_*7c8~YtUs>w(Re36fOgG#QInH??DY!z(kFWhFof(kdkN+r55T*MFTC-!tuM8 zDe5emP3(s{{}*YAewxuzgEN8}6cgnWnwX2`<+%PgBfa|F28g=vKOZp^Xc83zR1X1E zU)6u1chL0C-+K?Bkdt1hC5HxE{-GkH*}-V&}0 z^^L}M`k_Wf@AiQ1?}vtDqC^6_A;Z8091I zKNXd1j9UGezh~qRtP@RG2K~d^f4`O>Dn@8#Fb2wJ7F0i7)cAks(&z~Lpt#0pZ~s6~ zQTf6DTOBJ38j6M>{rkPMqTU=plxI??xk8uFiWa5cz8U;$O!Um7ef#?qp{+j={XhBm zCl-dN{%8U;nz!x$k2^!Z8~;gjMaK>WES08lj{~x3f^Y^=Y9+i{&Kl1-y1pWiOkQ{{o literal 0 HcmV?d00001 diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index a032328d..df5f19b2 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -782,14 +782,10 @@ public static void RecreateMenus() } }; Menu.OnMenuClose += (sender) => - { + { if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) { - Menu.RefreshIndex(); - MenuController.Menus.ForEach(delegate (Menu m) - { - m.RefreshIndex(); - }); + MenuController.ResetAllMenuIndex(); } }; // Add About Menu. @@ -1142,11 +1138,7 @@ private static void CreateSubmenus() { if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) { - Menu.RefreshIndex(); - MenuController.Menus.ForEach(delegate (Menu m) - { - m.RefreshIndex(); - }); + MenuController.ResetAllMenuIndex(); } }; // Add About Menu. diff --git a/vMenu/vMenuClient.csproj b/vMenu/vMenuClient.csproj index ea4b02c6..21eb42a6 100644 --- a/vMenu/vMenuClient.csproj +++ b/vMenu/vMenuClient.csproj @@ -15,7 +15,11 @@ - + + + ..\dependencies\client\MenuAPI.dll + true + @@ -26,6 +30,8 @@ ..\dependencies\shared\Newtonsoft.Json.dll true + + From 1b0800e5c2c9692569f0a5922f1d4739eebcdb8d Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 28 Aug 2023 18:02:10 -0400 Subject: [PATCH 45/49] Bug fix/nice to haves --- vMenu/FunctionsController.cs | 26 +++++++++++++++----------- vMenu/data/BlipInfo.cs | 12 ++++++++++++ vMenu/menus/PersonalVehicle.cs | 2 -- vMenu/menus/VehicleSpawner.cs | 25 +++++++++++++++++++++++++ vMenuServer/MainServer.cs | 24 ++++++++++++++++++++++++ vMenuServer/config/vehblips.json | 6 ++++++ vMenuServer/config/vehname.json | 9 +++++++++ vMenuServer/vMenuServer.csproj | 6 ++++++ 8 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 vMenuServer/config/vehblips.json create mode 100644 vMenuServer/config/vehname.json diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index f7866aa1..693961f4 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -2909,23 +2909,27 @@ private async Task PersonalVehicleBlip() { if (MainMenu.PersonalVehicleMenu.enableBlip.Checked && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle != null) { - if (Game.PlayerPed.IsInVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle)) + if (DoesEntityExist(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Handle)) { - if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle != null && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Exists() && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip != null && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) + + if (Game.PlayerPed.IsInVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle)) { - MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Delete(); + if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle != null && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Exists() && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip != null && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) + { + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Delete(); + } } - } - else - { - if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip == null || !MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) + else { - MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachBlip(); - MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Sprite = (BlipSprite)BlipInfo.GetBlipSpriteForVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Handle); - MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Name = "Personal Vehicle"; + if (MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip == null || !MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Exists()) + { + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachBlip(); + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Sprite = (BlipSprite)BlipInfo.GetBlipSpriteForVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Handle); + MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.AttachedBlip.Name = "Personal Vehicle"; + } } } - } + } await Delay(1000); await Task.FromResult(0); } diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index fd886bb5..285c2e23 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; +using Newtonsoft.Json; + using static CitizenFX.Core.Native.API; namespace vMenuClient.data @@ -162,6 +164,16 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("streamer216"), 865 }, }; + string jsonData = LoadResourceFile(GetCurrentResourceName(), "config/vehblips.json") ?? "{}"; + var vehblips = JsonConvert.DeserializeObject>>(jsonData); + + foreach (var blips in vehblips["vehblips"]) + { + uint veh = (uint)GetHashKey(blips.Key); + sprites[veh] = blips.Value; + } + + if (sprites.ContainsKey(model)) { return sprites[model]; diff --git a/vMenu/menus/PersonalVehicle.cs b/vMenu/menus/PersonalVehicle.cs index 830f82db..d0de8316 100644 --- a/vMenu/menus/PersonalVehicle.cs +++ b/vMenu/menus/PersonalVehicle.cs @@ -246,8 +246,6 @@ private void CreateMenu() { if (Game.PlayerPed == veh.Driver) { - if (CurrentPersonalVehicle != null && DoesEntityExist(CurrentPersonalVehicle.Handle)) - CurrentPersonalVehicle.AttachedBlip.Delete(); CurrentPersonalVehicle = veh; veh.PreviouslyOwnedByPlayer = true; veh.IsPersistent = true; diff --git a/vMenu/menus/VehicleSpawner.cs b/vMenu/menus/VehicleSpawner.cs index 01803223..e21b6cb8 100644 --- a/vMenu/menus/VehicleSpawner.cs +++ b/vMenu/menus/VehicleSpawner.cs @@ -23,6 +23,8 @@ public class VehicleSpawner public static Dictionary AddonVehicles; public bool SpawnInVehicle { get; private set; } = UserDefaults.VehicleSpawnerSpawnInside; public bool ReplaceVehicle { get; private set; } = UserDefaults.VehicleSpawnerReplacePrevious; + public bool loadcarnames { get; private set; } + public static List allowedCategories; private static readonly LanguageManager Lm = new LanguageManager(); @@ -122,7 +124,18 @@ private void CreateMenu() { sortedVehicleBrands.Add("Unknown"); } + while (!loadcarnames) + { + string vehname = LoadResourceFile(GetCurrentResourceName(), "config/vehname.json") ?? "{}"; + var vehnamejson = JsonConvert.DeserializeObject>>(vehname); + foreach (var vehnamedata in vehnamejson["vehname"]) + { + AddTextEntry(vehnamedata.Key, vehnamedata.Value); + } + loadcarnames = true; + break; + } foreach (string makeName in sortedVehicleBrands) { @@ -182,6 +195,7 @@ private void CreateMenu() // Add the models to the "unavailableCars" category foreach (string model in modelsToMoveToUnavailableCars) { + uint modelHash = (uint)GetHashKey(model); string localizedNameBrandCar = GetLabelText(GetDisplayNameFromVehicleModel(modelHash)); string modelname = localizedNameBrandCar != "NULL" ? localizedNameBrandCar : model; @@ -232,7 +246,18 @@ private void CreateMenu() return title; }) .ToDictionary(pair => pair.Key, pair => pair.Value); + while (!loadcarnames) + { + string vehname = LoadResourceFile(GetCurrentResourceName(), "config/vehname.json") ?? "{}"; + var vehnamejson = JsonConvert.DeserializeObject>>(vehname); + foreach (var vehnamedata in vehnamejson["vehname"]) + { + AddTextEntry(vehnamedata.Key, vehnamedata.Value); + } + loadcarnames = true; + break; + } for (var cat = 0; cat < 23; cat++) { diff --git a/vMenuServer/MainServer.cs b/vMenuServer/MainServer.cs index b24e12d2..4e21e138 100644 --- a/vMenuServer/MainServer.cs +++ b/vMenuServer/MainServer.cs @@ -253,6 +253,30 @@ public MainServer() Debug.WriteLine($"\n\n^1[vMenu] [ERROR] ^7Your addons.json file contains a problem! Error details: {ex.Message}\n\n"); } + // check extras file for errors + string vehname = LoadResourceFile(GetCurrentResourceName(), "config/vehname.json") ?? "{}"; + try + { + JsonConvert.DeserializeObject>>(vehname); + // If the above crashes, then the json is invalid and it'll throw warnings in the console. + } + catch (JsonReaderException ex) + { + Debug.WriteLine($"\n\n^1[vMenu] [ERROR] ^7Your vehname.json file contains a problem! Error details: {ex.Message}\n\n"); + } + + // check veh blips file for errors + string vehblips = LoadResourceFile(GetCurrentResourceName(), "config/vehblips.json") ?? "{}"; + try + { + JsonConvert.DeserializeObject>>(vehblips); + // If the above crashes, then the json is invalid and it'll throw warnings in the console. + } + catch (JsonReaderException ex) + { + Debug.WriteLine($"\n\n^1[vMenu] [ERROR] ^7Your vehblips.json file contains a problem! Error details: {ex.Message}\n\n"); + } + // check extras file for errors string extras = LoadResourceFile(GetCurrentResourceName(), "config/extras.json") ?? "{}"; try diff --git a/vMenuServer/config/vehblips.json b/vMenuServer/config/vehblips.json new file mode 100644 index 00000000..c56619c5 --- /dev/null +++ b/vMenuServer/config/vehblips.json @@ -0,0 +1,6 @@ +{ + "vehblips":{ // set vehicle map blip sprites https://docs.fivem.net/docs/game-references/blips/ + "chr20": 825, + "cullinan": 820, + } +} \ No newline at end of file diff --git a/vMenuServer/config/vehname.json b/vMenuServer/config/vehname.json new file mode 100644 index 00000000..51d929db --- /dev/null +++ b/vMenuServer/config/vehname.json @@ -0,0 +1,9 @@ +{ + "vehname":{ // should work for brand names or vehicle names + "chr20": "Charger Hellcat 2020", + "DODGE": "Dodge", + "cullinan": "Cullinan 2019", + "ROLLSROYCE": "Rolls-Royce", + } + +} \ No newline at end of file diff --git a/vMenuServer/vMenuServer.csproj b/vMenuServer/vMenuServer.csproj index 86f32a80..958fca77 100644 --- a/vMenuServer/vMenuServer.csproj +++ b/vMenuServer/vMenuServer.csproj @@ -37,6 +37,12 @@ Always + + Always + + + Always + Always From 3a370c4844e93274fc25a3e930afed36fd98934c Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Mon, 28 Aug 2023 18:23:41 -0400 Subject: [PATCH 46/49] Revert to old version of menuapi because of bug --- dependencies/client/MenuAPI.dll | Bin 101888 -> 93184 bytes vMenu/MainMenu.cs | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/dependencies/client/MenuAPI.dll b/dependencies/client/MenuAPI.dll index 91574402d196330ef87a344977cc3acf73ad0a7a..aa273864f246c44ebb5512e87e4534e6e3c9f52c 100644 GIT binary patch literal 93184 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

  • GIX#?+6}l*+5^k*;##e)W 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

    1&a#2sfU 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 diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index df5f19b2..262cd559 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -782,10 +782,14 @@ public static void RecreateMenus() } }; Menu.OnMenuClose += (sender) => - { + { if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) { - MenuController.ResetAllMenuIndex(); + Menu.RefreshIndex(); + MenuController.Menus.ForEach(delegate (Menu m) + { + m.RefreshIndex(); + }); } }; // Add About Menu. @@ -1138,7 +1142,11 @@ private static void CreateSubmenus() { if (MainMenu.MiscSettingsMenu.ResetIndex.Checked) { - MenuController.ResetAllMenuIndex(); + Menu.RefreshIndex(); + MenuController.Menus.ForEach(delegate (Menu m) + { + m.RefreshIndex(); + }); } }; // Add About Menu. @@ -1192,4 +1200,4 @@ private static void CreateSubmenus() } #endregion } -} +} \ No newline at end of file From d8b70320202efc7b8c1f75c7fb4aef6264a7264c Mon Sep 17 00:00:00 2001 From: ribbitpoison Date: Tue, 29 Aug 2023 23:19:18 -0400 Subject: [PATCH 47/49] Fixed Reduce Suspension Previously broken/entry removed when transitioning to the v3.6.0 base --- vMenu/menus/VehicleOptions.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 965a19d5..b818bc34 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -408,7 +408,7 @@ private void CreateMenu() { menu.AddMenuItem(infiniteFuel); } - if (IsAllowed(Permission.VOReduceDriftSuspension)) + if (IsAllowed(Permission.VOReduceDriftSuspension)) // REDUCE DRIFT SUSPENSION { menu.AddMenuItem(reduceDriftSuspension); } @@ -557,6 +557,11 @@ private void CreateMenu() vehicle.IsVisible = !vehicle.IsVisible; } } + // Reduce Drift Suspension + else if (item == reduceDriftSuspension) + { + SetVehicleDriftSuspension(); + } // Destroy vehicle engine else if (item == destroyEngine) { From a2d86adbddec2dfe50a9457a9535a7f543da11c9 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Thu, 7 Sep 2023 09:41:04 -0400 Subject: [PATCH 48/49] added discord rich presence --- SharedClasses/ConfigManager.cs | 13 +++++ vMenu/FunctionsController.cs | 93 ++++++++++++++++++++++++++++++ vMenuServer/config/permissions.cfg | 18 ++++++ 3 files changed, 124 insertions(+) diff --git a/SharedClasses/ConfigManager.cs b/SharedClasses/ConfigManager.cs index f55955e2..b95c78b7 100644 --- a/SharedClasses/ConfigManager.cs +++ b/SharedClasses/ConfigManager.cs @@ -63,6 +63,19 @@ public enum Setting vmenu_current_hour, vmenu_current_minute, vmenu_sync_to_machine_time, + + // Discord Rich Presence + vmenu_discord_appid, + vmenu_disable_richpresence, + vmenu_discord_link_two, + vmenu_discord_link_two_text, + vmenu_discord_link_one_text, + vmenu_discord_link_one, + vmenu_discord_text, + vmenu_discord_large_image, + vmenu_discord_small_image, + vmenu_discord_small_image_text, + vmenu_discord_large_image_text, } ///

    diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index 693961f4..87669470 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -111,6 +111,10 @@ public void SetupTickFunctions() { Tick += RestorePlayerAfterBeingDead; } + if (!GetSettingsBool(Setting.vmenu_disable_richpresence)) + { + Tick += DiscordRichPresence; + } if (!GetSettingsBool(Setting.vmenu_disable_entity_outlines_tool)) { Tick += SlowMiscTick; @@ -2797,6 +2801,95 @@ private async Task AnimalPedCameraChangeBlocker() } #endregion + #region discord rich presence + /// + /// discord rich presence + /// + /// + static string FilterString(string tofilter) + { + var filter = new Dictionary() + { + {"^0", ""}, + {"^1", ""}, + {"^2", ""}, + {"^3", ""}, + {"^4", ""}, + {"^5", ""}, + {"^6", ""}, + {"^7", ""}, + {"^8", ""}, + {"^9", ""}, + {"^*", ""}, + {"^_", ""}, + {"^~", ""}, + {"^*^", ""}, + {"^r", ""}, + {"/", ""}, + {@"\", ""}, + {"】", "]"}, + {"【", "["}, + }; + foreach ( var filtervl in new Dictionary(filter)) + { + tofilter = tofilter.Replace(filtervl.Key, filtervl.Value); + } + return tofilter; + } + static string CheckForSubstitutes(string Substitutes) + { + var streetName = new uint(); + var crossingRoad = new uint(); + var playerloc = GetEntityCoords(Game.PlayerPed.Handle, false); + GetStreetNameAtCoord(playerloc.X, playerloc.Y, playerloc.Z, ref streetName, ref crossingRoad); + var street = GetStreetNameFromHashKey(streetName); + int vehicle = GetVehiclePedIsIn(Game.PlayerPed.Handle, false); + var model = (uint)GetEntityModel(vehicle); + string currentvehicle = GetLabelText(GetDisplayNameFromVehicleModel(model)); + + Substitutes = Substitutes.Replace("%playercount%", $"{GetActivePlayers().Count}/{GetConvar("sv_maxClients", "48")}"); + Substitutes = Substitutes.Replace("%playername%", $"{FilterString(Game.Player.Name)}"); + Substitutes = Substitutes.Replace("%playerid%", $"{Game.Player.ServerId}"); + Substitutes = Substitutes.Replace("%playerstreet%", $"{street}"); + Substitutes = Substitutes.Replace("%pfversion%", $"{MainMenu.Version}"); + Substitutes = Substitutes.Replace("%pfversion%", $"{MainMenu.Version}"); + Substitutes = Substitutes.Replace("%newline%", "\n"); + + return Substitutes; + } + private async Task DiscordRichPresence() + { + Debug.WriteLine(GetSettingsString(Setting.vmenu_discord_appid)); + if (!((GetSettingsString(Setting.vmenu_discord_appid) == "") || (GetSettingsString(Setting.vmenu_discord_appid) == null))) + { + SetDiscordAppId(GetSettingsString(Setting.vmenu_discord_appid)); + if(!(GetSettingsString(Setting.vmenu_discord_text) == "" || GetSettingsString(Setting.vmenu_discord_text) == null)) + { + SetRichPresence(CheckForSubstitutes(GetSettingsString(Setting.vmenu_discord_text))); + } + if(!((GetSettingsString(Setting.vmenu_discord_link_one_text) == "" || GetSettingsString(Setting.vmenu_discord_link_one) == null)||(GetSettingsString(Setting.vmenu_discord_link_one_text) == null || GetSettingsString(Setting.vmenu_discord_link_one) == ""))) + { + SetDiscordRichPresenceAction(0, CheckForSubstitutes(GetSettingsString(Setting.vmenu_discord_link_one_text)), GetSettingsString(Setting.vmenu_discord_link_one)); + } + if(!((GetSettingsString(Setting.vmenu_discord_link_two_text) == "" || GetSettingsString(Setting.vmenu_discord_link_two) == null)||(GetSettingsString(Setting.vmenu_discord_link_two_text) == null || GetSettingsString(Setting.vmenu_discord_link_two) == ""))) + { + SetDiscordRichPresenceAction(1, CheckForSubstitutes(GetSettingsString(Setting.vmenu_discord_link_two_text)), GetSettingsString(Setting.vmenu_discord_link_two)); + } + if(!((GetSettingsString(Setting.vmenu_discord_large_image) == "" || GetSettingsString(Setting.vmenu_discord_large_image_text) == null)||(GetSettingsString(Setting.vmenu_discord_large_image) == null || GetSettingsString(Setting.vmenu_discord_large_image_text) == ""))) + { + SetDiscordRichPresenceAsset(GetSettingsString(Setting.vmenu_discord_large_image)); + SetDiscordRichPresenceAssetText(CheckForSubstitutes(GetSettingsString(Setting.vmenu_discord_large_image_text))); + } + if(!((GetSettingsString(Setting.vmenu_discord_small_image) == "" || GetSettingsString(Setting.vmenu_discord_small_image_text) == null)||(GetSettingsString(Setting.vmenu_discord_small_image) == null || GetSettingsString(Setting.vmenu_discord_small_image_text) == ""))) + { + SetDiscordRichPresenceAssetSmall(GetSettingsString(Setting.vmenu_discord_small_image)); + SetDiscordRichPresenceAssetSmallText(CheckForSubstitutes(GetSettingsString(Setting.vmenu_discord_small_image_text))); + } + } + await Delay(15000); + } + #endregion + #region Slow misc tick internal static float entityRange = 2000f; /// diff --git a/vMenuServer/config/permissions.cfg b/vMenuServer/config/permissions.cfg index 0c2363b9..c5c60326 100644 --- a/vMenuServer/config/permissions.cfg +++ b/vMenuServer/config/permissions.cfg @@ -6,6 +6,24 @@ #YOU NEED TO SET THIS setr vmenu_individual_server_id "" # can be any ascii character and no spaces. this is technically a public value dont make it a password or something you use +# Discord Rich Presence +# values you can use in text %playercount%, %playername%, %playerid%, %playerstreet%, %playervehicle%, %pfversion%, %newline% +setr vmenu_disable_richpresence false +setr vmenu_discord_appid 1149315535809564683 # replace with your own to use custom images +setr vmenu_discord_text "is currently on %playerstreet% %newline% Name:%playername% Id:%playerid%" + +# Rich Presence Images +setr vmenu_discord_large_image "pf-vmenu" +setr vmenu_discord_large_image_text "This Server Is Using PF-vMenu Version:%pfversion%" +setr vmenu_discord_small_image "pf-vmenu" +setr vmenu_discord_small_image_text "Player Count: %playercount%" + +# Rich Presence Links +setr vmenu_discord_link_one_text "Discord Link" +setr vmenu_discord_link_one "https://discord.gg/D7cVc8TzPN" +setr vmenu_discord_link_two_text "Github Link" +setr vmenu_discord_link_two "https://github.com/ProjectFairnessLabs/PF-vMenu" + # WARNING, if you set "use_permissions" to false, a 'default' permissions system will be used. # this makes sure that EVERYONE on the server can do EVERYTHING, besides, banning, unbanning, # kicking and killing using the Online Players menu. From b4dc4c1f012f47110091e6b8d8672e5aef679174 Mon Sep 17 00:00:00 2001 From: Ricky Merc Date: Thu, 7 Sep 2023 09:46:00 -0400 Subject: [PATCH 49/49] oops left Debug.WriteLine in --- vMenu/FunctionsController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index 87669470..5dcb6693 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -2859,7 +2859,6 @@ static string CheckForSubstitutes(string Substitutes) } private async Task DiscordRichPresence() { - Debug.WriteLine(GetSettingsString(Setting.vmenu_discord_appid)); if (!((GetSettingsString(Setting.vmenu_discord_appid) == "") || (GetSettingsString(Setting.vmenu_discord_appid) == null))) { SetDiscordAppId(GetSettingsString(Setting.vmenu_discord_appid));