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! 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/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/dependencies/client/MenuAPI.dll b/dependencies/client/MenuAPI.dll new file mode 100644 index 00000000..aa273864 Binary files /dev/null and b/dependencies/client/MenuAPI.dll differ diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 70371749..322cfdf5 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -1438,8 +1438,35 @@ 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); - + + 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"]); + SetMaterial.SetSecondaryMaterial(vehicle.Handle, vehicleInfo.colors["secondaryf"]); + } + 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"]); + SetMaterial.SetSecondaryMaterial(vehicle.Handle, vehicleInfo.colors["secondaryf"]); + + } + else + SetVehicleColours(vehicle.Handle, 0, vehicleInfo.colors["secondary"]); + + SetMaterial.SetPrimaryMaterial(vehicle.Handle, vehicleInfo.colors["primaryf"]); + + 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 +1568,74 @@ 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 = await GetMaterial.GetPrimaryMaterialAsync(veh.Handle); + var secondaryColor = 0; + var secondaryColorred = 0; + var secondaryColorgreen = 0; + var secondaryColorblue = 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); + + + 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); + + + 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); diff --git a/vMenu/EventManager.cs b/vMenu/EventManager.cs index 321f1a25..f5041402 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; } @@ -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); } @@ -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 6440a406..5dcb6693 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -107,10 +107,14 @@ public void SetupTickFunctions() } // Configuration based - if (!IsAllowed(Permission.PASpawnAsDefault)) + if (IsAllowed(Permission.PASpawnAsDefault)) { Tick += RestorePlayerAfterBeingDead; } + if (!GetSettingsBool(Setting.vmenu_disable_richpresence)) + { + Tick += DiscordRichPresence; + } if (!GetSettingsBool(Setting.vmenu_disable_entity_outlines_tool)) { Tick += SlowMiscTick; @@ -176,6 +180,10 @@ public void SetupTickFunctions() { Tick += PersonalVehicleOptions; } + if (IsAllowed(Permission.PVAddBlip)) + { + Tick += PersonalVehicleBlip; + } if (IsAllowed(Permission.PAAnimalPeds)) { Tick += AnimalPedCameraChangeBlocker; @@ -567,8 +575,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) @@ -2794,6 +2801,94 @@ 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() + { + 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; /// @@ -2896,6 +2991,42 @@ 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 && MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle != null) + { + if (DoesEntityExist(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Handle)) + { + + 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)BlipInfo.GetBlipSpriteForVehicle(MainMenu.PersonalVehicleMenu.CurrentPersonalVehicle.Handle); + 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. @@ -3242,5 +3373,4 @@ public async Task TeleportOptions() } } } -} - +} \ No newline at end of file diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 4d6c47d4..262cd559 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; @@ -624,7 +625,218 @@ 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("~g~Personal Vehicle Options~s~", "Opens the personal vehicle submenu.") + { + 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(); + } + } + }; + 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.") + { + 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 +1124,31 @@ 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(); + } + } + }; + 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(); @@ -964,4 +1200,4 @@ private static void CreateSubmenus() } #endregion } -} +} \ No newline at end of file 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(); diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index bfff5917..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 @@ -42,7 +44,6 @@ public static int GetBlipSpriteForVehicle(int vehicle) // { (uint)GetHashKey("apc"), 558 }, { (uint)GetHashKey("oppressor"), 559 }, - { (uint)GetHashKey("oppressor2"), 559 }, { (uint)GetHashKey("halftrack"), 560 }, { (uint)GetHashKey("dune3"), 561 }, { (uint)GetHashKey("tampa3"), 562 }, @@ -64,6 +65,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 }, @@ -74,8 +76,104 @@ public static int GetBlipSpriteForVehicle(int vehicle) { (uint)GetHashKey("barrage"), 601 }, { (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 }, + { (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"), 669 }, + { (uint)GetHashKey("zr3802"), 669 }, + { (uint)GetHashKey("zr3803"), 669 }, + // + { (uint)GetHashKey("everon"), 734 }, + { (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"), 753 }, + { (uint)GetHashKey("seasparrow3"), 753 }, + { (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("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 }, + // + { (uint)GetHashKey("avenger3"), 589 }, + { (uint)GetHashKey("avenger4"), 589 }, + { (uint)GetHashKey("raiju"), 861 }, + { (uint)GetHashKey("conada2"), 862 }, + { (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/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/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; 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/vMenu/menus/PersonalVehicle.cs b/vMenu/menus/PersonalVehicle.cs index a7386ea3..d0de8316 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")); @@ -187,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 @@ -253,7 +255,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); @@ -262,6 +264,7 @@ private void CreateMenu() name = veh.DisplayName; } item.Label = $"Current Vehicle: {name}"; + MainMenu.RecreateMenus(); } else { diff --git a/vMenu/menus/PlayerTimeWeatherOptions.cs b/vMenu/menus/PlayerTimeWeatherOptions.cs index c61ebfc0..fdbfe117 100644 --- a/vMenu/menus/PlayerTimeWeatherOptions.cs +++ b/vMenu/menus/PlayerTimeWeatherOptions.cs @@ -26,14 +26,16 @@ 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. /// 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(); @@ -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/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/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index c8753856..b818bc34 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.Threading.Tasks; using CitizenFX.Core; @@ -13,6 +14,7 @@ using static vMenuShared.ConfigManager; using static vMenuShared.PermissionsManager; + namespace vMenuClient.menus { public class VehicleOptions @@ -30,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; @@ -57,6 +59,17 @@ 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; + 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(); @@ -120,14 +133,14 @@ private void CreateMenu() { Label = "β†’β†’β†’" }; - var colorsMenuBtn = new MenuItem("Vehicle Colors", "Style your vehicle even further by giving it some ~g~Snailsome ~s~colors!") - { - Label = "β†’β†’β†’" - }; - var underglowMenuBtn = new MenuItem("Vehicle Neon Kits", "Make your vehicle shine with some fancy neon underglow!") + var colorsMenuBtn = new MenuItem("Vehicle Colours", "Style your vehicle even further by giving it an ~g~awesome ~s~paint job!") { 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."); @@ -220,9 +233,9 @@ 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")); + //VehicleUnderglowMenu = Lm.GetMenu(new Menu("Vehicle Neon Kits", "Vehicle Neon Underglow Options")); MenuController.AddSubmenu(menu, VehicleModMenu); MenuController.AddSubmenu(menu, VehicleDoorsMenu); @@ -231,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. @@ -308,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 { @@ -395,7 +408,7 @@ private void CreateMenu() { menu.AddMenuItem(infiniteFuel); } - if (IsAllowed(Permission.VOReduceDriftSuspension)) + if (IsAllowed(Permission.VOReduceDriftSuspension)) // REDUCE DRIFT SUSPENSION { menu.AddMenuItem(reduceDriftSuspension); } @@ -544,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) { @@ -971,23 +989,31 @@ 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() + { + "Normal", + "Metallic", + "Pearl", + "Matte", + "Metal", + "Chrome", + }; // color lists var classic = new List(); var matte = new List(); @@ -1047,13 +1073,13 @@ 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"); - VehicleColorsMenu.AddMenuItem(chrome); + //VehicleColorsMenu.AddMenuItem(chrome); VehicleColorsMenu.AddMenuItem(vehicleEnveffScale); VehicleColorsMenu.OnItemSelect += (sender, item, index) => @@ -1063,6 +1089,8 @@ private void CreateMenu() { if (item == chrome) { + ClearVehicleCustomPrimaryColour(veh.Handle); + ClearVehicleCustomSecondaryColour(veh.Handle); SetVehicleColours(veh.Handle, 120, 120); // chrome is index 120 } } @@ -1086,11 +1114,44 @@ 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); + // 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) @@ -1147,7 +1208,8 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in SetVehicleModKit(veh.Handle, 0); } } - + ClearVehicleCustomSecondaryColour(veh.Handle); + ClearVehicleCustomPrimaryColour(veh.Handle); SetVehicleColours(veh.Handle, primaryColor, secondaryColor); } else if (sender == secondaryColorsMenu) @@ -1174,6 +1236,8 @@ 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); } else if (sender == VehicleColorsMenu) @@ -1209,7 +1273,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."); } } @@ -1259,6 +1323,448 @@ void HandleListIndexChanges(Menu sender, MenuListItem listItem, int oldIndex, in secondaryColorsMenu.OnListIndexChange += HandleListIndexChanges; } } + + var primaryColorsMenuRGB = Lm.GetMenu(new Menu("Primary RGB Colours", "Primary RGB Colours")); + MenuController.AddSubmenu(primaryColorsMenu, primaryColorsMenuRGB); + + var primaryColorsRGBBtn = new MenuItem("Primary Colour RGB") { Label = "β†’β†’β†’" }; + primaryColorsMenu.AddMenuItem(primaryColorsRGBBtn); + MenuController.BindMenuItem(primaryColorsMenu, primaryColorsMenuRGB, primaryColorsRGBBtn); + 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 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 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 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 from Secondary", "Copies the Secondary Colour's colour data."); + primaryColorsMenuRGB.AddMenuItem(RedSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(GreenSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(BlueSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(HexColorPrimary); + primaryColorsMenuRGB.AddMenuItem(FinishSliderPrimary); + primaryColorsMenuRGB.AddMenuItem(pearlescentListPrimary); + primaryColorsMenuRGB.AddMenuItem(SecondaryMatchColorPrimary); + + primaryColorsMenu.OnItemSelect += async (sender, item, index) => + { + + 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 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}"; + }; + + 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) + { + var result = await GetUserInput(windowTitle: "Enter Colour Hex", defaultText: (HexColorPrimary.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); + + 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); + 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!"); + } + } + if (item == SecondaryMatchColorPrimary) + { + 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 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}"; + SetMaterial.SetPrimaryMaterial(veh.Handle, secondaryFinish); + SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); + + } + }; + + primaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => + { + if (sliderItem == RedSliderPrimary) + { + RedPrimary = newPosition; + 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 Colour ({RedPrimary})"; + + + } + if (sliderItem == GreenSliderPrimary) + { + GreenPrimary = newPosition; + 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 Colour ({GreenPrimary})"; + + } + if (sliderItem == BlueSliderPrimary) + { + BluePrimary = newPosition; + 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 Colour ({BluePrimary})"; + + } + + if (sliderItem == FinishSliderPrimary) + { + FinishPrimary = newPosition; + 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 = $"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}"; + + SetMaterial.SetPrimaryMaterial(veh.Handle, FinishPrimary); + + SetVehicleCustomPrimaryColour(veh.Handle, RedPrimary, GreenPrimary, BluePrimary); + + } + }; + var SecondaryColorsMenuRGB = Lm.GetMenu(new Menu("Secondary RGB Colours", "Secondary RGB Colours")); + MenuController.AddSubmenu(secondaryColorsMenu, SecondaryColorsMenuRGB); + + var SecondaryColorsRGBBtn = new MenuItem("Secondary Colour RGB") { Label = "β†’β†’β†’" }; + secondaryColorsMenu.AddMenuItem(SecondaryColorsRGBBtn); + MenuController.BindMenuItem(secondaryColorsMenu, SecondaryColorsMenuRGB, SecondaryColorsRGBBtn); + 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 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 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 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 from Primary Colour", "Copies the Primary Colour's colour data."); + + secondaryColorsMenu.OnItemSelect += async (sender, item, index) => + { + 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 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}"; + }; + SecondaryColorsMenuRGB.OnItemSelect += async (sender, item, index) => + { + if (item == HexColorSecondary) + { + var result = await GetUserInput(windowTitle: "Enter Colour Hex", defaultText: (HexColorSecondary.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); + + 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); + 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!"); + + } + + } + if (item == PrimaryMatchColorSecondary) + { + var veh = GetVehicle(); + var secondaryColorred = 0; + var secondaryColorgreen = 0; + var secondaryColorblue = 0; + var primaryFinish2 = await GetMaterial.GetPrimaryMaterialAsync(veh.Handle); + + + GetVehicleCustomPrimaryColour(veh.Handle, ref secondaryColorred, ref secondaryColorgreen, ref secondaryColorblue); + + + if (primaryFinish2 > 5) + primaryFinish2 = 0; + RedSliderSecondary.Position = secondaryColorred; + GreenSliderSecondary.Position = secondaryColorgreen; + BlueSliderSecondary.Position = secondaryColorblue; + FinishSliderSecondary.Position = primaryFinish2; + RedSecondary = secondaryColorred; + GreenSecondary = secondaryColorgreen; + BlueSecondary = secondaryColorblue; + FinishSecondary = 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}"; + + SetMaterial.SetSecondaryMaterial(veh.Handle, primaryFinish2); + + SetVehicleCustomSecondaryColour(veh.Handle, RedSecondary, GreenSecondary, BlueSecondary); + + } + }; + + SecondaryColorsMenuRGB.AddMenuItem(RedSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(GreenSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(BlueSliderSecondary); + SecondaryColorsMenuRGB.AddMenuItem(HexColorSecondary); + SecondaryColorsMenuRGB.AddMenuItem(FinishSliderSecondary); + + SecondaryColorsMenuRGB.AddMenuItem(PrimaryMatchColorSecondary); + + SecondaryColorsMenuRGB.OnSliderPositionChange += (m, sliderItem, oldPosition, newPosition, itemIndex) => + { + if (sliderItem == RedSliderSecondary) + { + RedSecondary = newPosition; + 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 Colour ({RedSecondary})"; + + + } + if (sliderItem == GreenSliderSecondary) + { + GreenSecondary = newPosition; + 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 Colour ({GreenSecondary})"; + + } + if (sliderItem == BlueSliderSecondary) + { + BlueSecondary = newPosition; + 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 Colour ({BlueSecondary})"; + + } + + if (sliderItem == FinishSliderSecondary) + { + FinishSecondary = newPosition; + 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 = $"Colour Finish ({ColorFInishes[FinishSecondary]})"; + + } + if ((sliderItem == RedSliderSecondary) || (sliderItem == GreenSliderSecondary) || (sliderItem == BlueSliderSecondary) || (sliderItem == FinishSliderSecondary)) + { + var veh = GetVehicle(); + 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 #region Vehicle Doors Submenu Stuff @@ -1611,21 +2117,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."); - - VehicleUnderglowMenu.AddMenuItem(underglowFront); - VehicleUnderglowMenu.AddMenuItem(underglowBack); - VehicleUnderglowMenu.AddMenuItem(underglowLeft); - VehicleUnderglowMenu.AddMenuItem(underglowRight); + 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); + + + 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); - VehicleUnderglowMenu.AddMenuItem(underglowColor); + } + 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); + } + }; - menu.OnItemSelect += (sender, item, index) => + 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) @@ -1682,11 +2285,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()) { @@ -1714,7 +2317,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) { @@ -1724,10 +2327,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 @@ -1847,7 +2509,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}"; - modlist.Add(name); + + if (name == "Engine #4 [6/6]") + modlist.Add("EMS Upgrade, Level 5 [6/6]"); + else + modlist.Add(name); } // Create the MenuListItem for this mod type. @@ -2076,7 +2742,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) @@ -2210,7 +2876,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()) @@ -2295,4 +2974,104 @@ private int GetIndexFromColor() } #endregion } -} \ No newline at end of file + 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) + { + + + 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/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/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 + + diff --git a/vMenuServer/MainServer.cs b/vMenuServer/MainServer.cs index e084e141..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 @@ -739,11 +763,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; + FreezeTime = true; + while (newHours != CurrentHours) + { + if ((CurrentMinutes + 1) > 59) + { + CurrentMinutes = 0; + if ((CurrentHours + 1) > 23) + { + CurrentHours = 0; + } + else + { + CurrentHours ++; + } + } + else + { + CurrentMinutes=CurrentMinutes+5; + } + await Delay(0); + } CurrentHours = newHours; CurrentMinutes = newMinutes; FreezeTime = freezeTimeNew; + } #endregion 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 diff --git a/vMenuServer/config/addons.json b/vMenuServer/config/addons.json index 67ec28aa..380abf3f 100644 --- a/vMenuServer/config/addons.json +++ b/vMenuServer/config/addons.json @@ -39,7 +39,6 @@ "KURUMA2", "PARAGON2", "SCHAFTER5", - "ZR350", "ZR380", "ZR3802", "ZR3803", @@ -215,7 +214,7 @@ "TANKERCAR", "CABLECAR", "AVENGER3", - "AVENGER4", + "AVENGER4" ] } \ No newline at end of file diff --git a/vMenuServer/config/permissions.cfg b/vMenuServer/config/permissions.cfg index cffaab16..795b464b 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. @@ -559,6 +577,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 #################################### 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/fxmanifest.lua b/vMenuServer/fxmanifest.lua index 136bf129..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' @@ -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' 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 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