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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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]);
                                }
                            }
                        }
                    }
                }
            });
        }
Esempio n. 5
0
        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!");
        }
Esempio n. 6
0
        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!");
            }
        }