Exemple #1
0
        public static Dictionary <string, ProgressionUnlocks> GetUnlocks()
        {
            Dictionary <string, ProgressionUnlocks> @return = new Dictionary <string, ProgressionUnlocks>();

            foreach (ulong key in TrackedFiles[0x75])
            {
                STUHero hero = GetInstance <STUHero>(key);
                if (hero == null)
                {
                    continue;
                }

                string name = GetString(hero.m_0EDCE350);
                if (name == null)
                {
                    continue;
                }

                ProgressionUnlocks unlocks = new ProgressionUnlocks(hero);

                @return[name] = unlocks;
            }

            return(@return);
        }
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = Path.Combine(flags.OutputPath, Container);
            }
            else
            {
                throw new Exception("no output path");
            }

            // Do normal heroes first then NPCs, this is because NPCs have a lot of duplicate sounds and normal heroes (should) have none
            // so any duplicate sounds would only come up while processing NPCs which can be ignored as they (probably) belong to heroes
            var heroes = Program.TrackedFiles[0x75]
                         .Select(x => new Hero(x))
                         .OrderBy(x => !x.IsHero)
                         .ThenBy(x => x.GUID.GUID)
                         .ToArray();

            foreach (var hero in heroes)
            {
                var heroStu = GetInstance <STUHero>(hero.GUID);

                string heroName = GetValidFilename((GetString(heroStu.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(hero.GUID)}").TrimEnd(' '));
                Logger.Log($"Processing {heroName}");

                Combo.ComboInfo baseInfo         = default;
                var             heroVoiceSetGuid = GetInstance <STUVoiceSetComponent>(heroStu.m_gameplayEntity)?.m_voiceDefinition;

                if (SaveVoiceSet(flags, basePath, heroName, heroVoiceSetGuid, ref baseInfo))
                {
                    var skins = new ProgressionUnlocks(heroStu).GetUnlocksOfType(UnlockType.Skin);
                    foreach (var unlock in skins)
                    {
                        TACTLib.Logger.Debug("Tool", $"Processing skin {unlock.Name}");
                        if (!(unlock.STU is STUUnlock_SkinTheme unlockSkinTheme))
                        {
                            return;
                        }
                        if (unlockSkinTheme.m_0B1BA7C1 != 0)
                        {
                            continue;
                        }

                        Combo.ComboInfo info      = default;
                        var             skinTheme = GetInstance <STUSkinTheme>(unlockSkinTheme.m_skinTheme);
                        if (skinTheme == null)
                        {
                            continue;
                        }

                        SaveVoiceSet(flags, basePath, heroName, heroVoiceSetGuid, ref info, baseInfo, SkinTheme.GetReplacements(skinTheme));
                    }
                }
            }
        }
Exemple #3
0
        public static List <Replay> ParseReplay(string filePath)
        {
            Console.Out.WriteLine($"Processing file: {Path.GetFileName(filePath)}");
            List <Replay> replays = new List <Replay>();

            var buffer = (Memory <byte>)File.ReadAllBytes(filePath);

            if (buffer.Length == 0)
            {
                return(replays);
            }

            foreach (var(filename, b64Str) in ProcessAtoms(buffer))    // hash, payload, settinghash?
            {
                byte[] bytes = Convert.FromBase64String(b64Str[1]);
                // string hex = BitConverter.ToString(bytes);

                var replayInfo = new Mp4Replay();
                replayInfo.Parse(bytes);

                var heroStu   = STUHelper.GetInstance <STUHero>(replayInfo.Header.HeroGuid);
                var hero      = new Hero(heroStu);
                var unlocks   = new ProgressionUnlocks(heroStu);
                var skins     = unlocks.GetUnlocksOfType(UnlockType.Skin);
                var skinTheme = skins.FirstOrDefault(skin => ((STUUnlock_SkinTheme)skin.STU)?.m_skinTheme == replayInfo.Header.SkinGuid);

                ulong mapHeaderGuid = (replayInfo.Header.MapGuid & ~0xFFFFFFFF00000000ul) | 0x0790000000000000ul;
                var   mapData       = new MapHeader(mapHeaderGuid);

                var replay = new Replay {
                    Title         = filename,
                    Hero          = hero.Name,
                    Map           = mapData.Name,
                    Skin          = skinTheme?.Name ?? "Unknown",
                    RecordedAt    = $"{DateTimeOffset.FromUnixTimeSeconds(replayInfo.Header.Timestamp).ToLocalTime()}",
                    HighlightType = $"{replayInfo.Header.Type:G}",
                    Quality       = $"{replayInfo.Header.QualityPct}% ({(ReplayQuality)replayInfo.Header.QualityPct})",
                    FilePath      = filePath
                };

                replays.Add(replay);
            }
            return(replays);
        }
Exemple #4
0
        public void Parse(ICLIFlags toolFlags)
        {
            var allUnlocks = new Dictionary <teResourceGUID, UnlockAll>();

            foreach (var key in TrackedFiles[0xA5])
            {
                var guid = (teResourceGUID)key;
                if (!allUnlocks.ContainsKey(guid))
                {
                    var unlock = new UnlockAll(key);
                    if (unlock.GUID != 0)
                    {
                        allUnlocks[guid] = unlock;
                    }
                }
            }

            var heroes = TrackedFiles[0x75].Select(STUHelper.GetInstance <STUHero>);

            foreach (var stuHero in heroes)
            {
                var hero        = new Hero(stuHero);
                var progression = new ProgressionUnlocks(stuHero);
                foreach (var unlock in progression.IterateUnlocks())
                {
                    if (allUnlocks.ContainsKey(unlock.GUID))
                    {
                        allUnlocks[unlock.GUID].Hero = hero.Name;
                    }
                }
            }

            if (toolFlags is ListFlags flags)
            {
                OutputJSON(allUnlocks, flags);
            }
        }
Exemple #5
0
        public void SaveUnlocksForHeroes(ICLIFlags flags, IEnumerable <STUHero> heroes, string basePath, bool npc = false)
        {
            if (flags.Positionals.Length < 4)
            {
                QueryHelp(QueryTypes);
                return;
            }

            Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes = ParseQuery(flags, QueryTypes, QueryNameOverrides);

            if (parsedTypes == null)
            {
                return;
            }

            foreach (STUHero hero in heroes)
            {
                if (hero == null)
                {
                    continue;
                }
                string heroNameActual = GetString(hero.m_0EDCE350);

                if (heroNameActual == null)
                {
                    continue;
                }

                Dictionary <string, ParsedArg> config = GetQuery(parsedTypes, heroNameActual.ToLowerInvariant(), "*");

                heroNameActual = heroNameActual.TrimEnd(' ');
                string heroFileName = GetValidFilename(heroNameActual);

                if (config.Count == 0)
                {
                    continue;
                }

                string heroPath = Path.Combine(basePath, RootDir, heroFileName);

                VoiceSet           voiceSet           = new VoiceSet(hero);
                ProgressionUnlocks progressionUnlocks = new ProgressionUnlocks(hero);
                if (progressionUnlocks.LevelUnlocks == null && !npc)
                {
                    continue;
                }
                if (progressionUnlocks.LootBoxesUnlocks != null && npc)
                {
                    continue;
                }

                Log($"Processing unlocks for {heroNameActual}");

                {
                    Combo.ComboInfo guiInfo = new Combo.ComboInfo();

                    foreach (STU_1A496D3C tex in hero.m_8203BFE1)
                    {
                        Combo.Find(guiInfo, tex.m_texture);
                        guiInfo.SetTextureName(tex.m_texture, teResourceGUID.AsString(tex.m_id));
                    }

                    SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(heroPath, "GUI"), guiInfo);
                }

                if (progressionUnlocks.OtherUnlocks != null)   // achievements and stuff
                {
                    Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> {
                        { "event", new TagExpectedValue("base") }
                    };
                    SaveUnlocks(flags, progressionUnlocks.OtherUnlocks, heroPath, "Achievement", config, tags, voiceSet, hero);
                }

                if (npc)
                {
                    foreach (var skin in hero.m_skinThemes)
                    {
                        if (!config.ContainsKey("skin") || !config["skin"].ShouldDo(GetFileName(skin.m_5E9665E3)))
                        {
                            continue;
                        }
                        SkinTheme.Save(flags, Path.Combine(heroPath, Unlock.GetTypeName(typeof(STUUnlock_SkinTheme)),
                                                           string.Empty, GetFileName(skin.m_5E9665E3)), skin, hero);
                    }
                    continue;
                }

                if (progressionUnlocks.LevelUnlocks != null)   // default unlocks
                {
                    Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> {
                        { "event", new TagExpectedValue("base") }
                    };
                    foreach (LevelUnlocks levelUnlocks in progressionUnlocks.LevelUnlocks)
                    {
                        SaveUnlocks(flags, levelUnlocks.Unlocks, heroPath, "Default", config, tags, voiceSet, hero);
                    }
                }

                if (progressionUnlocks.LootBoxesUnlocks != null)
                {
                    foreach (LootBoxUnlocks lootBoxUnlocks in progressionUnlocks.LootBoxesUnlocks)
                    {
                        if (lootBoxUnlocks.Unlocks == null)
                        {
                            continue;
                        }
                        string lootboxName = LootBox.GetName(lootBoxUnlocks.LootBoxType);

                        var tags = new Dictionary <string, TagExpectedValue> {
                            { "event", new TagExpectedValue(LootBox.GetBasicName(lootBoxUnlocks.LootBoxType)) }
                        };

                        SaveUnlocks(flags, lootBoxUnlocks.Unlocks, heroPath, lootboxName, config, tags, voiceSet, hero);
                    }
                }
            }
        }
Exemple #6
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is BetterVoiceFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            foreach (var key in Program.TrackedFiles[0x75])
            {
                var hero        = GetInstance <STUHero>(key);
                var progression = new ProgressionUnlocks(hero);
                if (progression.LootBoxesUnlocks == null)
                {
                    continue;                                       // no NPCs thanks
                }
                string heroNameActual    = GetValidFilename((GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(key)}").TrimEnd(' '));
                var    voiceSetComponent = GetInstance <STUVoiceSetComponent>(hero.m_gameplayEntity);
                if (voiceSetComponent?.m_voiceDefinition == null)
                {
                    continue;
                }

                var voiceSetsCombo = new Combo.ComboInfo();
                Combo.Find(voiceSetsCombo, voiceSetComponent.m_voiceDefinition);

                foreach (var voiceSet in voiceSetsCombo.VoiceSets)
                {
                    if (voiceSet.Value.VoiceLineInstances == null)
                    {
                        continue;
                    }

                    foreach (var voicelineInstanceInfo in voiceSet.Value.VoiceLineInstances)
                    {
                        foreach (var voiceLineInstance in voicelineInstanceInfo.Value)
                        {
                            var soundFilesCombo = new Combo.ComboInfo();;
                            var stimulus        = GetInstance <STUVoiceStimulus>(voiceLineInstance.VoiceStimulus);

                            if (stimulus == null)
                            {
                                continue;
                            }

                            var groupName = GetVoiceGroup(voiceLineInstance.VoiceStimulus, stimulus.m_category, stimulus.m_87DCD58E) ?? "Unknown";

                            foreach (var soundFile in voiceLineInstance.SoundFiles)
                            {
                                Combo.Find(soundFilesCombo, soundFile);
                            }

                            var path = flags.GroupByHero && flags.GroupByType
                                ? Path.Combine(basePath, Container, heroNameActual, groupName)
                                : Path.Combine(basePath, Container, flags.GroupByHero ? Path.Combine(groupName, heroNameActual) : groupName);

                            foreach (var soundInfo in soundFilesCombo.VoiceSoundFiles.Values)
                            {
                                var filename = soundInfo.GetName();
                                if (!flags.GroupByHero)
                                {
                                    filename = $"{heroNameActual}-{soundInfo.GetName()}";
                                }

                                SaveLogic.Combo.SaveSoundFile(flags, path, soundFilesCombo, soundInfo.GUID, true, filename);
                            }
                        }
                    }
                }
            }
        }
Exemple #7
0
        public void SaveHeroSounds(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            if (flags.Positionals.Length < 4)
            {
                QueryHelp(QueryTypes);
                return;
            }

            Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes = ParseQuery(flags, QueryTypes, QueryNameOverrides);

            if (parsedTypes == null)
            {
                return;
            }

            foreach (ulong heroFile in TrackedFiles[0x75])
            {
                STUHero hero = GetInstance <STUHero>(heroFile);
                if (hero == null)
                {
                    continue;
                }

                string heroNameActual = (GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(heroFile)}").TrimEnd(' ');


                Dictionary <string, ParsedArg> config = GetQuery(parsedTypes, heroNameActual.ToLowerInvariant(), "*");

                if (config.Count == 0)
                {
                    continue;
                }

                Log($"Processing data for {heroNameActual}");

                STUVoiceSetComponent baseComponent = default;
                Combo.ComboInfo      baseInfo      = default;

                string heroFileName = GetValidFilename(heroNameActual);

                if (SaveSet(flags, basePath, hero.m_gameplayEntity, heroFileName, "Default", ref baseComponent, ref baseInfo))
                {
                    if (hero.m_heroProgression == 0)
                    {
                        continue;
                    }
                    var progression = new ProgressionUnlocks(hero);

                    bool npc = progression.LootBoxesUnlocks == null;

                    foreach (Unlock itemInfo in progression.OtherUnlocks)
                    {
                        ProcessUnlock(itemInfo, flags, basePath, heroFileName, hero, baseComponent, baseInfo);
                    }

                    if (npc)
                    {
                        foreach (var skin in hero.m_skinThemes)
                        {
                            SaveSkin(flags, skin.m_5E9665E3, basePath, hero, heroFileName, GetFileName(skin.m_5E9665E3), baseComponent, baseInfo);
                        }
                        continue;
                    }

                    foreach (var defaultUnlocks in progression.LevelUnlocks)
                    {
                        foreach (Unlock unlock in defaultUnlocks.Unlocks)
                        {
                            ProcessUnlock(unlock, flags, basePath, heroFileName, hero, baseComponent, baseInfo);
                        }
                    }

                    foreach (var eventUnlocks in progression.LootBoxesUnlocks)
                    {
                        if (eventUnlocks?.Unlocks == null)
                        {
                            continue;
                        }

                        foreach (Unlock unlock in eventUnlocks.Unlocks)
                        {
                            ProcessUnlock(unlock, flags, basePath, heroFileName, hero, baseComponent, baseInfo);
                        }
                    }
                }
            }
        }
Exemple #8
0
        private static void ProcessHeroNames(DynamicChoicesContainer container)
        {
            var heroContainer = container.GetType(VALID_HERO_NAMES);
            var npcContainer  = container.GetType(VALID_NPC_NAMES);
            var owlTeams      = container.GetType(VALID_OWL_TEAMS);

            HashSet <string> handledTeams = new HashSet <string>();

            Dictionary <ulong, STUHero> heroes          = new Dictionary <ulong, STUHero>();
            Dictionary <string, int>    nameOccurrances = new Dictionary <string, int>();

            foreach (ulong heroGUID in Program.TrackedFiles[0x75])
            {
                var hero = STUHelper.GetInstance <STUHero>(heroGUID);
                if (hero == null)
                {
                    continue;
                }

                string heroNameActual = Hero.GetCleanName(hero);
                if (heroNameActual == null)
                {
                    continue;
                }

                heroes[heroGUID] = hero;
                if (nameOccurrances.TryGetValue(heroNameActual, out _))
                {
                    nameOccurrances[heroNameActual]++;
                }
                else
                {
                    nameOccurrances[heroNameActual] = 0;
                }
            }

            foreach (ulong heroGUID in Program.TrackedFiles[0x75])
            {
                if (!heroes.TryGetValue(heroGUID, out var hero))
                {
                    continue;
                }
                string heroNameActual = Hero.GetCleanName(hero);

                var doGuidName = nameOccurrances[heroNameActual] > 1;
                if (doGuidName)
                {
                    heroNameActual += $" ({teResourceGUID.Index(heroGUID):X})";
                }

                ProgressionUnlocks progressionUnlocks = new ProgressionUnlocks(hero);

                var choice = new DynamicChoice {
                    DisplayName = heroNameActual,
                    QueryName   = $"{teResourceGUID.Index(heroGUID):X}"
                };

                if (progressionUnlocks.LevelUnlocks == null)
                {
                    npcContainer.Choices.Add(choice);
                }
                else
                {
                    heroContainer.Choices.Add(choice);
                }

                foreach (var unlock in progressionUnlocks.IterateUnlocks())
                {
                    if (string.IsNullOrWhiteSpace(unlock.Name))
                    {
                        continue;
                    }

                    if (unlock.STU.m_0B1BA7C1 != null)
                    {
                        TeamDefinition teamDef = new TeamDefinition(unlock.STU.m_0B1BA7C1);
                        if (!(teamDef.Division == Enum_5A789F71.None && teamDef.Location == null))
                        {
                            if (handledTeams.Add(teamDef.FullName))
                            {
                                owlTeams.Choices.Add(new DynamicChoice {
                                    DisplayName = teamDef.FullName,
                                    QueryName   = teamDef.FullName
                                });
                            }
                            continue;
                        }
                    }

                    var key = "datatool.ux.valid_" + Unlock.GetTypeName(unlock.STU.GetType()).ToLowerInvariant() + "_names";

                    if (choice.Children == null)
                    {
                        choice.Children = new DynamicChoicesContainer();
                    }

                    var test = choice.Children.GetType(key);
                    test.Choices.Add(new DynamicChoice {
                        QueryName   = unlock.Name,
                        DisplayName = unlock.Name
                    });
                }
            }
        }
Exemple #9
0
        public static Task <Control> Get(ProgressWorker a1, SynchronizationContext context, Window window, bool npc)
        {
            var source = new TaskCompletionSource <Control>();

            context.Send(obj => {
                var control = new ImageGridView();
                var t       = new Thread(() => {
                    if (!(obj is Tuple <ProgressWorker, TaskCompletionSource <Control> > tuple))
                    {
                        return;
                    }
                    var worker = tuple.Item1;
                    var tcs    = tuple.Item2;
                    try {
                        var i = 0;
                        worker.ReportProgress(0, "Loading heroes...");
                        if (TrackedFiles == null || !TrackedFiles.ContainsKey(0x75))
                        {
                            throw new DataToolWpfException("Open storage first");
                        }

                        var max = TrackedFiles[0x75].Count;

                        foreach (var key in TrackedFiles[0x75])
                        {
                            try {
                                var hero = GetInstance <STUHero>(key);
                                if (hero == null)
                                {
                                    continue;
                                }
                                string heroNameActual = GetString(hero.m_0EDCE350) ?? teResourceGUID.Index(key).ToString("X");

                                heroNameActual = heroNameActual.TrimEnd(' ');

                                ProgressionUnlocks progressionUnlocks = new ProgressionUnlocks(hero);
                                if (progressionUnlocks.LevelUnlocks == null && !npc)
                                {
                                    continue;
                                }
                                if (progressionUnlocks.LootBoxesUnlocks != null && npc)
                                {
                                    continue;
                                }

                                var tex = hero.m_8203BFE1.FirstOrDefault(x => teResourceGUID.Index(x.m_id) == 0x40C9 || teResourceGUID.Index(x.m_id) == 0x40CA)?.m_texture;

                                if (tex == 0)
                                {
                                    tex = hero.m_8203BFE1.FirstOrDefault()?.m_texture;
                                }

                                var image = new byte[] { };

                                var width  = 128;
                                var height = 128;

                                if (tex != 0)
                                {
                                    teTexture texture = new teTexture(OpenFile(tex));
                                    if (texture.PayloadRequired)
                                    {
                                        ulong payload        = texture.GetPayloadGUID(tex);
                                        Stream payloadStream = OpenFile(payload);
                                        if (payloadStream != null)
                                        {
                                            texture.LoadPayload(payloadStream);
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }

                                    width  = texture.Header.Width;
                                    height = texture.Header.Height;

                                    Stream ms = texture.SaveToDDS();

                                    image = DDSConverter.ConvertDDS(ms, DXGI_FORMAT.R8G8B8A8_UNORM, DDSConverter.ImageFormat.PNG, 0);
                                }

                                var entry      = control.Add(heroNameActual, image, 128, (int)ImagingHelper.CalculateSizeAS(height, width, 128));
                                entry.Payload  = progressionUnlocks;
                                entry.OnClick += (sender, args) => {
                                    window.Close();
                                };
                            } catch {
                                // ignored
                            } finally {
                                i += 1;
                                worker.ReportProgress((int)(i / (float)max * 100));
                            }
                        }

                        tcs.SetResult(control);
                    } catch (Exception e) {
                        tcs.SetException(e);
                    } finally {
                        worker.ReportProgress(100);
                    }
                });
                t.SetApartmentState(ApartmentState.STA);
                t.Start();
            }, new Tuple <ProgressWorker, TaskCompletionSource <Control> >(a1, source));
            return(source.Task);
        }
 // Update is called once per frame
 void Start()
 {
     pu     = this;
     pc     = PlayerController.pc;
     picked = false;
 }
Exemple #11
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            foreach (var key in Program.TrackedFiles[0x75])
            {
                var hero        = GetInstance <STUHero>(key);
                var progression = new ProgressionUnlocks(hero);
                if (progression.LootBoxesUnlocks == null)
                {
                    continue;                                       // no NPCs thanks
                }
                string heroNameActual    = GetValidFilename((GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(key)}").TrimEnd(' '));
                var    voiceSetComponent = GetInstance <STUVoiceSetComponent>(hero.m_gameplayEntity);
                if (voiceSetComponent?.m_voiceDefinition == null)
                {
                    continue;
                }

                var voiceSetsCombo = new Combo.ComboInfo();
                Combo.Find(voiceSetsCombo, voiceSetComponent.m_voiceDefinition);

                foreach (var voiceSet in voiceSetsCombo.VoiceSets)
                {
                    if (voiceSet.Value.VoiceLineInstances == null)
                    {
                        continue;
                    }

                    foreach (var voicelineInstanceInfo in voiceSet.Value.VoiceLineInstances)
                    {
                        foreach (var voiceLineInstance in voicelineInstanceInfo.Value)
                        {
                            var soundFilesCombo = new Combo.ComboInfo();;
                            var stimulus        = GetInstance <STUVoiceStimulus>(voiceLineInstance.VoiceStimulus);

                            if (stimulus == null)
                            {
                                continue;
                            }

                            var stimulusId         = teResourceGUID.AsString(voiceLineInstance.VoiceStimulus);
                            var stimulusCategoryId = teResourceGUID.AsString(stimulus.m_category);
                            var stimulusUnknownId  = teResourceGUID.AsString(stimulus.m_87DCD58E);

                            // Some voices can be classified in multiple groups but we can only have one, we use use the Stimulus name first, then the unknown and finally the category
                            var stimMatches    = VoiceGroups.FirstOrDefault(x => x.StimulusSetIds.Contains(stimulusId));
                            var stimCatMatches = VoiceGroups.FirstOrDefault(x => x.StimulusCategoryIds.Contains(stimulusCategoryId));
                            var stimUnkMatches = VoiceGroups.FirstOrDefault(x => x.StimulusUnknownIds.Contains(stimulusUnknownId));

                            if (stimMatches == null && stimCatMatches == null && stimUnkMatches == null)
                            {
                                continue;
                            }

                            var groupName = stimMatches?.Name ?? stimUnkMatches?.Name ?? stimCatMatches?.Name;

                            foreach (var soundFile in voiceLineInstance.SoundFiles)
                            {
                                Combo.Find(soundFilesCombo, soundFile);
                            }

                            SaveLogic.Combo.SaveAllVoiceSoundFiles(toolFlags, Path.Combine(basePath, Container, groupName, heroNameActual), soundFilesCombo);
                        }
                    }
                }
            }
        }