private static MUnk_94549140 GenerateYmtPedPropItem(YmtPedDefinitionFile ymt, Unk_2834549053 anchor, ClothData clothData) { var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo) { AnchorId = (byte)anchor }; for (int i = 0; i < clothData.Textures.Count; i++) { var texture = new MUnk_254518642 { TexId = (byte)i }; item.TexData.Add(texture); } // Get or create linked anchor var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (aanchor == null) { aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo) { Anchor = anchor, PropsMap = { [item] = (byte)item.TexData.Count } }; ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor); } else { aanchor.PropsMap[item] = (byte)item.TexData.Count; } return(item); }
protected MUnk_94549140 GenerateYmtPedPropItem(YmtPedDefinitionFile ymt, Unk_2834549053 anchor, ClothData clothData) { var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo) { AnchorId = (byte)anchor, TexData = GetTexDataForCloth(clothData) }; // Get or create linked anchor var anchorProps = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (anchorProps == null) { anchorProps = new MCAnchorProps(ymt.Unk_376833625.PropInfo) { Anchor = anchor, PropsMap = { [item] = (byte)item.TexData.Count } }; ymt.Unk_376833625.PropInfo.AAnchors.Add(anchorProps); } else { anchorProps.PropsMap[item] = (byte)item.TexData.Count; } return(item); }
protected static MUnk_94549140 GenerateYmtPedPropItem(YmtPedDefinitionFile ymt, Unk_2834549053 anchor, ClothData clothData) { var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo) { AnchorId = (byte)anchor }; for (int i = 0; i < clothData.Textures.Count; i++) { byte texId = (byte)i; if (clothData.DrawableType == ClothNameResolver.DrawableTypes.Legs) { texId = 1; } else if (clothData.DrawableType == ClothNameResolver.DrawableTypes.Shoes) { texId = 0; } var texture = new MUnk_254518642 { TexId = texId }; item.TexData.Add(texture); } // Get or create linked anchor var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (aanchor == null) { aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo) { Anchor = anchor, PropsMap = { [item] = (byte)item.TexData.Count } }; ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor); } else { aanchor.PropsMap[item] = (byte)item.TexData.Count; } return(item); }
static void HandleGenPedDefsOptions(string[] args) { CommandLine.Parse <GenPedDefsOptions>(args, (opts, gOpts) => { var ymtRegex = new Regex("mp_(m|f)_freemode_01.*\\.ymt$"); var cYddRegex = new Regex("(head|berd|hair|uppr|lowr|hand|feet|teef|accs|task|decl|jbib)_(\\d\\d\\d)_u.ydd$"); var pYddRegex = new Regex("p_(head|ears|mouth|lhand|rhand|lwrist|rwrist|hip|lfoot|rfoot)_(\\d\\d\\d).ydd$"); var fileDlcLevels = new Dictionary <string, int>(); var overrides = new Dictionary <string, List <string> >(); if (opts.CreateMode) { if (opts.OutputDirectory == null) { Console.WriteLine("Please provide input directory with --output"); return; } if (!Directory.Exists(opts.OutputDirectory)) { Directory.CreateDirectory(opts.OutputDirectory); } Init(args); int maxDLCLevel = (Array.IndexOf(DLCList, opts.DLCLevel) == -1) ? DLCList.Length - 1 : Array.IndexOf(DLCList, opts.DLCLevel); var targets = opts.Targets?.ToList() ?? new List <string>(); var dlcpaths = new Dictionary <string, int>(); var dlcdirs = new Dictionary <string, int>(); var processed = new List <string>(); ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) => { string[] path = fullFileName.Split('\\'); string folder = path[path.Length - 2]; string fileName = path[path.Length - 1]; string name = fileName.Split('.').First(); string outPath; bool isOverride = false; var ymtMatch = ymtRegex.Match(fileName); var cYddMatch = cYddRegex.Match(fileName); var pYddMatch = pYddRegex.Match(fileName); int dlcLevel = GetDLCLevel(fullFileName); if (dlcLevel > maxDLCLevel) { return; } if (targets.Count > 0 && opts.Targets.Where(e => e == name || (e + "_p") == name || e == folder || (e + "_p") == folder).ToArray().Length == 0) { return; } // Found interesting entry if (ymtMatch.Success || cYddMatch.Success || pYddMatch.Success) { string pathPart; // Found definition file (.ymt) if (ymtMatch.Success) { if (!path[path.Length - 1].Contains("_freemode_01")) { return; } outPath = opts.OutputDirectory; pathPart = path[path.Length - 1]; if (!dlcpaths.ContainsKey(pathPart)) { dlcpaths[pathPart] = dlcLevel; isOverride = true; } else if (dlcLevel > dlcpaths[pathPart]) { dlcpaths[pathPart] = dlcLevel; isOverride = true; } } else // Found model file (component or prop) { if (!path[path.Length - 2].Contains("_freemode_01")) { return; } outPath = opts.OutputDirectory + "\\" + path[path.Length - 2]; pathPart = path[path.Length - 2] + "\\" + path[path.Length - 1]; string dir = path[path.Length - 2]; dlcLevel = GetDLCLevel(fullFileName); // Console.WriteLine(pathPart); if (!dlcpaths.ContainsKey(pathPart)) { dlcpaths[pathPart] = dlcLevel; Console.WriteLine(DLCList[dlcLevel] + " [" + dlcLevel + "] => " + pathPart); dlcdirs[dir] = dlcLevel; isOverride = true; } else if (dlcLevel > dlcdirs[dir]) { Console.WriteLine(DLCList[dlcLevel] + " [" + dlcLevel + "] => " + pathPart); dlcpaths[pathPart] = dlcLevel; dlcdirs[dir] = dlcLevel; isOverride = true; } } Directory.CreateDirectory(outPath); // If dlc level of this directory is superior to current matching one if (isOverride) { // Write higher level ymt if (ymtMatch.Success) { using (var ms = new MemoryStream()) { file.Export(ms); var rMeta = new ResourceFile_GTA5_pc <MetaFile>(); rMeta.Load(ms); string xml = MetaXml.GetXml(rMeta.ResourceData); File.WriteAllText(outPath + "\\" + fileName + ".xml", xml); } } else if (cYddMatch.Success) { foreach (var entry in ComponentFilePrefix) { Directory.CreateDirectory(outPath + "\\components\\" + entry.Value); } } else if (pYddMatch.Success) { foreach (var entry in AnchorFilePrefix) { Directory.CreateDirectory(outPath + "\\props\\" + entry.Value); } } if (cYddMatch.Success || pYddMatch.Success) { dynamic directoryInfos = new JObject(); string dlc = DLCList[dlcLevel]; directoryInfos["dlc"] = dlc; directoryInfos["path"] = Directory.GetParent(fullFileName); var jsonString = JsonConvert.SerializeObject(directoryInfos, new JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented }); File.WriteAllText(outPath + "\\directory.json", jsonString); } } } }); } else { if (opts.InputDirectory == null) { Console.WriteLine("Please provide input directory with --input"); return; } if (opts.OutputDirectory == null) { Console.WriteLine("Please provide input directory with --output"); return; } Init(args); int maxDLCLevel = (Array.IndexOf(DLCList, opts.DLCLevel) == -1) ? DLCList.Length - 1 : Array.IndexOf(DLCList, opts.DLCLevel); string[] files = Directory.GetFiles(opts.InputDirectory).Where(e => e.EndsWith("ymt.xml")).ToArray(); string[] dirs = Directory.GetDirectories(opts.InputDirectory); var addonDirs = new List <string>(); var ymts = new Dictionary <string, YmtPedDefinitionFile>(); var processedYmts = new Dictionary <string, Tuple < Dictionary <string, Tuple <string, int, int, int, string, string> >, Dictionary <string, int>, Dictionary <string, Tuple <string, int, int, int, string, string> >, Dictionary <string, int> > >(); for (int j = 0; j < files.Length; j++) { string targetMetaXml = files[j]; string targetName = targetMetaXml.Split('\\').Last().Replace(".ymt.xml", ""); string parentDirectoryPath = Directory.GetParent(targetMetaXml).FullName; string parentDirectoryName = parentDirectoryPath.Split('\\').Last(); // Parse .ymt.xml string xml = File.ReadAllText(targetMetaXml); var doc = new XmlDocument(); doc.LoadXml(xml); var meta = XmlMeta.GetMeta(doc); var ymt = new YmtPedDefinitionFile(); ymt.ResourceFile.ResourceData = meta; ymt.Parse(); ymts[targetName] = ymt; } if (opts.FiveMFormat) { Directory.CreateDirectory(opts.OutputDirectory + "\\stream"); File.Create(opts.OutputDirectory + "\\__resource.lua"); } else { Directory.CreateDirectory(opts.OutputDirectory + "\\x64\\models\\cdimages\\streamedpeds_mp.rpf"); Directory.CreateDirectory(opts.OutputDirectory + "\\x64\\models\\cdimages\\streamedpedprops.rpf"); string contentXml = @"<?xml version=""1.0"" encoding=""UTF-8""?> <CDataFileMgr__ContentsOfDataFileXml> <disabledFiles /> <includedXmlFiles /> <includedDataFiles /> <dataFiles> <Item> <filename>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpeds_mp.rpf</filename> <fileType>RPF_FILE</fileType> <overlay value=""true"" /> <disabled value=""true"" /> <persistent value=""true"" /> </Item> <Item> <filename>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpedprops.rpf</filename> <fileType>RPF_FILE</fileType> <overlay value=""true"" /> <disabled value=""true"" /> <persistent value=""true"" /> </Item> </dataFiles> <contentChangeSets> <Item> <changeSetName>gtauclothes_AUTOGEN</changeSetName> <filesToDisable /> <filesToEnable> <Item>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpeds_mp.rpf</Item> <Item>dlc_gtauclothes:/%PLATFORM%/models/cdimages/streamedpedprops.rpf</Item> </filesToEnable> <txdToLoad /> <txdToUnload /> <residentResources /> <unregisterResources /> </Item> </contentChangeSets> <patchFiles /> </CDataFileMgr__ContentsOfDataFileXml>"; string setup2Xml = @"<?xml version=""1.0"" encoding=""UTF-8""?> <SSetupData> <deviceName>dlc_gtauclothes</deviceName> <datFile>content.xml</datFile> <timeStamp>03/30/2018 17:26:39</timeStamp> <nameHash>gtauclothes</nameHash> <contentChangeSetGroups> <Item> <NameHash>GROUP_STARTUP</NameHash> <ContentChangeSets> <Item>gtauclothes_AUTOGEN</Item> </ContentChangeSets> </Item> </contentChangeSetGroups> </SSetupData>"; File.WriteAllText(opts.OutputDirectory + "\\content.xml", contentXml); File.WriteAllText(opts.OutputDirectory + "\\setup2.xml", setup2Xml); } foreach (var ymtEntry in ymts) { var targetName = ymtEntry.Key; var ymt = ymtEntry.Value; // Components var cCount = new Dictionary <Unk_884254308, int>(); var cYddMapping = new Dictionary <string, Tuple <string, int, int, int, string, string> >(); // sourceYddPath => prefix, origPos, pos, count, folder, yddFileName var cTextureCount = new Dictionary <string, int>(); // Props var pCount = new Dictionary <Unk_2834549053, int>(); var pYddMapping = new Dictionary <string, Tuple <string, int, int, int, string, string> >(); // sourceYddPath => prefix, origPos, pos, count, folder, yddFileName var pTextureCount = new Dictionary <string, int>(); // Set component base count Unk_884254308[] cValues = (Unk_884254308[])Enum.GetValues(typeof(Unk_884254308)); foreach (Unk_884254308 component in cValues) { if (component == Unk_884254308.PV_COMP_INVALID || component == Unk_884254308.PV_COMP_MAX) { continue; } cCount[component] = (ymt.Unk_376833625.Components[component] ?? new MUnk_3538495220()).Unk_1756136273.Count; } // Set prop base count Unk_2834549053[] pValues = (Unk_2834549053[])Enum.GetValues(typeof(Unk_2834549053)); foreach (Unk_2834549053 anchor in pValues) { if (anchor == Unk_2834549053.NUM_ANCHORS) { continue; } int max = (opts.ReservePropEntries > ymt.Unk_376833625.PropInfo.Props[anchor].Count) ? opts.ReservePropEntries : ymt.Unk_376833625.PropInfo.Props[anchor].Count; pCount[anchor] = (ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>()).Count; } foreach (var entry in ComponentFilePrefix) { Unk_884254308 component = entry.Key; string prefix = entry.Value; string targetDirectory = opts.InputDirectory + "\\" + targetName + "\\components\\" + prefix; if (Directory.Exists(targetDirectory)) { IEnumerable <string> addonFilesUnordered = Directory.GetFiles(targetDirectory).Where(e => e.EndsWith(".ydd")); int padLen = 0; if (addonFilesUnordered.Count() > 0) { padLen = addonFilesUnordered.Max(e => e.Length); } string[] addonFiles = addonFilesUnordered.OrderBy(e => e.PadLeft(padLen, '0')).ToArray(); var addons = new List <int>(); for (int k = 0; k < addonFiles.Length; k++) { addons.Add(k); } if (addons.Count > 0) { // Create addon component entries var def = ymt.Unk_376833625.Components[component] ?? new MUnk_3538495220(); for (int k = 0; k < addons.Count; k++) { int addonPos = def.Unk_1756136273.Count(); string textureDirectory = targetDirectory + "\\" + addons[k]; var addonTextures = new List <int>(); var item = new MUnk_1535046754(); IEnumerable <string> texturesUnordered = Directory.GetFiles(textureDirectory).Where(e => e.EndsWith(".ytd")); int padLen1 = 0; if (texturesUnordered.Count() > 0) { padLen1 = texturesUnordered.Max(e => e.Length); } string[] textures = texturesUnordered.OrderBy(e => e.PadLeft(padLen1, '0')).ToArray(); string yddFileName = prefix + "_" + addonPos.ToString().PadLeft(3, '0') + "_u.ydd"; cYddMapping[addonFiles[k]] = new Tuple <string, int, int, int, string, string>(prefix, addons[k], addonPos, addons.Count, targetDirectory, yddFileName); // Create addon texture entries for (int l = 0; l < textures.Length; l++) { addonTextures.Add(l); } cTextureCount[addonFiles[k]] = addonTextures.Count; for (int l = 0; l < addonTextures.Count; l++) { var texture = new MUnk_1036962405(); item.ATexData.Add(texture); // Create componentinfo var cInfo = new MCComponentInfo(); cInfo.Unk_2114993291 = 0; cInfo.Unk_3509540765 = (byte)component; cInfo.Unk_4196345791 = (byte)l; ymt.Unk_376833625.CompInfos.Add(cInfo); } if (File.Exists(addonFiles[k].Replace(".ydd", ".yld"))) { item.ClothData.Unk_2828247905 = 1; } def.Unk_1756136273.Add(item); cCount[component]++; } ymt.Unk_376833625.Components[component] = def; } } } foreach (var entry in AnchorFilePrefix) { Unk_2834549053 anchor = entry.Key; string prefix = entry.Value; string targetDirectory = opts.InputDirectory + "\\" + targetName + "_p" + "\\props\\" + prefix; if (Directory.Exists(targetDirectory)) { IEnumerable <string> addonFilesUnordered = Directory.GetFiles(targetDirectory).Where(e => e.EndsWith(".ydd")); int padLen = 0; if (addonFilesUnordered.Count() > 0) { padLen = addonFilesUnordered.Max(e => e.Length); } string[] addonFiles = addonFilesUnordered.OrderBy(e => e.PadLeft(padLen, '0')).ToArray(); var addons = new List <int>(); for (int k = 0; k < addonFiles.Length; k++) { addons.Add(k); } if (addons.Count > 0) { // Create addon prop entries var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>(); for (int k = 0; k < addons.Count; k++) { int addonPos = defs.Count(); string textureDirectory = targetDirectory + "\\" + addons[k]; var addonTextures = new List <int>(); var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo); IEnumerable <string> texturesUnordered = Directory.GetFiles(textureDirectory).Where(e => e.EndsWith(".ytd")); int padLen2 = 0; if (texturesUnordered.Count() > 0) { padLen2 = texturesUnordered.Max(e => e.Length); } string[] textures = texturesUnordered.OrderBy(e => e.PadLeft(padLen2, '0')).ToArray(); string yddFileName = "p_" + prefix + "_" + addonPos.ToString().PadLeft(3, '0') + ".ydd"; item.AnchorId = (byte)anchor; pYddMapping[addonFiles[k]] = new Tuple <string, int, int, int, string, string>(prefix, addons[k], addonPos, addons.Count, targetDirectory, yddFileName); // Create addon texture entries for (int l = 0; l < textures.Length; l++) { addonTextures.Add(l); } pTextureCount[addonFiles[k]] = addonTextures.Count; for (int l = 0; l < addonTextures.Count; l++) { var texture = new MUnk_254518642(); item.TexData.Add(texture); } // Get or create linked anchor var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (aanchor == null) { aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo); aanchor.PropsMap[item] = (byte)item.TexData.Count; ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor); } else { aanchor.PropsMap[item] = (byte)item.TexData.Count; } defs.Add(item); pCount[anchor]++; } ymt.Unk_376833625.PropInfo.Props[anchor] = defs; } } } // Create reserved component entries foreach (Unk_884254308 component in cValues) { if (component == Unk_884254308.PV_COMP_INVALID || component == Unk_884254308.PV_COMP_MAX) { continue; } int count = cCount[component]; int max = (opts.ReservePropEntries > count) ? opts.ReservePropEntries : count; var def = ymt.Unk_376833625.Components[component] ?? new MUnk_3538495220(); for (int i = count; i < max; i++) { var item = new MUnk_1535046754(); var texture = new MUnk_1036962405(); item.ATexData.Add(texture); // Create componentinfo var cInfo = new MCComponentInfo(); cInfo.Unk_2114993291 = 0; cInfo.Unk_3509540765 = (byte)component; cInfo.Unk_4196345791 = (byte)i; ymt.Unk_376833625.CompInfos.Add(cInfo); def.Unk_1756136273.Add(item); } if (def.Unk_1756136273.Count > 0) { ymt.Unk_376833625.Components[component] = def; } } // Create reserved prop entries foreach (Unk_2834549053 anchor in pValues) { if (anchor == Unk_2834549053.NUM_ANCHORS) { continue; } int count = pCount[anchor]; int max = (opts.ReservePropEntries > count) ? opts.ReservePropEntries : count; var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>(); for (int i = count; i < max; i++) { var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo); item.AnchorId = (byte)anchor; var texture = new MUnk_254518642(); item.TexData.Add(texture); var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (aanchor == null) { aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo); aanchor.Anchor = anchor; aanchor.PropsMap[item] = 1; ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor); } else { aanchor.PropsMap[item] = 1; } defs.Add(item); } if (defs.Count > 0) { ymt.Unk_376833625.PropInfo.Props[anchor] = defs; } } processedYmts[targetName] = new Tuple < Dictionary <string, Tuple <string, int, int, int, string, string> >, Dictionary <string, int>, Dictionary <string, Tuple <string, int, int, int, string, string> >, Dictionary <string, int> >(cYddMapping, cTextureCount, pYddMapping, pTextureCount); if (opts.FiveMFormat) { ymt.Save(opts.OutputDirectory + "\\stream\\" + targetName + ".ymt"); // var xml2 = MetaXml.GetXml(ymt.ResourceFile.ResourceData); // File.WriteAllText(opts.OutputDirectory + "\\stream\\" + targetMetaYmtFileName + ".xml", xml2); } else { ymt.Save(opts.OutputDirectory + "\\x64\\models\\cdimages\\streamedpeds_mp.rpf\\" + targetName + ".ymt"); } dynamic overrideInfos = new JObject(); overrideInfos["components"] = new JObject(); overrideInfos["props"] = new JObject(); foreach (Unk_884254308 component in cValues) { if (component == Unk_884254308.PV_COMP_INVALID || component == Unk_884254308.PV_COMP_MAX) { continue; } int count = ymt.Unk_376833625.Components[component]?.Unk_1756136273.Count ?? 0; int max = (opts.ReserveEntries > count) ? opts.ReserveEntries : count; overrideInfos["components"][ComponentFilePrefix[component]] = new JObject() { ["start"] = cCount[component], ["end"] = max }; } foreach (Unk_2834549053 anchor in pValues) { if (anchor == Unk_2834549053.NUM_ANCHORS) { continue; } int count = ymt.Unk_376833625.PropInfo.Props[anchor]?.Count ?? 0; int max = (opts.ReservePropEntries > count) ? opts.ReservePropEntries : count; overrideInfos["props"][AnchorFilePrefix[anchor]] = new JObject() { ["start"] = pCount[anchor], ["end"] = max }; } var jsonString = JsonConvert.SerializeObject(overrideInfos, new JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented }); File.WriteAllText(opts.OutputDirectory + "\\" + targetName + ".override.json", jsonString); } // Check which directories contains addon component / props for (int i = 0; i < dirs.Length; i++) { bool found = false; foreach (var entry in ComponentFilePrefix) { string prefix = entry.Value; if (Directory.Exists(dirs[i] + "\\components\\" + prefix) && Directory.GetFiles(dirs[i] + "\\components\\" + prefix).Where(e => e.EndsWith(".ydd")).Count() > 0) { found = true; break; } if (Directory.Exists(dirs[i] + "\\props\\" + prefix) && Directory.GetFiles(dirs[i] + "\\props\\" + prefix).Where(e => e.EndsWith(".ydd")).Count() > 0) { found = true; break; } if (found) { break; } } if (found) { addonDirs.Add(dirs[i]); } } for (int i = 0; i < addonDirs.Count; i++) { Console.WriteLine(addonDirs[i]); string directory = addonDirs[i]; string[] path = directory.Split('\\'); string name = path[path.Length - 1]; string ymtDirName = name; if (ymtDirName.EndsWith("_p")) { ymtDirName = ymtDirName.Substring(0, ymtDirName.Length - 2); } Tuple < Dictionary <string, Tuple <string, int, int, int, string, string> >, Dictionary <string, int>, Dictionary <string, Tuple <string, int, int, int, string, string> >, Dictionary <string, int> > processedYmtData = null; // Copy models / textures with resolved names to build directory if (processedYmts.TryGetValue(ymtDirName, out processedYmtData)) { foreach (var entry in processedYmtData.Item1) { if (opts.FiveMFormat) { GenPedDefs_CreateComponentFiles_FiveM(opts, ymtDirName, entry, processedYmtData.Item2[entry.Key]); } else { GenPedDefs_CreateComponentFiles(opts, ymtDirName, entry, processedYmtData.Item2[entry.Key]); } } foreach (var entry in processedYmtData.Item3) { if (opts.FiveMFormat) { GenPedDefs_CreatePropFiles_FiveM(opts, ymtDirName, entry, processedYmtData.Item4[entry.Key]); } else { GenPedDefs_CreatePropFiles(opts, ymtDirName, entry, processedYmtData.Item4[entry.Key]); } } } } } }); }
public static void BuildResourceFivem(string outputFolder, string collectionName) { List <string> resourceLUAMetas = new List <string>(); for (int sexNr = 0; sexNr < 2; ++sexNr) { //Male YMT generating YmtPedDefinitionFile ymt = new YmtPedDefinitionFile(); ymt.metaYmtName = prefixes[sexNr] + collectionName; ymt.Unk_376833625.DlcName = RageLib.Hash.Jenkins.Hash(prefixes[sexNr] + collectionName); MUnk_3538495220[] componentTextureBindings = { null, null, null, null, null, null, null, null, null, null, null, null }; int[] componentIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int[] propIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //ymt.Unk_376833625.Unk_1235281004 = 0; //ymt.Unk_376833625.Unk_4086467184 = 0; //ymt.Unk_376833625.Unk_911147899 = 0; //ymt.Unk_376833625.Unk_315291935 = 0; //ymt.Unk_376833625.Unk_2996560424 = ; bool isAnyClothAdded = false; bool isAnyPropAdded = false; foreach (ClothData cd in MainWindow.clothes) { if (cd.IsComponent()) { byte componentTypeID = cd.GetComponentTypeID(); if (cd.textures.Count > 0 && (int)cd.targetSex == sexNr) { YmtPedDefinitionFile targetYmt = ymt; if (componentTextureBindings[componentTypeID] == null) { componentTextureBindings[componentTypeID] = new MUnk_3538495220(); } MUnk_1535046754 textureDescription = new MUnk_1535046754(); byte nextPropMask = 17; switch (componentTypeID) { case 2: case 7: nextPropMask = 11; break; case 5: case 8: nextPropMask = 65; break; case 9: nextPropMask = 1; break; case 10: nextPropMask = 5; break; case 11: nextPropMask = 1; break; default: break; } textureDescription.PropMask = nextPropMask; textureDescription.Unk_2806194106 = (byte)(cd.fpModelPath != "" ? 1 : 0); byte texId = (byte)(cd.mainPath.EndsWith("_u.ydd") ? 0 : 1); string postfix = cd.mainPath.EndsWith("_u.ydd") ? "u" : "r"; string ytdPostfix = cd.mainPath.EndsWith("_u.ydd") ? "uni" : "whi"; foreach (string texPath in cd.textures) { MUnk_1036962405 texInfo = new MUnk_1036962405(); texInfo.Distribution = 255; texInfo.TexId = texId; textureDescription.ATexData.Add(texInfo); } textureDescription.ClothData.Unk_2828247905 = 0; componentTextureBindings[componentTypeID].Unk_1756136273.Add(textureDescription); byte componentTextureLocalId = (byte)(componentTextureBindings[componentTypeID].Unk_1756136273.Count - 1); MCComponentInfo componentInfo = new MCComponentInfo(); componentInfo.Unk_802196719 = 0; componentInfo.Unk_4233133352 = 0; componentInfo.Unk_128864925.b0 = (byte)(cd.componentFlags.unkFlag1 ? 1 : 0); componentInfo.Unk_128864925.b1 = (byte)(cd.componentFlags.unkFlag2 ? 1 : 0); componentInfo.Unk_128864925.b2 = (byte)(cd.componentFlags.unkFlag3 ? 1 : 0); componentInfo.Unk_128864925.b3 = (byte)(cd.componentFlags.unkFlag4 ? 1 : 0); componentInfo.Unk_128864925.b4 = (byte)(cd.componentFlags.isHighHeels ? 1 : 0); componentInfo.Flags = 0; componentInfo.Inclusions = 0; componentInfo.Exclusions = 0; componentInfo.Unk_1613922652 = 0; componentInfo.Unk_2114993291 = 0; componentInfo.Unk_3509540765 = componentTypeID; componentInfo.Unk_4196345791 = componentTextureLocalId; targetYmt.Unk_376833625.CompInfos.Add(componentInfo); if (!isAnyClothAdded) { isAnyClothAdded = true; Directory.CreateDirectory(outputFolder + "\\stream"); Directory.CreateDirectory(outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName); } int currentComponentIndex = componentIndexes[componentTypeID]++; string componentNumerics = currentComponentIndex.ToString().PadLeft(3, '0'); string prefix = cd.GetPrefix(); File.Copy(cd.mainPath, outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + "\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + "^" + prefix + "_" + componentNumerics + "_" + postfix + ".ydd", true); char offsetLetter = 'a'; for (int i = 0; i < cd.textures.Count; ++i) { File.Copy(cd.textures[i], outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + "\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + "^" + prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + "_" + ytdPostfix + ".ytd", true); } if (cd.fpModelPath != "") { File.Copy(cd.fpModelPath, outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + "\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + "^" + prefix + "_" + componentNumerics + "_" + postfix + "_1.ydd", true); } } } else { Unk_2834549053 anchor = (Unk_2834549053)cd.GetPedPropTypeID(); if (cd.textures.Count > 0 && (int)cd.targetSex == sexNr) { YmtPedDefinitionFile targetYmt = ymt; var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>(); var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo); item.AnchorId = (byte)anchor; for (int i = 0; i < cd.textures.Count; i++) { var texture = new MUnk_254518642(); texture.TexId = (byte)i; item.TexData.Add(texture); } // Get or create linked anchor var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (aanchor == null) { aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo) { Anchor = anchor }; aanchor.PropsMap[item] = (byte)item.TexData.Count; ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor); } else { aanchor.PropsMap[item] = (byte)item.TexData.Count; } defs.Add(item); if (!isAnyPropAdded) { isAnyPropAdded = true; Directory.CreateDirectory(outputFolder + "\\stream"); Directory.CreateDirectory(outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName); } int currentPropIndex = propIndexes[(byte)anchor]++; string componentNumerics = currentPropIndex.ToString().PadLeft(3, '0'); string prefix = cd.GetPrefix(); File.Copy(cd.mainPath, outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName + "\\" + prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName + "^" + prefix + "_" + componentNumerics + ".ydd", true); char offsetLetter = 'a'; for (int i = 0; i < cd.textures.Count; ++i) { File.Copy(cd.textures[i], outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName + "\\" + prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName + "^" + prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + ".ytd", true); } } } } if (isAnyClothAdded) { int arrIndex = 0; for (int i = 0; i < componentTextureBindings.Length; ++i) { if (componentTextureBindings[i] != null) { byte id = (byte)(arrIndex++); ymt.Unk_376833625.Unk_2996560424.SetByte(i, id); } ymt.Unk_376833625.Components[(Unk_884254308)i] = componentTextureBindings[i]; } } if (isAnyClothAdded || isAnyPropAdded) { ymt.Save(outputFolder + "\\stream\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + ".ymt"); File.WriteAllText(outputFolder + "\\" + prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + ".meta", GenerateShopMeta((Sex)sexNr, collectionName)); resourceLUAMetas.Add(prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + ".meta"); } } File.WriteAllText(outputFolder + "\\fxmanifest.lua", GenerateResourceLua(resourceLUAMetas)); MessageBox.Show("Resource built!"); }
public static void BuildResourceSingle(string outputFolder, string collectionName) { Utils.EnsureKeys(); using (RageArchiveWrapper7 rpf = RageArchiveWrapper7.Create(outputFolder + @"\dlc.rpf")) { rpf.archive_.Encryption = RageArchiveEncryption7.NG; var dir = rpf.Root.CreateDirectory(); dir.Name = "common"; var dataDir = dir.CreateDirectory(); dataDir.Name = "data"; dir = rpf.Root.CreateDirectory(); dir.Name = "x64"; dir = dir.CreateDirectory(); dir.Name = "models"; var cdimagesDir = dir.CreateDirectory(); cdimagesDir.Name = "cdimages"; RageArchiveWrapper7 currComponentRpf = null; IArchiveDirectory currComponentDir = null; RageArchiveWrapper7 currPropRpf = null; IArchiveDirectory currPropDir = null; bool hasMale = false; bool hasFemale = false; bool hasMaleProps = false; bool hasFemaleProps = false; for (int sexNr = 0; sexNr < 2; ++sexNr) { //Male YMT generating YmtPedDefinitionFile ymt = new YmtPedDefinitionFile(); ymt.metaYmtName = prefixes[sexNr] + collectionName; ymt.Unk_376833625.DlcName = RageLib.Hash.Jenkins.Hash(prefixes[sexNr] + collectionName); MUnk_3538495220[] componentTextureBindings = { null, null, null, null, null, null, null, null, null, null, null, null }; int[] componentIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int[] propIndexes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //ymt.Unk_376833625.Unk_1235281004 = 0; //ymt.Unk_376833625.Unk_4086467184 = 0; //ymt.Unk_376833625.Unk_911147899 = 0; //ymt.Unk_376833625.Unk_315291935 = 0; //ymt.Unk_376833625.Unk_2996560424 = ; bool isAnyClothAdded = false; bool isAnyPropAdded = false; foreach (ClothData cd in MainWindow.clothes) { if (cd.IsComponent()) { byte componentTypeID = cd.GetComponentTypeID(); if (cd.textures.Count > 0 && (int)cd.targetSex == sexNr) { YmtPedDefinitionFile targetYmt = ymt; if (componentTextureBindings[componentTypeID] == null) { componentTextureBindings[componentTypeID] = new MUnk_3538495220(); } MUnk_1535046754 textureDescription = new MUnk_1535046754(); byte nextPropMask = 17; switch (componentTypeID) { case 2: case 7: nextPropMask = 11; break; case 5: case 8: nextPropMask = 65; break; case 9: nextPropMask = 1; break; case 10: nextPropMask = 5; break; case 11: nextPropMask = 1; break; default: break; } textureDescription.PropMask = nextPropMask; textureDescription.Unk_2806194106 = (byte)(cd.fpModelPath != "" ? 1 : 0); byte texId = (byte)(cd.mainPath.EndsWith("_u.ydd") ? 0 : 1); string postfix = cd.mainPath.EndsWith("_u.ydd") ? "u" : "r"; string ytdPostfix = cd.mainPath.EndsWith("_u.ydd") ? "uni" : "whi"; foreach (string texPath in cd.textures) { MUnk_1036962405 texInfo = new MUnk_1036962405(); texInfo.Distribution = 255; texInfo.TexId = texId; textureDescription.ATexData.Add(texInfo); } textureDescription.ClothData.Unk_2828247905 = 0; componentTextureBindings[componentTypeID].Unk_1756136273.Add(textureDescription); byte componentTextureLocalId = (byte)(componentTextureBindings[componentTypeID].Unk_1756136273.Count - 1); MCComponentInfo componentInfo = new MCComponentInfo(); componentInfo.Unk_802196719 = 0; componentInfo.Unk_4233133352 = 0; componentInfo.Unk_128864925.b0 = (byte)(cd.componentFlags.unkFlag1 ? 1 : 0); componentInfo.Unk_128864925.b1 = (byte)(cd.componentFlags.unkFlag2 ? 1 : 0); componentInfo.Unk_128864925.b2 = (byte)(cd.componentFlags.unkFlag3 ? 1 : 0); componentInfo.Unk_128864925.b3 = (byte)(cd.componentFlags.unkFlag4 ? 1 : 0); componentInfo.Unk_128864925.b4 = (byte)(cd.componentFlags.isHighHeels ? 1 : 0); componentInfo.Flags = 0; componentInfo.Inclusions = 0; componentInfo.Exclusions = 0; componentInfo.Unk_1613922652 = 0; componentInfo.Unk_2114993291 = 0; componentInfo.Unk_3509540765 = componentTypeID; componentInfo.Unk_4196345791 = componentTextureLocalId; targetYmt.Unk_376833625.CompInfos.Add(componentInfo); if (!isAnyClothAdded) { isAnyClothAdded = true; var ms = new MemoryStream(); currComponentRpf = RageArchiveWrapper7.Create(ms, folderNames[sexNr].Replace("ped_", collectionName + "_") + ".rpf"); currComponentRpf.archive_.Encryption = RageArchiveEncryption7.NG; currComponentDir = currComponentRpf.Root.CreateDirectory(); currComponentDir.Name = prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName; } int currentComponentIndex = componentIndexes[componentTypeID]++; string componentNumerics = currentComponentIndex.ToString().PadLeft(3, '0'); string prefix = cd.GetPrefix(); var resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + "_" + postfix + ".ydd"; resource.Import(cd.mainPath); char offsetLetter = 'a'; for (int i = 0; i < cd.textures.Count; ++i) { resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + "_" + ytdPostfix + ".ytd"; resource.Import(cd.textures[i]); } if (cd.fpModelPath != "") { resource = currComponentDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + "_" + postfix + "_1.ydd"; resource.Import(cd.fpModelPath); } } } else { Unk_2834549053 anchor = (Unk_2834549053)cd.GetPedPropTypeID(); if (cd.textures.Count > 0 && (int)cd.targetSex == sexNr) { YmtPedDefinitionFile targetYmt = ymt; var defs = ymt.Unk_376833625.PropInfo.Props[anchor] ?? new List <MUnk_94549140>(); var item = new MUnk_94549140(ymt.Unk_376833625.PropInfo); item.AnchorId = (byte)anchor; for (int i = 0; i < cd.textures.Count; i++) { var texture = new MUnk_254518642(); texture.TexId = (byte)i; item.TexData.Add(texture); } // Get or create linked anchor var aanchor = ymt.Unk_376833625.PropInfo.AAnchors.Find(e => e.Anchor == anchor); if (aanchor == null) { aanchor = new MCAnchorProps(ymt.Unk_376833625.PropInfo) { Anchor = anchor }; aanchor.PropsMap[item] = (byte)item.TexData.Count; ymt.Unk_376833625.PropInfo.AAnchors.Add(aanchor); } else { aanchor.PropsMap[item] = (byte)item.TexData.Count; } defs.Add(item); if (!isAnyPropAdded) { isAnyPropAdded = true; var ms = new MemoryStream(); currPropRpf = RageArchiveWrapper7.Create(ms, folderNames[sexNr].Replace("ped_", collectionName + "_") + "_p.rpf"); currPropRpf.archive_.Encryption = RageArchiveEncryption7.NG; currPropDir = currPropRpf.Root.CreateDirectory(); currPropDir.Name = prefixes[sexNr] + "freemode_01_p_" + prefixes[sexNr] + collectionName; } int currentPropIndex = propIndexes[(byte)anchor]++; string componentNumerics = currentPropIndex.ToString().PadLeft(3, '0'); string prefix = cd.GetPrefix(); var resource = currPropDir.CreateResourceFile(); resource.Name = prefix + "_" + componentNumerics + ".ydd"; resource.Import(cd.mainPath); char offsetLetter = 'a'; for (int i = 0; i < cd.textures.Count; ++i) { resource = currPropDir.CreateResourceFile(); resource.Name = prefix + "_diff_" + componentNumerics + "_" + (char)(offsetLetter + i) + ".ytd"; resource.Import(cd.textures[i]); } } } } if (isAnyClothAdded) { if (sexNr == 0) { hasMale = true; } else if (sexNr == 1) { hasFemale = true; } int arrIndex = 0; for (int i = 0; i < componentTextureBindings.Length; ++i) { if (componentTextureBindings[i] != null) { byte id = (byte)(arrIndex++); ymt.Unk_376833625.Unk_2996560424.SetByte(i, id); } ymt.Unk_376833625.Components[(Unk_884254308)i] = componentTextureBindings[i]; } } if (isAnyClothAdded || isAnyPropAdded) { using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateShopMeta((Sex)sexNr, collectionName)))) { var binFile = dataDir.CreateBinaryFile(); binFile.Name = prefixes[sexNr] + "freemode_01_" + prefixes[sexNr] + collectionName + ".meta"; binFile.Import(stream); } currComponentRpf.Flush(); var binRpfFile = cdimagesDir.CreateBinaryFile(); binRpfFile.Name = folderNames[sexNr].Replace("ped_", collectionName + "_") + ".rpf"; binRpfFile.Import(currComponentRpf.archive_.BaseStream); currComponentRpf.Dispose(); } if (isAnyPropAdded) { if (sexNr == 0) { hasMaleProps = true; } else if (sexNr == 1) { hasFemaleProps = true; } currPropRpf.Flush(); var binRpfFile = cdimagesDir.CreateBinaryFile(); binRpfFile.Name = folderNames[sexNr].Replace("ped_", collectionName + "_") + "_p.rpf"; binRpfFile.Import(currPropRpf.archive_.BaseStream); currPropRpf.Dispose(); } } using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateContentXML(collectionName, hasMale, hasFemale, hasMaleProps, hasFemaleProps)))) { var binFile = rpf.Root.CreateBinaryFile(); binFile.Name = "content.xml"; binFile.Import(stream); } using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(GenerateSetup2XML(collectionName)))) { var binFile = rpf.Root.CreateBinaryFile(); binFile.Name = "setup2.xml"; binFile.Import(stream); } rpf.Flush(); rpf.Dispose(); MessageBox.Show("Resource built!"); } }