private static void RandomizeAudio(IMEPackage package, int topLevelUIndex, bool female) { var audioToChange = package.Exports.Where(x => x.idxLink == topLevelUIndex && x.ClassName == "WwiseStream").ToList(); var audioSources = MERFileSystem.LoadedFiles.Keys.Where(x => x.Contains("_LOC_INT", StringComparison.InvariantCultureIgnoreCase) && x.Contains("Bio")).ToList(); foreach (var aExp in audioToChange) { bool installed = false; while (!installed) { var rAudioSourceF = audioSources.RandomElement(); var rAudioSourceP = MEPackageHandler.OpenMEPackage(MERFileSystem.GetPackageFile(rAudioSourceF)); var audioOptions = rAudioSourceP.Exports.Where(x => x.ClassName == "WwiseStream").ToList(); if (!audioOptions.Any()) { continue; } var audioChoice = audioOptions.RandomElement(); // Repoint the TLK to match what's going to be said var nTlk = WwiseTools.ExtractTLKIdFromExportName(audioChoice); var oTlk = WwiseTools.ExtractTLKIdFromExportName(aExp); if (nTlk != -1 && oTlk != -1 && !string.IsNullOrWhiteSpace(TLKHandler.TLKLookupByLang(nTlk, "INT"))) { TLKHandler.ReplaceString(oTlk, TLKHandler.TLKLookupByLang(nTlk, "INT")); WwiseTools.RepointWwiseStream(audioChoice, aExp); installed = true; } } } }
public static bool UwuifyText(RandomizationOption option) { bool keepCasing = option.HasSubOptionSelected(RTexts.SUBOPTIONKEY_UWU_KEEPCASING); bool addReactions = option.HasSubOptionSelected(RTexts.SUBOPTIONKEY_REACTIONS_ENABLED); var existingTLK = TLKHandler.GetBuildingTLK(); var skipIDs = existingTLK.StringRefs.Select(x => x.StringID).ToList(); var MERTlks = TLKHandler.GetMERTLKs(); var nonMerTLKs = TLKHandler.GetAllTLKs().Where(x => !MERTlks.Contains(x)); option.ProgressValue = 0; option.ProgressMax = nonMerTLKs.Where(x => x.name.EndsWith(@"INT.tlk")).Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data))); option.ProgressMax += MERTlks.Where(x => x.name.EndsWith(@"INT.tlk")).Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data))); option.ProgressIndeterminate = false; // UwUify MER TLK first foreach (TalkFile tf in MERTlks) { UwuifyTalkFile(tf, keepCasing, addReactions, skipIDs, true, option); } // UwUify non MER TLK foreach (TalkFile tf in nonMerTLKs) { UwuifyTalkFile(tf, keepCasing, addReactions, skipIDs, false, option); } return(true); }
public Talent(ExportEntry powerClass, bool isEvolution = false) { PowerExport = powerClass; IsEvolution = isEvolution; var baseClass = powerClass; var baseClassObj = baseClass.GetDefaults().GetProperty <ObjectProperty>("EvolvedPowerClass1"); while (baseClassObj == null || baseClassObj.Value == 0) { baseClass = (ExportEntry)baseClass.SuperClass; baseClassObj = baseClass.GetDefaults().GetProperty <ObjectProperty>("EvolvedPowerClass1"); } BasePower = baseClass; if (BasePower.ObjectName.Name.Contains("Passive")) { IsPassive = true; } else { var baseName = baseClass.GetDefaults().GetProperty <NameProperty>("BaseName"); while (baseName == null) { baseClass = (ExportEntry)baseClass.SuperClass; baseName = baseClass.GetDefaults().GetProperty <NameProperty>("BaseName"); } BaseName = baseName.Value.Name; } // Setup name var superDefaults = PowerExport.GetDefaults(); var displayNameProps = superDefaults.GetProperties(); var superProps = displayNameProps; var displayName = superProps.GetProp <StringRefProperty>("DisplayName"); while (displayName == null) { superDefaults = ((superDefaults.Class as ExportEntry).SuperClass as ExportEntry).GetDefaults(); superProps = superDefaults.GetProperties(); superProps.GetProp <StringRefProperty>("DisplayName"); displayName = superProps.GetProp <StringRefProperty>("DisplayName"); } PowerName = TLKHandler.TLKLookupByLang(displayName.Value, "INT"); if (IsEvolution) { // Setup the blurb var blurbDesc = TLKHandler.TLKLookupByLang(displayNameProps.GetProp <StringRefProperty>("TalentDescription").Value, "INT").Split('\n')[0]; EvolvedBlurb = $"{PowerName}: {blurbDesc}"; } IsAmmoPower = PowerName.Contains("Ammo"); IsCombatPower = !IsAmmoPower && !IsPassive; }
public static bool RandomizeGameOverText(RandomizationOption arg) { string fileContents = MERUtilities.GetEmbeddedStaticFilesTextFile("gameovertexts.xml"); XElement rootElement = XElement.Parse(fileContents); var gameoverTexts = rootElement.Elements("gameovertext").Select(x => x.Value).ToList(); var gameOverText = gameoverTexts[ThreadSafeRandom.Next(gameoverTexts.Count)]; TLKHandler.ReplaceString(157152, gameOverText); return(true); }
private static void RandomizeVowelsInternal(TalkFile tf, List <int> skipIDs, Dictionary <char, char> translationMap, bool isMERTlk, RandomizationOption option) { var tfName = Path.GetFileNameWithoutExtension(tf.path); var langCode = tfName.Substring(tfName.LastIndexOf("_", StringComparison.InvariantCultureIgnoreCase) + 1); foreach (var sref in tf.StringRefs.Where(x => x.StringID > 0 && !string.IsNullOrWhiteSpace(x.Data)).ToList()) { option.IncrementProgressValue(); if (sref.Data.Contains("DLC_")) { continue; // Don't modify } if (!isMERTlk && skipIDs.Contains(sref.StringID)) { continue; // Do not randomize this version of the string as it's in the DLC version specifically } // See if strref has CUSTOMTOKEN or a control symbol List <int> skipRanges = new List <int>(); FindSkipRanges(sref, skipRanges); var newStr = sref.Data.ToArray(); for (int i = 0; i < sref.Data.Length; i++) // For every letter { // Skip any items we should not skip. if (skipRanges.Any() && skipRanges[0] == i) { i = skipRanges[1] - 1; // We subtract one as the next iteration of the loop will +1 it again, which then will make it read the 'next' character skipRanges.RemoveAt(0); // remove first 2 skipRanges.RemoveAt(0); // remove first 2 if (i >= sref.Data.Length - 1) { break; } continue; } if (translationMap.ContainsKey(newStr[i])) { // Remap the letter newStr[i] = translationMap[newStr[i]]; } else { // Do not change the letter. It might be something like <. } TLKHandler.ReplaceString(sref.StringID, new string(newStr), langCode); } } }
public static bool RandomizeIntroText(RandomizationOption arg) { string fileContents = MERUtilities.GetEmbeddedStaticFilesTextFile("openingcrawls.xml"); XElement rootElement = XElement.Parse(fileContents); var gameoverTexts = rootElement.Elements("CrawlText").Select(x => x.Value).ToList(); // The trim calls here will remove first and last lines that are blank. The TrimForIntro() will remove whitespace per line. TLKHandler.ReplaceString(331765, TrimForIntro(gameoverTexts.RandomElement().Trim())); TLKHandler.ReplaceString(263408, TrimForIntro(gameoverTexts.RandomElement().Trim())); TLKHandler.ReplaceString(348756, TrimForIntro(gameoverTexts.RandomElement().Trim())); TLKHandler.ReplaceString(391285, TrimForIntro(gameoverTexts.RandomElement().Trim())); // Genesis DLC uses this extra string for some reason return(true); }
private static void RandomizeFlyerSpawnPawns() { string[] files = { "BioD_EndGm2_420CombatZone.pcc", "BioD_EndGm2_430ReaperCombat.pcc" }; ChangeFlyersInFiles(files); // Install names TLKHandler.ReplaceString(7892160, "Indoctrinated Krogan"); //Garm update TLKHandler.ReplaceString(7892161, "Enthralled Batarian"); //Batarian Commando update //TLKHandler.ReplaceString(7892162, "Collected Human"); //Batarian Commando update }
private static int InstallName(int stringId = 0) { count++; if (PawnNameListInstanced.Any()) { var newPawnName = PawnNameListInstanced.PullFirstItem(); if (stringId == 0) { stringId = TLKHandler.GetNewTLKID(); } TLKHandler.ReplaceString(stringId, newPawnName); return(stringId); } return(0); // Not changed }
public static bool RandomizePsychProfiles(RandomizationOption option) { //Psych Profiles string fileContents = MERUtilities.GetEmbeddedStaticFilesTextFile("psychprofiles.xml"); XElement rootElement = XElement.Parse(fileContents); var childhoods = rootElement.Descendants("childhood").Where(x => x.Value != "").Select(x => (x.Attribute("name").Value, string.Join("\n", x.Value.Split('\n').Select(s => s.Trim())))).ToList(); var reputations = rootElement.Descendants("reputation").Where(x => x.Value != "").Select(x => (x.Attribute("name").Value, string.Join("\n", x.Value.Split('\n').Select(s => s.Trim())))).ToList(); childhoods.Shuffle(); reputations.Shuffle(); var backgroundTlkPairs = new List <(int nameId, int descriptionId)>(); backgroundTlkPairs.Add((45477, 34931)); //Spacer backgroundTlkPairs.Add((45508, 34940)); //Earthborn backgroundTlkPairs.Add((45478, 34971)); //Colonist foreach (var pair in backgroundTlkPairs) { var childHood = childhoods.PullFirstItem(); TLKHandler.ReplaceString(pair.nameId, childHood.Value); TLKHandler.ReplaceString(pair.descriptionId, childHood.Item2.Trim()); } backgroundTlkPairs.Clear(); backgroundTlkPairs.Add((45482, 34934)); //Sole Survivor backgroundTlkPairs.Add((45483, 34936)); //War Hero backgroundTlkPairs.Add((45484, 34938)); //Ruthless foreach (var pair in backgroundTlkPairs) { var reputation = reputations.PullFirstItem(); TLKHandler.ReplaceString(pair.nameId, reputation.Value); TLKHandler.ReplaceString(pair.descriptionId, reputation.Item2.Trim()); } return(true); }
/// <summary> /// Swap the vowels around. Optional hard mode allows swapping 2 consonants to make it extra difficult to read /// </summary> /// <param name="Tlks"></param> public static bool RandomizeVowels(RandomizationOption option) { // Map of what letter maps to what other letter MERLog.Information("Randomizing vowels in words"); var hardMode = option.HasSubOptionSelected(RTexts.SUBOPTIONKEY_VOWELS_HARDMODE); var existingTLK = TLKHandler.GetBuildingTLK(); var skipIDs = existingTLK.StringRefs.Select(x => x.StringID).ToList(); var MERTLKs = TLKHandler.GetMERTLKs(); Dictionary <char, char> vowels = null; List <char> vowelValues = null; bool retryMapping = true; while (retryMapping) { bool failed = false; vowels = GetVowelMap(); vowelValues = vowels.Values.ToList(); int numAttemptsRemaining = 10; foreach (var sourceVowel in vowels.Keys) { var value = vowelValues.RandomElement(); while (hardMode && value == sourceVowel && numAttemptsRemaining > 0) { value = vowelValues.RandomElement(); numAttemptsRemaining--; } if (numAttemptsRemaining == 0 && hardMode && value == sourceVowel) { // This attempt has failed MERLog.Warning(@"Hard mode vowel randomization failed, retrying"); failed = true; break; } vowelValues.Remove(value); // Do not allow reassignment of same vowel Debug.WriteLine($"Vowel Randomizer: {sourceVowel} -> {value}"); vowels[sourceVowel] = value; } if (!failed) { retryMapping = false; } } var consonants = GetConsonantMap(); if (hardMode) { // Swap some consontants around var numConsonantsToRandomize = 2; var consonantValues = consonants.Values.ToList(); while (numConsonantsToRandomize > 0) { var sourceValue = consonantValues.RandomElement(); var value = consonantValues.RandomElement(); while (sourceValue == value) { value = consonantValues.RandomElement(); } consonantValues.Remove(value); // Do not allow reassignment of same vowel consonantValues.Remove(sourceValue); // Do not allow reassignment of same vowel Debug.WriteLine($"Vowel Randomizer Hard Mode: {sourceValue} -> {value}"); consonants[sourceValue] = value; consonants[value] = sourceValue; numConsonantsToRandomize--; } } // Build full translation map (uppercase) var translationMapUC = new[] { vowels, consonants }.SelectMany(dict => dict) .ToDictionary(pair => pair.Key, pair => pair.Value); // Add lowercase translation var lowerCaseMap = translationMapUC.ToDictionary(x => char.ToLowerInvariant(x.Key), x => char.ToLowerInvariant(x.Value)); // Build a full translation var translationMap = new[] { translationMapUC, lowerCaseMap }.SelectMany(dict => dict) .ToDictionary(pair => pair.Key, pair => pair.Value); var nonMERTLKs = TLKHandler.GetAllTLKs().Where(x => !MERTLKs.Contains(x)).ToList(); // MER option.ProgressValue = 0; option.ProgressMax = nonMERTLKs.Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data))); option.ProgressMax += MERTLKs.Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data))); option.ProgressIndeterminate = false; foreach (var merTLK in MERTLKs) { RandomizeVowelsInternal(merTLK, skipIDs, translationMap, true, option); } // Non MER Parallel.ForEach(nonMERTLKs, tf => { RandomizeVowelsInternal(tf, skipIDs, translationMap, false, option); }); return(true); }
private static void UwuifyTalkFile(TalkFile tf, bool keepCasing, bool addReactions, List <int> skipIDs, bool isMERTlk, RandomizationOption option) { var tfName = Path.GetFileNameWithoutExtension(tf.path); var langCode = tfName.Substring(tfName.LastIndexOf("_", StringComparison.InvariantCultureIgnoreCase) + 1); if (langCode != "INT") { return; } foreach (var sref in tf.StringRefs.Where(x => x.StringID > 0 && !string.IsNullOrWhiteSpace(x.Data))) { option.IncrementProgressValue(); var strData = sref.Data; //strData = "New Game"; if (strData.Contains("DLC_")) { continue; // Don't modify } if (!isMERTlk && skipIDs.Contains(sref.StringID)) { continue; // Do not randomize this version of the string as it's in the DLC version specifically } //if (sref.StringID != 325648) // continue; // See if strref has CUSTOMTOKEN or a control symbol List <int> skipRanges = new List <int>(); FindSkipRanges(sref, skipRanges); // uwuify it StringBuilder sb = new StringBuilder(); char previousChar = (char)0x00; char currentChar; for (int i = 0; i < strData.Length; i++) { if (skipRanges.Any() && skipRanges[0] == i) { sb.Append(strData.Substring(skipRanges[0], skipRanges[1] - skipRanges[0])); previousChar = (char)0x00; i = skipRanges[1] - 1; // We subtract one as the next iteration of the loop will +1 it again, which then will make it read the 'next' character skipRanges.RemoveAt(0); // remove first 2 skipRanges.RemoveAt(0); // remove first 2 if (i >= strData.Length - 1) { break; } continue; } currentChar = strData[i]; if (currentChar == 'L' || currentChar == 'R') { sb.Append(keepCasing ? 'W' : 'w'); } else if (currentChar == 'l' || currentChar == 'r') { sb.Append('w'); if (ThreadSafeRandom.Next(5) == 0) { sb.Append('w'); // append another w 20% of the time if (ThreadSafeRandom.Next(8) == 0) { sb.Append('w'); // append another w 20% of the time } } } else if (currentChar == 'N' && (previousChar == 0x00 || previousChar == ' ')) { sb.Append(keepCasing ? "Nyaa" : "nyaa"); } else if (currentChar == 'O' || currentChar == 'o') { if (previousChar == 'N' || previousChar == 'n' || previousChar == 'M' || previousChar == 'm') { sb.Append("yo"); } else { sb.Append(keepCasing ? strData[i] : char.ToLower(strData[i])); } } else if (currentChar == '!' && !addReactions) { sb.Append(currentChar); if (ThreadSafeRandom.Next(2) == 0) { sb.Append(currentChar); // append another ! 50% of the time } } else { sb.Append(keepCasing ? strData[i] : char.ToLower(strData[i])); } previousChar = currentChar; } var str = sb.ToString(); if (addReactions) { str = AddReactionToLine(strData, str, keepCasing); } else { str = str.Replace("f**k", keepCasing ? "UwU" : "uwu", StringComparison.InvariantCultureIgnoreCase); } TLKHandler.ReplaceString(sref.StringID, str, langCode); } }