diff --git a/vMenu/MpPedDataManager.cs b/vMenu/MpPedDataManager.cs index fa2d41f7..14e446e3 100644 --- a/vMenu/MpPedDataManager.cs +++ b/vMenu/MpPedDataManager.cs @@ -8,12 +8,32 @@ public class MpPedDataManager : BaseScript { public struct DrawableVariations { - public Dictionary> clothes; + public Dictionary> clothes; // legacy + public Dictionary clothesWithCollection; // new + } + public class CharacterClothingData + { + public int ComponentIndex { get; set; } + public int Drawable { get; set; } + public int Texture { get; set; } + public string Collection { get; set; } + } + public static class ClothingCollections + { + public const string BaseGame = "base"; } public struct PropVariations { - public Dictionary> props; + public Dictionary> props; // legacy + public Dictionary propsWithCollection; // new + } + public class CharacterPropData + { + public int PropIndex { get; set; } + public int Drawable { get; set; } + public int Texture { get; set; } + public string Collection { get; set; } } public struct FaceShapeFeatures @@ -109,6 +129,8 @@ public struct MultiplayerPedData public PedAppearance PedAppearance; public PedTattoos PedTatttoos; public PedFacePaints PedFacePaints; + public Dictionary clothesWithCollection; + public Dictionary propsWithCollection; public bool IsMale; public uint ModelHash; public string SaveName; diff --git a/vMenu/menus/MpPedCustomization.cs b/vMenu/menus/MpPedCustomization.cs index 61e55e77..86ec017c 100644 --- a/vMenu/menus/MpPedCustomization.cs +++ b/vMenu/menus/MpPedCustomization.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -14,6 +15,8 @@ using static CitizenFX.Core.Native.API; using static vMenuClient.CommonFunctions; using static vMenuClient.MpPedDataManager; +using static vMenuClient.MpPedDataManager.DrawableVariations; +using static vMenuClient.MpPedDataManager.PropVariations; using static vMenuShared.ConfigManager; namespace vMenuClient.menus @@ -146,7 +149,9 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) { currentCharacter = new MultiplayerPedData(); currentCharacter.DrawableVariations.clothes = new Dictionary>(); + currentCharacter.DrawableVariations.clothesWithCollection = new Dictionary(); currentCharacter.PropVariations.props = new Dictionary>(); + currentCharacter.PropVariations.propsWithCollection = new Dictionary(); currentCharacter.PedHeadBlendData = Game.PlayerPed.GetHeadBlendData(); currentCharacter.Version = 1; currentCharacter.ModelHash = male ? (uint)GetHashKey("mp_m_freemode_01") : (uint)GetHashKey("mp_f_freemode_01"); @@ -181,7 +186,9 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) } currentCharacter.DrawableVariations.clothes ??= new Dictionary>(); + currentCharacter.DrawableVariations.clothesWithCollection ??= new Dictionary(); currentCharacter.PropVariations.props ??= new Dictionary>(); + currentCharacter.PropVariations.propsWithCollection ??= new Dictionary(); // Set the facial expression to default in case it doesn't exist yet, or keep the current one if it does. currentCharacter.FacialExpression ??= facial_expressions[0]; @@ -550,14 +557,46 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) #region clothing options menu var clothingCategoryNames = new string[12] { "Unused (head)", "Masks", "Unused (hair)", "Upper Body", "Lower Body", "Bags & Parachutes", "Shoes", "Scarfs & Chains", "Shirt & Accessory", "Body Armor & Accessory 2", "Badges & Logos", "Shirt Overlay & Jackets" }; + for (var i = 0; i < 12; i++) { if (i is not 0 and not 2) { - var currentVariationIndex = editPed && currentCharacter.DrawableVariations.clothes.ContainsKey(i) ? currentCharacter.DrawableVariations.clothes[i].Key : GetPedDrawableVariation(Game.PlayerPed.Handle, i); - var currentVariationTextureIndex = editPed && currentCharacter.DrawableVariations.clothes.ContainsKey(i) ? currentCharacter.DrawableVariations.clothes[i].Value : GetPedTextureVariation(Game.PlayerPed.Handle, i); + int currentVariationIndex; + int currentVariationTextureIndex; + + if (editPed) + { + // New format + if (currentCharacter.DrawableVariations.clothesWithCollection != null && currentCharacter.DrawableVariations.clothesWithCollection.TryGetValue(i, out var cloth)) + { + if (cloth.Collection == "base") + currentVariationIndex = cloth.Drawable; // use local index for base + else + currentVariationIndex = GetPedDrawableGlobalIndexFromCollection(Game.PlayerPed.Handle, i, cloth.Collection, cloth.Drawable); + + currentVariationTextureIndex = cloth.Texture; + } + // Legacy fallback + else if (currentCharacter.DrawableVariations.clothes != null && currentCharacter.DrawableVariations.clothes.TryGetValue(i, out var legacyCloth)) + { + currentVariationIndex = legacyCloth.Key; + currentVariationTextureIndex = legacyCloth.Value; + } + else + { + currentVariationIndex = GetPedDrawableVariation(Game.PlayerPed.Handle, i); + currentVariationTextureIndex = GetPedTextureVariation(Game.PlayerPed.Handle, i); + } + } + else + { + currentVariationIndex = GetPedDrawableVariation(Game.PlayerPed.Handle, i); + currentVariationTextureIndex = GetPedTextureVariation(Game.PlayerPed.Handle, i); + } var maxDrawables = GetNumberOfPedDrawableVariations(Game.PlayerPed.Handle, i); + var maxTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, i, currentVariationIndex); var items = new List(); for (var x = 0; x < maxDrawables; x++) @@ -565,8 +604,6 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) items.Add($"Drawable #{x} (of {maxDrawables})"); } - var maxTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, i, currentVariationIndex); - var listItem = new MenuListItem(clothingCategoryNames[i], items, currentVariationIndex, $"Select a drawable using the arrow keys and press ~o~enter~s~ to cycle through all available textures. Currently selected texture: #{currentVariationTextureIndex + 1} (of {maxTextures})."); clothesMenu.AddMenuItem(listItem); } @@ -575,26 +612,53 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) #region props options menu var propNames = new string[5] { "Hats & Helmets", "Glasses", "Misc Props", "Watches", "Bracelets" }; + for (var x = 0; x < 5; x++) { - var propId = x; - if (x > 2) + var propId = x > 2 ? x + 3 : x; + + int currentProp; + int currentPropTexture; + + if (editPed) { - propId += 3; - } + // New format + if (currentCharacter.PropVariations.propsWithCollection != null && currentCharacter.PropVariations.propsWithCollection.TryGetValue(propId, out var prop)) + { + if (prop.Collection == "base") + currentProp = prop.Drawable; + else + currentProp = GetPedPropGlobalIndexFromCollection(Game.PlayerPed.Handle, propId, prop.Collection, prop.Drawable); - var currentProp = editPed && currentCharacter.PropVariations.props.ContainsKey(propId) ? currentCharacter.PropVariations.props[propId].Key : GetPedPropIndex(Game.PlayerPed.Handle, propId); - var currentPropTexture = editPed && currentCharacter.PropVariations.props.ContainsKey(propId) ? currentCharacter.PropVariations.props[propId].Value : GetPedPropTextureIndex(Game.PlayerPed.Handle, propId); + currentPropTexture = prop.Texture; + } + // Legacy fallback + else if (currentCharacter.PropVariations.props != null && currentCharacter.PropVariations.props.TryGetValue(propId, out var legacyProp)) + { + currentProp = legacyProp.Key; + currentPropTexture = legacyProp.Value; + } + else + { + currentProp = GetPedPropIndex(Game.PlayerPed.Handle, propId); + currentPropTexture = GetPedPropTextureIndex(Game.PlayerPed.Handle, propId); + } + } + else + { + currentProp = GetPedPropIndex(Game.PlayerPed.Handle, propId); + currentPropTexture = GetPedPropTextureIndex(Game.PlayerPed.Handle, propId); + } var propsList = new List(); - for (var i = 0; i < GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propId); i++) + var maxProps = GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propId); + for (var i = 0; i < maxProps; i++) { - propsList.Add($"Prop #{i} (of {GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propId)})"); + propsList.Add($"Prop #{i} (of {maxProps})"); } propsList.Add("No Prop"); - - if (GetPedPropIndex(Game.PlayerPed.Handle, propId) != -1) + if (currentProp != -1) { var maxPropTextures = GetNumberOfPedPropTextureVariations(Game.PlayerPed.Handle, propId, currentProp); var propListItem = new MenuListItem($"{propNames[x]}", propsList, currentProp, $"Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures. Currently selected texture: #{currentPropTexture + 1} (of {maxPropTextures})."); @@ -602,11 +666,9 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) } else { - var propListItem = new MenuListItem($"{propNames[x]}", propsList, currentProp, "Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."); + var propListItem = new MenuListItem($"{propNames[x]}", propsList, 0, "Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."); propsMenu.AddMenuItem(propListItem); } - - } #endregion @@ -796,8 +858,13 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) private async Task SavePed() { currentCharacter.PedHeadBlendData = Game.PlayerPed.GetHeadBlendData(); + currentCharacter = ReplacePedDataClothing(currentCharacter); if (isEdidtingPed) { + // Ensure SaveName is set + if (string.IsNullOrEmpty(currentCharacter.SaveName)) + currentCharacter.SaveName = "mp_ped_" + selectedSavedCharacterManageName; + var json = JsonConvert.SerializeObject(currentCharacter); if (StorageManager.SaveJsonData(currentCharacter.SaveName, json, true)) { @@ -836,7 +903,6 @@ private async Task SavePed() } } } - } /// @@ -1382,20 +1448,31 @@ int UnclampMix(float value) #region clothes clothesMenu.OnListIndexChange += (_menu, listItem, oldSelectionIndex, newSelectionIndex, realIndex) => { - var componentIndex = realIndex + 1; + int componentIndex = realIndex + 1; if (realIndex > 0) { componentIndex += 1; } - var textureIndex = GetPedTextureVariation(Game.PlayerPed.Handle, componentIndex); - var newTextureIndex = 0; - SetPedComponentVariation(Game.PlayerPed.Handle, componentIndex, newSelectionIndex, newTextureIndex, 0); - currentCharacter.DrawableVariations.clothes ??= new Dictionary>(); + int newTextureIndex = 0; - var maxTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, componentIndex, newSelectionIndex); + SetPedComponentVariation(Game.PlayerPed.Handle, componentIndex, newSelectionIndex, newTextureIndex, 0); + currentCharacter.DrawableVariations.clothes ??= new Dictionary>(); currentCharacter.DrawableVariations.clothes[componentIndex] = new KeyValuePair(newSelectionIndex, newTextureIndex); + + string collectionName = GetPedDrawableVariationCollectionName(Game.PlayerPed.Handle, componentIndex) ?? "base"; + + currentCharacter.DrawableVariations.clothesWithCollection ??= new(); + currentCharacter.DrawableVariations.clothesWithCollection[componentIndex] = new CharacterClothingData + { + ComponentIndex = componentIndex, + Drawable = GetPedDrawableVariationCollectionLocalIndex(componentIndex, newSelectionIndex), + Texture = newTextureIndex, + Collection = collectionName + }; + + int maxTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, componentIndex, newSelectionIndex); listItem.Description = $"Select a drawable using the arrow keys and press ~o~enter~s~ to cycle through all available textures. Currently selected texture: #{newTextureIndex + 1} (of {maxTextures})."; }; @@ -1407,14 +1484,27 @@ int UnclampMix(float value) componentIndex += 1; } - var textureIndex = GetPedTextureVariation(Game.PlayerPed.Handle, componentIndex); - var newTextureIndex = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, componentIndex, listIndex) - 1 < textureIndex + 1 ? 0 : textureIndex + 1; + int textureIndex = GetPedTextureVariation(Game.PlayerPed.Handle, componentIndex); + int newTextureIndex = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, componentIndex, listIndex) - 1 < textureIndex + 1 ? 0 : textureIndex + 1; + SetPedComponentVariation(Game.PlayerPed.Handle, componentIndex, listIndex, newTextureIndex, 0); + currentCharacter.DrawableVariations.clothes ??= new Dictionary>(); + currentCharacter.DrawableVariations.clothes[componentIndex] = new KeyValuePair(listIndex, newTextureIndex); - var maxTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, componentIndex, listIndex); + string collectionName = GetPedDrawableVariationCollectionName(Game.PlayerPed.Handle, componentIndex); + if (string.IsNullOrEmpty(collectionName)) collectionName = "base"; - currentCharacter.DrawableVariations.clothes[componentIndex] = new KeyValuePair(listIndex, newTextureIndex); + currentCharacter.DrawableVariations.clothesWithCollection ??= new Dictionary(); + currentCharacter.DrawableVariations.clothesWithCollection[componentIndex] = new CharacterClothingData + { + ComponentIndex = componentIndex, + Drawable = GetPedDrawableVariationCollectionLocalIndex(componentIndex, listIndex), + Texture = newTextureIndex, + Collection = collectionName + }; + + int maxTextures = GetNumberOfPedTextureVariations(Game.PlayerPed.Handle, componentIndex, listIndex); listItem.Description = $"Select a drawable using the arrow keys and press ~o~enter~s~ to cycle through all available textures. Currently selected texture: #{newTextureIndex + 1} (of {maxTextures})."; }; #endregion @@ -1422,7 +1512,7 @@ int UnclampMix(float value) #region props propsMenu.OnListIndexChange += (_menu, listItem, oldSelectionIndex, newSelectionIndex, realIndex) => { - var propIndex = realIndex; + int propIndex = realIndex; if (realIndex == 3) { propIndex = 6; @@ -1431,28 +1521,56 @@ int UnclampMix(float value) { propIndex = 7; } + int textureIndex = 0; + + int maxDrawables = GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propIndex); + bool isNoProp = newSelectionIndex >= GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propIndex); + + currentCharacter.PropVariations.props ??= new Dictionary>(); + currentCharacter.PropVariations.propsWithCollection ??= new Dictionary(); - var textureIndex = 0; - if (newSelectionIndex >= GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propIndex)) + if (isNoProp) { SetPedPropIndex(Game.PlayerPed.Handle, propIndex, -1, -1, false); ClearPedProp(Game.PlayerPed.Handle, propIndex); currentCharacter.PropVariations.props ??= new Dictionary>(); currentCharacter.PropVariations.props[propIndex] = new KeyValuePair(-1, -1); - listItem.Description = $"Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."; + currentCharacter.PropVariations.propsWithCollection ??= new Dictionary(); + currentCharacter.PropVariations.propsWithCollection[propIndex] = new CharacterPropData + { + PropIndex = propIndex, + Drawable = -1, + Texture = -1, + Collection = "base" + }; + + listItem.Description = "Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."; } else { SetPedPropIndex(Game.PlayerPed.Handle, propIndex, newSelectionIndex, textureIndex, true); currentCharacter.PropVariations.props ??= new Dictionary>(); currentCharacter.PropVariations.props[propIndex] = new KeyValuePair(newSelectionIndex, textureIndex); + + string collectionName = GetPedCollectionNameFromProp(Game.PlayerPed.Handle, propIndex, newSelectionIndex); + if (string.IsNullOrEmpty(collectionName)) collectionName = "base"; + + currentCharacter.PropVariations.propsWithCollection ??= new Dictionary(); + currentCharacter.PropVariations.propsWithCollection[propIndex] = new CharacterPropData + { + PropIndex = propIndex, + Drawable = GetPedCollectionLocalIndexFromProp(Game.PlayerPed.Handle, propIndex, newSelectionIndex), + Texture = textureIndex, + Collection = collectionName + }; + if (GetPedPropIndex(Game.PlayerPed.Handle, propIndex) == -1) { listItem.Description = $"Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."; } else { - var maxPropTextures = GetNumberOfPedPropTextureVariations(Game.PlayerPed.Handle, propIndex, newSelectionIndex); + int maxPropTextures = GetNumberOfPedPropTextureVariations(Game.PlayerPed.Handle, propIndex, newSelectionIndex); listItem.Description = $"Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures. Currently selected texture: #{textureIndex + 1} (of {maxPropTextures})."; } } @@ -1470,14 +1588,22 @@ int UnclampMix(float value) propIndex = 7; } - var textureIndex = GetPedPropTextureIndex(Game.PlayerPed.Handle, propIndex); - var newTextureIndex = GetNumberOfPedPropTextureVariations(Game.PlayerPed.Handle, propIndex, listIndex) - 1 < textureIndex + 1 ? 0 : textureIndex + 1; - if (textureIndex >= GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propIndex)) + int textureIndex = GetPedPropTextureIndex(Game.PlayerPed.Handle, propIndex); + int newTextureIndex = GetNumberOfPedPropTextureVariations(Game.PlayerPed.Handle, propIndex, listIndex) - 1 < textureIndex + 1 ? 0 : textureIndex + 1; + if (listIndex >= GetNumberOfPedPropDrawableVariations(Game.PlayerPed.Handle, propIndex)) { SetPedPropIndex(Game.PlayerPed.Handle, propIndex, -1, -1, false); ClearPedProp(Game.PlayerPed.Handle, propIndex); currentCharacter.PropVariations.props ??= new Dictionary>(); currentCharacter.PropVariations.props[propIndex] = new KeyValuePair(-1, -1); + currentCharacter.PropVariations.propsWithCollection ??= new Dictionary(); + currentCharacter.PropVariations.propsWithCollection[propIndex] = new CharacterPropData + { + PropIndex = propIndex, + Drawable = -1, + Texture = -1, + Collection = "base" + }; listItem.Description = $"Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."; } else @@ -1485,6 +1611,18 @@ int UnclampMix(float value) SetPedPropIndex(Game.PlayerPed.Handle, propIndex, listIndex, newTextureIndex, true); currentCharacter.PropVariations.props ??= new Dictionary>(); currentCharacter.PropVariations.props[propIndex] = new KeyValuePair(listIndex, newTextureIndex); + + string collectionName = GetPedCollectionNameFromProp(Game.PlayerPed.Handle, propIndex, listIndex); + if (string.IsNullOrEmpty(collectionName)) collectionName = "base"; + + currentCharacter.PropVariations.props[propIndex] = new KeyValuePair(listIndex, newTextureIndex); + currentCharacter.PropVariations.propsWithCollection[propIndex] = new CharacterPropData + { + PropIndex = propIndex, + Drawable = GetPedCollectionLocalIndexFromProp(Game.PlayerPed.Handle, propIndex, listIndex), + Texture = newTextureIndex, + Collection = collectionName + }; if (GetPedPropIndex(Game.PlayerPed.Handle, propIndex) == -1) { listItem.Description = $"Select a prop using the arrow keys and press ~o~enter~s~ to cycle through all available textures."; @@ -3068,21 +3206,84 @@ private MultiplayerPedData ReplacePedDataClothing(MultiplayerPedData character) { int handle = Game.PlayerPed.Handle; - // Drawables + // Init if null + character.DrawableVariations.clothes ??= new Dictionary>(); + character.DrawableVariations.clothesWithCollection ??= new Dictionary(); + character.PropVariations.props ??= new Dictionary>(); + character.PropVariations.propsWithCollection ??= new Dictionary(); + for (int i = 0; i < 12; i++) { - int drawable = GetPedDrawableVariation(handle, i); int texture = GetPedTextureVariation(handle, i); - character.DrawableVariations.clothes[i] = new KeyValuePair(drawable, texture); + string collectionName = GetPedDrawableVariationCollectionName(handle, i); + + int drawable; + if (string.IsNullOrEmpty(collectionName) || collectionName == "base") + { + drawable = GetPedDrawableVariation(handle, i); + collectionName = "base"; + character.DrawableVariations.clothes[i] = new KeyValuePair(drawable, texture); + } + else + { + drawable = GetPedDrawableVariationCollectionLocalIndex(handle, i); + character.DrawableVariations.clothes[i] = new KeyValuePair(GetPedDrawableGlobalIndexFromCollection(handle, i, collectionName, drawable), texture); + } + + character.DrawableVariations.clothesWithCollection[i] = new CharacterClothingData + { + ComponentIndex = i, + Drawable = drawable, + Texture = texture, + Collection = collectionName + }; } for (int i = 0; i < 8; i++) { - int prop = GetPedPropIndex(handle, i); int texture = GetPedPropTextureIndex(handle, i); - character.PropVariations.props[i] = new KeyValuePair(prop, texture); + string collectionName = GetPedCollectionNameFromProp(handle, i, GetPedPropIndex(handle, i)); + + + int drawable; + if (string.IsNullOrEmpty(collectionName) || collectionName == "base") + { + drawable = GetPedPropIndex(handle, i); + collectionName = "base"; + character.PropVariations.props[i] = new KeyValuePair(drawable, texture); + } + else + { + drawable = GetPedCollectionLocalIndexFromProp(handle, i, GetPedPropIndex(handle, i)); + character.PropVariations.props[i] = new KeyValuePair(GetPedPropGlobalIndexFromCollection(handle, i, collectionName, drawable), texture); + } + + + if (drawable == -1) // no prop at this index + { + character.PropVariations.props[i] = new KeyValuePair(-1, -1); + character.PropVariations.propsWithCollection[i] = new CharacterPropData + { + PropIndex = i, + Drawable = -1, + Texture = -1, + Collection = "base" + }; + continue; + } + + character.PropVariations.propsWithCollection[i] = new CharacterPropData + { + PropIndex = i, + Drawable = drawable, + Texture = texture, + Collection = collectionName + }; } + /*character.clothesWithCollection = character.DrawableVariations.clothesWithCollection; + character.propsWithCollection = character.PropVariations.propsWithCollection;*/ + return character; } @@ -3317,24 +3518,57 @@ internal async Task AppySavedDataToPed(MultiplayerPedData character, int pedHand #endregion #region Clothing Data - if (character.DrawableVariations.clothes != null && character.DrawableVariations.clothes.Count > 0) + // Apply clothing (supports old KeyValuePair and new object structure) + if (character.DrawableVariations.clothesWithCollection != null && character.DrawableVariations.clothesWithCollection?.Count > 0) + { + foreach (var item in character.DrawableVariations.clothesWithCollection.Values) + { + if (item.Collection == "base") + { + SetPedComponentVariation(pedHandle, item.ComponentIndex, item.Drawable, item.Texture, 0); + } + else + { + SetPedCollectionComponentVariation(pedHandle, item.ComponentIndex, item.Collection, item.Drawable, item.Texture, 0); + } + } + } + else if (character.DrawableVariations.clothes != null && character.DrawableVariations.clothes.Count > 0) { - foreach (var cd in character.DrawableVariations.clothes) + foreach (var kvp in character.DrawableVariations.clothes) { - SetPedComponentVariation(pedHandle, cd.Key, cd.Value.Key, cd.Value.Value, 0); + SetPedComponentVariation(pedHandle, kvp.Key, kvp.Value.Key, kvp.Value.Value, 0); } } #endregion #region Props Data - if (character.PropVariations.props != null && character.PropVariations.props.Count > 0) + // Apply props (supports old KeyValuePair and new object structure) + if (character.PropVariations.propsWithCollection != null && character.PropVariations.propsWithCollection.Count > 0) + { + foreach (var item in character.PropVariations.propsWithCollection.Values) + { + if (item.Drawable > -1) + { + if (item.Collection == "base") + { + SetPedPropIndex(pedHandle, item.PropIndex, item.Drawable, item.Texture, true); + } + else + { + SetPedCollectionPropIndex(pedHandle, item.PropIndex, item.Collection, item.Drawable, item.Texture, true); + } + } + } + } + else if (character.PropVariations.props != null && character.PropVariations.props.Count > 0) { - foreach (var cd in character.PropVariations.props) + foreach (var kvp in character.PropVariations.props) { - if (cd.Value.Key > -1) + if (kvp.Value.Key > -1) { - int textureIndex = cd.Value.Value > -1 ? cd.Value.Value : 0; - SetPedPropIndex(pedHandle, cd.Key, cd.Value.Key, textureIndex, true); + int texture = kvp.Value.Value > -1 ? kvp.Value.Value : 0; + SetPedPropIndex(pedHandle, kvp.Key, kvp.Value.Key, texture, true); } } } diff --git a/vMenu/vMenuClient.csproj b/vMenu/vMenuClient.csproj index b2d0084b..9208decf 100644 --- a/vMenu/vMenuClient.csproj +++ b/vMenu/vMenuClient.csproj @@ -16,14 +16,13 @@ + + runtime + - - runtime - - ..\dependencies\shared\Newtonsoft.Json.dll true