public Dictionary <string, HeroInfo> GetHeroes() { Dictionary <string, HeroInfo> @return = new Dictionary <string, HeroInfo>(); foreach (ulong key in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(key); if (hero == null) { continue; } string name = GetString(hero.Name) ?? $"Unknown{GUID.Index(key):X}"; string description = GetDescriptionString(hero.Description); string color = null; if (hero.GalleryColor != null) { color = hero.GalleryColor.Hex(); } @return[name] = new HeroInfo(key, name, description, color, GetAbilities(hero)); } return(@return); }
private static IDictionary <ulong, string> GetHeroItemMapping() { Log("Generating hero to item mapping"); Dictionary <ulong, string> @return = new Dictionary <ulong, string>(); foreach (var key in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(key); if (hero?.LootboxUnlocks == null) { continue; } string heroName = GetString(hero.Name); Dictionary <string, HashSet <ItemInfo> > unlocks = ListHeroUnlocks.GetUnlocksForHero(hero.LootboxUnlocks); foreach (KeyValuePair <string, HashSet <ItemInfo> > unlockPair in unlocks) { if (unlockPair.Value?.Count == 0 || unlockPair.Value == null) { continue; } foreach (ItemInfo unlock in unlockPair.Value) { @return[unlock.GUID] = heroName; } } } return(@return); }
public Hero(STUHero hero) { Name = GetString(hero.m_0EDCE350); Description = GetDescriptionString(hero.m_3446F580); Gender = hero.m_gender; Size = hero.m_heroSize; GalleryColor = hero.m_heroColor; //if (hero.m_skinThemes != null) { // SkinThemes = new List<HeroSkinTheme>(); // foreach (STU_63172E83 skinTheme in hero.m_skinThemes) { // SkinThemes.Add(new HeroSkinTheme(skinTheme)); // } //} if (hero.m_heroLoadout != null) { Loadouts = new List <Loadout>(); foreach (teResourceGUID loadout in hero.m_heroLoadout) { STULoadout stuLoadout = GetInstance <STULoadout>(loadout); if (stuLoadout == null) { continue; } Loadouts.Add(new Loadout(stuLoadout)); } } }
public static void Save(ICLIFlags flags, string path, STUHero hero, STUHeroSkin skin, bool quiet = true) { STUSkinOverride skinOverride = GetInstance <STUSkinOverride>(skin.SkinOverride); LoudLog($"Extracting skin {GetString(hero.Name)} {GetFileName(skin.SkinOverride)}"); Save(flags, GetFileName(skin.SkinOverride), path, hero, "", skinOverride, null, null, quiet); }
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 GetSoundbanks() { foreach (ulong key in Program.TrackedFiles[0x54]) { STUGenericSettings_HeroSettings settings = GetInstance <STUGenericSettings_HeroSettings>(key); if (settings == null) { continue; } Dictionary <ulong, string> categories = new Dictionary <ulong, string>(); foreach (STUHeroSettingCategory category in settings.m_categories) { categories[category.m_identifier] = GetString(category.m_name); } foreach (STUHeroSpecificSettings heroSpecificSettings in settings.m_heroSpecificSettings) { STUHero hero = GetInstance <STUHero>(heroSpecificSettings.m_hero); Console.Out.WriteLine($"{GetString(hero.m_0EDCE350)}:"); PrintSettings(settings.m_142A3CA9.Concat(heroSpecificSettings.m_settings).ToArray(), categories); } } }
public static Dictionary <string, Dictionary <string, HashSet <ItemInfo> > > GetUnlocks() { Dictionary <string, Dictionary <string, HashSet <ItemInfo> > > @return = new Dictionary <string, Dictionary <string, HashSet <ItemInfo> > >(); foreach (ulong key in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(key); if (hero == null) { continue; } string name = GetString(hero.Name); if (name == null) { continue; } Dictionary <string, HashSet <ItemInfo> > unlocks = GetUnlocksForHero(hero.LootboxUnlocks); if (unlocks == null) { continue; } @return[name] = unlocks; } return(@return); }
public Dictionary <string, AbilityInfo> GetAbilities(STUHero hero) { Dictionary <string, AbilityInfo> @return = new Dictionary <string, AbilityInfo>(); if (hero.Abilities == null) { return(null); } foreach (Common.STUGUID ability in hero.Abilities) { AbilityInfo abi = GetAbility(ability); if (abi == null) { continue; } if (abi == null) { continue; } string name = abi.Name == null ? $"Unknown{GUID.Index(ability):X}" : $"{abi.Name}:{GUID.Index(ability):X}"; @return[name] = abi; } return(@return); }
private void Init(STUHero hero, ulong key = default) { GUID = (teResourceGUID)key; Name = GetString(hero.m_0EDCE350); Description = GetDescriptionString(hero.m_3446F580); Gender = hero.m_gender; Size = hero.m_heroSize; GalleryColor = hero.m_heroColor; //if (hero.m_skinThemes != null) { // SkinThemes = new List<HeroSkinTheme>(); // foreach (STU_63172E83 skinTheme in hero.m_skinThemes) { // SkinThemes.Add(new HeroSkinTheme(skinTheme)); // } //} if (hero.m_heroLoadout != null) { Loadouts = new List <Loadout>(); foreach (teResourceGUID loadoutGUID in hero.m_heroLoadout) { var loadout = Loadout.GetLoadout(loadoutGUID); if (loadout == null) { continue; } Loadouts.Add(loadout); } } }
public void GetHeroes(ICLIFlags toolFlags) { string basePath; if (toolFlags is ExtractFlags flags) { basePath = flags.OutputPath; } else { throw new Exception("no output path"); } foreach (ulong key in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(key); if (hero == null) { continue; } Dictionary <string, HashSet <ItemInfo> > unlocks = ListHeroUnlocks.GetUnlocksForHero(hero.LootboxUnlocks); if (unlocks == null) { continue; } List <ItemInfo> skins = unlocks.SelectMany(x => x.Value.Where(y => y.Type == "Skin")).ToList(); List <ItemInfo> weaponSkins = unlocks.SelectMany(x => x.Value.Where(y => y.Type == "Weapon")).ToList(); foreach (ItemInfo skin in skins) { Skin.Save(flags, $"{basePath}\\HeroSkinDebug", hero, skin.Rarity, skin.Unlock as STUUnlock_Skin, weaponSkins, null, false); } } }
public void ExtractHeroes(ICLIFlags toolFlags) { string basePath; if (toolFlags is ExtractFlags flags) { basePath = flags.OutputPath; } else { throw new Exception("no output path"); } const string container = "DebugCombo"; foreach (ulong key in TrackedFiles[0x75]) { // if (GUID.Index(key) != 0xDEADBEEF) continue; STUHero hero = GetInstance <STUHero>(key); string heroName = GetString(hero.Name); if (heroName != "Tracer") { continue; } Stopwatch stopwatch = Stopwatch.StartNew(); Combo.ComboInfo info = new Combo.ComboInfo(); Combo.Find(info, hero.EntityHeroSelect); Combo.Find(info, hero.EntityHighlightIntro); Combo.Find(info, hero.EntityMain); Combo.Find(info, hero.EntityPlayable); Combo.Find(info, hero.EntityThirdPerson); info.SetEntityName(hero.EntityHeroSelect, $"{heroName}-HeroSelect"); info.SetEntityName(hero.EntityHighlightIntro, $"{heroName}-HighlightIntro"); info.SetEntityName(hero.EntityMain, $"{heroName}-Main"); info.SetEntityName(hero.EntityPlayable, $"{heroName}-Playable"); info.SetEntityName(hero.EntityThirdPerson, $"{heroName}-Thirdperson"); stopwatch.Stop(); long newTime = stopwatch.ElapsedMilliseconds; SaveLogic.Combo.Save(flags, Path.Combine(basePath, heroName), info); // stopwatch.Reset(); // stopwatch.Start(); // // HashSet<ModelInfo> models = new HashSet<ModelInfo>(); // Model.FindModels(models, hero.EntityHeroSelect); // Model.FindModels(models, hero.EntityHighlightIntro); // Model.FindModels(models, hero.EntityMain); // Model.FindModels(models, hero.EntityPlayable); // Model.FindModels(models, hero.EntityThirdPerson); // stopwatch.Stop(); // long oldTime = stopwatch.ElapsedMilliseconds; } }
public Hero(ulong key) { STUHero stu = GetInstance <STUHero>(key); if (stu == null) { return; } Init(stu, key); }
public static void Save(ICLIFlags flags, string path, STUHero hero, string rarity, STUUnlock_Skin skin, List <ItemInfo> weaponSkins, List <STULoadout> abilities, bool quiet = true) { if (skin == null) { return; } LoudLog($"Extracting skin {GetString(hero.Name)} {GetString(skin.CosmeticName)}"); if (weaponSkins == null) { weaponSkins = new List <ItemInfo>(); } STUSkinOverride skinOverride = GetInstance <STUSkinOverride>(skin.SkinResource); Save(flags, GetString(skin.CosmeticName).TrimEnd(' '), path, hero, rarity, skinOverride, weaponSkins, abilities, quiet); }
public Dictionary <teResourceGUID, Hero> GetHeroes() { Dictionary <teResourceGUID, Hero> @return = new Dictionary <teResourceGUID, Hero>(); foreach (teResourceGUID key in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(key); if (hero == null) { continue; } @return[key] = new Hero(hero); } return(@return); }
public VoiceSet(STUHero hero) { STUVoiceSetComponent voiceSetComponent = GetInstance <STUVoiceSetComponent>(hero.m_gameplayEntity); if (voiceSetComponent?.m_voiceDefinition == null) { Debugger.Log(0, "DataTool.DataModels.VoiceSet", "Hero VoiceSet not found"); return; } STUVoiceSet set = GetInstance <STUVoiceSet>(voiceSetComponent.m_voiceDefinition); if (set == null) { return; } Init(set); }
public void ListAnimBlendTrees() { List <ulong> blendTreeSets = new List <ulong>(); // this is posthash foreach (ulong heroKey in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(heroKey); if (GetString(hero?.Name) != "Tracer") { continue; } foreach (Common.STUGUID heroEntity in new [] { hero.EntityHeroSelect, hero.EntityHighlightIntro, hero.EntityMain, hero.EntityPlayable, hero.EntityThirdPerson }) { STUModelComponent modelComponent = GetInstance <STUModelComponent>(heroEntity); if (modelComponent?.AnimBlendTreeSet == null) { continue; } blendTreeSets.Add(modelComponent.AnimBlendTreeSet); } } // add breakpoint and copy from posthash thing (yes I'm sorry) // blendTreeSets = new List<ulong> { // 18014398509483732, 18014398509483760, 18014398509483769, 18014398509483562, 18014398509483771 // orisa // }; blendTreeSets = new List <ulong> { 18014398509482072, 18014398509483458, 18014398509483479, 18014398509481986, 18014398509483575 // tracer }; // this is prehash // foreach (ulong key in TrackedFiles[0x21]) { // if (!blendTreeSets.Contains(key)) continue; // STUAnimBlendTreeSet animBlendTreeSet = GetInstance<STUAnimBlendTreeSet>(key); // // if (animBlendTreeSet?.BlendTreeItems == null) continue; // foreach (STUAnimBlendTreeSet_BlendTreeItem blendTreeItem in animBlendTreeSet.BlendTreeItems) { // if (blendTreeItem.m_45C6E995 == null) continue; // STUAnimNode_Strafe8Way strafe8Way = GetInstance<STUAnimNode_Strafe8Way>(blendTreeItem.m_45C6E995); // if (strafe8Way != null) Debugger.Break(); // } // } }
public Dictionary <string, Hero> GetHeroes() { Dictionary <string, Hero> @return = new Dictionary <string, Hero>(); foreach (ulong key in TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(key); if (hero == null) { continue; } string name = GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(key):X}"; @return[name] = new Hero(key, hero); } return(@return); }
private void Init(STUHero hero, ulong key = default) { STU = hero; GUID = (teResourceGUID)key; Name = GetString(hero.m_0EDCE350); Description = GetDescriptionString(hero.m_3446F580); Class = GetNullableGUIDName(hero.m_category); Gender = hero.m_gender; Size = hero.m_heroSize; GalleryColor = hero.m_heroColor; Color = GalleryColor.ToHex(); sRGBColor = GalleryColor.ToNonLinear().ToHex(); SupportsAi = hero.m_906C3711 > 0; IsHero = hero.m_62746D34 > 0; if (hero.m_heroLoadout != null) { Loadouts = new List <LoadoutLite>(); foreach (teResourceGUID loadoutGUID in hero.m_heroLoadout) { var loadout = Loadout.GetLoadout(loadoutGUID); if (loadout == null) { continue; } Loadouts.Add(loadout.ToLite()); } } // Contains array of various hero images, hero gallery portraits, small hero select icons, etc. if (hero.m_8203BFE1 != null) { Images = new List <HeroImage>(); foreach (var imageSet in hero.m_8203BFE1) { Images.Add(new HeroImage { Id = imageSet.m_id, TextureGUID = imageSet.m_texture }); } } }
protected HighlightInfoJSON GetHighlightInfo(Highlight.HighlightInfoNew infoNew) { HighlightInfoJSON outputJson = new HighlightInfoJSON(); STUHero hero = GetInstance <STUHero>(infoNew.HeroMasterKey); outputJson.Hero = GetString(hero?.Name); outputJson.Player = infoNew.PlayerName; STUUnlock_HighlightIntro intro = GetInstance <STUUnlock_HighlightIntro>(infoNew.HighlightIntro); outputJson.HighlightIntro = GetString(intro.CosmeticName); // todo: outputJson.WeaponSkin // todo: outputJson.Skin STUHighlightType highlightType = GetInstance <STUHighlightType>(infoNew.HighlightType); outputJson.HighlightType = GetString(highlightType?.Name) ?? ""; return(outputJson); }
protected HeroInfoJSON GetHeroInfo(Common.HeroInfo heroInfo) { STUHero hero = GetInstance <STUHero>(heroInfo.HeroMasterKey); HeroInfoJSON outputHero = new HeroInfoJSON { Hero = GetString(hero.Name), Sprays = new List <string>(), Emotes = new List <string>(), VoiceLines = new List <string>() }; foreach (uint sprayId in heroInfo.SprayIds) { STUUnlock_Spray spray = GetInstance <STUUnlock_Spray>(GetCosmeticKey(sprayId)); outputHero.Sprays.Add(GetString(spray.CosmeticName)); } foreach (uint emoteId in heroInfo.EmoteIds) { STUUnlock_Emote emote = GetInstance <STUUnlock_Emote>(GetCosmeticKey(emoteId)); outputHero.Emotes.Add(GetString(emote.CosmeticName)); } foreach (uint voiceLineId in heroInfo.VoiceLineIds) { STUUnlock_VoiceLine voiceLine = GetInstance <STUUnlock_VoiceLine>(GetCosmeticKey(voiceLineId)); outputHero.VoiceLines.Add(GetString(voiceLine.CosmeticName)); } STUUnlock_HighlightIntro intro = GetInstance <STUUnlock_HighlightIntro>(GetCosmeticKey(heroInfo.HighlightIntro)); outputHero.HighlightIntro = GetString(intro.CosmeticName); // Skin skin = GetInstance<Skin>(GetSkinKey(heroInfo.SkinId)); // todo: this is by skin override // outputHero.Skin = GetString(skin?.CosmeticName); // Weapon weaponSkin = GetInstance<Weapon>(GetCosmeticKey(heroInfo.WeaponSkinId)); // todo: this is by weapon skin override // outputHero.WeaponSkin = GetString(weaponSkin?.CosmeticName); return(outputHero); }
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.Name) ?? $"Unknown{GUID.Index(heroFile)}").TrimEnd(' '); Log($"Processing data for {heroNameActual}"); Dictionary <string, ParsedArg> config = new Dictionary <string, ParsedArg>(); foreach (string key in new[] { heroNameActual.ToLowerInvariant(), "*" }) { if (!parsedTypes.ContainsKey(key)) { continue; } foreach (KeyValuePair <string, ParsedArg> parsedArg in parsedTypes[key]) { if (config.ContainsKey(parsedArg.Key)) { config[parsedArg.Key] = config[parsedArg.Key].Combine(parsedArg.Value); } else { config[parsedArg.Key] = parsedArg.Value.Combine(null); // clone for safety } } } if (config.Count == 0) { continue; } STUVoiceSetComponent baseComponent = default(STUVoiceSetComponent); Combo.ComboInfo baseInfo = default(Combo.ComboInfo); string heroFileName = GetValidFilename(heroNameActual); if (SaveSet(flags, basePath, hero.EntityMain, heroFileName, "Default", ref baseComponent, ref baseInfo)) { var unlocks = GetInstance <STUHeroUnlocks>(hero.LootboxUnlocks); if (unlocks == null) { continue; } bool npc = unlocks.LootboxUnlocks == null; var achievementUnlocks = GatherUnlocks(unlocks?.SystemUnlocks?.Unlocks?.Select(it => (ulong)it)).Where(item => item?.Unlock is STUUnlock_Skin).ToList(); foreach (ItemInfo itemInfo in achievementUnlocks) { if (itemInfo == null) { continue; } if ((itemInfo.Unlock as STUUnlock_Skin)?.LeagueTeam != 0) { continue; } SaveSkin(flags, (itemInfo.Unlock as STUUnlock_Skin)?.SkinResource, basePath, hero, heroFileName, itemInfo.Name, baseComponent, baseInfo); } if (npc) { foreach (STUHeroSkin skin in hero.Skins) { SaveSkin(flags, skin.SkinOverride, basePath, hero, heroFileName, GetFileName(skin.SkinOverride), baseComponent, baseInfo); } continue; } foreach (var defaultUnlocks in unlocks.Unlocks) { var dUnlocks = GatherUnlocks(defaultUnlocks.Unlocks.Select(it => (ulong)it)).Where(item => item?.Unlock is STUUnlock_Skin).ToList(); foreach (ItemInfo itemInfo in dUnlocks) { if (itemInfo == null) { continue; } if ((itemInfo.Unlock as STUUnlock_Skin)?.LeagueTeam != 0) { continue; } SaveSkin(flags, (itemInfo.Unlock as STUUnlock_Skin)?.SkinResource, basePath, hero, heroFileName, itemInfo.Name, baseComponent, baseInfo); } } foreach (var eventUnlocks in unlocks.LootboxUnlocks) { if (eventUnlocks?.Unlocks?.Unlocks == null) { continue; } var eUnlocks = eventUnlocks.Unlocks.Unlocks.Select(it => GatherUnlock(it)).Where(item => item?.Unlock is STUUnlock_Skin).ToList(); foreach (ItemInfo itemInfo in eUnlocks) { if (itemInfo == null) { continue; } if ((itemInfo.Unlock as STUUnlock_Skin)?.LeagueTeam != 0) { continue; } SaveSkin(flags, (itemInfo.Unlock as STUUnlock_Skin)?.SkinResource, basePath, hero, heroFileName, itemInfo.Name, baseComponent, baseInfo); } } } } }
public static void SaveUnlock(ICLIFlags flags, Unlock unlock, string path, string eventKey, Dictionary <string, ParsedArg> config, Dictionary <string, TagExpectedValue> tags, VoiceSet voiceSet, STUHero hero) { string rarity; if (tags != null) { if (unlock.STU.m_0B1BA7C1 == null) { rarity = unlock.Rarity.ToString(); tags["leagueTeam"] = new TagExpectedValue("none"); } else { TeamDefinition teamDef = new TeamDefinition(unlock.STU.m_0B1BA7C1); tags["leagueTeam"] = new TagExpectedValue(teamDef.Abbreviation, // NY teamDef.Location, // New York teamDef.Name, // Excelsior teamDef.FullName, // New York Excelsior (teamDef.Division == Enum_5A789F71.None && teamDef.Abbreviation == null) ? "none" : "*", "*"); // all // nice file structure rarity = ""; eventKey = "League"; } tags["rarity"] = new TagExpectedValue(unlock.Rarity.ToString()); tags["special"] = new TagExpectedValue(unlock.Tag ?? "none"); } else { rarity = ""; // for general unlocks } var eventMap = GetEventConfig(); if (unlock.STU.m_BEE9BCDA != null) { var formalEventKey = unlock.STU.m_BEE9BCDA.FirstOrDefault(x => eventMap.ContainsKey(x)); if (eventMap.ContainsKey(formalEventKey)) { eventKey = eventMap[formalEventKey]; } } string thisPath = Path.Combine(path, unlock.GetTypeNameEnum(), eventKey, rarity, GetValidFilename(unlock.GetName())); if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SprayPaint))) { SprayAndIcon.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_AvatarPortrait))) { SprayAndIcon.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_POTGAnimation))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Emote))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Pose))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_VoiceLine))) { VoiceLine.Save(flags, thisPath, unlock, voiceSet); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SkinTheme))) { SkinTheme.Save(flags, thisPath, unlock, hero); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_PortraitFrame))) { thisPath = Path.Combine(path, unlock.Type); PortraitFrame.Save(flags, thisPath, unlock); } }
public static void SaveUnlocks(ICLIFlags flags, Unlock[] unlocks, string path, string eventKey, Dictionary <string, ParsedArg> config, Dictionary <string, TagExpectedValue> tags, VoiceSet voiceSet, STUHero hero) { if (unlocks == null) { return; } foreach (Unlock unlock in unlocks) { SaveUnlock(flags, unlock, path, eventKey, config, tags, voiceSet, hero); } }
public void SaveItemInfo(ItemInfo itemInfo, string basePath, string heroFileName, ICLIFlags flags, STUHero hero, string eventKey, Dictionary <string, ParsedArg> config, Dictionary <string, TagExpectedValue> tags, List <ItemInfo> weaponSkins) { if (itemInfo?.Unlock == null) { return; } if (itemInfo.Unlock.LeagueTeam != null) { STULeagueTeam team = GetInstance <STULeagueTeam>(itemInfo.Unlock.LeagueTeam); tags["leagueTeam"] = new TagExpectedValue(GetString(team.Abbreviation), // NXL GetString(team.Location), // New York GetString(team.Name), // Excelsior $"{GetString(team.Location)} {GetString(team.Name)}", // New York Excelsior "*"); // all eventKey = "League"; itemInfo.Rarity = ""; } else { tags["leagueTeam"] = new TagExpectedValue("none"); } if (eventKey == "Achievement" && itemInfo.Type == "Skin") { itemInfo.Rarity = ""; } tags["rarity"] = new TagExpectedValue(itemInfo.Rarity); if (itemInfo.Type == "Spray" && config.ContainsKey("spray") && config["spray"].ShouldDo(itemInfo.Name, tags)) { SprayAndIcon.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "PlayerIcon" && config.ContainsKey("icon") && config["icon"].ShouldDo(itemInfo.Name, tags)) { SprayAndIcon.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "Skin" && config.ContainsKey("skin") && config["skin"].ShouldDo(itemInfo.Name, tags)) { Skin.Save(flags, $"{basePath}\\{RootDir}", hero, $"{eventKey}\\{itemInfo.Rarity}", itemInfo.Unlock as STUUnlock_Skin, weaponSkins, null, false); } if (itemInfo.Type == "Pose" && config.ContainsKey("victorypose") && config["victorypose"].ShouldDo(itemInfo.Name, tags)) { AnimationItem.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "HighlightIntro" && config.ContainsKey("highlightintro") && config["highlightintro"].ShouldDo(itemInfo.Name, tags)) { AnimationItem.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "Emote" && config.ContainsKey("emote") && config["emote"].ShouldDo(itemInfo.Name, tags)) { AnimationItem.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "VoiceLine" && config.ContainsKey("voiceline") && config["voiceline"].ShouldDo(itemInfo.Name, tags)) { VoiceLine.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo, hero); } }
public void ExtractHeroConvos(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; } string path = Path.Combine(basePath, Container); Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes = ParseQuery(flags, QueryTypes, QueryNameOverrides); if (parsedTypes == null) { return; } Dictionary <ulong, VoiceSet> allVoiceSets = new Dictionary <ulong, VoiceSet>(); foreach (var voiceSetGUID in Program.TrackedFiles[0x5F]) { STUVoiceSet set = GetInstance <STUVoiceSet>(voiceSetGUID); if (set?.m_voiceLineInstances == null) { continue; } allVoiceSets[voiceSetGUID] = new VoiceSet(set); } // Dictionary<uint, string> mapNames = new Dictionary<uint, string>(); // foreach (ulong mapGuid in Program.TrackedFiles[0x9F]) { // STUMapHeader mapHeader = GetInstance<STUMapHeader>(mapGuid); // if (mapHeader == null) continue; // // mapNames[teResourceGUID.Index(mapGuid)] = GetValidFilename(GetString(mapHeader.m_1C706502) ?? GetString(mapHeader.m_displayName)); // } Combo.ComboInfo comboInfo = new Combo.ComboInfo(); foreach (ulong heroGuid in Program.TrackedFiles[0x75]) { STUHero hero = GetInstance <STUHero>(heroGuid); if (hero == null) { continue; } STUVoiceSetComponent voiceSetComponent = GetInstance <STUVoiceSetComponent>(hero.m_gameplayEntity); if (voiceSetComponent?.m_voiceDefinition == null || !allVoiceSets.TryGetValue(voiceSetComponent.m_voiceDefinition, out var set)) { Debugger.Log(0, "DataTool.SaveLogic.Unlock.VoiceLine", "[DataTool.SaveLogic.Unlock.VoiceLine]: VoiceSet not found\r\n"); continue; } string heroNameActual = (GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(heroGuid)}").TrimEnd(' '); Dictionary <string, ParsedArg> config = GetQuery(parsedTypes, heroNameActual.ToLowerInvariant(), "*"); if (config.Count == 0) { continue; } Log($"Processing data for {heroNameActual}"); heroNameActual = GetValidFilename(heroNameActual); foreach (VoiceLineInstance lineInstance in set.VoiceLines.Values) { // if (lineInstance.STU.m_voiceLineRuntime.m_4FF98D41 != null) { // var cond = lineInstance.STU.m_voiceLineRuntime.m_4FF98D41; // // HandleCondition(flags, comboInfo, lineInstance, path, heroNameActual, cond, mapNames); // } if (lineInstance.VoiceConversation == 0) { continue; } STUVoiceConversation conversation = GetInstance <STUVoiceConversation>(lineInstance.VoiceConversation); if (conversation == null) { continue; // wtf, blizz pls } string convoDir = Path.Combine(path, heroNameActual, GetFileName(lineInstance.VoiceConversation)); foreach (STUVoiceConversationLine line in conversation.m_voiceConversationLine) { string linePath = Path.Combine(convoDir, line.m_B4D405A1.ToString()); foreach (VoiceSet voiceSet in allVoiceSets.Values) { if (voiceSet.VoiceLines.ContainsKey(line.m_lineGUID)) { VoiceLine.SaveVoiceLine(flags, voiceSet.VoiceLines[line.m_lineGUID], linePath, comboInfo); } } } } } }
public ProgressionUnlocks(STUHero hero) { var unlocks = STUHelper.GetInstance <STUProgressionUnlocks>(hero.m_heroProgression); Init(unlocks); }
public static void SaveItem(string basePath, string heroName, string containerName, string folderName, ICLIFlags flags, ItemInfo item, STUHero hero) { if (item == null) { return; } if (!(item.Unlock is STUUnlock_VoiceLine vl)) { return; } const string type = "VoiceLines"; string name = GetValidFilename(item.Name).Replace(".", ""); STUVoiceSetComponent soundSetComponentContainer = GetInstance <STUVoiceSetComponent>(hero.EntityMain); if (soundSetComponentContainer?.VoiceSet == null) { Debugger.Log(0, "DataTool.SaveLogic.Unlock.VoiceLine", "[DataTool.SaveLogic.Unlock.VoiceLine]: VoiceSet not found"); return; } FindLogic.Combo.ComboInfo info = new FindLogic.Combo.ComboInfo(); FindLogic.Combo.Find(info, soundSetComponentContainer.VoiceSet); FindLogic.Combo.VoiceSetInfo voiceSetInfo = info.VoiceSets[soundSetComponentContainer.VoiceSet]; List <FindLogic.Combo.VoiceLineInstanceInfo> voiceLineInstances = new List <FindLogic.Combo.VoiceLineInstanceInfo>(); using (Stream vlStream = OpenFile(vl.EffectResource)) { using (Chunked vlChunk = new Chunked(vlStream)) { foreach (SVCE svce in vlChunk.GetAllOfTypeFlat <SVCE>()) { if (svce == null) { continue; } if (voiceSetInfo.VoiceLineInstances.ContainsKey(svce.Data.VoiceStimulus)) { voiceLineInstances.AddRange(voiceSetInfo.VoiceLineInstances[svce.Data.VoiceStimulus]); } } } } string output = Path.Combine(basePath, containerName, heroName ?? "", type, folderName, name); Combo.SaveVoiceStimuli(flags, output, info, voiceLineInstances, false); }
public static void Save(ICLIFlags flags, string directory, STUSkinBase skin, STUHero hero) { Dictionary <ulong, ulong> replacements = GetReplacements(skin); LoudLog("\t\tFinding"); FindLogic.Combo.ComboInfo info = new FindLogic.Combo.ComboInfo(); FindLogic.Combo.Find(info, hero.m_gameplayEntity, replacements); info.SetEntityName(hero.m_gameplayEntity, "Gameplay3P"); FindLogic.Combo.Find(info, hero.m_previewEmoteEntity, replacements); info.SetEntityName(hero.m_previewEmoteEntity, "PreviewEmote"); FindLogic.Combo.Find(info, hero.m_322C521A, replacements); info.SetEntityName(hero.m_322C521A, "Showcase"); FindLogic.Combo.Find(info, hero.m_26D71549, replacements); info.SetEntityName(hero.m_26D71549, "HeroGallery"); FindLogic.Combo.Find(info, hero.m_8125713E, replacements); info.SetEntityName(hero.m_8125713E, "HighlightIntro"); if (skin is STUSkinTheme skinTheme) { info.Config.DoExistingEntities = true; foreach (var weaponOverrideGUID in skinTheme.m_heroWeapons) { STUHeroWeapon heroWeapon = GetInstance <STUHeroWeapon>(weaponOverrideGUID); if (heroWeapon == null) { continue; } Dictionary <ulong, ulong> weaponReplacements = GetReplacements(heroWeapon); SavePreviewWeapons(info, weaponReplacements, hero.m_previewWeaponEntities); SavePreviewWeapons(info, weaponReplacements, hero.m_C2FE396F); } info.Config.DoExistingEntities = false; } foreach (STU_1A496D3C tex in hero.m_8203BFE1) { FindLogic.Combo.Find(info, tex.m_texture, replacements); info.SetTextureName(tex.m_texture, teResourceGUID.AsString(tex.m_id)); } Combo.SaveLooseTextures(flags, Path.Combine(directory, "GUI"), info); if (replacements != null) { string soundDirectory = Path.Combine(directory, "Sound"); FindLogic.Combo.ComboInfo diffInfoBefore = new FindLogic.Combo.ComboInfo(); FindLogic.Combo.ComboInfo diffInfoAfter = new FindLogic.Combo.ComboInfo(); foreach (KeyValuePair <ulong, ulong> replacement in replacements) { uint diffReplacementType = teResourceGUID.Type(replacement.Value); if (diffReplacementType != 0x2C && diffReplacementType != 0x3F && diffReplacementType != 0xB2) { continue; // no voice sets, use extract-hero-voice } FindLogic.Combo.Find(diffInfoAfter, replacement.Value); FindLogic.Combo.Find(diffInfoBefore, replacement.Key); } foreach (KeyValuePair <ulong, FindLogic.Combo.VoiceSetInfo> voiceSet in diffInfoAfter.VoiceSets) { if (diffInfoBefore.VoiceSets.ContainsKey(voiceSet.Key)) { continue; } Combo.SaveVoiceSet(flags, soundDirectory, diffInfoAfter, voiceSet.Key); } foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileInfo> soundFile in diffInfoAfter.SoundFiles) { if (diffInfoBefore.SoundFiles.ContainsKey(soundFile.Key)) { continue; } Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfter, soundFile.Key, false); } foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileInfo> soundFile in diffInfoAfter.VoiceSoundFiles) { if (diffInfoBefore.VoiceSoundFiles.ContainsKey(soundFile.Key)) { continue; } Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfter, soundFile.Key, true); } } LoudLog("\t\tSaving"); Combo.Save(flags, directory, info); LoudLog("\t\tDone"); }
public static void SaveSkin(ICLIFlags flags, ulong skinResource, string basePath, STUHero hero, string heroFileName, string name, STUVoiceSetComponent baseComponent, Combo.ComboInfo baseInfo) { STUSkinOverride skin = GetInstance <STUSkinOverride>(skinResource); if (skin == null) { return; } STUVoiceSetComponent component = default(STUVoiceSetComponent); Combo.ComboInfo info = default(Combo.ComboInfo); if (SaveSet(flags, basePath, hero.EntityMain, heroFileName, GetValidFilename(name), ref component, ref info, baseComponent, baseInfo, skin.ProperReplacements)) { return; } }
public static void Save(ICLIFlags flags, string skinName, string basePath, STUHero hero, string rarity, STUSkinOverride skinOverride, List <ItemInfo> weaponSkins, List <STULoadout> abilities, bool quiet = true) { string heroName = GetString(hero.Name); string heroNamePath = GetValidFilename(heroName) ?? "Unknown"; heroNamePath = heroNamePath.TrimEnd(' '); string path = Path.Combine(basePath, $"{heroNamePath}\\Skins\\{rarity}\\{GetValidFilename(skinName)}"); Dictionary <uint, ItemInfo> realWeaponSkins = new Dictionary <uint, ItemInfo>(); if (weaponSkins != null) { foreach (ItemInfo weaponSkin in weaponSkins) { realWeaponSkins[((STUUnlock_Weapon)weaponSkin.Unlock).Index] = weaponSkin; } } Dictionary <ulong, ulong> replacements = skinOverride.ProperReplacements; LoudLog("\tFinding"); FindLogic.Combo.ComboInfo info = new FindLogic.Combo.ComboInfo(); FindLogic.Combo.Find(info, hero.EntityMain, replacements); FindLogic.Combo.Find(info, hero.EntityHeroSelect, replacements); FindLogic.Combo.Find(info, hero.EntityHighlightIntro, replacements); FindLogic.Combo.Find(info, hero.EntityPlayable, replacements); FindLogic.Combo.Find(info, hero.EntityThirdPerson, replacements); info.Config.DoExistingEntities = true; uint replacementIndex = 0; foreach (Common.STUGUID weaponOverrideGUID in skinOverride.Weapons) { STUHeroWeapon weaponOverride = GetInstance <STUHeroWeapon>(weaponOverrideGUID); if (weaponOverride == null) { continue; } string weaponSkinName = null; if (realWeaponSkins.ContainsKey(replacementIndex)) { weaponSkinName = GetValidFilename(GetString(realWeaponSkins[replacementIndex].Unlock.CosmeticName)); } Dictionary <ulong, ulong> weaponReplacements = weaponOverride.ProperReplacements?.ToDictionary(x => x.Key, y => y.Value) ?? new Dictionary <ulong, ulong>(); List <STUHeroWeaponEntity> weaponEntities = new List <STUHeroWeaponEntity>(); if (hero.WeaponComponents1 != null) { weaponEntities.AddRange(hero.WeaponComponents1); } if (hero.WeaponComponents2 != null) { weaponEntities.AddRange(hero.WeaponComponents2); } foreach (STUHeroWeaponEntity heroWeapon in weaponEntities) { FindLogic.Combo.Find(info, heroWeapon.Entity, weaponReplacements); STUModelComponent modelComponent = GetInstance <STUModelComponent>(heroWeapon.Entity); if (modelComponent?.Look == null || weaponSkinName == null) { continue; } ulong modelLook = FindLogic.Combo.GetReplacement(modelComponent.Look, weaponReplacements); if (!info.ModelLooks.ContainsKey(modelLook)) { continue; } FindLogic.Combo.ModelLookInfo modelLookInfo = info.ModelLooks[modelLook]; modelLookInfo.Name = weaponSkinName; } replacementIndex++; } info.Config.DoExistingEntities = false; foreach (Common.STUGUID guiImage in new[] { hero.ImageResource1, hero.ImageResource2, hero.ImageResource3, hero.ImageResource3, hero.ImageResource4, skinOverride.SkinImage, hero.SpectatorIcon }) { FindLogic.Combo.Find(info, guiImage, replacements); } Combo.SaveLooseTextures(flags, Path.Combine(path, "GUI"), info); info.SetEntityName(hero.EntityHeroSelect, $"{heroName}-HeroSelect"); info.SetEntityName(hero.EntityPlayable, $"{heroName}-Playable-ThirdPerson"); info.SetEntityName(hero.EntityThirdPerson, $"{heroName}-ThirdPerson"); info.SetEntityName(hero.EntityMain, $"{heroName}-Base"); info.SetEntityName(hero.EntityHighlightIntro, $"{heroName}-HighlightIntro"); string soundDirectory = Path.Combine(path, "Sound"); FindLogic.Combo.ComboInfo diffInfoBefore = new FindLogic.Combo.ComboInfo(); FindLogic.Combo.ComboInfo diffInfoAfter = new FindLogic.Combo.ComboInfo(); if (replacements != null) { foreach (KeyValuePair <ulong, ulong> replacement in replacements) { uint diffReplacementType = GUID.Type(replacement.Value); if (diffReplacementType != 0x2C && diffReplacementType != 0x5F && diffReplacementType != 0x3F && diffReplacementType != 0xB2) { continue; } FindLogic.Combo.Find(diffInfoAfter, replacement.Value); FindLogic.Combo.Find(diffInfoBefore, replacement.Key); } diffInfoAfter.SaveRuntimeData = new FindLogic.Combo.ComboSaveRuntimeData { Threads = false }; foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileInfo> soundFile in diffInfoAfter.SoundFiles) { if (diffInfoBefore.SoundFiles.ContainsKey(soundFile.Key)) { continue; } Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfter, soundFile.Key, false); } foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileInfo> soundFile in diffInfoAfter.VoiceSoundFiles) { if (diffInfoBefore.VoiceSoundFiles.ContainsKey(soundFile.Key)) { continue; } Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfter, soundFile.Key, true); } } LoudLog("\tSaving"); Combo.Save(flags, path, info); LoudLog("\tDone"); }